1 // Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 #include "SMESH_MeshEditor_i.hxx"
32 #include "SMDS_LinearEdge.hxx"
33 #include "SMDS_Mesh0DElement.hxx"
34 #include "SMDS_MeshFace.hxx"
35 #include "SMDS_MeshVolume.hxx"
36 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMESHDS_Group.hxx"
39 #include "SMESH_ControlsDef.hxx"
40 #include "SMESH_Filter_i.hxx"
41 #include "SMESH_Gen_i.hxx"
42 #include "SMESH_Group_i.hxx"
43 #include "SMESH_PythonDump.hxx"
44 #include "SMESH_subMeshEventListener.hxx"
45 #include "SMESH_subMesh_i.hxx"
47 #include "utilities.h"
48 #include "Utils_ExceptHandlers.hxx"
49 #include "Utils_CorbaException.hxx"
51 #include <BRepAdaptor_Surface.hxx>
52 #include <BRep_Tool.hxx>
53 #include <TopExp_Explorer.hxx>
55 #include <TopoDS_Edge.hxx>
56 #include <TopoDS_Face.hxx>
61 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
65 #include <Standard_Failure.hxx>
68 #include <Standard_ErrorHandler.hxx>
74 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
77 using SMESH::TPythonDump;
81 //=============================================================================
83 * \brief Mesh to apply modifications for preview purposes
85 //=============================================================================
87 struct TPreviewMesh: public SMESH_Mesh
89 SMDSAbs_ElementType myPreviewType; // type to show
91 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
92 _isShapeToMesh = (_id =_studyId =_idDoc = 0);
93 _myMeshDS = new SMESHDS_Mesh( _id, true );
94 myPreviewType = previewElements;
97 virtual ~TPreviewMesh() { delete _myMeshDS; }
98 //!< Copy a set of elements
99 void Copy(const TIDSortedElemSet & theElements,
100 TIDSortedElemSet& theCopyElements,
101 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
102 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
104 // loop on theIDsOfElements
105 TIDSortedElemSet::const_iterator eIt = theElements.begin();
106 for ( ; eIt != theElements.end(); ++eIt )
108 const SMDS_MeshElement* anElem = *eIt;
109 if ( !anElem ) continue;
110 SMDSAbs_ElementType type = anElem->GetType();
111 if ( type == theAvoidType ||
112 ( theSelectType != SMDSAbs_All && type != theSelectType ))
115 if ( const SMDS_MeshElement* anElemCopy = Copy( anElem ))
116 theCopyElements.insert( theCopyElements.end(), anElemCopy );
120 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
122 // copy element nodes
123 int anElemNbNodes = anElem->NbNodes();
124 vector< int > anElemNodesID( anElemNbNodes ) ;
125 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
126 for ( int i = 0; itElemNodes->more(); i++)
128 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
130 anElemNodesID[i] = anElemNode->GetID();
133 // creates a corresponding element on copied nodes
134 SMDS_MeshElement* anElemCopy = 0;
135 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
137 const SMDS_VtkVolume* ph =
138 dynamic_cast<const SMDS_VtkVolume*> (anElem);
140 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
141 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
144 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
151 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
153 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
154 anElemNode->GetID());
156 };// struct TPreviewMesh
158 static SMESH_NodeSearcher * theNodeSearcher = 0;
159 static SMESH_ElementSearcher * theElementSearcher = 0;
161 //=============================================================================
163 * \brief Deleter of theNodeSearcher at any compute event occured
165 //=============================================================================
167 struct TSearchersDeleter : public SMESH_subMeshEventListener
170 string myMeshPartIOR;
172 TSearchersDeleter(): SMESH_subMeshEventListener( false ), // won't be deleted by submesh
174 //!< Delete theNodeSearcher
177 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
178 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
180 typedef map < int, SMESH_subMesh * > TDependsOnMap;
181 //!< The meshod called by submesh: do my main job
182 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
183 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
185 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
187 Unset( sm->GetFather() );
190 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
191 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
193 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
200 myMeshPartIOR = meshPartIOR;
201 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
202 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
203 TDependsOnMap::const_iterator sm;
204 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
205 sm->second->SetEventListener( this, 0, sm->second );
209 //!< delete self from all submeshes
210 void Unset(SMESH_Mesh* mesh)
212 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
213 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
214 TDependsOnMap::const_iterator sm;
215 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
216 sm->second->DeleteEventListener( this );
221 } theSearchersDeleter;
223 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
225 TCollection_AsciiString typeStr;
226 switch ( theMirrorType ) {
227 case SMESH::SMESH_MeshEditor::POINT:
228 typeStr = "SMESH.SMESH_MeshEditor.POINT";
230 case SMESH::SMESH_MeshEditor::AXIS:
231 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
234 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
238 //================================================================================
240 * \brief function for conversion of long_array to TIDSortedElemSet
241 * \param IDs - array of IDs
242 * \param aMesh - mesh
243 * \param aMap - collection to fill
244 * \param aType - element type
246 //================================================================================
248 void arrayToSet(const SMESH::long_array & IDs,
249 const SMESHDS_Mesh* aMesh,
250 TIDSortedElemSet& aMap,
251 const SMDSAbs_ElementType aType = SMDSAbs_All )
253 for (int i=0; i<IDs.length(); i++) {
254 CORBA::Long ind = IDs[i];
255 const SMDS_MeshElement * elem =
256 (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
257 if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
261 //================================================================================
263 * \brief Retrieve elements of given type from SMESH_IDSource
265 //================================================================================
267 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
268 const SMESHDS_Mesh* theMeshDS,
269 TIDSortedElemSet& theElemSet,
270 const SMDSAbs_ElementType theType,
271 const bool emptyIfIsMesh=false)
274 if ( CORBA::is_nil( theIDSource ) )
276 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
279 SMESH::long_array_var anIDs = theIDSource->GetIDs();
280 if ( anIDs->length() == 0 )
282 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
283 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
285 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
286 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
292 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
296 //================================================================================
298 * \brief Retrieve nodes from SMESH_IDSource
300 //================================================================================
302 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
303 const SMESHDS_Mesh* theMeshDS,
304 TIDSortedNodeSet& theNodeSet)
307 if ( CORBA::is_nil( theObject ) )
309 SMESH::array_of_ElementType_var types = theObject->GetTypes();
310 SMESH::long_array_var aElementsId = theObject->GetIDs();
311 if ( types->length() == 1 && types[0] == SMESH::NODE)
313 for(int i = 0; i < aElementsId->length(); i++)
314 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
315 theNodeSet.insert( theNodeSet.end(), n);
317 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
319 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
320 while ( nIt->more( ))
321 if( const SMDS_MeshElement * elem = nIt->next() )
322 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
326 for(int i = 0; i < aElementsId->length(); i++)
327 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
328 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
332 //================================================================================
334 * \brief Returns elements connected to the given elements
336 //================================================================================
338 void getElementsAround(const TIDSortedElemSet& theElements,
339 const SMESHDS_Mesh* theMeshDS,
340 TIDSortedElemSet& theElementsAround)
342 if ( theElements.empty() ) return;
344 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
345 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
347 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
348 return; // all the elements are in theElements
351 elemType = SMDSAbs_All;
353 TIDSortedElemSet visitedNodes;
354 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
355 for ( ; elemIt != theElements.end(); ++elemIt )
357 const SMDS_MeshElement* e = *elemIt;
358 int i = e->NbCornerNodes();
361 const SMDS_MeshNode* n = e->GetNode( i );
362 if ( visitedNodes.insert( n ).second )
364 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
365 while ( invIt->more() )
367 const SMDS_MeshElement* elemAround = invIt->next();
368 if ( !theElements.count( elemAround ))
369 theElementsAround.insert( elemAround );
377 //=============================================================================
381 //=============================================================================
383 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview)
386 myMesh = & theMesh->GetImpl();
387 myPreviewMode = isPreview;
390 //================================================================================
394 //================================================================================
396 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
400 //================================================================================
402 * \brief Clear members
404 //================================================================================
406 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
408 if ( myPreviewMode ) {
409 myPreviewData = new SMESH::MeshPreviewStruct();
412 myLastCreatedElems = new SMESH::long_array();
413 myLastCreatedNodes = new SMESH::long_array();
414 if ( deleteSearchers )
415 TSearchersDeleter::Delete();
419 //=======================================================================
420 //function : MakeIDSource
421 //purpose : Wrap a sequence of ids in a SMESH_IDSource
422 //=======================================================================
424 struct _IDSource : public POA_SMESH::SMESH_IDSource
426 SMESH::long_array _ids;
427 SMESH::ElementType _type;
428 SMESH::SMESH_Mesh_ptr _mesh;
429 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
430 SMESH::long_array* GetMeshInfo() { return 0; }
431 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
432 SMESH::array_of_ElementType* GetTypes()
434 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
435 if ( _ids.length() > 0 ) {
439 return types._retn();
443 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
444 SMESH::ElementType type)
446 _IDSource* anIDSource = new _IDSource;
447 anIDSource->_ids = ids;
448 anIDSource->_type = type;
449 anIDSource->_mesh = myMesh_i->_this();
450 SMESH::SMESH_IDSource_var anIDSourceVar = anIDSource->_this();
452 return anIDSourceVar._retn();
455 //=============================================================================
459 //=============================================================================
462 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
466 ::SMESH_MeshEditor anEditor( myMesh );
469 for (int i = 0; i < IDsOfElements.length(); i++)
470 IdList.push_back( IDsOfElements[i] );
472 // Update Python script
473 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
476 bool ret = anEditor.Remove( IdList, false );
477 myMesh->GetMeshDS()->Modified();
478 if ( IDsOfElements.length() )
479 myMesh->SetIsModified( true ); // issue 0020693
483 //=============================================================================
487 //=============================================================================
489 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
493 ::SMESH_MeshEditor anEditor( myMesh );
495 for (int i = 0; i < IDsOfNodes.length(); i++)
496 IdList.push_back( IDsOfNodes[i] );
498 // Update Python script
499 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
501 bool ret = anEditor.Remove( IdList, true );
502 myMesh->GetMeshDS()->Modified();
503 if ( IDsOfNodes.length() )
504 myMesh->SetIsModified( true ); // issue 0020693
508 //=============================================================================
512 //=============================================================================
514 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
518 ::SMESH_MeshEditor anEditor( myMesh );
520 // Update Python script
521 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
523 // Create filter to find all orphan nodes
524 SMESH::Controls::Filter::TIdSequence seq;
525 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
526 SMESH::Controls::Filter::GetElementsId( GetMeshDS(), predicate, seq );
528 // remove orphan nodes (if there are any)
530 for ( int i = 0; i < seq.size(); i++ )
531 IdList.push_back( seq[i] );
533 bool ret = anEditor.Remove( IdList, true );
534 myMesh->GetMeshDS()->Modified();
536 myMesh->SetIsModified( true );
541 //=============================================================================
545 //=============================================================================
547 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
548 CORBA::Double y, CORBA::Double z)
552 const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
554 // Update Python script
555 TPythonDump() << "nodeID = " << this << ".AddNode( "
556 << x << ", " << y << ", " << z << " )";
558 myMesh->GetMeshDS()->Modified();
559 myMesh->SetIsModified( true ); // issue 0020693
563 //=============================================================================
567 //=============================================================================
568 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
572 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
573 SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode);
575 // Update Python script
576 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
578 myMesh->GetMeshDS()->Modified();
579 myMesh->SetIsModified( true ); // issue 0020693
582 return elem->GetID();
587 //=============================================================================
591 //=============================================================================
593 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
597 int NbNodes = IDsOfNodes.length();
598 SMDS_MeshElement* elem = 0;
601 CORBA::Long index1 = IDsOfNodes[0];
602 CORBA::Long index2 = IDsOfNodes[1];
603 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
605 // Update Python script
606 TPythonDump() << "edge = " << this << ".AddEdge([ "
607 << index1 << ", " << index2 <<" ])";
610 CORBA::Long n1 = IDsOfNodes[0];
611 CORBA::Long n2 = IDsOfNodes[1];
612 CORBA::Long n12 = IDsOfNodes[2];
613 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
614 GetMeshDS()->FindNode(n2),
615 GetMeshDS()->FindNode(n12));
616 // Update Python script
617 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
618 <<n1<<", "<<n2<<", "<<n12<<" ])";
621 myMesh->GetMeshDS()->Modified();
623 return myMesh->SetIsModified( true ), elem->GetID();
628 //=============================================================================
632 //=============================================================================
634 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
638 int NbNodes = IDsOfNodes.length();
644 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
645 for (int i = 0; i < NbNodes; i++)
646 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
648 SMDS_MeshElement* elem = 0;
650 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
652 else if (NbNodes == 4) {
653 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
655 else if (NbNodes == 6) {
656 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
659 else if (NbNodes == 8) {
660 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
661 nodes[4], nodes[5], nodes[6], nodes[7]);
663 else if (NbNodes > 2) {
664 elem = GetMeshDS()->AddPolygonalFace(nodes);
667 // Update Python script
668 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
670 myMesh->GetMeshDS()->Modified();
672 return myMesh->SetIsModified( true ), elem->GetID();
677 //=============================================================================
681 //=============================================================================
682 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
686 int NbNodes = IDsOfNodes.length();
687 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
688 for (int i = 0; i < NbNodes; i++)
689 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
691 const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
693 // Update Python script
694 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
696 myMesh->GetMeshDS()->Modified();
697 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
700 //=============================================================================
704 //=============================================================================
706 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
710 int NbNodes = IDsOfNodes.length();
711 vector< const SMDS_MeshNode*> n(NbNodes);
712 for(int i=0;i<NbNodes;i++)
713 n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
715 SMDS_MeshElement* elem = 0;
718 case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
719 case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
720 case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
721 case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
722 case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
723 n[6],n[7],n[8],n[9]);
725 case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
726 n[7],n[8],n[9],n[10],n[11],n[12]);
728 case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
729 n[9],n[10],n[11],n[12],n[13],n[14]);
731 case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
732 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
733 n[15],n[16],n[17],n[18],n[19]);
737 // Update Python script
738 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
740 myMesh->GetMeshDS()->Modified();
742 return myMesh->SetIsModified( true ), elem->GetID();
747 //=============================================================================
749 * AddPolyhedralVolume
751 //=============================================================================
752 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
753 const SMESH::long_array & Quantities)
757 int NbNodes = IDsOfNodes.length();
758 std::vector<const SMDS_MeshNode*> n (NbNodes);
759 for (int i = 0; i < NbNodes; i++)
761 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
762 if (!aNode) return 0;
766 int NbFaces = Quantities.length();
767 std::vector<int> q (NbFaces);
768 for (int j = 0; j < NbFaces; j++)
769 q[j] = Quantities[j];
771 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
773 // Update Python script
774 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
775 << IDsOfNodes << ", " << Quantities << " )";
776 myMesh->GetMeshDS()->Modified();
778 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
781 //=============================================================================
783 * AddPolyhedralVolumeByFaces
785 //=============================================================================
786 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
790 int NbFaces = IdsOfFaces.length();
791 std::vector<const SMDS_MeshNode*> poly_nodes;
792 std::vector<int> quantities (NbFaces);
794 for (int i = 0; i < NbFaces; i++) {
795 const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
796 quantities[i] = aFace->NbNodes();
798 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
800 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
804 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
806 // Update Python script
807 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
808 << IdsOfFaces << " )";
809 myMesh->GetMeshDS()->Modified();
811 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
814 //=============================================================================
816 * \brief Bind a node to a vertex
817 * \param NodeID - node ID
818 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
819 * \retval boolean - false if NodeID or VertexID is invalid
821 //=============================================================================
823 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
824 throw (SALOME::SALOME_Exception)
826 Unexpect aCatch(SALOME_SalomeException);
828 SMESHDS_Mesh * mesh = GetMeshDS();
829 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
831 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
833 if ( mesh->MaxShapeIndex() < VertexID )
834 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
836 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
837 if ( shape.ShapeType() != TopAbs_VERTEX )
838 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
840 mesh->SetNodeOnVertex( node, VertexID );
842 myMesh->SetIsModified( true );
845 //=============================================================================
847 * \brief Store node position on an edge
848 * \param NodeID - node ID
849 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
850 * \param paramOnEdge - parameter on edge where the node is located
851 * \retval boolean - false if any parameter is invalid
853 //=============================================================================
855 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
856 CORBA::Double paramOnEdge)
857 throw (SALOME::SALOME_Exception)
859 Unexpect aCatch(SALOME_SalomeException);
861 SMESHDS_Mesh * mesh = GetMeshDS();
862 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
864 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
866 if ( mesh->MaxShapeIndex() < EdgeID )
867 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
869 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
870 if ( shape.ShapeType() != TopAbs_EDGE )
871 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
874 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
875 if ( paramOnEdge < f || paramOnEdge > l )
876 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
878 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
880 myMesh->SetIsModified( true );
883 //=============================================================================
885 * \brief Store node position on a face
886 * \param NodeID - node ID
887 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
888 * \param u - U parameter on face where the node is located
889 * \param v - V parameter on face where the node is located
890 * \retval boolean - false if any parameter is invalid
892 //=============================================================================
894 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
895 CORBA::Double u, CORBA::Double v)
896 throw (SALOME::SALOME_Exception)
898 Unexpect aCatch(SALOME_SalomeException);
900 SMESHDS_Mesh * mesh = GetMeshDS();
901 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
903 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
905 if ( mesh->MaxShapeIndex() < FaceID )
906 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
908 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
909 if ( shape.ShapeType() != TopAbs_FACE )
910 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
912 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
913 bool isOut = ( u < surf.FirstUParameter() ||
914 u > surf.LastUParameter() ||
915 v < surf.FirstVParameter() ||
916 v > surf.LastVParameter() );
920 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
921 << " u( " << surf.FirstUParameter()
922 << "," << surf.LastUParameter()
923 << ") v( " << surf.FirstVParameter()
924 << "," << surf.LastVParameter() << ")" );
926 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
929 mesh->SetNodeOnFace( node, FaceID, u, v );
930 myMesh->SetIsModified( true );
933 //=============================================================================
935 * \brief Bind a node to a solid
936 * \param NodeID - node ID
937 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
938 * \retval boolean - false if NodeID or SolidID is invalid
940 //=============================================================================
942 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
943 throw (SALOME::SALOME_Exception)
945 Unexpect aCatch(SALOME_SalomeException);
947 SMESHDS_Mesh * mesh = GetMeshDS();
948 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
950 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
952 if ( mesh->MaxShapeIndex() < SolidID )
953 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
955 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
956 if ( shape.ShapeType() != TopAbs_SOLID &&
957 shape.ShapeType() != TopAbs_SHELL)
958 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
960 mesh->SetNodeInVolume( node, SolidID );
962 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
965 //=============================================================================
967 * \brief Bind an element to a shape
968 * \param ElementID - element ID
969 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
970 * \retval boolean - false if ElementID or ShapeID is invalid
972 //=============================================================================
974 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
976 throw (SALOME::SALOME_Exception)
978 Unexpect aCatch(SALOME_SalomeException);
980 SMESHDS_Mesh * mesh = GetMeshDS();
981 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
983 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
985 if ( mesh->MaxShapeIndex() < ShapeID )
986 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
988 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
989 if ( shape.ShapeType() != TopAbs_EDGE &&
990 shape.ShapeType() != TopAbs_FACE &&
991 shape.ShapeType() != TopAbs_SOLID &&
992 shape.ShapeType() != TopAbs_SHELL )
993 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
995 mesh->SetMeshElementOnShape( elem, ShapeID );
997 myMesh->SetIsModified( true );
1000 //=============================================================================
1004 //=============================================================================
1006 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1007 CORBA::Long NodeID2)
1011 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1012 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1016 // Update Python script
1017 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1018 << NodeID1 << ", " << NodeID2 << " )";
1021 ::SMESH_MeshEditor aMeshEditor( myMesh );
1022 int ret = aMeshEditor.InverseDiag ( n1, n2 );
1023 myMesh->GetMeshDS()->Modified();
1024 myMesh->SetIsModified( true );
1028 //=============================================================================
1032 //=============================================================================
1034 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1035 CORBA::Long NodeID2)
1039 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1040 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1044 // Update Python script
1045 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1046 << NodeID1 << ", " << NodeID2 << " )";
1048 ::SMESH_MeshEditor aMeshEditor( myMesh );
1050 bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
1052 myMesh->GetMeshDS()->Modified();
1054 myMesh->SetIsModified( true ); // issue 0020693
1056 storeResult(aMeshEditor);
1061 //=============================================================================
1065 //=============================================================================
1067 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1071 ::SMESH_MeshEditor anEditor( myMesh );
1072 for (int i = 0; i < IDsOfElements.length(); i++)
1074 CORBA::Long index = IDsOfElements[i];
1075 const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
1077 anEditor.Reorient( elem );
1079 // Update Python script
1080 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1082 myMesh->GetMeshDS()->Modified();
1083 if ( IDsOfElements.length() )
1084 myMesh->SetIsModified( true ); // issue 0020693
1090 //=============================================================================
1094 //=============================================================================
1096 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1100 TPythonDump aTPythonDump; // suppress dump in Reorient()
1102 SMESH::long_array_var anElementsId = theObject->GetIDs();
1103 CORBA::Boolean isDone = Reorient(anElementsId);
1105 // Update Python script
1106 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1111 //=============================================================================
1115 //=============================================================================
1116 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1117 SMESH::NumericalFunctor_ptr Criterion,
1118 CORBA::Double MaxAngle)
1122 SMESHDS_Mesh* aMesh = GetMeshDS();
1123 TIDSortedElemSet faces;
1124 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1126 SMESH::NumericalFunctor_i* aNumericalFunctor =
1127 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1128 SMESH::Controls::NumericalFunctorPtr aCrit;
1129 if ( !aNumericalFunctor )
1130 aCrit.reset( new SMESH::Controls::AspectRatio() );
1132 aCrit = aNumericalFunctor->GetNumericalFunctor();
1134 // Update Python script
1135 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1136 << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1138 ::SMESH_MeshEditor anEditor( myMesh );
1140 bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
1141 myMesh->GetMeshDS()->Modified();
1143 myMesh->SetIsModified( true ); // issue 0020693
1145 storeResult(anEditor);
1151 //=============================================================================
1155 //=============================================================================
1156 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1157 SMESH::NumericalFunctor_ptr Criterion,
1158 CORBA::Double MaxAngle)
1162 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1163 SMESH::long_array_var anElementsId = theObject->GetIDs();
1164 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1166 SMESH::NumericalFunctor_i* aNumericalFunctor =
1167 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1169 // Update Python script
1170 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1171 << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1177 //=============================================================================
1181 //=============================================================================
1182 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1183 SMESH::NumericalFunctor_ptr Criterion)
1187 SMESHDS_Mesh* aMesh = GetMeshDS();
1188 TIDSortedElemSet faces;
1189 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1191 SMESH::NumericalFunctor_i* aNumericalFunctor =
1192 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1193 SMESH::Controls::NumericalFunctorPtr aCrit;
1194 if ( !aNumericalFunctor )
1195 aCrit.reset( new SMESH::Controls::AspectRatio() );
1197 aCrit = aNumericalFunctor->GetNumericalFunctor();
1200 // Update Python script
1201 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1203 ::SMESH_MeshEditor anEditor( myMesh );
1204 CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
1205 myMesh->GetMeshDS()->Modified();
1207 myMesh->SetIsModified( true ); // issue 0020693
1209 storeResult(anEditor);
1215 //=============================================================================
1219 //=============================================================================
1220 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1221 SMESH::NumericalFunctor_ptr Criterion)
1225 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1227 SMESH::long_array_var anElementsId = theObject->GetIDs();
1228 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1230 SMESH::NumericalFunctor_i* aNumericalFunctor =
1231 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1233 // Update Python script
1234 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1240 //=============================================================================
1244 //=============================================================================
1245 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1246 CORBA::Boolean Diag13)
1250 SMESHDS_Mesh* aMesh = GetMeshDS();
1251 TIDSortedElemSet faces;
1252 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1254 // Update Python script
1255 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1256 << IDsOfElements << ", " << Diag13 << " )";
1258 ::SMESH_MeshEditor anEditor( myMesh );
1259 CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
1260 myMesh->GetMeshDS()->Modified();
1262 myMesh->SetIsModified( true ); // issue 0020693
1265 storeResult(anEditor);
1271 //=============================================================================
1275 //=============================================================================
1276 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1277 CORBA::Boolean Diag13)
1281 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1283 SMESH::long_array_var anElementsId = theObject->GetIDs();
1284 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1286 // Update Python script
1287 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1288 << theObject << ", " << Diag13 << " )";
1294 //=============================================================================
1298 //=============================================================================
1299 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1300 SMESH::NumericalFunctor_ptr Criterion)
1304 const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1305 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1307 SMESH::NumericalFunctor_i* aNumericalFunctor =
1308 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1309 SMESH::Controls::NumericalFunctorPtr aCrit;
1310 if (aNumericalFunctor)
1311 aCrit = aNumericalFunctor->GetNumericalFunctor();
1313 aCrit.reset(new SMESH::Controls::AspectRatio());
1315 ::SMESH_MeshEditor anEditor (myMesh);
1316 return anEditor.BestSplit(quad, aCrit);
1321 //================================================================================
1323 * \brief Split volumic elements into tetrahedrons
1325 //================================================================================
1327 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1328 CORBA::Short methodFlags)
1329 throw (SALOME::SALOME_Exception)
1331 Unexpect aCatch(SALOME_SalomeException);
1335 SMESH::long_array_var anElementsId = elems->GetIDs();
1336 TIDSortedElemSet elemSet;
1337 arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume );
1339 ::SMESH_MeshEditor anEditor (myMesh);
1340 anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1341 myMesh->GetMeshDS()->Modified();
1343 storeResult(anEditor);
1345 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1346 // myMesh->SetIsModified( true ); // issue 0020693
1348 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1349 << elems << ", " << methodFlags << " )";
1352 //=======================================================================
1355 //=======================================================================
1358 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1359 const SMESH::long_array & IDsOfFixedNodes,
1360 CORBA::Long MaxNbOfIterations,
1361 CORBA::Double MaxAspectRatio,
1362 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1364 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1365 MaxAspectRatio, Method, false );
1369 //=======================================================================
1370 //function : SmoothParametric
1372 //=======================================================================
1375 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1376 const SMESH::long_array & IDsOfFixedNodes,
1377 CORBA::Long MaxNbOfIterations,
1378 CORBA::Double MaxAspectRatio,
1379 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1381 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1382 MaxAspectRatio, Method, true );
1386 //=======================================================================
1387 //function : SmoothObject
1389 //=======================================================================
1392 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1393 const SMESH::long_array & IDsOfFixedNodes,
1394 CORBA::Long MaxNbOfIterations,
1395 CORBA::Double MaxAspectRatio,
1396 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1398 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1399 MaxAspectRatio, Method, false);
1403 //=======================================================================
1404 //function : SmoothParametricObject
1406 //=======================================================================
1409 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1410 const SMESH::long_array & IDsOfFixedNodes,
1411 CORBA::Long MaxNbOfIterations,
1412 CORBA::Double MaxAspectRatio,
1413 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1415 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1416 MaxAspectRatio, Method, true);
1420 //=============================================================================
1424 //=============================================================================
1427 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1428 const SMESH::long_array & IDsOfFixedNodes,
1429 CORBA::Long MaxNbOfIterations,
1430 CORBA::Double MaxAspectRatio,
1431 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1436 SMESHDS_Mesh* aMesh = GetMeshDS();
1438 TIDSortedElemSet elements;
1439 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1441 set<const SMDS_MeshNode*> fixedNodes;
1442 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1443 CORBA::Long index = IDsOfFixedNodes[i];
1444 const SMDS_MeshNode * node = aMesh->FindNode(index);
1446 fixedNodes.insert( node );
1448 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1449 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1450 method = ::SMESH_MeshEditor::CENTROIDAL;
1452 ::SMESH_MeshEditor anEditor( myMesh );
1453 anEditor.Smooth(elements, fixedNodes, method,
1454 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1456 myMesh->GetMeshDS()->Modified();
1457 myMesh->SetIsModified( true ); // issue 0020693
1459 storeResult(anEditor);
1461 // Update Python script
1462 TPythonDump() << "isDone = " << this << "."
1463 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1464 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1465 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1466 << "SMESH.SMESH_MeshEditor."
1467 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1468 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1474 //=============================================================================
1478 //=============================================================================
1481 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1482 const SMESH::long_array & IDsOfFixedNodes,
1483 CORBA::Long MaxNbOfIterations,
1484 CORBA::Double MaxAspectRatio,
1485 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1490 TPythonDump aTPythonDump; // suppress dump in smooth()
1492 SMESH::long_array_var anElementsId = theObject->GetIDs();
1493 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1494 MaxAspectRatio, Method, IsParametric);
1496 // Update Python script
1497 aTPythonDump << "isDone = " << this << "."
1498 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1499 << theObject << ", " << IDsOfFixedNodes << ", "
1500 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1501 << "SMESH.SMESH_MeshEditor."
1502 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1503 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1509 //=============================================================================
1513 //=============================================================================
1515 void SMESH_MeshEditor_i::RenumberNodes()
1517 // Update Python script
1518 TPythonDump() << this << ".RenumberNodes()";
1520 GetMeshDS()->Renumber( true );
1524 //=============================================================================
1528 //=============================================================================
1530 void SMESH_MeshEditor_i::RenumberElements()
1532 // Update Python script
1533 TPythonDump() << this << ".RenumberElements()";
1535 GetMeshDS()->Renumber( false );
1538 //=======================================================================
1540 * \brief Return groups by their IDs
1542 //=======================================================================
1544 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1548 myMesh_i->CreateGroupServants();
1549 return myMesh_i->GetGroups( *groupIDs );
1552 //=======================================================================
1553 //function : rotationSweep
1555 //=======================================================================
1557 SMESH::ListOfGroups*
1558 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1559 const SMESH::AxisStruct & theAxis,
1560 CORBA::Double theAngleInRadians,
1561 CORBA::Long theNbOfSteps,
1562 CORBA::Double theTolerance,
1563 const bool theMakeGroups,
1564 const SMDSAbs_ElementType theElementType)
1568 TIDSortedElemSet inElements, copyElements;
1569 arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
1571 TIDSortedElemSet* workElements = & inElements;
1572 TPreviewMesh tmpMesh( SMDSAbs_Face );
1573 SMESH_Mesh* mesh = 0;
1574 bool makeWalls=true;
1575 if ( myPreviewMode )
1577 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1578 tmpMesh.Copy( inElements, copyElements, select, avoid );
1580 workElements = & copyElements;
1581 //makeWalls = false;
1588 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
1589 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1591 ::SMESH_MeshEditor anEditor( mesh );
1592 ::SMESH_MeshEditor::PGroupIDs groupIds =
1593 anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1594 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
1595 storeResult(anEditor);
1596 myMesh->GetMeshDS()->Modified();
1598 // myMesh->SetIsModified( true ); -- it does not influence Compute()
1600 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1603 //=======================================================================
1604 //function : RotationSweep
1606 //=======================================================================
1608 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1609 const SMESH::AxisStruct & theAxis,
1610 CORBA::Double theAngleInRadians,
1611 CORBA::Long theNbOfSteps,
1612 CORBA::Double theTolerance)
1614 if ( !myPreviewMode ) {
1615 TPythonDump() << this << ".RotationSweep( "
1616 << theIDsOfElements << ", "
1618 << theAngleInRadians << ", "
1619 << theNbOfSteps << ", "
1620 << theTolerance << " )";
1622 rotationSweep(theIDsOfElements,
1630 //=======================================================================
1631 //function : RotationSweepMakeGroups
1633 //=======================================================================
1635 SMESH::ListOfGroups*
1636 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1637 const SMESH::AxisStruct& theAxis,
1638 CORBA::Double theAngleInRadians,
1639 CORBA::Long theNbOfSteps,
1640 CORBA::Double theTolerance)
1642 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1644 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
1650 if (!myPreviewMode) {
1651 DumpGroupsList(aPythonDump, aGroups);
1652 aPythonDump << this << ".RotationSweepMakeGroups( "
1653 << theIDsOfElements << ", "
1655 << theAngleInRadians << ", "
1656 << theNbOfSteps << ", "
1657 << theTolerance << " )";
1662 //=======================================================================
1663 //function : RotationSweepObject
1665 //=======================================================================
1667 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1668 const SMESH::AxisStruct & theAxis,
1669 CORBA::Double theAngleInRadians,
1670 CORBA::Long theNbOfSteps,
1671 CORBA::Double theTolerance)
1673 if ( !myPreviewMode ) {
1674 TPythonDump() << this << ".RotationSweepObject( "
1675 << theObject << ", "
1677 << theAngleInRadians << ", "
1678 << theNbOfSteps << ", "
1679 << theTolerance << " )";
1681 SMESH::long_array_var anElementsId = theObject->GetIDs();
1682 rotationSweep(anElementsId,
1690 //=======================================================================
1691 //function : RotationSweepObject1D
1693 //=======================================================================
1695 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1696 const SMESH::AxisStruct & theAxis,
1697 CORBA::Double theAngleInRadians,
1698 CORBA::Long theNbOfSteps,
1699 CORBA::Double theTolerance)
1701 if ( !myPreviewMode ) {
1702 TPythonDump() << this << ".RotationSweepObject1D( "
1703 << theObject << ", "
1705 << theAngleInRadians << ", "
1706 << theNbOfSteps << ", "
1707 << theTolerance << " )";
1709 SMESH::long_array_var anElementsId = theObject->GetIDs();
1710 rotationSweep(anElementsId,
1719 //=======================================================================
1720 //function : RotationSweepObject2D
1722 //=======================================================================
1724 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1725 const SMESH::AxisStruct & theAxis,
1726 CORBA::Double theAngleInRadians,
1727 CORBA::Long theNbOfSteps,
1728 CORBA::Double theTolerance)
1730 if ( !myPreviewMode ) {
1731 TPythonDump() << this << ".RotationSweepObject2D( "
1732 << theObject << ", "
1734 << theAngleInRadians << ", "
1735 << theNbOfSteps << ", "
1736 << theTolerance << " )";
1738 SMESH::long_array_var anElementsId = theObject->GetIDs();
1739 rotationSweep(anElementsId,
1748 //=======================================================================
1749 //function : RotationSweepObjectMakeGroups
1751 //=======================================================================
1753 SMESH::ListOfGroups*
1754 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1755 const SMESH::AxisStruct& theAxis,
1756 CORBA::Double theAngleInRadians,
1757 CORBA::Long theNbOfSteps,
1758 CORBA::Double theTolerance)
1760 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1762 SMESH::long_array_var anElementsId = theObject->GetIDs();
1763 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1769 if (!myPreviewMode) {
1770 DumpGroupsList(aPythonDump, aGroups);
1771 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
1772 << theObject << ", "
1774 << theAngleInRadians << ", "
1775 << theNbOfSteps << ", "
1776 << theTolerance << " )";
1781 //=======================================================================
1782 //function : RotationSweepObject1DMakeGroups
1784 //=======================================================================
1786 SMESH::ListOfGroups*
1787 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1788 const SMESH::AxisStruct& theAxis,
1789 CORBA::Double theAngleInRadians,
1790 CORBA::Long theNbOfSteps,
1791 CORBA::Double theTolerance)
1793 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1795 SMESH::long_array_var anElementsId = theObject->GetIDs();
1796 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1803 if (!myPreviewMode) {
1804 DumpGroupsList(aPythonDump, aGroups);
1805 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
1806 << theObject << ", "
1808 << theAngleInRadians << ", "
1809 << theNbOfSteps << ", "
1810 << theTolerance << " )";
1815 //=======================================================================
1816 //function : RotationSweepObject2DMakeGroups
1818 //=======================================================================
1820 SMESH::ListOfGroups*
1821 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1822 const SMESH::AxisStruct& theAxis,
1823 CORBA::Double theAngleInRadians,
1824 CORBA::Long theNbOfSteps,
1825 CORBA::Double theTolerance)
1827 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1829 SMESH::long_array_var anElementsId = theObject->GetIDs();
1830 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1837 if (!myPreviewMode) {
1838 DumpGroupsList(aPythonDump, aGroups);
1839 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
1840 << theObject << ", "
1842 << theAngleInRadians << ", "
1843 << theNbOfSteps << ", "
1844 << theTolerance << " )";
1850 //=======================================================================
1851 //function : extrusionSweep
1853 //=======================================================================
1855 SMESH::ListOfGroups*
1856 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
1857 const SMESH::DirStruct & theStepVector,
1858 CORBA::Long theNbOfSteps,
1860 const SMDSAbs_ElementType theElementType)
1868 TIDSortedElemSet elements, copyElements;
1869 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
1871 const SMESH::PointStruct * P = &theStepVector.PS;
1872 gp_Vec stepVec( P->x, P->y, P->z );
1874 TIDSortedElemSet* workElements = & elements;
1875 TPreviewMesh tmpMesh( SMDSAbs_Face );
1876 SMESH_Mesh* mesh = myMesh;
1878 if ( myPreviewMode ) {
1879 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1880 tmpMesh.Copy( elements, copyElements, select, avoid );
1882 workElements = & copyElements;
1883 theMakeGroups = false;
1886 TElemOfElemListMap aHystory;
1887 ::SMESH_MeshEditor anEditor( mesh );
1888 ::SMESH_MeshEditor::PGroupIDs groupIds =
1889 anEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
1891 myMesh->GetMeshDS()->Modified();
1892 storeResult(anEditor);
1894 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1896 } catch(Standard_Failure) {
1897 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1898 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
1903 //=======================================================================
1904 //function : ExtrusionSweep
1906 //=======================================================================
1908 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
1909 const SMESH::DirStruct & theStepVector,
1910 CORBA::Long theNbOfSteps)
1912 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
1913 if (!myPreviewMode) {
1914 TPythonDump() << this << ".ExtrusionSweep( "
1915 << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
1920 //=======================================================================
1921 //function : ExtrusionSweepObject
1923 //=======================================================================
1925 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1926 const SMESH::DirStruct & theStepVector,
1927 CORBA::Long theNbOfSteps)
1929 SMESH::long_array_var anElementsId = theObject->GetIDs();
1930 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
1931 if (!myPreviewMode) {
1932 TPythonDump() << this << ".ExtrusionSweepObject( "
1933 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1937 //=======================================================================
1938 //function : ExtrusionSweepObject1D
1940 //=======================================================================
1942 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1943 const SMESH::DirStruct & theStepVector,
1944 CORBA::Long theNbOfSteps)
1946 SMESH::long_array_var anElementsId = theObject->GetIDs();
1947 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
1948 if ( !myPreviewMode ) {
1949 TPythonDump() << this << ".ExtrusionSweepObject1D( "
1950 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1954 //=======================================================================
1955 //function : ExtrusionSweepObject2D
1957 //=======================================================================
1959 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1960 const SMESH::DirStruct & theStepVector,
1961 CORBA::Long theNbOfSteps)
1963 SMESH::long_array_var anElementsId = theObject->GetIDs();
1964 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
1965 if ( !myPreviewMode ) {
1966 TPythonDump() << this << ".ExtrusionSweepObject2D( "
1967 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1971 //=======================================================================
1972 //function : ExtrusionSweepMakeGroups
1974 //=======================================================================
1976 SMESH::ListOfGroups*
1977 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1978 const SMESH::DirStruct& theStepVector,
1979 CORBA::Long theNbOfSteps)
1981 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1983 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
1985 if (!myPreviewMode) {
1986 DumpGroupsList(aPythonDump, aGroups);
1987 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
1988 << ", " << theStepVector <<", " << theNbOfSteps << " )";
1993 //=======================================================================
1994 //function : ExtrusionSweepObjectMakeGroups
1996 //=======================================================================
1998 SMESH::ListOfGroups*
1999 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2000 const SMESH::DirStruct& theStepVector,
2001 CORBA::Long theNbOfSteps)
2003 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2005 SMESH::long_array_var anElementsId = theObject->GetIDs();
2006 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2008 if (!myPreviewMode) {
2009 DumpGroupsList(aPythonDump, aGroups);
2010 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2011 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2016 //=======================================================================
2017 //function : ExtrusionSweepObject1DMakeGroups
2019 //=======================================================================
2021 SMESH::ListOfGroups*
2022 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2023 const SMESH::DirStruct& theStepVector,
2024 CORBA::Long theNbOfSteps)
2026 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2028 SMESH::long_array_var anElementsId = theObject->GetIDs();
2029 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2030 theNbOfSteps, true, SMDSAbs_Edge);
2031 if (!myPreviewMode) {
2032 DumpGroupsList(aPythonDump, aGroups);
2033 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2034 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2039 //=======================================================================
2040 //function : ExtrusionSweepObject2DMakeGroups
2042 //=======================================================================
2044 SMESH::ListOfGroups*
2045 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2046 const SMESH::DirStruct& theStepVector,
2047 CORBA::Long theNbOfSteps)
2049 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2051 SMESH::long_array_var anElementsId = theObject->GetIDs();
2052 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2053 theNbOfSteps, true, SMDSAbs_Face);
2054 if (!myPreviewMode) {
2055 DumpGroupsList(aPythonDump, aGroups);
2056 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2057 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2063 //=======================================================================
2064 //function : advancedExtrusion
2066 //=======================================================================
2068 SMESH::ListOfGroups*
2069 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2070 const SMESH::DirStruct & theStepVector,
2071 CORBA::Long theNbOfSteps,
2072 CORBA::Long theExtrFlags,
2073 CORBA::Double theSewTolerance,
2074 const bool theMakeGroups)
2078 TIDSortedElemSet elements;
2079 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2081 const SMESH::PointStruct * P = &theStepVector.PS;
2082 gp_Vec stepVec( P->x, P->y, P->z );
2084 ::SMESH_MeshEditor anEditor( myMesh );
2085 TElemOfElemListMap aHystory;
2086 ::SMESH_MeshEditor::PGroupIDs groupIds =
2087 anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2088 theMakeGroups, theExtrFlags, theSewTolerance);
2089 storeResult(anEditor);
2091 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2094 //=======================================================================
2095 //function : AdvancedExtrusion
2097 //=======================================================================
2099 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2100 const SMESH::DirStruct & theStepVector,
2101 CORBA::Long theNbOfSteps,
2102 CORBA::Long theExtrFlags,
2103 CORBA::Double theSewTolerance)
2105 if ( !myPreviewMode ) {
2106 TPythonDump() << "stepVector = " << theStepVector;
2107 TPythonDump() << this << ".AdvancedExtrusion("
2110 << theNbOfSteps << ","
2111 << theExtrFlags << ", "
2112 << theSewTolerance << " )";
2114 advancedExtrusion( theIDsOfElements,
2122 //=======================================================================
2123 //function : AdvancedExtrusionMakeGroups
2125 //=======================================================================
2126 SMESH::ListOfGroups*
2127 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2128 const SMESH::DirStruct& theStepVector,
2129 CORBA::Long theNbOfSteps,
2130 CORBA::Long theExtrFlags,
2131 CORBA::Double theSewTolerance)
2133 if (!myPreviewMode) {
2134 TPythonDump() << "stepVector = " << theStepVector;
2136 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2138 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2145 if (!myPreviewMode) {
2146 DumpGroupsList(aPythonDump, aGroups);
2147 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2150 << theNbOfSteps << ","
2151 << theExtrFlags << ", "
2152 << theSewTolerance << " )";
2158 //================================================================================
2160 * \brief Convert extrusion error to IDL enum
2162 //================================================================================
2164 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2166 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2170 RETCASE( EXTR_NO_ELEMENTS );
2171 RETCASE( EXTR_PATH_NOT_EDGE );
2172 RETCASE( EXTR_BAD_PATH_SHAPE );
2173 RETCASE( EXTR_BAD_STARTING_NODE );
2174 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2175 RETCASE( EXTR_CANT_GET_TANGENT );
2177 return SMESH::SMESH_MeshEditor::EXTR_OK;
2181 //=======================================================================
2182 //function : extrusionAlongPath
2184 //=======================================================================
2185 SMESH::ListOfGroups*
2186 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2187 SMESH::SMESH_Mesh_ptr thePathMesh,
2188 GEOM::GEOM_Object_ptr thePathShape,
2189 CORBA::Long theNodeStart,
2190 CORBA::Boolean theHasAngles,
2191 const SMESH::double_array & theAngles,
2192 CORBA::Boolean theHasRefPoint,
2193 const SMESH::PointStruct & theRefPoint,
2194 const bool theMakeGroups,
2195 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2196 const SMDSAbs_ElementType theElementType)
2198 MESSAGE("extrusionAlongPath");
2201 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2202 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2205 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2207 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2208 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2210 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2211 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2215 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2217 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2221 TIDSortedElemSet elements;
2222 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2224 list<double> angles;
2225 for (int i = 0; i < theAngles.length(); i++) {
2226 angles.push_back( theAngles[i] );
2229 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2231 int nbOldGroups = myMesh->NbGroup();
2233 ::SMESH_MeshEditor anEditor( myMesh );
2234 ::SMESH_MeshEditor::Extrusion_Error error =
2235 anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2236 theHasAngles, angles, false,
2237 theHasRefPoint, refPnt, theMakeGroups );
2238 myMesh->GetMeshDS()->Modified();
2239 storeResult(anEditor);
2240 theError = convExtrError( error );
2242 if ( theMakeGroups ) {
2243 list<int> groupIDs = myMesh->GetGroupIds();
2244 list<int>::iterator newBegin = groupIDs.begin();
2245 std::advance( newBegin, nbOldGroups ); // skip old groups
2246 groupIDs.erase( groupIDs.begin(), newBegin );
2247 return getGroups( & groupIDs );
2253 //=======================================================================
2254 //function : extrusionAlongPathX
2256 //=======================================================================
2257 SMESH::ListOfGroups*
2258 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2259 SMESH::SMESH_IDSource_ptr Path,
2260 CORBA::Long NodeStart,
2261 CORBA::Boolean HasAngles,
2262 const SMESH::double_array& Angles,
2263 CORBA::Boolean LinearVariation,
2264 CORBA::Boolean HasRefPoint,
2265 const SMESH::PointStruct& RefPoint,
2267 const SMDSAbs_ElementType ElementType,
2268 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2270 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2274 list<double> angles;
2275 for (int i = 0; i < Angles.length(); i++) {
2276 angles.push_back( Angles[i] );
2278 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2279 int nbOldGroups = myMesh->NbGroup();
2281 if ( Path->_is_nil() ) {
2282 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2286 TIDSortedElemSet elements, copyElements;
2287 arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
2289 TIDSortedElemSet* workElements = &elements;
2290 TPreviewMesh tmpMesh( SMDSAbs_Face );
2291 SMESH_Mesh* mesh = myMesh;
2293 if ( myPreviewMode )
2295 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2296 tmpMesh.Copy( elements, copyElements, select, avoid );
2298 workElements = & copyElements;
2302 ::SMESH_MeshEditor anEditor( mesh );
2303 ::SMESH_MeshEditor::Extrusion_Error error;
2305 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2308 SMDS_MeshNode* aNodeStart =
2309 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2310 if ( !aNodeStart ) {
2311 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2314 error = anEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2315 HasAngles, angles, LinearVariation,
2316 HasRefPoint, refPnt, MakeGroups );
2317 myMesh->GetMeshDS()->Modified();
2319 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2322 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2323 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2324 SMDS_MeshNode* aNodeStart =
2325 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2326 if ( !aNodeStart ) {
2327 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2330 SMESH_subMesh* aSubMesh =
2331 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2332 error = anEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2333 HasAngles, angles, LinearVariation,
2334 HasRefPoint, refPnt, MakeGroups );
2335 myMesh->GetMeshDS()->Modified();
2337 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2339 // path as group of 1D elements
2345 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2349 storeResult(anEditor);
2350 Error = convExtrError( error );
2353 list<int> groupIDs = myMesh->GetGroupIds();
2354 list<int>::iterator newBegin = groupIDs.begin();
2355 std::advance( newBegin, nbOldGroups ); // skip old groups
2356 groupIDs.erase( groupIDs.begin(), newBegin );
2357 return getGroups( & groupIDs );
2363 //=======================================================================
2364 //function : ExtrusionAlongPath
2366 //=======================================================================
2367 SMESH::SMESH_MeshEditor::Extrusion_Error
2368 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2369 SMESH::SMESH_Mesh_ptr thePathMesh,
2370 GEOM::GEOM_Object_ptr thePathShape,
2371 CORBA::Long theNodeStart,
2372 CORBA::Boolean theHasAngles,
2373 const SMESH::double_array & theAngles,
2374 CORBA::Boolean theHasRefPoint,
2375 const SMESH::PointStruct & theRefPoint)
2377 MESSAGE("ExtrusionAlongPath");
2378 if ( !myPreviewMode ) {
2379 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2380 << theIDsOfElements << ", "
2381 << thePathMesh << ", "
2382 << thePathShape << ", "
2383 << theNodeStart << ", "
2384 << theHasAngles << ", "
2385 << theAngles << ", "
2386 << theHasRefPoint << ", "
2387 << "SMESH.PointStruct( "
2388 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2389 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2390 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2392 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2393 extrusionAlongPath( theIDsOfElements,
2406 //=======================================================================
2407 //function : ExtrusionAlongPathObject
2409 //=======================================================================
2410 SMESH::SMESH_MeshEditor::Extrusion_Error
2411 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2412 SMESH::SMESH_Mesh_ptr thePathMesh,
2413 GEOM::GEOM_Object_ptr thePathShape,
2414 CORBA::Long theNodeStart,
2415 CORBA::Boolean theHasAngles,
2416 const SMESH::double_array & theAngles,
2417 CORBA::Boolean theHasRefPoint,
2418 const SMESH::PointStruct & theRefPoint)
2420 if ( !myPreviewMode ) {
2421 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2422 << theObject << ", "
2423 << thePathMesh << ", "
2424 << thePathShape << ", "
2425 << theNodeStart << ", "
2426 << theHasAngles << ", "
2427 << theAngles << ", "
2428 << theHasRefPoint << ", "
2429 << "SMESH.PointStruct( "
2430 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2431 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2432 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2434 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2435 SMESH::long_array_var anElementsId = theObject->GetIDs();
2436 extrusionAlongPath( anElementsId,
2449 //=======================================================================
2450 //function : ExtrusionAlongPathObject1D
2452 //=======================================================================
2453 SMESH::SMESH_MeshEditor::Extrusion_Error
2454 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2455 SMESH::SMESH_Mesh_ptr thePathMesh,
2456 GEOM::GEOM_Object_ptr thePathShape,
2457 CORBA::Long theNodeStart,
2458 CORBA::Boolean theHasAngles,
2459 const SMESH::double_array & theAngles,
2460 CORBA::Boolean theHasRefPoint,
2461 const SMESH::PointStruct & theRefPoint)
2463 if ( !myPreviewMode ) {
2464 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2465 << theObject << ", "
2466 << thePathMesh << ", "
2467 << thePathShape << ", "
2468 << theNodeStart << ", "
2469 << theHasAngles << ", "
2470 << theAngles << ", "
2471 << theHasRefPoint << ", "
2472 << "SMESH.PointStruct( "
2473 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2474 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2475 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2477 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2478 SMESH::long_array_var anElementsId = theObject->GetIDs();
2479 extrusionAlongPath( anElementsId,
2493 //=======================================================================
2494 //function : ExtrusionAlongPathObject2D
2496 //=======================================================================
2497 SMESH::SMESH_MeshEditor::Extrusion_Error
2498 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
2499 SMESH::SMESH_Mesh_ptr thePathMesh,
2500 GEOM::GEOM_Object_ptr thePathShape,
2501 CORBA::Long theNodeStart,
2502 CORBA::Boolean theHasAngles,
2503 const SMESH::double_array & theAngles,
2504 CORBA::Boolean theHasRefPoint,
2505 const SMESH::PointStruct & theRefPoint)
2507 if ( !myPreviewMode ) {
2508 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
2509 << theObject << ", "
2510 << thePathMesh << ", "
2511 << thePathShape << ", "
2512 << theNodeStart << ", "
2513 << theHasAngles << ", "
2514 << theAngles << ", "
2515 << theHasRefPoint << ", "
2516 << "SMESH.PointStruct( "
2517 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2518 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2519 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2521 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2522 SMESH::long_array_var anElementsId = theObject->GetIDs();
2523 extrusionAlongPath( anElementsId,
2538 //=======================================================================
2539 //function : ExtrusionAlongPathMakeGroups
2541 //=======================================================================
2542 SMESH::ListOfGroups*
2543 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
2544 SMESH::SMESH_Mesh_ptr thePathMesh,
2545 GEOM::GEOM_Object_ptr thePathShape,
2546 CORBA::Long theNodeStart,
2547 CORBA::Boolean theHasAngles,
2548 const SMESH::double_array& theAngles,
2549 CORBA::Boolean theHasRefPoint,
2550 const SMESH::PointStruct& theRefPoint,
2551 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2553 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2555 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
2565 if (!myPreviewMode) {
2566 bool isDumpGroups = aGroups && aGroups->length() > 0;
2568 aPythonDump << "(" << aGroups << ", error)";
2570 aPythonDump <<"error";
2572 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
2573 << theIDsOfElements << ", "
2574 << thePathMesh << ", "
2575 << thePathShape << ", "
2576 << theNodeStart << ", "
2577 << theHasAngles << ", "
2578 << theAngles << ", "
2579 << theHasRefPoint << ", "
2580 << "SMESH.PointStruct( "
2581 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2582 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2583 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2588 //=======================================================================
2589 //function : ExtrusionAlongPathObjectMakeGroups
2591 //=======================================================================
2592 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2593 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2594 SMESH::SMESH_Mesh_ptr thePathMesh,
2595 GEOM::GEOM_Object_ptr thePathShape,
2596 CORBA::Long theNodeStart,
2597 CORBA::Boolean theHasAngles,
2598 const SMESH::double_array& theAngles,
2599 CORBA::Boolean theHasRefPoint,
2600 const SMESH::PointStruct& theRefPoint,
2601 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2603 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2605 SMESH::long_array_var anElementsId = theObject->GetIDs();
2606 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2617 if (!myPreviewMode) {
2618 bool isDumpGroups = aGroups && aGroups->length() > 0;
2620 aPythonDump << "(" << aGroups << ", error)";
2622 aPythonDump <<"error";
2624 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
2625 << theObject << ", "
2626 << thePathMesh << ", "
2627 << thePathShape << ", "
2628 << theNodeStart << ", "
2629 << theHasAngles << ", "
2630 << theAngles << ", "
2631 << theHasRefPoint << ", "
2632 << "SMESH.PointStruct( "
2633 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2634 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2635 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2640 //=======================================================================
2641 //function : ExtrusionAlongPathObject1DMakeGroups
2643 //=======================================================================
2644 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2645 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2646 SMESH::SMESH_Mesh_ptr thePathMesh,
2647 GEOM::GEOM_Object_ptr thePathShape,
2648 CORBA::Long theNodeStart,
2649 CORBA::Boolean theHasAngles,
2650 const SMESH::double_array& theAngles,
2651 CORBA::Boolean theHasRefPoint,
2652 const SMESH::PointStruct& theRefPoint,
2653 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2655 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2657 SMESH::long_array_var anElementsId = theObject->GetIDs();
2658 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2670 if (!myPreviewMode) {
2671 bool isDumpGroups = aGroups && aGroups->length() > 0;
2673 aPythonDump << "(" << aGroups << ", error)";
2675 aPythonDump << "error";
2677 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
2678 << theObject << ", "
2679 << thePathMesh << ", "
2680 << thePathShape << ", "
2681 << theNodeStart << ", "
2682 << theHasAngles << ", "
2683 << theAngles << ", "
2684 << theHasRefPoint << ", "
2685 << "SMESH.PointStruct( "
2686 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2687 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2688 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2693 //=======================================================================
2694 //function : ExtrusionAlongPathObject2DMakeGroups
2696 //=======================================================================
2697 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2698 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2699 SMESH::SMESH_Mesh_ptr thePathMesh,
2700 GEOM::GEOM_Object_ptr thePathShape,
2701 CORBA::Long theNodeStart,
2702 CORBA::Boolean theHasAngles,
2703 const SMESH::double_array& theAngles,
2704 CORBA::Boolean theHasRefPoint,
2705 const SMESH::PointStruct& theRefPoint,
2706 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2708 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2710 SMESH::long_array_var anElementsId = theObject->GetIDs();
2711 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2723 if (!myPreviewMode) {
2724 bool isDumpGroups = aGroups && aGroups->length() > 0;
2726 aPythonDump << "(" << aGroups << ", error)";
2728 aPythonDump << "error";
2730 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
2731 << theObject << ", "
2732 << thePathMesh << ", "
2733 << thePathShape << ", "
2734 << theNodeStart << ", "
2735 << theHasAngles << ", "
2736 << theAngles << ", "
2737 << theHasRefPoint << ", "
2738 << "SMESH.PointStruct( "
2739 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2740 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2741 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2747 //=======================================================================
2748 //function : ExtrusionAlongPathObjX
2750 //=======================================================================
2751 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2752 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
2753 SMESH::SMESH_IDSource_ptr Path,
2754 CORBA::Long NodeStart,
2755 CORBA::Boolean HasAngles,
2756 const SMESH::double_array& Angles,
2757 CORBA::Boolean LinearVariation,
2758 CORBA::Boolean HasRefPoint,
2759 const SMESH::PointStruct& RefPoint,
2760 CORBA::Boolean MakeGroups,
2761 SMESH::ElementType ElemType,
2762 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2764 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2766 SMESH::long_array_var anElementsId = Object->GetIDs();
2767 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
2776 (SMDSAbs_ElementType)ElemType,
2779 if (!myPreviewMode) {
2780 bool isDumpGroups = aGroups && aGroups->length() > 0;
2782 aPythonDump << "(" << *aGroups << ", error)";
2784 aPythonDump << "error";
2786 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
2789 << NodeStart << ", "
2790 << HasAngles << ", "
2792 << LinearVariation << ", "
2793 << HasRefPoint << ", "
2794 << "SMESH.PointStruct( "
2795 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2796 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2797 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2798 << MakeGroups << ", "
2799 << ElemType << " )";
2805 //=======================================================================
2806 //function : ExtrusionAlongPathX
2808 //=======================================================================
2809 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2810 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
2811 SMESH::SMESH_IDSource_ptr Path,
2812 CORBA::Long NodeStart,
2813 CORBA::Boolean HasAngles,
2814 const SMESH::double_array& Angles,
2815 CORBA::Boolean LinearVariation,
2816 CORBA::Boolean HasRefPoint,
2817 const SMESH::PointStruct& RefPoint,
2818 CORBA::Boolean MakeGroups,
2819 SMESH::ElementType ElemType,
2820 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2822 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2824 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
2833 (SMDSAbs_ElementType)ElemType,
2836 if (!myPreviewMode) {
2837 bool isDumpGroups = aGroups && aGroups->length() > 0;
2839 aPythonDump << "(" << *aGroups << ", error)";
2841 aPythonDump <<"error";
2843 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
2844 << IDsOfElements << ", "
2846 << NodeStart << ", "
2847 << HasAngles << ", "
2849 << LinearVariation << ", "
2850 << HasRefPoint << ", "
2851 << "SMESH.PointStruct( "
2852 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2853 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2854 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2855 << MakeGroups << ", "
2856 << ElemType << " )";
2862 //================================================================================
2864 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2865 * of given angles along path steps
2866 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2867 * which proceeds the extrusion
2868 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2869 * is used to define the sub-mesh for the path
2871 //================================================================================
2873 SMESH::double_array*
2874 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2875 GEOM::GEOM_Object_ptr thePathShape,
2876 const SMESH::double_array & theAngles)
2878 SMESH::double_array_var aResult = new SMESH::double_array();
2879 int nbAngles = theAngles.length();
2880 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2882 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2883 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2884 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2885 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2886 return aResult._retn();
2887 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2888 if ( nbSteps == nbAngles )
2890 aResult.inout() = theAngles;
2894 aResult->length( nbSteps );
2895 double rAn2St = double( nbAngles ) / double( nbSteps );
2896 double angPrev = 0, angle;
2897 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2899 double angCur = rAn2St * ( iSt+1 );
2900 double angCurFloor = floor( angCur );
2901 double angPrevFloor = floor( angPrev );
2902 if ( angPrevFloor == angCurFloor )
2903 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2906 int iP = int( angPrevFloor );
2907 double angPrevCeil = ceil(angPrev);
2908 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2910 int iC = int( angCurFloor );
2911 if ( iC < nbAngles )
2912 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2914 iP = int( angPrevCeil );
2916 angle += theAngles[ iC ];
2918 aResult[ iSt ] = angle;
2923 // Update Python script
2924 TPythonDump() << "rotAngles = " << theAngles;
2925 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
2926 << thePathMesh << ", "
2927 << thePathShape << ", "
2930 return aResult._retn();
2934 //=======================================================================
2937 //=======================================================================
2939 SMESH::ListOfGroups*
2940 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
2941 const SMESH::AxisStruct & theAxis,
2942 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2943 CORBA::Boolean theCopy,
2945 ::SMESH_Mesh* theTargetMesh)
2949 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
2950 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
2952 if ( theTargetMesh )
2956 switch ( theMirrorType ) {
2957 case SMESH::SMESH_MeshEditor::POINT:
2958 aTrsf.SetMirror( P );
2960 case SMESH::SMESH_MeshEditor::AXIS:
2961 aTrsf.SetMirror( gp_Ax1( P, V ));
2964 aTrsf.SetMirror( gp_Ax2( P, V ));
2967 TIDSortedElemSet copyElements;
2968 TPreviewMesh tmpMesh;
2969 TIDSortedElemSet* workElements = & theElements;
2970 SMESH_Mesh* mesh = myMesh;
2972 if ( myPreviewMode )
2974 tmpMesh.Copy( theElements, copyElements);
2975 if ( !theCopy && !theTargetMesh )
2977 TIDSortedElemSet elemsAround, elemsAroundCopy;
2978 getElementsAround( theElements, GetMeshDS(), elemsAround );
2979 tmpMesh.Copy( elemsAround, elemsAroundCopy);
2982 workElements = & copyElements;
2983 theMakeGroups = false;
2986 ::SMESH_MeshEditor anEditor( mesh );
2987 ::SMESH_MeshEditor::PGroupIDs groupIds =
2988 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
2990 if(theCopy || myPreviewMode)
2991 storeResult(anEditor);
2994 myMesh->SetIsModified( true );
2995 myMesh->GetMeshDS()->Modified();
2997 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3000 //=======================================================================
3003 //=======================================================================
3005 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3006 const SMESH::AxisStruct & theAxis,
3007 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3008 CORBA::Boolean theCopy)
3010 if ( !myPreviewMode ) {
3011 TPythonDump() << this << ".Mirror( "
3012 << theIDsOfElements << ", "
3014 << mirrorTypeName(theMirrorType) << ", "
3017 if ( theIDsOfElements.length() > 0 )
3019 TIDSortedElemSet elements;
3020 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3021 mirror(elements, theAxis, theMirrorType, theCopy, false);
3026 //=======================================================================
3027 //function : MirrorObject
3029 //=======================================================================
3031 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3032 const SMESH::AxisStruct & theAxis,
3033 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3034 CORBA::Boolean theCopy)
3036 if ( !myPreviewMode ) {
3037 TPythonDump() << this << ".MirrorObject( "
3038 << theObject << ", "
3040 << mirrorTypeName(theMirrorType) << ", "
3043 TIDSortedElemSet elements;
3045 bool emptyIfIsMesh = myPreviewMode ? false : true;
3047 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3048 mirror(elements, theAxis, theMirrorType, theCopy, false);
3051 //=======================================================================
3052 //function : MirrorMakeGroups
3054 //=======================================================================
3056 SMESH::ListOfGroups*
3057 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3058 const SMESH::AxisStruct& theMirror,
3059 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3061 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3063 SMESH::ListOfGroups * aGroups = 0;
3064 if ( theIDsOfElements.length() > 0 )
3066 TIDSortedElemSet elements;
3067 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3068 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3070 if (!myPreviewMode) {
3071 DumpGroupsList(aPythonDump, aGroups);
3072 aPythonDump << this << ".MirrorMakeGroups( "
3073 << theIDsOfElements << ", "
3074 << theMirror << ", "
3075 << mirrorTypeName(theMirrorType) << " )";
3080 //=======================================================================
3081 //function : MirrorObjectMakeGroups
3083 //=======================================================================
3085 SMESH::ListOfGroups*
3086 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3087 const SMESH::AxisStruct& theMirror,
3088 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3090 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3092 SMESH::ListOfGroups * aGroups = 0;
3093 TIDSortedElemSet elements;
3094 if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3095 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3099 DumpGroupsList(aPythonDump,aGroups);
3100 aPythonDump << this << ".MirrorObjectMakeGroups( "
3101 << theObject << ", "
3102 << theMirror << ", "
3103 << mirrorTypeName(theMirrorType) << " )";
3108 //=======================================================================
3109 //function : MirrorMakeMesh
3111 //=======================================================================
3113 SMESH::SMESH_Mesh_ptr
3114 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3115 const SMESH::AxisStruct& theMirror,
3116 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3117 CORBA::Boolean theCopyGroups,
3118 const char* theMeshName)
3120 SMESH_Mesh_i* mesh_i;
3121 SMESH::SMESH_Mesh_var mesh;
3122 { // open new scope to dump "MakeMesh" command
3123 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3125 TPythonDump pydump; // to prevent dump at mesh creation
3127 mesh = makeMesh( theMeshName );
3128 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3129 if (mesh_i && theIDsOfElements.length() > 0 )
3131 TIDSortedElemSet elements;
3132 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3133 mirror(elements, theMirror, theMirrorType,
3134 false, theCopyGroups, & mesh_i->GetImpl());
3135 mesh_i->CreateGroupServants();
3138 if (!myPreviewMode) {
3139 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3140 << theIDsOfElements << ", "
3141 << theMirror << ", "
3142 << mirrorTypeName(theMirrorType) << ", "
3143 << theCopyGroups << ", '"
3144 << theMeshName << "' )";
3149 if (!myPreviewMode && mesh_i)
3150 mesh_i->GetGroups();
3152 return mesh._retn();
3155 //=======================================================================
3156 //function : MirrorObjectMakeMesh
3158 //=======================================================================
3160 SMESH::SMESH_Mesh_ptr
3161 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3162 const SMESH::AxisStruct& theMirror,
3163 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3164 CORBA::Boolean theCopyGroups,
3165 const char* theMeshName)
3167 SMESH_Mesh_i* mesh_i;
3168 SMESH::SMESH_Mesh_var mesh;
3169 { // open new scope to dump "MakeMesh" command
3170 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3172 TPythonDump pydump; // to prevent dump at mesh creation
3174 mesh = makeMesh( theMeshName );
3175 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3176 TIDSortedElemSet elements;
3178 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3180 mirror(elements, theMirror, theMirrorType,
3181 false, theCopyGroups, & mesh_i->GetImpl());
3182 mesh_i->CreateGroupServants();
3184 if (!myPreviewMode) {
3185 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3186 << theObject << ", "
3187 << theMirror << ", "
3188 << mirrorTypeName(theMirrorType) << ", "
3189 << theCopyGroups << ", '"
3190 << theMeshName << "' )";
3195 if (!myPreviewMode && mesh_i)
3196 mesh_i->GetGroups();
3198 return mesh._retn();
3201 //=======================================================================
3202 //function : translate
3204 //=======================================================================
3206 SMESH::ListOfGroups*
3207 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3208 const SMESH::DirStruct & theVector,
3209 CORBA::Boolean theCopy,
3211 ::SMESH_Mesh* theTargetMesh)
3215 if ( theTargetMesh )
3219 const SMESH::PointStruct * P = &theVector.PS;
3220 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3222 TIDSortedElemSet copyElements;
3223 TIDSortedElemSet* workElements = &theElements;
3224 TPreviewMesh tmpMesh;
3225 SMESH_Mesh* mesh = myMesh;
3227 if ( myPreviewMode )
3229 tmpMesh.Copy( theElements, copyElements);
3230 if ( !theCopy && !theTargetMesh )
3232 TIDSortedElemSet elemsAround, elemsAroundCopy;
3233 getElementsAround( theElements, GetMeshDS(), elemsAround );
3234 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3237 workElements = & copyElements;
3238 theMakeGroups = false;
3241 ::SMESH_MeshEditor anEditor( mesh );
3242 ::SMESH_MeshEditor::PGroupIDs groupIds =
3243 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3245 if(theCopy || myPreviewMode)
3246 storeResult(anEditor);
3249 myMesh->GetMeshDS()->Modified();
3250 myMesh->SetIsModified( true );
3253 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3256 //=======================================================================
3257 //function : Translate
3259 //=======================================================================
3261 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3262 const SMESH::DirStruct & theVector,
3263 CORBA::Boolean theCopy)
3265 if (!myPreviewMode) {
3266 TPythonDump() << this << ".Translate( "
3267 << theIDsOfElements << ", "
3268 << theVector << ", "
3271 if (theIDsOfElements.length()) {
3272 TIDSortedElemSet elements;
3273 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3274 translate(elements, theVector, theCopy, false);
3278 //=======================================================================
3279 //function : TranslateObject
3281 //=======================================================================
3283 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3284 const SMESH::DirStruct & theVector,
3285 CORBA::Boolean theCopy)
3287 if (!myPreviewMode) {
3288 TPythonDump() << this << ".TranslateObject( "
3289 << theObject << ", "
3290 << theVector << ", "
3293 TIDSortedElemSet elements;
3295 bool emptyIfIsMesh = myPreviewMode ? false : true;
3297 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3298 translate(elements, theVector, theCopy, false);
3301 //=======================================================================
3302 //function : TranslateMakeGroups
3304 //=======================================================================
3306 SMESH::ListOfGroups*
3307 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3308 const SMESH::DirStruct& theVector)
3310 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3312 SMESH::ListOfGroups * aGroups = 0;
3313 if (theIDsOfElements.length()) {
3314 TIDSortedElemSet elements;
3315 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3316 aGroups = translate(elements,theVector,true,true);
3318 if (!myPreviewMode) {
3319 DumpGroupsList(aPythonDump, aGroups);
3320 aPythonDump << this << ".TranslateMakeGroups( "
3321 << theIDsOfElements << ", "
3322 << theVector << " )";
3327 //=======================================================================
3328 //function : TranslateObjectMakeGroups
3330 //=======================================================================
3332 SMESH::ListOfGroups*
3333 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3334 const SMESH::DirStruct& theVector)
3336 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3338 SMESH::ListOfGroups * aGroups = 0;
3339 TIDSortedElemSet elements;
3340 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3341 aGroups = translate(elements, theVector, true, true);
3343 if (!myPreviewMode) {
3344 DumpGroupsList(aPythonDump, aGroups);
3345 aPythonDump << this << ".TranslateObjectMakeGroups( "
3346 << theObject << ", "
3347 << theVector << " )";
3352 //=======================================================================
3353 //function : TranslateMakeMesh
3355 //=======================================================================
3357 SMESH::SMESH_Mesh_ptr
3358 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3359 const SMESH::DirStruct& theVector,
3360 CORBA::Boolean theCopyGroups,
3361 const char* theMeshName)
3363 SMESH_Mesh_i* mesh_i;
3364 SMESH::SMESH_Mesh_var mesh;
3366 { // open new scope to dump "MakeMesh" command
3367 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3369 TPythonDump pydump; // to prevent dump at mesh creation
3371 mesh = makeMesh( theMeshName );
3372 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3374 if ( mesh_i && theIDsOfElements.length() )
3376 TIDSortedElemSet elements;
3377 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3378 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3379 mesh_i->CreateGroupServants();
3382 if ( !myPreviewMode ) {
3383 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3384 << theIDsOfElements << ", "
3385 << theVector << ", "
3386 << theCopyGroups << ", '"
3387 << theMeshName << "' )";
3392 if (!myPreviewMode && mesh_i)
3393 mesh_i->GetGroups();
3395 return mesh._retn();
3398 //=======================================================================
3399 //function : TranslateObjectMakeMesh
3401 //=======================================================================
3403 SMESH::SMESH_Mesh_ptr
3404 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3405 const SMESH::DirStruct& theVector,
3406 CORBA::Boolean theCopyGroups,
3407 const char* theMeshName)
3409 SMESH_Mesh_i* mesh_i;
3410 SMESH::SMESH_Mesh_var mesh;
3411 { // open new scope to dump "MakeMesh" command
3412 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3414 TPythonDump pydump; // to prevent dump at mesh creation
3415 mesh = makeMesh( theMeshName );
3416 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3418 TIDSortedElemSet elements;
3420 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3422 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3423 mesh_i->CreateGroupServants();
3425 if ( !myPreviewMode ) {
3426 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3427 << theObject << ", "
3428 << theVector << ", "
3429 << theCopyGroups << ", '"
3430 << theMeshName << "' )";
3435 if (!myPreviewMode && mesh_i)
3436 mesh_i->GetGroups();
3438 return mesh._retn();
3441 //=======================================================================
3444 //=======================================================================
3446 SMESH::ListOfGroups*
3447 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3448 const SMESH::AxisStruct & theAxis,
3449 CORBA::Double theAngle,
3450 CORBA::Boolean theCopy,
3452 ::SMESH_Mesh* theTargetMesh)
3456 if ( theTargetMesh )
3459 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3460 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3463 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3465 TIDSortedElemSet copyElements;
3466 TIDSortedElemSet* workElements = &theElements;
3467 TPreviewMesh tmpMesh;
3468 SMESH_Mesh* mesh = myMesh;
3470 if ( myPreviewMode ) {
3471 tmpMesh.Copy( theElements, copyElements );
3472 if ( !theCopy && !theTargetMesh )
3474 TIDSortedElemSet elemsAround, elemsAroundCopy;
3475 getElementsAround( theElements, GetMeshDS(), elemsAround );
3476 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3479 workElements = ©Elements;
3480 theMakeGroups = false;
3483 ::SMESH_MeshEditor anEditor( mesh );
3484 ::SMESH_MeshEditor::PGroupIDs groupIds =
3485 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3487 if(theCopy || myPreviewMode)
3488 storeResult(anEditor);
3491 myMesh->GetMeshDS()->Modified();
3492 myMesh->SetIsModified( true );
3495 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3498 //=======================================================================
3501 //=======================================================================
3503 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3504 const SMESH::AxisStruct & theAxis,
3505 CORBA::Double theAngle,
3506 CORBA::Boolean theCopy)
3508 if (!myPreviewMode) {
3509 TPythonDump() << this << ".Rotate( "
3510 << theIDsOfElements << ", "
3515 if (theIDsOfElements.length() > 0)
3517 TIDSortedElemSet elements;
3518 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3519 rotate(elements,theAxis,theAngle,theCopy,false);
3523 //=======================================================================
3524 //function : RotateObject
3526 //=======================================================================
3528 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3529 const SMESH::AxisStruct & theAxis,
3530 CORBA::Double theAngle,
3531 CORBA::Boolean theCopy)
3533 if ( !myPreviewMode ) {
3534 TPythonDump() << this << ".RotateObject( "
3535 << theObject << ", "
3540 TIDSortedElemSet elements;
3541 bool emptyIfIsMesh = myPreviewMode ? false : true;
3542 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3543 rotate(elements,theAxis,theAngle,theCopy,false);
3546 //=======================================================================
3547 //function : RotateMakeGroups
3549 //=======================================================================
3551 SMESH::ListOfGroups*
3552 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3553 const SMESH::AxisStruct& theAxis,
3554 CORBA::Double theAngle)
3556 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3558 SMESH::ListOfGroups * aGroups = 0;
3559 if (theIDsOfElements.length() > 0)
3561 TIDSortedElemSet elements;
3562 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3563 aGroups = rotate(elements,theAxis,theAngle,true,true);
3565 if (!myPreviewMode) {
3566 DumpGroupsList(aPythonDump, aGroups);
3567 aPythonDump << this << ".RotateMakeGroups( "
3568 << theIDsOfElements << ", "
3570 << theAngle << " )";
3575 //=======================================================================
3576 //function : RotateObjectMakeGroups
3578 //=======================================================================
3580 SMESH::ListOfGroups*
3581 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3582 const SMESH::AxisStruct& theAxis,
3583 CORBA::Double theAngle)
3585 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3587 SMESH::ListOfGroups * aGroups = 0;
3588 TIDSortedElemSet elements;
3589 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3590 aGroups = rotate(elements, theAxis, theAngle, true, true);
3592 if (!myPreviewMode) {
3593 DumpGroupsList(aPythonDump, aGroups);
3594 aPythonDump << this << ".RotateObjectMakeGroups( "
3595 << theObject << ", "
3597 << theAngle << " )";
3602 //=======================================================================
3603 //function : RotateMakeMesh
3605 //=======================================================================
3607 SMESH::SMESH_Mesh_ptr
3608 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3609 const SMESH::AxisStruct& theAxis,
3610 CORBA::Double theAngleInRadians,
3611 CORBA::Boolean theCopyGroups,
3612 const char* theMeshName)
3614 SMESH::SMESH_Mesh_var mesh;
3615 SMESH_Mesh_i* mesh_i;
3617 { // open new scope to dump "MakeMesh" command
3618 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3620 TPythonDump pydump; // to prevent dump at mesh creation
3622 mesh = makeMesh( theMeshName );
3623 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3625 if ( mesh_i && theIDsOfElements.length() > 0 )
3627 TIDSortedElemSet elements;
3628 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3629 rotate(elements, theAxis, theAngleInRadians,
3630 false, theCopyGroups, & mesh_i->GetImpl());
3631 mesh_i->CreateGroupServants();
3633 if ( !myPreviewMode ) {
3634 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3635 << theIDsOfElements << ", "
3637 << theAngleInRadians << ", "
3638 << theCopyGroups << ", '"
3639 << theMeshName << "' )";
3644 if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3645 mesh_i->GetGroups();
3647 return mesh._retn();
3650 //=======================================================================
3651 //function : RotateObjectMakeMesh
3653 //=======================================================================
3655 SMESH::SMESH_Mesh_ptr
3656 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3657 const SMESH::AxisStruct& theAxis,
3658 CORBA::Double theAngleInRadians,
3659 CORBA::Boolean theCopyGroups,
3660 const char* theMeshName)
3662 SMESH::SMESH_Mesh_var mesh;
3663 SMESH_Mesh_i* mesh_i;
3665 {// open new scope to dump "MakeMesh" command
3666 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3668 TPythonDump pydump; // to prevent dump at mesh creation
3669 mesh = makeMesh( theMeshName );
3670 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3672 TIDSortedElemSet elements;
3674 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3676 rotate(elements, theAxis, theAngleInRadians,
3677 false, theCopyGroups, & mesh_i->GetImpl());
3678 mesh_i->CreateGroupServants();
3680 if ( !myPreviewMode ) {
3681 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3682 << theObject << ", "
3684 << theAngleInRadians << ", "
3685 << theCopyGroups << ", '"
3686 << theMeshName << "' )";
3691 if (!myPreviewMode && mesh_i)
3692 mesh_i->GetGroups();
3694 return mesh._retn();
3697 //=======================================================================
3700 //=======================================================================
3702 SMESH::ListOfGroups*
3703 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3704 const SMESH::PointStruct& thePoint,
3705 const SMESH::double_array& theScaleFact,
3706 CORBA::Boolean theCopy,
3708 ::SMESH_Mesh* theTargetMesh)
3711 if ( theScaleFact.length() < 1 )
3712 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3713 if ( theScaleFact.length() == 2 )
3714 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3716 if ( theTargetMesh )
3719 TIDSortedElemSet elements;
3720 bool emptyIfIsMesh = myPreviewMode ? false : true;
3721 if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3726 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3727 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3729 double tol = std::numeric_limits<double>::max();
3731 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3732 0, S[1], 0, thePoint.y * (1-S[1]),
3733 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3735 TIDSortedElemSet copyElements;
3736 TPreviewMesh tmpMesh;
3737 TIDSortedElemSet* workElements = &elements;
3738 SMESH_Mesh* mesh = myMesh;
3740 if ( myPreviewMode )
3742 tmpMesh.Copy( elements, copyElements);
3743 if ( !theCopy && !theTargetMesh )
3745 TIDSortedElemSet elemsAround, elemsAroundCopy;
3746 getElementsAround( elements, GetMeshDS(), elemsAround );
3747 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3750 workElements = & copyElements;
3751 theMakeGroups = false;
3754 ::SMESH_MeshEditor anEditor( mesh );
3755 ::SMESH_MeshEditor::PGroupIDs groupIds =
3756 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3758 if(theCopy || myPreviewMode )
3759 storeResult(anEditor);
3762 myMesh->GetMeshDS()->Modified();
3763 myMesh->SetIsModified( true );
3765 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3768 //=======================================================================
3771 //=======================================================================
3773 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3774 const SMESH::PointStruct& thePoint,
3775 const SMESH::double_array& theScaleFact,
3776 CORBA::Boolean theCopy)
3778 if ( !myPreviewMode ) {
3779 TPythonDump() << this << ".Scale( "
3780 << theObject << ", "
3781 << "SMESH.PointStruct( " << thePoint.x << ", "
3782 << thePoint.y << ", " << thePoint.z << " ) ,"
3783 << theScaleFact << ", "
3786 scale(theObject, thePoint, theScaleFact, theCopy, false);
3790 //=======================================================================
3791 //function : ScaleMakeGroups
3793 //=======================================================================
3795 SMESH::ListOfGroups*
3796 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3797 const SMESH::PointStruct& thePoint,
3798 const SMESH::double_array& theScaleFact)
3800 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3802 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3803 if (!myPreviewMode) {
3804 DumpGroupsList(aPythonDump, aGroups);
3805 aPythonDump << this << ".Scale("
3807 << "SMESH.PointStruct(" <<thePoint.x << ","
3808 << thePoint.y << "," << thePoint.z << "),"
3809 << theScaleFact << ",True,True)";
3815 //=======================================================================
3816 //function : ScaleMakeMesh
3818 //=======================================================================
3820 SMESH::SMESH_Mesh_ptr
3821 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3822 const SMESH::PointStruct& thePoint,
3823 const SMESH::double_array& theScaleFact,
3824 CORBA::Boolean theCopyGroups,
3825 const char* theMeshName)
3827 SMESH_Mesh_i* mesh_i;
3828 SMESH::SMESH_Mesh_var mesh;
3829 { // open new scope to dump "MakeMesh" command
3830 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3832 TPythonDump pydump; // to prevent dump at mesh creation
3833 mesh = makeMesh( theMeshName );
3834 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3838 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
3839 mesh_i->CreateGroupServants();
3841 if ( !myPreviewMode )
3842 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
3843 << theObject << ", "
3844 << "SMESH.PointStruct( " << thePoint.x << ", "
3845 << thePoint.y << ", " << thePoint.z << " ) ,"
3846 << theScaleFact << ", "
3847 << theCopyGroups << ", '"
3848 << theMeshName << "' )";
3852 if (!myPreviewMode && mesh_i)
3853 mesh_i->GetGroups();
3855 return mesh._retn();
3859 //=======================================================================
3860 //function : FindCoincidentNodes
3862 //=======================================================================
3864 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
3865 SMESH::array_of_long_array_out GroupsOfNodes)
3869 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3870 ::SMESH_MeshEditor anEditor( myMesh );
3871 TIDSortedNodeSet nodes; // no input nodes
3872 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3874 GroupsOfNodes = new SMESH::array_of_long_array;
3875 GroupsOfNodes->length( aListOfListOfNodes.size() );
3876 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3877 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
3878 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3879 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3880 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3881 aGroup.length( aListOfNodes.size() );
3882 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3883 aGroup[ j ] = (*lIt)->GetID();
3885 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
3886 << Tolerance << " )";
3889 //=======================================================================
3890 //function : FindCoincidentNodesOnPart
3892 //=======================================================================
3893 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
3894 CORBA::Double Tolerance,
3895 SMESH::array_of_long_array_out GroupsOfNodes)
3899 TIDSortedNodeSet nodes;
3900 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3902 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3903 ::SMESH_MeshEditor anEditor( myMesh );
3905 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3907 GroupsOfNodes = new SMESH::array_of_long_array;
3908 GroupsOfNodes->length( aListOfListOfNodes.size() );
3909 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3910 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3912 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3913 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3914 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3915 aGroup.length( aListOfNodes.size() );
3916 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3917 aGroup[ j ] = (*lIt)->GetID();
3919 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
3921 << Tolerance << " )";
3924 //================================================================================
3926 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
3927 * ExceptSubMeshOrGroups
3929 //================================================================================
3931 void SMESH_MeshEditor_i::
3932 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
3933 CORBA::Double theTolerance,
3934 SMESH::array_of_long_array_out theGroupsOfNodes,
3935 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
3939 TIDSortedNodeSet nodes;
3940 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3942 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
3944 TIDSortedNodeSet exceptNodes;
3945 idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
3946 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
3947 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
3948 nodes.erase( *avoidNode );
3950 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3951 ::SMESH_MeshEditor anEditor( myMesh );
3953 anEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
3955 theGroupsOfNodes = new SMESH::array_of_long_array;
3956 theGroupsOfNodes->length( aListOfListOfNodes.size() );
3957 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3958 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3960 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3961 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3962 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
3963 aGroup.length( aListOfNodes.size() );
3964 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3965 aGroup[ j ] = (*lIt)->GetID();
3967 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
3969 << theTolerance << ", "
3970 << theExceptSubMeshOrGroups << " )";
3973 //=======================================================================
3974 //function : MergeNodes
3976 //=======================================================================
3978 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
3982 SMESHDS_Mesh* aMesh = GetMeshDS();
3984 TPythonDump aTPythonDump;
3985 aTPythonDump << this << ".MergeNodes([";
3986 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3987 for (int i = 0; i < GroupsOfNodes.length(); i++)
3989 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
3990 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
3991 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
3992 for ( int j = 0; j < aNodeGroup.length(); j++ )
3994 CORBA::Long index = aNodeGroup[ j ];
3995 const SMDS_MeshNode * node = aMesh->FindNode(index);
3997 aListOfNodes.push_back( node );
3999 if ( aListOfNodes.size() < 2 )
4000 aListOfListOfNodes.pop_back();
4002 if ( i > 0 ) aTPythonDump << ", ";
4003 aTPythonDump << aNodeGroup;
4005 ::SMESH_MeshEditor anEditor( myMesh );
4006 anEditor.MergeNodes( aListOfListOfNodes );
4008 aTPythonDump << "])";
4009 myMesh->GetMeshDS()->Modified();
4010 myMesh->SetIsModified( true );
4013 //=======================================================================
4014 //function : FindEqualElements
4016 //=======================================================================
4017 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4018 SMESH::array_of_long_array_out GroupsOfElementsID)
4022 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4023 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4025 typedef list<int> TListOfIDs;
4026 set<const SMDS_MeshElement*> elems;
4027 SMESH::long_array_var aElementsId = theObject->GetIDs();
4028 SMESHDS_Mesh* aMesh = GetMeshDS();
4030 for(int i = 0; i < aElementsId->length(); i++) {
4031 CORBA::Long anID = aElementsId[i];
4032 const SMDS_MeshElement * elem = aMesh->FindElement(anID);
4038 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4039 ::SMESH_MeshEditor anEditor( myMesh );
4040 anEditor.FindEqualElements( elems, aListOfListOfElementsID );
4042 GroupsOfElementsID = new SMESH::array_of_long_array;
4043 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4045 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
4046 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
4047 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4048 TListOfIDs& listOfIDs = *arraysIt;
4049 aGroup.length( listOfIDs.size() );
4050 TListOfIDs::iterator idIt = listOfIDs.begin();
4051 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
4052 aGroup[ k ] = *idIt;
4056 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4061 //=======================================================================
4062 //function : MergeElements
4064 //=======================================================================
4066 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4070 TPythonDump aTPythonDump;
4071 aTPythonDump << this << ".MergeElements( [";
4073 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4075 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4076 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4077 aListOfListOfElementsID.push_back( list< int >() );
4078 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4079 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4080 CORBA::Long id = anElemsIDGroup[ j ];
4081 aListOfElemsID.push_back( id );
4083 if ( aListOfElemsID.size() < 2 )
4084 aListOfListOfElementsID.pop_back();
4085 if ( i > 0 ) aTPythonDump << ", ";
4086 aTPythonDump << anElemsIDGroup;
4089 ::SMESH_MeshEditor anEditor( myMesh );
4090 anEditor.MergeElements(aListOfListOfElementsID);
4091 myMesh->GetMeshDS()->Modified();
4092 myMesh->SetIsModified( true );
4094 aTPythonDump << "] )";
4097 //=======================================================================
4098 //function : MergeEqualElements
4100 //=======================================================================
4102 void SMESH_MeshEditor_i::MergeEqualElements()
4106 ::SMESH_MeshEditor anEditor( myMesh );
4107 anEditor.MergeEqualElements();
4109 TPythonDump() << this << ".MergeEqualElements()";
4112 //=============================================================================
4114 * Move the node to a given point
4116 //=============================================================================
4118 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4123 initData(/*deleteSearchers=*/false);
4125 const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
4129 if ( theNodeSearcher )
4130 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4132 if ( myPreviewMode ) // make preview data
4134 // in a preview mesh, make edges linked to a node
4135 TPreviewMesh tmpMesh;
4136 TIDSortedElemSet linkedNodes;
4137 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4138 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4139 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4140 for ( ; nIt != linkedNodes.end(); ++nIt )
4142 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4143 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4147 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4148 // fill preview data
4149 ::SMESH_MeshEditor anEditor( & tmpMesh );
4150 storeResult( anEditor );
4152 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4153 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4155 GetMeshDS()->MoveNode(node, x, y, z);
4157 if ( !myPreviewMode )
4159 // Update Python script
4160 TPythonDump() << "isDone = " << this << ".MoveNode( "
4161 << NodeID << ", " << x << ", " << y << ", " << z << " )";
4162 myMesh->GetMeshDS()->Modified();
4163 myMesh->SetIsModified( true );
4169 //================================================================================
4171 * \brief Return ID of node closest to a given point
4173 //================================================================================
4175 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4179 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4181 if ( !theNodeSearcher ) {
4182 ::SMESH_MeshEditor anEditor( myMesh );
4183 theNodeSearcher = anEditor.GetNodeSearcher();
4186 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4187 return node->GetID();
4192 //================================================================================
4194 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4195 * move the node closest to the point to point's location and return ID of the node
4197 //================================================================================
4199 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4202 CORBA::Long theNodeID)
4204 // We keep theNodeSearcher until any mesh modification:
4205 // 1) initData() deletes theNodeSearcher at any edition,
4206 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4208 initData(/*deleteSearchers=*/false);
4210 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4212 int nodeID = theNodeID;
4213 const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
4214 if ( !node ) // preview moving node
4216 if ( !theNodeSearcher ) {
4217 ::SMESH_MeshEditor anEditor( myMesh );
4218 theNodeSearcher = anEditor.GetNodeSearcher();
4221 node = theNodeSearcher->FindClosestTo( p );
4224 nodeID = node->GetID();
4225 if ( myPreviewMode ) // make preview data
4227 // in a preview mesh, make edges linked to a node
4228 TPreviewMesh tmpMesh;
4229 TIDSortedElemSet linkedNodes;
4230 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4231 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4232 for ( ; nIt != linkedNodes.end(); ++nIt )
4234 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4235 tmpMesh.Copy( &edge );
4238 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4240 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4241 // fill preview data
4242 ::SMESH_MeshEditor anEditor( & tmpMesh );
4243 storeResult( anEditor );
4245 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4247 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4251 GetMeshDS()->MoveNode(node, x, y, z);
4255 if ( !myPreviewMode )
4257 TPythonDump() << "nodeID = " << this
4258 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4259 << ", " << nodeID << " )";
4261 myMesh->GetMeshDS()->Modified();
4262 myMesh->SetIsModified( true );
4268 //=======================================================================
4270 * Return elements of given type where the given point is IN or ON.
4272 * 'ALL' type means elements of any type excluding nodes
4274 //=======================================================================
4276 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4279 SMESH::ElementType type)
4281 SMESH::long_array_var res = new SMESH::long_array;
4282 vector< const SMDS_MeshElement* > foundElems;
4284 theSearchersDeleter.Set( myMesh );
4285 if ( !theElementSearcher ) {
4286 ::SMESH_MeshEditor anEditor( myMesh );
4287 theElementSearcher = anEditor.GetElementSearcher();
4289 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4290 SMDSAbs_ElementType( type ),
4292 res->length( foundElems.size() );
4293 for ( int i = 0; i < foundElems.size(); ++i )
4294 res[i] = foundElems[i]->GetID();
4296 if ( !myPreviewMode ) // call from tui
4297 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4306 //=======================================================================
4307 //function : FindAmongElementsByPoint
4308 //purpose : Searching among the given elements, return elements of given type
4309 // where the given point is IN or ON.
4310 // 'ALL' type means elements of any type excluding nodes
4311 //=======================================================================
4314 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4318 SMESH::ElementType type)
4320 SMESH::long_array_var res = new SMESH::long_array;
4322 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4323 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4324 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D ) &&
4325 type != types[0] ) // but search of elements of dim > 0
4328 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4329 return FindElementsByPoint( x,y,z, type );
4331 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( elementIDs );
4332 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( elementIDs ))
4333 // take into account passible group modification
4334 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
4335 partIOR += SMESH_Comment( type );
4337 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4339 theSearchersDeleter.Set( myMesh, partIOR );
4340 if ( !theElementSearcher )
4342 // create a searcher from elementIDs
4343 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4344 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4346 if ( !idSourceToSet( elementIDs, meshDS, elements,
4347 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4350 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4351 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4353 ::SMESH_MeshEditor anEditor( myMesh );
4354 theElementSearcher = anEditor.GetElementSearcher(elemsIt);
4357 vector< const SMDS_MeshElement* > foundElems;
4359 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4360 SMDSAbs_ElementType( type ),
4362 res->length( foundElems.size() );
4363 for ( int i = 0; i < foundElems.size(); ++i )
4364 res[i] = foundElems[i]->GetID();
4366 if ( !myPreviewMode ) // call from tui
4367 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4368 << elementIDs << ", "
4377 //=======================================================================
4378 //function : GetPointState
4379 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4380 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4381 //=======================================================================
4383 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4387 theSearchersDeleter.Set( myMesh );
4388 if ( !theElementSearcher ) {
4389 ::SMESH_MeshEditor anEditor( myMesh );
4390 theElementSearcher = anEditor.GetElementSearcher();
4392 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4395 //=======================================================================
4396 //function : convError
4398 //=======================================================================
4400 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4402 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4406 RETCASE( SEW_BORDER1_NOT_FOUND );
4407 RETCASE( SEW_BORDER2_NOT_FOUND );
4408 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4409 RETCASE( SEW_BAD_SIDE_NODES );
4410 RETCASE( SEW_VOLUMES_TO_SPLIT );
4411 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4412 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4413 RETCASE( SEW_BAD_SIDE1_NODES );
4414 RETCASE( SEW_BAD_SIDE2_NODES );
4416 return SMESH::SMESH_MeshEditor::SEW_OK;
4419 //=======================================================================
4420 //function : SewFreeBorders
4422 //=======================================================================
4424 SMESH::SMESH_MeshEditor::Sew_Error
4425 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4426 CORBA::Long SecondNodeID1,
4427 CORBA::Long LastNodeID1,
4428 CORBA::Long FirstNodeID2,
4429 CORBA::Long SecondNodeID2,
4430 CORBA::Long LastNodeID2,
4431 CORBA::Boolean CreatePolygons,
4432 CORBA::Boolean CreatePolyedrs)
4436 SMESHDS_Mesh* aMesh = GetMeshDS();
4438 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4439 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4440 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4441 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4442 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4443 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4445 if (!aBorderFirstNode ||
4446 !aBorderSecondNode||
4448 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4449 if (!aSide2FirstNode ||
4450 !aSide2SecondNode ||
4452 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4454 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4455 << FirstNodeID1 << ", "
4456 << SecondNodeID1 << ", "
4457 << LastNodeID1 << ", "
4458 << FirstNodeID2 << ", "
4459 << SecondNodeID2 << ", "
4460 << LastNodeID2 << ", "
4461 << CreatePolygons<< ", "
4462 << CreatePolyedrs<< " )";
4464 ::SMESH_MeshEditor anEditor( myMesh );
4465 SMESH::SMESH_MeshEditor::Sew_Error error =
4466 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4476 storeResult(anEditor);
4478 myMesh->GetMeshDS()->Modified();
4479 myMesh->SetIsModified( true );
4485 //=======================================================================
4486 //function : SewConformFreeBorders
4488 //=======================================================================
4490 SMESH::SMESH_MeshEditor::Sew_Error
4491 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4492 CORBA::Long SecondNodeID1,
4493 CORBA::Long LastNodeID1,
4494 CORBA::Long FirstNodeID2,
4495 CORBA::Long SecondNodeID2)
4499 SMESHDS_Mesh* aMesh = GetMeshDS();
4501 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4502 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4503 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4504 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4505 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4506 const SMDS_MeshNode* aSide2ThirdNode = 0;
4508 if (!aBorderFirstNode ||
4509 !aBorderSecondNode||
4511 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4512 if (!aSide2FirstNode ||
4514 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4516 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4517 << FirstNodeID1 << ", "
4518 << SecondNodeID1 << ", "
4519 << LastNodeID1 << ", "
4520 << FirstNodeID2 << ", "
4521 << SecondNodeID2 << " )";
4523 ::SMESH_MeshEditor anEditor( myMesh );
4524 SMESH::SMESH_MeshEditor::Sew_Error error =
4525 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4534 storeResult(anEditor);
4536 myMesh->GetMeshDS()->Modified();
4537 myMesh->SetIsModified( true );
4543 //=======================================================================
4544 //function : SewBorderToSide
4546 //=======================================================================
4548 SMESH::SMESH_MeshEditor::Sew_Error
4549 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4550 CORBA::Long SecondNodeIDOnFreeBorder,
4551 CORBA::Long LastNodeIDOnFreeBorder,
4552 CORBA::Long FirstNodeIDOnSide,
4553 CORBA::Long LastNodeIDOnSide,
4554 CORBA::Boolean CreatePolygons,
4555 CORBA::Boolean CreatePolyedrs)
4559 SMESHDS_Mesh* aMesh = GetMeshDS();
4561 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4562 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4563 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4564 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4565 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4566 const SMDS_MeshNode* aSide2ThirdNode = 0;
4568 if (!aBorderFirstNode ||
4569 !aBorderSecondNode||
4571 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4572 if (!aSide2FirstNode ||
4574 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4576 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4577 << FirstNodeIDOnFreeBorder << ", "
4578 << SecondNodeIDOnFreeBorder << ", "
4579 << LastNodeIDOnFreeBorder << ", "
4580 << FirstNodeIDOnSide << ", "
4581 << LastNodeIDOnSide << ", "
4582 << CreatePolygons << ", "
4583 << CreatePolyedrs << ") ";
4585 ::SMESH_MeshEditor anEditor( myMesh );
4586 SMESH::SMESH_MeshEditor::Sew_Error error =
4587 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4597 storeResult(anEditor);
4599 myMesh->GetMeshDS()->Modified();
4600 myMesh->SetIsModified( true );
4606 //=======================================================================
4607 //function : SewSideElements
4609 //=======================================================================
4611 SMESH::SMESH_MeshEditor::Sew_Error
4612 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
4613 const SMESH::long_array& IDsOfSide2Elements,
4614 CORBA::Long NodeID1OfSide1ToMerge,
4615 CORBA::Long NodeID1OfSide2ToMerge,
4616 CORBA::Long NodeID2OfSide1ToMerge,
4617 CORBA::Long NodeID2OfSide2ToMerge)
4621 SMESHDS_Mesh* aMesh = GetMeshDS();
4623 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
4624 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
4625 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
4626 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
4628 if (!aFirstNode1ToMerge ||
4629 !aFirstNode2ToMerge )
4630 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
4631 if (!aSecondNode1ToMerge||
4632 !aSecondNode2ToMerge)
4633 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
4635 TIDSortedElemSet aSide1Elems, aSide2Elems;
4636 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
4637 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
4639 TPythonDump() << "error = " << this << ".SewSideElements( "
4640 << IDsOfSide1Elements << ", "
4641 << IDsOfSide2Elements << ", "
4642 << NodeID1OfSide1ToMerge << ", "
4643 << NodeID1OfSide2ToMerge << ", "
4644 << NodeID2OfSide1ToMerge << ", "
4645 << NodeID2OfSide2ToMerge << ")";
4647 ::SMESH_MeshEditor anEditor( myMesh );
4648 SMESH::SMESH_MeshEditor::Sew_Error error =
4649 convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
4652 aSecondNode1ToMerge,
4653 aSecondNode2ToMerge));
4655 storeResult(anEditor);
4657 myMesh->GetMeshDS()->Modified();
4658 myMesh->SetIsModified( true );
4663 //================================================================================
4665 * \brief Set new nodes for given element
4666 * \param ide - element id
4667 * \param newIDs - new node ids
4668 * \retval CORBA::Boolean - true if result is OK
4670 //================================================================================
4672 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
4673 const SMESH::long_array& newIDs)
4677 const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
4678 if(!elem) return false;
4680 int nbn = newIDs.length();
4682 vector<const SMDS_MeshNode*> aNodes(nbn);
4685 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
4688 aNodes[nbn1] = aNode;
4691 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
4692 << ide << ", " << newIDs << " )";
4694 MESSAGE("ChangeElementNodes");
4695 bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
4697 myMesh->GetMeshDS()->Modified();
4699 myMesh->SetIsModified( true );
4704 //================================================================================
4706 * \brief Update myLastCreated* or myPreviewData
4707 * \param anEditor - it contains last modification results
4709 //================================================================================
4711 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
4713 if ( myPreviewMode ) { // --- MeshPreviewStruct filling ---
4715 list<int> aNodesConnectivity;
4716 typedef map<int, int> TNodesMap;
4719 TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
4720 SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
4722 SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
4723 int nbEdges = aMeshDS->NbEdges();
4724 int nbFaces = aMeshDS->NbFaces();
4725 int nbVolum = aMeshDS->NbVolumes();
4726 switch ( previewType ) {
4727 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
4728 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
4729 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
4732 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
4733 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
4735 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
4737 while ( itMeshElems->more() ) {
4738 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
4739 if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
4742 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
4743 while ( itElemNodes->more() ) {
4744 const SMDS_MeshNode* aMeshNode =
4745 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
4746 int aNodeID = aMeshNode->GetID();
4747 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
4748 if ( anIter == nodesMap.end() ) {
4749 // filling the nodes coordinates
4750 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
4751 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
4752 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
4753 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
4756 aNodesConnectivity.push_back(anIter->second);
4759 // filling the elements types
4760 SMDSAbs_ElementType aType;
4762 /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
4763 aType = SMDSAbs_Node;
4767 aType = aMeshElem->GetType();
4768 isPoly = aMeshElem->IsPoly();
4771 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
4772 myPreviewData->elementTypes[i].isPoly = isPoly;
4773 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
4777 myPreviewData->nodesXYZ.length( j );
4779 // filling the elements connectivities
4780 list<int>::iterator aConnIter = aNodesConnectivity.begin();
4781 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
4782 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
4783 myPreviewData->elementConnectivities[i] = *aConnIter;
4789 // append new nodes into myLastCreatedNodes
4790 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
4791 int j = myLastCreatedNodes->length();
4792 int newLen = j + aSeq.Length();
4793 myLastCreatedNodes->length( newLen );
4794 for(int i=0; j<newLen; i++,j++)
4795 myLastCreatedNodes[j] = aSeq.Value(i+1)->GetID();
4798 // append new elements into myLastCreatedElems
4799 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
4800 int j = myLastCreatedElems->length();
4801 int newLen = j + aSeq.Length();
4802 myLastCreatedElems->length( newLen );
4803 for(int i=0; j<newLen; i++,j++)
4804 myLastCreatedElems[j] = aSeq.Value(i+1)->GetID();
4808 //================================================================================
4810 * Return data of mesh edition preview
4812 //================================================================================
4814 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
4816 return myPreviewData._retn();
4819 //================================================================================
4821 * \brief Returns list of it's IDs of created nodes
4822 * \retval SMESH::long_array* - list of node ID
4824 //================================================================================
4826 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
4828 return myLastCreatedNodes._retn();
4831 //================================================================================
4833 * \brief Returns list of it's IDs of created elements
4834 * \retval SMESH::long_array* - list of elements' ID
4836 //================================================================================
4838 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
4840 return myLastCreatedElems._retn();
4843 //=======================================================================
4844 //function : ConvertToQuadratic
4846 //=======================================================================
4848 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
4850 ::SMESH_MeshEditor anEditor( myMesh );
4851 anEditor.ConvertToQuadratic(theForce3d);
4852 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
4853 myMesh->GetMeshDS()->Modified();
4854 myMesh->SetIsModified( true );
4857 //=======================================================================
4858 //function : ConvertFromQuadratic
4860 //=======================================================================
4862 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
4864 ::SMESH_MeshEditor anEditor( myMesh );
4865 CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
4866 TPythonDump() << this << ".ConvertFromQuadratic()";
4867 myMesh->GetMeshDS()->Modified();
4869 myMesh->SetIsModified( true );
4872 //================================================================================
4874 * \brief Makes a part of the mesh quadratic
4876 //================================================================================
4878 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
4879 SMESH::SMESH_IDSource_ptr theObject)
4880 throw (SALOME::SALOME_Exception)
4882 Unexpect aCatch(SALOME_SalomeException);
4884 TIDSortedElemSet elems;
4885 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4887 if ( elems.empty() )
4889 ConvertToQuadratic( theForce3d );
4891 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4893 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4897 ::SMESH_MeshEditor anEditor( myMesh );
4898 anEditor.ConvertToQuadratic(theForce3d, elems);
4901 myMesh->GetMeshDS()->Modified();
4902 myMesh->SetIsModified( true );
4904 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
4907 //================================================================================
4909 * \brief Makes a part of the mesh linear
4911 //================================================================================
4913 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
4914 throw (SALOME::SALOME_Exception)
4916 Unexpect aCatch(SALOME_SalomeException);
4918 TIDSortedElemSet elems;
4919 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4921 if ( elems.empty() )
4923 ConvertFromQuadratic();
4925 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4927 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4931 ::SMESH_MeshEditor anEditor( myMesh );
4932 anEditor.ConvertFromQuadratic(elems);
4935 myMesh->GetMeshDS()->Modified();
4936 myMesh->SetIsModified( true );
4938 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
4941 //=======================================================================
4942 //function : makeMesh
4943 //purpose : create a named imported mesh
4944 //=======================================================================
4946 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
4948 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
4949 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
4950 SALOMEDS::Study_var study = gen->GetCurrentStudy();
4951 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
4952 gen->SetName( meshSO, theMeshName, "Mesh" );
4953 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
4955 return mesh._retn();
4958 //=======================================================================
4959 //function : DumpGroupsList
4961 //=======================================================================
4962 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
4963 const SMESH::ListOfGroups * theGroupList)
4965 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
4966 if(isDumpGroupList) {
4967 theDumpPython << theGroupList << " = ";
4971 //================================================================================
4973 \brief Generates the unique group name.
4974 \param thePrefix name prefix
4977 //================================================================================
4978 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
4980 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
4981 set<string> groupNames;
4983 // Get existing group names
4984 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
4985 SMESH::SMESH_GroupBase_var aGroup = groups[i];
4986 if (CORBA::is_nil(aGroup))
4989 groupNames.insert(aGroup->GetName());
4993 string name = thePrefix;
4996 while (!groupNames.insert(name).second) {
5001 TCollection_AsciiString nbStr(index+1);
5002 name.resize( name.rfind('_')+1 );
5003 name += nbStr.ToCString();
5011 //================================================================================
5013 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5014 \param theNodes - identifiers of nodes to be doubled
5015 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5016 nodes. If list of element identifiers is empty then nodes are doubled but
5017 they not assigned to elements
5018 \return TRUE if operation has been completed successfully, FALSE otherwise
5019 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5021 //================================================================================
5023 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5024 const SMESH::long_array& theModifiedElems )
5028 ::SMESH_MeshEditor aMeshEditor( myMesh );
5029 list< int > aListOfNodes;
5031 for ( i = 0, n = theNodes.length(); i < n; i++ )
5032 aListOfNodes.push_back( theNodes[ i ] );
5034 list< int > aListOfElems;
5035 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5036 aListOfElems.push_back( theModifiedElems[ i ] );
5038 bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
5040 myMesh->GetMeshDS()->Modified();
5041 storeResult( aMeshEditor) ;
5043 myMesh->SetIsModified( true );
5045 // Update Python script
5046 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5051 //================================================================================
5053 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5054 This method provided for convenience works as DoubleNodes() described above.
5055 \param theNodeId - identifier of node to be doubled.
5056 \param theModifiedElems - identifiers of elements to be updated.
5057 \return TRUE if operation has been completed successfully, FALSE otherwise
5058 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5060 //================================================================================
5062 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5063 const SMESH::long_array& theModifiedElems )
5065 SMESH::long_array_var aNodes = new SMESH::long_array;
5066 aNodes->length( 1 );
5067 aNodes[ 0 ] = theNodeId;
5069 TPythonDump pyDump; // suppress dump by the next line
5071 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5073 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5078 //================================================================================
5080 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5081 This method provided for convenience works as DoubleNodes() described above.
5082 \param theNodes - group of nodes to be doubled.
5083 \param theModifiedElems - group of elements to be updated.
5084 \return TRUE if operation has been completed successfully, FALSE otherwise
5085 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5087 //================================================================================
5089 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5090 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5092 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5095 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5096 SMESH::long_array_var aModifiedElems;
5097 if ( !CORBA::is_nil( theModifiedElems ) )
5098 aModifiedElems = theModifiedElems->GetListOfID();
5101 aModifiedElems = new SMESH::long_array;
5102 aModifiedElems->length( 0 );
5105 TPythonDump pyDump; // suppress dump by the next line
5107 bool done = DoubleNodes( aNodes, aModifiedElems );
5109 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5115 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5116 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5117 * \param theNodes - group of nodes to be doubled.
5118 * \param theModifiedElems - group of elements to be updated.
5119 * \return a new group with newly created nodes
5120 * \sa DoubleNodeGroup()
5122 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5123 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5125 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5128 SMESH::SMESH_Group_var aNewGroup;
5131 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5132 SMESH::long_array_var aModifiedElems;
5133 if ( !CORBA::is_nil( theModifiedElems ) )
5134 aModifiedElems = theModifiedElems->GetListOfID();
5136 aModifiedElems = new SMESH::long_array;
5137 aModifiedElems->length( 0 );
5140 TPythonDump pyDump; // suppress dump by the next line
5142 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5146 // Create group with newly created nodes
5147 SMESH::long_array_var anIds = GetLastCreatedNodes();
5148 if (anIds->length() > 0) {
5149 string anUnindexedName (theNodes->GetName());
5150 string aNewName = generateGroupName(anUnindexedName + "_double");
5151 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5152 aNewGroup->Add(anIds);
5156 pyDump << "createdNodes = " << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5157 << theModifiedElems << " )";
5159 return aNewGroup._retn();
5162 //================================================================================
5164 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5165 This method provided for convenience works as DoubleNodes() described above.
5166 \param theNodes - list of groups of nodes to be doubled
5167 \param theModifiedElems - list of groups of elements to be updated.
5168 \return TRUE if operation has been completed successfully, FALSE otherwise
5169 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5171 //================================================================================
5173 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5174 const SMESH::ListOfGroups& theModifiedElems )
5178 ::SMESH_MeshEditor aMeshEditor( myMesh );
5180 std::list< int > aNodes;
5182 for ( i = 0, n = theNodes.length(); i < n; i++ )
5184 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5185 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5187 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5188 for ( j = 0, m = aCurr->length(); j < m; j++ )
5189 aNodes.push_back( aCurr[ j ] );
5193 std::list< int > anElems;
5194 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5196 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5197 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5199 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5200 for ( j = 0, m = aCurr->length(); j < m; j++ )
5201 anElems.push_back( aCurr[ j ] );
5205 bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
5207 storeResult( aMeshEditor) ;
5209 myMesh->GetMeshDS()->Modified();
5211 myMesh->SetIsModified( true );
5214 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5219 //================================================================================
5221 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5222 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5223 * \param theNodes - group of nodes to be doubled.
5224 * \param theModifiedElems - group of elements to be updated.
5225 * \return a new group with newly created nodes
5226 * \sa DoubleNodeGroups()
5228 //================================================================================
5230 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5231 const SMESH::ListOfGroups& theModifiedElems )
5233 SMESH::SMESH_Group_var aNewGroup;
5235 TPythonDump pyDump; // suppress dump by the next line
5237 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5241 // Create group with newly created nodes
5242 SMESH::long_array_var anIds = GetLastCreatedNodes();
5243 if (anIds->length() > 0) {
5244 string anUnindexedName (theNodes[0]->GetName());
5245 string aNewName = generateGroupName(anUnindexedName + "_double");
5246 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5247 aNewGroup->Add(anIds);
5251 pyDump << "createdNodes = " << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5252 << theModifiedElems << " )";
5254 return aNewGroup._retn();
5258 //================================================================================
5260 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5261 \param theElems - the list of elements (edges or faces) to be replicated
5262 The nodes for duplication could be found from these elements
5263 \param theNodesNot - list of nodes to NOT replicate
5264 \param theAffectedElems - the list of elements (cells and edges) to which the
5265 replicated nodes should be associated to.
5266 \return TRUE if operation has been completed successfully, FALSE otherwise
5267 \sa DoubleNodeGroup(), DoubleNodeGroups()
5269 //================================================================================
5271 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5272 const SMESH::long_array& theNodesNot,
5273 const SMESH::long_array& theAffectedElems )
5278 ::SMESH_MeshEditor aMeshEditor( myMesh );
5280 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5281 TIDSortedElemSet anElems, aNodes, anAffected;
5282 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5283 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5284 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5286 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5288 storeResult( aMeshEditor) ;
5290 myMesh->GetMeshDS()->Modified();
5292 myMesh->SetIsModified( true );
5294 // Update Python script
5295 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5296 << theNodesNot << ", " << theAffectedElems << " )";
5300 //================================================================================
5302 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5303 \param theElems - the list of elements (edges or faces) to be replicated
5304 The nodes for duplication could be found from these elements
5305 \param theNodesNot - list of nodes to NOT replicate
5306 \param theShape - shape to detect affected elements (element which geometric center
5307 located on or inside shape).
5308 The replicated nodes should be associated to affected elements.
5309 \return TRUE if operation has been completed successfully, FALSE otherwise
5310 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5312 //================================================================================
5314 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5315 const SMESH::long_array& theNodesNot,
5316 GEOM::GEOM_Object_ptr theShape )
5321 ::SMESH_MeshEditor aMeshEditor( myMesh );
5323 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5324 TIDSortedElemSet anElems, aNodes;
5325 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5326 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5328 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5329 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5331 storeResult( aMeshEditor) ;
5333 myMesh->GetMeshDS()->Modified();
5335 myMesh->SetIsModified( true );
5337 // Update Python script
5338 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5339 << theNodesNot << ", " << theShape << " )";
5343 //================================================================================
5345 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5346 \param theElems - group of of elements (edges or faces) to be replicated
5347 \param theNodesNot - group of nodes not to replicated
5348 \param theAffectedElems - group of elements to which the replicated nodes
5349 should be associated to.
5350 \return TRUE if operation has been completed successfully, FALSE otherwise
5351 \sa DoubleNodes(), DoubleNodeGroups()
5353 //================================================================================
5355 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5356 SMESH::SMESH_GroupBase_ptr theNodesNot,
5357 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5359 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5364 ::SMESH_MeshEditor aMeshEditor( myMesh );
5366 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5367 TIDSortedElemSet anElems, aNodes, anAffected;
5368 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5369 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5370 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5372 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5374 storeResult( aMeshEditor) ;
5376 myMesh->GetMeshDS()->Modified();
5378 myMesh->SetIsModified( true );
5380 // Update Python script
5381 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5382 << theNodesNot << ", " << theAffectedElems << " )";
5387 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5388 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5389 * \param theElems - group of of elements (edges or faces) to be replicated
5390 * \param theNodesNot - group of nodes not to replicated
5391 * \param theAffectedElems - group of elements to which the replicated nodes
5392 * should be associated to.
5393 * \return a new group with newly created elements
5394 * \sa DoubleNodeElemGroup()
5396 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5397 SMESH::SMESH_GroupBase_ptr theNodesNot,
5398 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5400 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5403 SMESH::SMESH_Group_var aNewGroup;
5407 ::SMESH_MeshEditor aMeshEditor( myMesh );
5409 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5410 TIDSortedElemSet anElems, aNodes, anAffected;
5411 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5412 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5413 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5416 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5418 storeResult( aMeshEditor) ;
5421 myMesh->SetIsModified( true );
5423 // Create group with newly created elements
5424 SMESH::long_array_var anIds = GetLastCreatedElems();
5425 if (anIds->length() > 0) {
5426 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5427 string anUnindexedName (theElems->GetName());
5428 string aNewName = generateGroupName(anUnindexedName + "_double");
5429 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5430 aNewGroup->Add(anIds);
5434 // Update Python script
5435 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupNew( " << theElems << ", "
5436 << theNodesNot << ", " << theAffectedElems << " )";
5437 return aNewGroup._retn();
5440 //================================================================================
5442 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5443 \param theElems - group of of elements (edges or faces) to be replicated
5444 \param theNodesNot - group of nodes not to replicated
5445 \param theShape - shape to detect affected elements (element which geometric center
5446 located on or inside shape).
5447 The replicated nodes should be associated to affected elements.
5448 \return TRUE if operation has been completed successfully, FALSE otherwise
5449 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5451 //================================================================================
5453 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5454 SMESH::SMESH_GroupBase_ptr theNodesNot,
5455 GEOM::GEOM_Object_ptr theShape )
5458 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5463 ::SMESH_MeshEditor aMeshEditor( myMesh );
5465 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5466 TIDSortedElemSet anElems, aNodes, anAffected;
5467 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5468 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5470 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5471 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5473 storeResult( aMeshEditor) ;
5475 myMesh->GetMeshDS()->Modified();
5477 myMesh->SetIsModified( true );
5479 // Update Python script
5480 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5481 << theNodesNot << ", " << theShape << " )";
5485 //================================================================================
5487 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5488 This method provided for convenience works as DoubleNodes() described above.
5489 \param theElems - list of groups of elements (edges or faces) to be replicated
5490 \param theNodesNot - list of groups of nodes not to replicated
5491 \param theAffectedElems - group of elements to which the replicated nodes
5492 should be associated to.
5493 \return TRUE if operation has been completed successfully, FALSE otherwise
5494 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5496 //================================================================================
5498 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5499 SMESHDS_Mesh* theMeshDS,
5500 TIDSortedElemSet& theElemSet,
5501 const bool theIsNodeGrp)
5503 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5505 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5506 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5507 : aGrp->GetType() != SMESH::NODE ) )
5509 SMESH::long_array_var anIDs = aGrp->GetIDs();
5510 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5515 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5516 const SMESH::ListOfGroups& theNodesNot,
5517 const SMESH::ListOfGroups& theAffectedElems)
5521 ::SMESH_MeshEditor aMeshEditor( myMesh );
5523 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5524 TIDSortedElemSet anElems, aNodes, anAffected;
5525 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5526 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5527 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5529 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5531 storeResult( aMeshEditor) ;
5533 myMesh->GetMeshDS()->Modified();
5535 myMesh->SetIsModified( true );
5537 // Update Python script
5538 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5539 << &theNodesNot << ", " << &theAffectedElems << " )";
5543 //================================================================================
5545 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5546 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5547 \param theElems - list of groups of elements (edges or faces) to be replicated
5548 \param theNodesNot - list of groups of nodes not to replicated
5549 \param theAffectedElems - group of elements to which the replicated nodes
5550 should be associated to.
5551 * \return a new group with newly created elements
5552 * \sa DoubleNodeElemGroups()
5554 //================================================================================
5556 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5557 const SMESH::ListOfGroups& theNodesNot,
5558 const SMESH::ListOfGroups& theAffectedElems)
5560 SMESH::SMESH_Group_var aNewGroup;
5564 ::SMESH_MeshEditor aMeshEditor( myMesh );
5566 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5567 TIDSortedElemSet anElems, aNodes, anAffected;
5568 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5569 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5570 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5572 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5574 storeResult( aMeshEditor) ;
5576 myMesh->GetMeshDS()->Modified();
5578 myMesh->SetIsModified( true );
5580 // Create group with newly created elements
5581 SMESH::long_array_var anIds = GetLastCreatedElems();
5582 if (anIds->length() > 0) {
5583 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5584 string anUnindexedName (theElems[0]->GetName());
5585 string aNewName = generateGroupName(anUnindexedName + "_double");
5586 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5587 aNewGroup->Add(anIds);
5591 // Update Python script
5592 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupsNew( " << &theElems << ", "
5593 << &theNodesNot << ", " << &theAffectedElems << " )";
5594 return aNewGroup._retn();
5597 //================================================================================
5599 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5600 This method provided for convenience works as DoubleNodes() described above.
5601 \param theElems - list of groups of elements (edges or faces) to be replicated
5602 \param theNodesNot - list of groups of nodes not to replicated
5603 \param theShape - shape to detect affected elements (element which geometric center
5604 located on or inside shape).
5605 The replicated nodes should be associated to affected elements.
5606 \return TRUE if operation has been completed successfully, FALSE otherwise
5607 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
5609 //================================================================================
5612 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
5613 const SMESH::ListOfGroups& theNodesNot,
5614 GEOM::GEOM_Object_ptr theShape )
5618 ::SMESH_MeshEditor aMeshEditor( myMesh );
5620 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5621 TIDSortedElemSet anElems, aNodes;
5622 listOfGroupToSet(theElems, aMeshDS, anElems,false );
5623 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5625 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5626 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5628 storeResult( aMeshEditor) ;
5630 myMesh->GetMeshDS()->Modified();
5632 myMesh->SetIsModified( true );
5634 // Update Python script
5635 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
5636 << &theNodesNot << ", " << theShape << " )";
5640 //================================================================================
5642 \brief Generated skin mesh (containing 2D cells) from 3D mesh
5643 The created 2D mesh elements based on nodes of free faces of boundary volumes
5644 \return TRUE if operation has been completed successfully, FALSE otherwise
5646 //================================================================================
5648 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
5652 ::SMESH_MeshEditor aMeshEditor( myMesh );
5653 bool aResult = aMeshEditor.Make2DMeshFrom3D();
5654 storeResult( aMeshEditor) ;
5655 myMesh->GetMeshDS()->Modified();
5656 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
5660 //================================================================================
5662 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
5663 * The list of groups must describe a partition of the mesh volumes.
5664 * The nodes of the internal faces at the boundaries of the groups are doubled.
5665 * In option, the internal faces are replaced by flat elements.
5666 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5667 * The flat elements are stored in groups of volumes.
5668 * @param theDomains - list of groups of volumes
5669 * @param createJointElems - if TRUE, create the elements
5670 * @return TRUE if operation has been completed successfully, FALSE otherwise
5672 //================================================================================
5674 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
5675 CORBA::Boolean createJointElems )
5676 throw (SALOME::SALOME_Exception)
5680 ::SMESH_MeshEditor aMeshEditor( myMesh );
5682 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5684 vector<TIDSortedElemSet> domains;
5687 for ( int i = 0, n = theDomains.length(); i < n; i++ )
5689 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
5690 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
5692 if ( aGrp->GetType() != SMESH::VOLUME )
5693 THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
5694 TIDSortedElemSet domain;
5696 domains.push_back(domain);
5697 SMESH::long_array_var anIDs = aGrp->GetIDs();
5698 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
5702 bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
5703 // TODO publish the groups of flat elements in study
5705 storeResult( aMeshEditor) ;
5706 myMesh->GetMeshDS()->Modified();
5708 // Update Python script
5709 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
5710 << ", " << createJointElems << " )";
5714 //================================================================================
5716 * \brief Double nodes on some external faces and create flat elements.
5717 * Flat elements are mainly used by some types of mechanic calculations.
5719 * Each group of the list must be constituted of faces.
5720 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5721 * @param theGroupsOfFaces - list of groups of faces
5722 * @return TRUE if operation has been completed successfully, FALSE otherwise
5724 //================================================================================
5726 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
5730 ::SMESH_MeshEditor aMeshEditor( myMesh );
5732 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5734 vector<TIDSortedElemSet> faceGroups;
5737 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
5739 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
5740 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
5742 TIDSortedElemSet faceGroup;
5744 faceGroups.push_back(faceGroup);
5745 SMESH::long_array_var anIDs = aGrp->GetIDs();
5746 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
5750 bool aResult = aMeshEditor.CreateFlatElementsOnFacesGroups( faceGroups );
5751 // TODO publish the groups of flat elements in study
5753 storeResult( aMeshEditor) ;
5754 myMesh->GetMeshDS()->Modified();
5756 // Update Python script
5757 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
5761 // issue 20749 ===================================================================
5763 * \brief Creates missing boundary elements
5764 * \param elements - elements whose boundary is to be checked
5765 * \param dimension - defines type of boundary elements to create
5766 * \param groupName - a name of group to store created boundary elements in,
5767 * "" means not to create the group
5768 * \param meshName - a name of new mesh to store created boundary elements in,
5769 * "" means not to create the new mesh
5770 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
5771 * \param toCopyExistingBondary - if true, not only new but also pre-existing
5772 * boundary elements will be copied into the new mesh
5773 * \param group - returns the create group, if any
5774 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
5776 // ================================================================================
5778 SMESH::SMESH_Mesh_ptr
5779 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
5780 SMESH::Bnd_Dimension dim,
5781 const char* groupName,
5782 const char* meshName,
5783 CORBA::Boolean toCopyElements,
5784 CORBA::Boolean toCopyExistingBondary,
5785 SMESH::SMESH_Group_out group)
5789 if ( dim > SMESH::BND_1DFROM2D )
5790 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5792 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5794 SMESH::SMESH_Mesh_var mesh_var;
5795 SMESH::SMESH_Group_var group_var;
5799 TIDSortedElemSet elements;
5800 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
5801 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
5805 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
5806 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5808 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
5810 // group of new boundary elements
5811 SMESH_Group* smesh_group = 0;
5812 if ( strlen(groupName) )
5814 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
5815 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5816 smesh_group = group_i->GetSmeshGroup();
5820 ::SMESH_MeshEditor aMeshEditor( myMesh );
5821 aMeshEditor.MakeBoundaryMesh( elements,
5822 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5826 toCopyExistingBondary);
5827 storeResult( aMeshEditor );
5830 smesh_mesh->GetMeshDS()->Modified();
5833 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
5835 // result of MakeBoundaryMesh() is a tuple (mesh, group)
5836 if ( mesh_var->_is_nil() )
5837 pyDump << myMesh_i->_this() << ", ";
5839 pyDump << mesh_var << ", ";
5840 if ( group_var->_is_nil() )
5841 pyDump << "_NoneGroup = "; // assignment to None is forbiden
5843 pyDump << group_var << " = ";
5844 pyDump << this << ".MakeBoundaryMesh( "
5846 << "SMESH." << dimName[int(dim)] << ", "
5847 << "'" << groupName << "', "
5848 << "'" << meshName<< "', "
5849 << toCopyElements << ", "
5850 << toCopyExistingBondary << ")";
5852 group = group_var._retn();
5853 return mesh_var._retn();
5856 //================================================================================
5858 * \brief Creates missing boundary elements
5859 * \param dimension - defines type of boundary elements to create
5860 * \param groupName - a name of group to store all boundary elements in,
5861 * "" means not to create the group
5862 * \param meshName - a name of a new mesh, which is a copy of the initial
5863 * mesh + created boundary elements; "" means not to create the new mesh
5864 * \param toCopyAll - if true, the whole initial mesh will be copied into
5865 * the new mesh else only boundary elements will be copied into the new mesh
5866 * \param groups - optional groups of elements to make boundary around
5867 * \param mesh - returns the mesh where elements were added to
5868 * \param group - returns the created group, if any
5869 * \retval long - number of added boundary elements
5871 //================================================================================
5873 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
5874 const char* groupName,
5875 const char* meshName,
5876 CORBA::Boolean toCopyAll,
5877 const SMESH::ListOfIDSources& groups,
5878 SMESH::SMESH_Mesh_out mesh,
5879 SMESH::SMESH_Group_out group)
5880 throw (SALOME::SALOME_Exception)
5882 Unexpect aCatch(SALOME_SalomeException);
5886 if ( dim > SMESH::BND_1DFROM2D )
5887 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5889 // separate groups belonging to this and other mesh
5890 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
5891 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
5892 groupsOfThisMesh->length( groups.length() );
5893 groupsOfOtherMesh->length( groups.length() );
5894 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
5895 for ( int i = 0; i < groups.length(); ++i )
5897 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
5898 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
5899 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
5901 groupsOfThisMesh[ nbGroups++ ] = groups[i];
5902 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
5903 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
5905 groupsOfThisMesh->length( nbGroups );
5906 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
5911 if ( nbGroupsOfOtherMesh > 0 )
5913 // process groups belonging to another mesh
5914 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
5915 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
5916 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
5917 groupsOfOtherMesh, mesh, group );
5920 SMESH::SMESH_Mesh_var mesh_var;
5921 SMESH::SMESH_Group_var group_var;
5924 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
5925 const bool toCopyMesh = ( strlen( meshName ) > 0 );
5929 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
5931 /*toCopyGroups=*/false,
5932 /*toKeepIDs=*/true);
5934 mesh_var = makeMesh(meshName);
5936 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5937 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
5940 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
5941 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
5943 // group of boundary elements
5944 SMESH_Group* smesh_group = 0;
5945 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
5946 if ( strlen(groupName) )
5948 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
5949 group_var = mesh_i->CreateGroup( groupType, groupName );
5950 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5951 smesh_group = group_i->GetSmeshGroup();
5954 TIDSortedElemSet elements;
5956 if ( groups.length() > 0 )
5958 for ( int i = 0; i < nbGroups; ++i )
5961 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
5963 SMESH::Bnd_Dimension bdim =
5964 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
5965 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5966 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5967 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
5970 /*toCopyElements=*/false,
5971 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
5972 /*toAddExistingBondary=*/true,
5973 /*aroundElements=*/true);
5974 storeResult( aMeshEditor );
5980 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5981 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5982 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5985 /*toCopyElements=*/false,
5986 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
5987 /*toAddExistingBondary=*/true);
5988 storeResult( aMeshEditor );
5990 tgtMesh->GetMeshDS()->Modified();
5992 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
5994 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
5995 pyDump << "nbAdded, ";
5996 if ( mesh_var->_is_nil() )
5997 pyDump << myMesh_i->_this() << ", ";
5999 pyDump << mesh_var << ", ";
6000 if ( group_var->_is_nil() )
6001 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6003 pyDump << group_var << " = ";
6004 pyDump << this << ".MakeBoundaryElements( "
6005 << "SMESH." << dimName[int(dim)] << ", "
6006 << "'" << groupName << "', "
6007 << "'" << meshName<< "', "
6008 << toCopyAll << ", "
6011 mesh = mesh_var._retn();
6012 group = group_var._retn();