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 == 9) {
664 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
665 nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
667 else if (NbNodes > 2) {
668 elem = GetMeshDS()->AddPolygonalFace(nodes);
671 // Update Python script
672 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
674 myMesh->GetMeshDS()->Modified();
676 return myMesh->SetIsModified( true ), elem->GetID();
681 //=============================================================================
685 //=============================================================================
686 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
690 int NbNodes = IDsOfNodes.length();
691 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
692 for (int i = 0; i < NbNodes; i++)
693 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
695 const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
697 // Update Python script
698 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
700 myMesh->GetMeshDS()->Modified();
701 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
704 //=============================================================================
708 //=============================================================================
710 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
714 int NbNodes = IDsOfNodes.length();
715 vector< const SMDS_MeshNode*> n(NbNodes);
716 for(int i=0;i<NbNodes;i++)
717 n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
719 SMDS_MeshElement* elem = 0;
722 case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
723 case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
724 case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
725 case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
726 case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
727 n[6],n[7],n[8],n[9]);
729 case 12:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
730 n[6],n[7],n[8],n[9],n[10],n[11]);
732 case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
733 n[7],n[8],n[9],n[10],n[11],n[12]);
735 case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
736 n[9],n[10],n[11],n[12],n[13],n[14]);
738 case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
739 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
740 n[15],n[16],n[17],n[18],n[19]);
742 case 27:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
743 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
744 n[15],n[16],n[17],n[18],n[19],
745 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
749 // Update Python script
750 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
752 myMesh->GetMeshDS()->Modified();
754 return myMesh->SetIsModified( true ), elem->GetID();
759 //=============================================================================
761 * AddPolyhedralVolume
763 //=============================================================================
764 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
765 const SMESH::long_array & Quantities)
769 int NbNodes = IDsOfNodes.length();
770 std::vector<const SMDS_MeshNode*> n (NbNodes);
771 for (int i = 0; i < NbNodes; i++)
773 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
774 if (!aNode) return 0;
778 int NbFaces = Quantities.length();
779 std::vector<int> q (NbFaces);
780 for (int j = 0; j < NbFaces; j++)
781 q[j] = Quantities[j];
783 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
785 // Update Python script
786 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
787 << IDsOfNodes << ", " << Quantities << " )";
788 myMesh->GetMeshDS()->Modified();
790 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
793 //=============================================================================
795 * AddPolyhedralVolumeByFaces
797 //=============================================================================
798 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
802 int NbFaces = IdsOfFaces.length();
803 std::vector<const SMDS_MeshNode*> poly_nodes;
804 std::vector<int> quantities (NbFaces);
806 for (int i = 0; i < NbFaces; i++) {
807 const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
808 quantities[i] = aFace->NbNodes();
810 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
812 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
816 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
818 // Update Python script
819 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
820 << IdsOfFaces << " )";
821 myMesh->GetMeshDS()->Modified();
823 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
826 //=============================================================================
828 * \brief Bind a node to a vertex
829 * \param NodeID - node ID
830 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
831 * \retval boolean - false if NodeID or VertexID is invalid
833 //=============================================================================
835 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
836 throw (SALOME::SALOME_Exception)
838 Unexpect aCatch(SALOME_SalomeException);
840 SMESHDS_Mesh * mesh = GetMeshDS();
841 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
843 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
845 if ( mesh->MaxShapeIndex() < VertexID )
846 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
848 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
849 if ( shape.ShapeType() != TopAbs_VERTEX )
850 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
852 mesh->SetNodeOnVertex( node, VertexID );
854 myMesh->SetIsModified( true );
857 //=============================================================================
859 * \brief Store node position on an edge
860 * \param NodeID - node ID
861 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
862 * \param paramOnEdge - parameter on edge where the node is located
863 * \retval boolean - false if any parameter is invalid
865 //=============================================================================
867 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
868 CORBA::Double paramOnEdge)
869 throw (SALOME::SALOME_Exception)
871 Unexpect aCatch(SALOME_SalomeException);
873 SMESHDS_Mesh * mesh = GetMeshDS();
874 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
876 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
878 if ( mesh->MaxShapeIndex() < EdgeID )
879 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
881 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
882 if ( shape.ShapeType() != TopAbs_EDGE )
883 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
886 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
887 if ( paramOnEdge < f || paramOnEdge > l )
888 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
890 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
892 myMesh->SetIsModified( true );
895 //=============================================================================
897 * \brief Store node position on a face
898 * \param NodeID - node ID
899 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
900 * \param u - U parameter on face where the node is located
901 * \param v - V parameter on face where the node is located
902 * \retval boolean - false if any parameter is invalid
904 //=============================================================================
906 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
907 CORBA::Double u, CORBA::Double v)
908 throw (SALOME::SALOME_Exception)
910 Unexpect aCatch(SALOME_SalomeException);
912 SMESHDS_Mesh * mesh = GetMeshDS();
913 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
915 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
917 if ( mesh->MaxShapeIndex() < FaceID )
918 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
920 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
921 if ( shape.ShapeType() != TopAbs_FACE )
922 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
924 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
925 bool isOut = ( u < surf.FirstUParameter() ||
926 u > surf.LastUParameter() ||
927 v < surf.FirstVParameter() ||
928 v > surf.LastVParameter() );
932 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
933 << " u( " << surf.FirstUParameter()
934 << "," << surf.LastUParameter()
935 << ") v( " << surf.FirstVParameter()
936 << "," << surf.LastVParameter() << ")" );
938 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
941 mesh->SetNodeOnFace( node, FaceID, u, v );
942 myMesh->SetIsModified( true );
945 //=============================================================================
947 * \brief Bind a node to a solid
948 * \param NodeID - node ID
949 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
950 * \retval boolean - false if NodeID or SolidID is invalid
952 //=============================================================================
954 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
955 throw (SALOME::SALOME_Exception)
957 Unexpect aCatch(SALOME_SalomeException);
959 SMESHDS_Mesh * mesh = GetMeshDS();
960 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
962 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
964 if ( mesh->MaxShapeIndex() < SolidID )
965 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
967 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
968 if ( shape.ShapeType() != TopAbs_SOLID &&
969 shape.ShapeType() != TopAbs_SHELL)
970 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
972 mesh->SetNodeInVolume( node, SolidID );
974 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
977 //=============================================================================
979 * \brief Bind an element to a shape
980 * \param ElementID - element ID
981 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
982 * \retval boolean - false if ElementID or ShapeID is invalid
984 //=============================================================================
986 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
988 throw (SALOME::SALOME_Exception)
990 Unexpect aCatch(SALOME_SalomeException);
992 SMESHDS_Mesh * mesh = GetMeshDS();
993 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
995 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
997 if ( mesh->MaxShapeIndex() < ShapeID )
998 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1000 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1001 if ( shape.ShapeType() != TopAbs_EDGE &&
1002 shape.ShapeType() != TopAbs_FACE &&
1003 shape.ShapeType() != TopAbs_SOLID &&
1004 shape.ShapeType() != TopAbs_SHELL )
1005 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1007 mesh->SetMeshElementOnShape( elem, ShapeID );
1009 myMesh->SetIsModified( true );
1012 //=============================================================================
1016 //=============================================================================
1018 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1019 CORBA::Long NodeID2)
1023 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1024 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1028 // Update Python script
1029 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1030 << NodeID1 << ", " << NodeID2 << " )";
1033 ::SMESH_MeshEditor aMeshEditor( myMesh );
1034 int ret = aMeshEditor.InverseDiag ( n1, n2 );
1035 myMesh->GetMeshDS()->Modified();
1036 myMesh->SetIsModified( true );
1040 //=============================================================================
1044 //=============================================================================
1046 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1047 CORBA::Long NodeID2)
1051 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1052 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1056 // Update Python script
1057 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1058 << NodeID1 << ", " << NodeID2 << " )";
1060 ::SMESH_MeshEditor aMeshEditor( myMesh );
1062 bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
1064 myMesh->GetMeshDS()->Modified();
1066 myMesh->SetIsModified( true ); // issue 0020693
1068 storeResult(aMeshEditor);
1073 //=============================================================================
1077 //=============================================================================
1079 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1083 ::SMESH_MeshEditor anEditor( myMesh );
1084 for (int i = 0; i < IDsOfElements.length(); i++)
1086 CORBA::Long index = IDsOfElements[i];
1087 const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
1089 anEditor.Reorient( elem );
1091 // Update Python script
1092 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1094 myMesh->GetMeshDS()->Modified();
1095 if ( IDsOfElements.length() )
1096 myMesh->SetIsModified( true ); // issue 0020693
1102 //=============================================================================
1106 //=============================================================================
1108 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1112 TPythonDump aTPythonDump; // suppress dump in Reorient()
1114 SMESH::long_array_var anElementsId = theObject->GetIDs();
1115 CORBA::Boolean isDone = Reorient(anElementsId);
1117 // Update Python script
1118 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1123 //=============================================================================
1127 //=============================================================================
1128 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1129 SMESH::NumericalFunctor_ptr Criterion,
1130 CORBA::Double MaxAngle)
1134 SMESHDS_Mesh* aMesh = GetMeshDS();
1135 TIDSortedElemSet faces;
1136 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1138 SMESH::NumericalFunctor_i* aNumericalFunctor =
1139 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1140 SMESH::Controls::NumericalFunctorPtr aCrit;
1141 if ( !aNumericalFunctor )
1142 aCrit.reset( new SMESH::Controls::AspectRatio() );
1144 aCrit = aNumericalFunctor->GetNumericalFunctor();
1146 // Update Python script
1147 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1148 << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1150 ::SMESH_MeshEditor anEditor( myMesh );
1152 bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
1153 myMesh->GetMeshDS()->Modified();
1155 myMesh->SetIsModified( true ); // issue 0020693
1157 storeResult(anEditor);
1163 //=============================================================================
1167 //=============================================================================
1168 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1169 SMESH::NumericalFunctor_ptr Criterion,
1170 CORBA::Double MaxAngle)
1174 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1175 SMESH::long_array_var anElementsId = theObject->GetIDs();
1176 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1178 SMESH::NumericalFunctor_i* aNumericalFunctor =
1179 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1181 // Update Python script
1182 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1183 << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1189 //=============================================================================
1193 //=============================================================================
1194 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1195 SMESH::NumericalFunctor_ptr Criterion)
1199 SMESHDS_Mesh* aMesh = GetMeshDS();
1200 TIDSortedElemSet faces;
1201 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1203 SMESH::NumericalFunctor_i* aNumericalFunctor =
1204 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1205 SMESH::Controls::NumericalFunctorPtr aCrit;
1206 if ( !aNumericalFunctor )
1207 aCrit.reset( new SMESH::Controls::AspectRatio() );
1209 aCrit = aNumericalFunctor->GetNumericalFunctor();
1212 // Update Python script
1213 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1215 ::SMESH_MeshEditor anEditor( myMesh );
1216 CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
1217 myMesh->GetMeshDS()->Modified();
1219 myMesh->SetIsModified( true ); // issue 0020693
1221 storeResult(anEditor);
1227 //=============================================================================
1231 //=============================================================================
1232 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1233 SMESH::NumericalFunctor_ptr Criterion)
1237 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1239 SMESH::long_array_var anElementsId = theObject->GetIDs();
1240 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1242 SMESH::NumericalFunctor_i* aNumericalFunctor =
1243 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1245 // Update Python script
1246 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1252 //=============================================================================
1256 //=============================================================================
1257 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1258 CORBA::Boolean Diag13)
1262 SMESHDS_Mesh* aMesh = GetMeshDS();
1263 TIDSortedElemSet faces;
1264 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1266 // Update Python script
1267 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1268 << IDsOfElements << ", " << Diag13 << " )";
1270 ::SMESH_MeshEditor anEditor( myMesh );
1271 CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
1272 myMesh->GetMeshDS()->Modified();
1274 myMesh->SetIsModified( true ); // issue 0020693
1277 storeResult(anEditor);
1283 //=============================================================================
1287 //=============================================================================
1288 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1289 CORBA::Boolean Diag13)
1293 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1295 SMESH::long_array_var anElementsId = theObject->GetIDs();
1296 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1298 // Update Python script
1299 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1300 << theObject << ", " << Diag13 << " )";
1306 //=============================================================================
1310 //=============================================================================
1311 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1312 SMESH::NumericalFunctor_ptr Criterion)
1316 const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1317 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1319 SMESH::NumericalFunctor_i* aNumericalFunctor =
1320 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1321 SMESH::Controls::NumericalFunctorPtr aCrit;
1322 if (aNumericalFunctor)
1323 aCrit = aNumericalFunctor->GetNumericalFunctor();
1325 aCrit.reset(new SMESH::Controls::AspectRatio());
1327 ::SMESH_MeshEditor anEditor (myMesh);
1328 return anEditor.BestSplit(quad, aCrit);
1333 //================================================================================
1335 * \brief Split volumic elements into tetrahedrons
1337 //================================================================================
1339 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1340 CORBA::Short methodFlags)
1341 throw (SALOME::SALOME_Exception)
1343 Unexpect aCatch(SALOME_SalomeException);
1347 SMESH::long_array_var anElementsId = elems->GetIDs();
1348 TIDSortedElemSet elemSet;
1349 arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume );
1351 ::SMESH_MeshEditor anEditor (myMesh);
1352 anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1353 myMesh->GetMeshDS()->Modified();
1355 storeResult(anEditor);
1357 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1358 // myMesh->SetIsModified( true ); // issue 0020693
1360 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1361 << elems << ", " << methodFlags << " )";
1364 //=======================================================================
1367 //=======================================================================
1370 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1371 const SMESH::long_array & IDsOfFixedNodes,
1372 CORBA::Long MaxNbOfIterations,
1373 CORBA::Double MaxAspectRatio,
1374 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1376 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1377 MaxAspectRatio, Method, false );
1381 //=======================================================================
1382 //function : SmoothParametric
1384 //=======================================================================
1387 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1388 const SMESH::long_array & IDsOfFixedNodes,
1389 CORBA::Long MaxNbOfIterations,
1390 CORBA::Double MaxAspectRatio,
1391 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1393 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1394 MaxAspectRatio, Method, true );
1398 //=======================================================================
1399 //function : SmoothObject
1401 //=======================================================================
1404 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1405 const SMESH::long_array & IDsOfFixedNodes,
1406 CORBA::Long MaxNbOfIterations,
1407 CORBA::Double MaxAspectRatio,
1408 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1410 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1411 MaxAspectRatio, Method, false);
1415 //=======================================================================
1416 //function : SmoothParametricObject
1418 //=======================================================================
1421 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1422 const SMESH::long_array & IDsOfFixedNodes,
1423 CORBA::Long MaxNbOfIterations,
1424 CORBA::Double MaxAspectRatio,
1425 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1427 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1428 MaxAspectRatio, Method, true);
1432 //=============================================================================
1436 //=============================================================================
1439 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1440 const SMESH::long_array & IDsOfFixedNodes,
1441 CORBA::Long MaxNbOfIterations,
1442 CORBA::Double MaxAspectRatio,
1443 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1448 SMESHDS_Mesh* aMesh = GetMeshDS();
1450 TIDSortedElemSet elements;
1451 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1453 set<const SMDS_MeshNode*> fixedNodes;
1454 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1455 CORBA::Long index = IDsOfFixedNodes[i];
1456 const SMDS_MeshNode * node = aMesh->FindNode(index);
1458 fixedNodes.insert( node );
1460 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1461 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1462 method = ::SMESH_MeshEditor::CENTROIDAL;
1464 ::SMESH_MeshEditor anEditor( myMesh );
1465 anEditor.Smooth(elements, fixedNodes, method,
1466 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1468 myMesh->GetMeshDS()->Modified();
1469 myMesh->SetIsModified( true ); // issue 0020693
1471 storeResult(anEditor);
1473 // Update Python script
1474 TPythonDump() << "isDone = " << this << "."
1475 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1476 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1477 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1478 << "SMESH.SMESH_MeshEditor."
1479 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1480 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1486 //=============================================================================
1490 //=============================================================================
1493 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1494 const SMESH::long_array & IDsOfFixedNodes,
1495 CORBA::Long MaxNbOfIterations,
1496 CORBA::Double MaxAspectRatio,
1497 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1502 TPythonDump aTPythonDump; // suppress dump in smooth()
1504 SMESH::long_array_var anElementsId = theObject->GetIDs();
1505 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1506 MaxAspectRatio, Method, IsParametric);
1508 // Update Python script
1509 aTPythonDump << "isDone = " << this << "."
1510 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1511 << theObject << ", " << IDsOfFixedNodes << ", "
1512 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1513 << "SMESH.SMESH_MeshEditor."
1514 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1515 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1521 //=============================================================================
1525 //=============================================================================
1527 void SMESH_MeshEditor_i::RenumberNodes()
1529 // Update Python script
1530 TPythonDump() << this << ".RenumberNodes()";
1532 GetMeshDS()->Renumber( true );
1536 //=============================================================================
1540 //=============================================================================
1542 void SMESH_MeshEditor_i::RenumberElements()
1544 // Update Python script
1545 TPythonDump() << this << ".RenumberElements()";
1547 GetMeshDS()->Renumber( false );
1550 //=======================================================================
1552 * \brief Return groups by their IDs
1554 //=======================================================================
1556 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1560 myMesh_i->CreateGroupServants();
1561 return myMesh_i->GetGroups( *groupIDs );
1564 //=======================================================================
1565 //function : rotationSweep
1567 //=======================================================================
1569 SMESH::ListOfGroups*
1570 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1571 const SMESH::AxisStruct & theAxis,
1572 CORBA::Double theAngleInRadians,
1573 CORBA::Long theNbOfSteps,
1574 CORBA::Double theTolerance,
1575 const bool theMakeGroups,
1576 const SMDSAbs_ElementType theElementType)
1580 TIDSortedElemSet inElements, copyElements;
1581 arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
1583 TIDSortedElemSet* workElements = & inElements;
1584 TPreviewMesh tmpMesh( SMDSAbs_Face );
1585 SMESH_Mesh* mesh = 0;
1586 bool makeWalls=true;
1587 if ( myPreviewMode )
1589 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1590 tmpMesh.Copy( inElements, copyElements, select, avoid );
1592 workElements = & copyElements;
1593 //makeWalls = false;
1600 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
1601 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1603 ::SMESH_MeshEditor anEditor( mesh );
1604 ::SMESH_MeshEditor::PGroupIDs groupIds =
1605 anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1606 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
1607 storeResult(anEditor);
1608 myMesh->GetMeshDS()->Modified();
1610 // myMesh->SetIsModified( true ); -- it does not influence Compute()
1612 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1615 //=======================================================================
1616 //function : RotationSweep
1618 //=======================================================================
1620 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1621 const SMESH::AxisStruct & theAxis,
1622 CORBA::Double theAngleInRadians,
1623 CORBA::Long theNbOfSteps,
1624 CORBA::Double theTolerance)
1626 if ( !myPreviewMode ) {
1627 TPythonDump() << this << ".RotationSweep( "
1628 << theIDsOfElements << ", "
1630 << theAngleInRadians << ", "
1631 << theNbOfSteps << ", "
1632 << theTolerance << " )";
1634 rotationSweep(theIDsOfElements,
1642 //=======================================================================
1643 //function : RotationSweepMakeGroups
1645 //=======================================================================
1647 SMESH::ListOfGroups*
1648 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1649 const SMESH::AxisStruct& theAxis,
1650 CORBA::Double theAngleInRadians,
1651 CORBA::Long theNbOfSteps,
1652 CORBA::Double theTolerance)
1654 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1656 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
1662 if (!myPreviewMode) {
1663 DumpGroupsList(aPythonDump, aGroups);
1664 aPythonDump << this << ".RotationSweepMakeGroups( "
1665 << theIDsOfElements << ", "
1667 << theAngleInRadians << ", "
1668 << theNbOfSteps << ", "
1669 << theTolerance << " )";
1674 //=======================================================================
1675 //function : RotationSweepObject
1677 //=======================================================================
1679 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1680 const SMESH::AxisStruct & theAxis,
1681 CORBA::Double theAngleInRadians,
1682 CORBA::Long theNbOfSteps,
1683 CORBA::Double theTolerance)
1685 if ( !myPreviewMode ) {
1686 TPythonDump() << this << ".RotationSweepObject( "
1687 << theObject << ", "
1689 << theAngleInRadians << ", "
1690 << theNbOfSteps << ", "
1691 << theTolerance << " )";
1693 SMESH::long_array_var anElementsId = theObject->GetIDs();
1694 rotationSweep(anElementsId,
1702 //=======================================================================
1703 //function : RotationSweepObject1D
1705 //=======================================================================
1707 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1708 const SMESH::AxisStruct & theAxis,
1709 CORBA::Double theAngleInRadians,
1710 CORBA::Long theNbOfSteps,
1711 CORBA::Double theTolerance)
1713 if ( !myPreviewMode ) {
1714 TPythonDump() << this << ".RotationSweepObject1D( "
1715 << theObject << ", "
1717 << theAngleInRadians << ", "
1718 << theNbOfSteps << ", "
1719 << theTolerance << " )";
1721 SMESH::long_array_var anElementsId = theObject->GetIDs();
1722 rotationSweep(anElementsId,
1731 //=======================================================================
1732 //function : RotationSweepObject2D
1734 //=======================================================================
1736 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1737 const SMESH::AxisStruct & theAxis,
1738 CORBA::Double theAngleInRadians,
1739 CORBA::Long theNbOfSteps,
1740 CORBA::Double theTolerance)
1742 if ( !myPreviewMode ) {
1743 TPythonDump() << this << ".RotationSweepObject2D( "
1744 << theObject << ", "
1746 << theAngleInRadians << ", "
1747 << theNbOfSteps << ", "
1748 << theTolerance << " )";
1750 SMESH::long_array_var anElementsId = theObject->GetIDs();
1751 rotationSweep(anElementsId,
1760 //=======================================================================
1761 //function : RotationSweepObjectMakeGroups
1763 //=======================================================================
1765 SMESH::ListOfGroups*
1766 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1767 const SMESH::AxisStruct& theAxis,
1768 CORBA::Double theAngleInRadians,
1769 CORBA::Long theNbOfSteps,
1770 CORBA::Double theTolerance)
1772 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1774 SMESH::long_array_var anElementsId = theObject->GetIDs();
1775 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1781 if (!myPreviewMode) {
1782 DumpGroupsList(aPythonDump, aGroups);
1783 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
1784 << theObject << ", "
1786 << theAngleInRadians << ", "
1787 << theNbOfSteps << ", "
1788 << theTolerance << " )";
1793 //=======================================================================
1794 //function : RotationSweepObject1DMakeGroups
1796 //=======================================================================
1798 SMESH::ListOfGroups*
1799 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1800 const SMESH::AxisStruct& theAxis,
1801 CORBA::Double theAngleInRadians,
1802 CORBA::Long theNbOfSteps,
1803 CORBA::Double theTolerance)
1805 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1807 SMESH::long_array_var anElementsId = theObject->GetIDs();
1808 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1815 if (!myPreviewMode) {
1816 DumpGroupsList(aPythonDump, aGroups);
1817 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
1818 << theObject << ", "
1820 << theAngleInRadians << ", "
1821 << theNbOfSteps << ", "
1822 << theTolerance << " )";
1827 //=======================================================================
1828 //function : RotationSweepObject2DMakeGroups
1830 //=======================================================================
1832 SMESH::ListOfGroups*
1833 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1834 const SMESH::AxisStruct& theAxis,
1835 CORBA::Double theAngleInRadians,
1836 CORBA::Long theNbOfSteps,
1837 CORBA::Double theTolerance)
1839 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1841 SMESH::long_array_var anElementsId = theObject->GetIDs();
1842 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1849 if (!myPreviewMode) {
1850 DumpGroupsList(aPythonDump, aGroups);
1851 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
1852 << theObject << ", "
1854 << theAngleInRadians << ", "
1855 << theNbOfSteps << ", "
1856 << theTolerance << " )";
1862 //=======================================================================
1863 //function : extrusionSweep
1865 //=======================================================================
1867 SMESH::ListOfGroups*
1868 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
1869 const SMESH::DirStruct & theStepVector,
1870 CORBA::Long theNbOfSteps,
1872 const SMDSAbs_ElementType theElementType)
1880 TIDSortedElemSet elements, copyElements;
1881 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
1883 const SMESH::PointStruct * P = &theStepVector.PS;
1884 gp_Vec stepVec( P->x, P->y, P->z );
1886 TIDSortedElemSet* workElements = & elements;
1887 TPreviewMesh tmpMesh( SMDSAbs_Face );
1888 SMESH_Mesh* mesh = myMesh;
1890 if ( myPreviewMode ) {
1891 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1892 tmpMesh.Copy( elements, copyElements, select, avoid );
1894 workElements = & copyElements;
1895 theMakeGroups = false;
1898 TElemOfElemListMap aHystory;
1899 ::SMESH_MeshEditor anEditor( mesh );
1900 ::SMESH_MeshEditor::PGroupIDs groupIds =
1901 anEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
1903 myMesh->GetMeshDS()->Modified();
1904 storeResult(anEditor);
1906 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1908 } catch(Standard_Failure) {
1909 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1910 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
1915 //=======================================================================
1916 //function : ExtrusionSweep
1918 //=======================================================================
1920 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
1921 const SMESH::DirStruct & theStepVector,
1922 CORBA::Long theNbOfSteps)
1924 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
1925 if (!myPreviewMode) {
1926 TPythonDump() << this << ".ExtrusionSweep( "
1927 << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
1932 //=======================================================================
1933 //function : ExtrusionSweepObject
1935 //=======================================================================
1937 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1938 const SMESH::DirStruct & theStepVector,
1939 CORBA::Long theNbOfSteps)
1941 SMESH::long_array_var anElementsId = theObject->GetIDs();
1942 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
1943 if (!myPreviewMode) {
1944 TPythonDump() << this << ".ExtrusionSweepObject( "
1945 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1949 //=======================================================================
1950 //function : ExtrusionSweepObject1D
1952 //=======================================================================
1954 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1955 const SMESH::DirStruct & theStepVector,
1956 CORBA::Long theNbOfSteps)
1958 SMESH::long_array_var anElementsId = theObject->GetIDs();
1959 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
1960 if ( !myPreviewMode ) {
1961 TPythonDump() << this << ".ExtrusionSweepObject1D( "
1962 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1966 //=======================================================================
1967 //function : ExtrusionSweepObject2D
1969 //=======================================================================
1971 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1972 const SMESH::DirStruct & theStepVector,
1973 CORBA::Long theNbOfSteps)
1975 SMESH::long_array_var anElementsId = theObject->GetIDs();
1976 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
1977 if ( !myPreviewMode ) {
1978 TPythonDump() << this << ".ExtrusionSweepObject2D( "
1979 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1983 //=======================================================================
1984 //function : ExtrusionSweepMakeGroups
1986 //=======================================================================
1988 SMESH::ListOfGroups*
1989 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1990 const SMESH::DirStruct& theStepVector,
1991 CORBA::Long theNbOfSteps)
1993 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1995 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
1997 if (!myPreviewMode) {
1998 DumpGroupsList(aPythonDump, aGroups);
1999 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2000 << ", " << theStepVector <<", " << theNbOfSteps << " )";
2005 //=======================================================================
2006 //function : ExtrusionSweepObjectMakeGroups
2008 //=======================================================================
2010 SMESH::ListOfGroups*
2011 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2012 const SMESH::DirStruct& theStepVector,
2013 CORBA::Long theNbOfSteps)
2015 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2017 SMESH::long_array_var anElementsId = theObject->GetIDs();
2018 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2020 if (!myPreviewMode) {
2021 DumpGroupsList(aPythonDump, aGroups);
2022 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2023 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2028 //=======================================================================
2029 //function : ExtrusionSweepObject1DMakeGroups
2031 //=======================================================================
2033 SMESH::ListOfGroups*
2034 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2035 const SMESH::DirStruct& theStepVector,
2036 CORBA::Long theNbOfSteps)
2038 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2040 SMESH::long_array_var anElementsId = theObject->GetIDs();
2041 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2042 theNbOfSteps, true, SMDSAbs_Edge);
2043 if (!myPreviewMode) {
2044 DumpGroupsList(aPythonDump, aGroups);
2045 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2046 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2051 //=======================================================================
2052 //function : ExtrusionSweepObject2DMakeGroups
2054 //=======================================================================
2056 SMESH::ListOfGroups*
2057 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2058 const SMESH::DirStruct& theStepVector,
2059 CORBA::Long theNbOfSteps)
2061 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2063 SMESH::long_array_var anElementsId = theObject->GetIDs();
2064 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2065 theNbOfSteps, true, SMDSAbs_Face);
2066 if (!myPreviewMode) {
2067 DumpGroupsList(aPythonDump, aGroups);
2068 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2069 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2075 //=======================================================================
2076 //function : advancedExtrusion
2078 //=======================================================================
2080 SMESH::ListOfGroups*
2081 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2082 const SMESH::DirStruct & theStepVector,
2083 CORBA::Long theNbOfSteps,
2084 CORBA::Long theExtrFlags,
2085 CORBA::Double theSewTolerance,
2086 const bool theMakeGroups)
2090 TIDSortedElemSet elements;
2091 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2093 const SMESH::PointStruct * P = &theStepVector.PS;
2094 gp_Vec stepVec( P->x, P->y, P->z );
2096 ::SMESH_MeshEditor anEditor( myMesh );
2097 TElemOfElemListMap aHystory;
2098 ::SMESH_MeshEditor::PGroupIDs groupIds =
2099 anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2100 theMakeGroups, theExtrFlags, theSewTolerance);
2101 storeResult(anEditor);
2103 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2106 //=======================================================================
2107 //function : AdvancedExtrusion
2109 //=======================================================================
2111 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2112 const SMESH::DirStruct & theStepVector,
2113 CORBA::Long theNbOfSteps,
2114 CORBA::Long theExtrFlags,
2115 CORBA::Double theSewTolerance)
2117 if ( !myPreviewMode ) {
2118 TPythonDump() << "stepVector = " << theStepVector;
2119 TPythonDump() << this << ".AdvancedExtrusion("
2122 << theNbOfSteps << ","
2123 << theExtrFlags << ", "
2124 << theSewTolerance << " )";
2126 advancedExtrusion( theIDsOfElements,
2134 //=======================================================================
2135 //function : AdvancedExtrusionMakeGroups
2137 //=======================================================================
2138 SMESH::ListOfGroups*
2139 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2140 const SMESH::DirStruct& theStepVector,
2141 CORBA::Long theNbOfSteps,
2142 CORBA::Long theExtrFlags,
2143 CORBA::Double theSewTolerance)
2145 if (!myPreviewMode) {
2146 TPythonDump() << "stepVector = " << theStepVector;
2148 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2150 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2157 if (!myPreviewMode) {
2158 DumpGroupsList(aPythonDump, aGroups);
2159 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2162 << theNbOfSteps << ","
2163 << theExtrFlags << ", "
2164 << theSewTolerance << " )";
2170 //================================================================================
2172 * \brief Convert extrusion error to IDL enum
2174 //================================================================================
2176 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2178 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2182 RETCASE( EXTR_NO_ELEMENTS );
2183 RETCASE( EXTR_PATH_NOT_EDGE );
2184 RETCASE( EXTR_BAD_PATH_SHAPE );
2185 RETCASE( EXTR_BAD_STARTING_NODE );
2186 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2187 RETCASE( EXTR_CANT_GET_TANGENT );
2189 return SMESH::SMESH_MeshEditor::EXTR_OK;
2193 //=======================================================================
2194 //function : extrusionAlongPath
2196 //=======================================================================
2197 SMESH::ListOfGroups*
2198 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2199 SMESH::SMESH_Mesh_ptr thePathMesh,
2200 GEOM::GEOM_Object_ptr thePathShape,
2201 CORBA::Long theNodeStart,
2202 CORBA::Boolean theHasAngles,
2203 const SMESH::double_array & theAngles,
2204 CORBA::Boolean theHasRefPoint,
2205 const SMESH::PointStruct & theRefPoint,
2206 const bool theMakeGroups,
2207 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2208 const SMDSAbs_ElementType theElementType)
2210 MESSAGE("extrusionAlongPath");
2213 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2214 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2217 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2219 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2220 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2222 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2223 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2227 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2229 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2233 TIDSortedElemSet elements;
2234 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2236 list<double> angles;
2237 for (int i = 0; i < theAngles.length(); i++) {
2238 angles.push_back( theAngles[i] );
2241 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2243 int nbOldGroups = myMesh->NbGroup();
2245 ::SMESH_MeshEditor anEditor( myMesh );
2246 ::SMESH_MeshEditor::Extrusion_Error error =
2247 anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2248 theHasAngles, angles, false,
2249 theHasRefPoint, refPnt, theMakeGroups );
2250 myMesh->GetMeshDS()->Modified();
2251 storeResult(anEditor);
2252 theError = convExtrError( error );
2254 if ( theMakeGroups ) {
2255 list<int> groupIDs = myMesh->GetGroupIds();
2256 list<int>::iterator newBegin = groupIDs.begin();
2257 std::advance( newBegin, nbOldGroups ); // skip old groups
2258 groupIDs.erase( groupIDs.begin(), newBegin );
2259 return getGroups( & groupIDs );
2265 //=======================================================================
2266 //function : extrusionAlongPathX
2268 //=======================================================================
2269 SMESH::ListOfGroups*
2270 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2271 SMESH::SMESH_IDSource_ptr Path,
2272 CORBA::Long NodeStart,
2273 CORBA::Boolean HasAngles,
2274 const SMESH::double_array& Angles,
2275 CORBA::Boolean LinearVariation,
2276 CORBA::Boolean HasRefPoint,
2277 const SMESH::PointStruct& RefPoint,
2279 const SMDSAbs_ElementType ElementType,
2280 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2282 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2286 list<double> angles;
2287 for (int i = 0; i < Angles.length(); i++) {
2288 angles.push_back( Angles[i] );
2290 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2291 int nbOldGroups = myMesh->NbGroup();
2293 if ( Path->_is_nil() ) {
2294 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2298 TIDSortedElemSet elements, copyElements;
2299 arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
2301 TIDSortedElemSet* workElements = &elements;
2302 TPreviewMesh tmpMesh( SMDSAbs_Face );
2303 SMESH_Mesh* mesh = myMesh;
2305 if ( myPreviewMode )
2307 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2308 tmpMesh.Copy( elements, copyElements, select, avoid );
2310 workElements = & copyElements;
2314 ::SMESH_MeshEditor anEditor( mesh );
2315 ::SMESH_MeshEditor::Extrusion_Error error;
2317 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2320 SMDS_MeshNode* aNodeStart =
2321 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2322 if ( !aNodeStart ) {
2323 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2326 error = anEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2327 HasAngles, angles, LinearVariation,
2328 HasRefPoint, refPnt, MakeGroups );
2329 myMesh->GetMeshDS()->Modified();
2331 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2334 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2335 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2336 SMDS_MeshNode* aNodeStart =
2337 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2338 if ( !aNodeStart ) {
2339 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2342 SMESH_subMesh* aSubMesh =
2343 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2344 error = anEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2345 HasAngles, angles, LinearVariation,
2346 HasRefPoint, refPnt, MakeGroups );
2347 myMesh->GetMeshDS()->Modified();
2349 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2351 // path as group of 1D elements
2357 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2361 storeResult(anEditor);
2362 Error = convExtrError( error );
2365 list<int> groupIDs = myMesh->GetGroupIds();
2366 list<int>::iterator newBegin = groupIDs.begin();
2367 std::advance( newBegin, nbOldGroups ); // skip old groups
2368 groupIDs.erase( groupIDs.begin(), newBegin );
2369 return getGroups( & groupIDs );
2375 //=======================================================================
2376 //function : ExtrusionAlongPath
2378 //=======================================================================
2379 SMESH::SMESH_MeshEditor::Extrusion_Error
2380 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2381 SMESH::SMESH_Mesh_ptr thePathMesh,
2382 GEOM::GEOM_Object_ptr thePathShape,
2383 CORBA::Long theNodeStart,
2384 CORBA::Boolean theHasAngles,
2385 const SMESH::double_array & theAngles,
2386 CORBA::Boolean theHasRefPoint,
2387 const SMESH::PointStruct & theRefPoint)
2389 MESSAGE("ExtrusionAlongPath");
2390 if ( !myPreviewMode ) {
2391 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2392 << theIDsOfElements << ", "
2393 << thePathMesh << ", "
2394 << thePathShape << ", "
2395 << theNodeStart << ", "
2396 << theHasAngles << ", "
2397 << theAngles << ", "
2398 << theHasRefPoint << ", "
2399 << "SMESH.PointStruct( "
2400 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2401 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2402 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2404 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2405 extrusionAlongPath( theIDsOfElements,
2418 //=======================================================================
2419 //function : ExtrusionAlongPathObject
2421 //=======================================================================
2422 SMESH::SMESH_MeshEditor::Extrusion_Error
2423 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2424 SMESH::SMESH_Mesh_ptr thePathMesh,
2425 GEOM::GEOM_Object_ptr thePathShape,
2426 CORBA::Long theNodeStart,
2427 CORBA::Boolean theHasAngles,
2428 const SMESH::double_array & theAngles,
2429 CORBA::Boolean theHasRefPoint,
2430 const SMESH::PointStruct & theRefPoint)
2432 if ( !myPreviewMode ) {
2433 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2434 << theObject << ", "
2435 << thePathMesh << ", "
2436 << thePathShape << ", "
2437 << theNodeStart << ", "
2438 << theHasAngles << ", "
2439 << theAngles << ", "
2440 << theHasRefPoint << ", "
2441 << "SMESH.PointStruct( "
2442 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2443 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2444 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2446 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2447 SMESH::long_array_var anElementsId = theObject->GetIDs();
2448 extrusionAlongPath( anElementsId,
2461 //=======================================================================
2462 //function : ExtrusionAlongPathObject1D
2464 //=======================================================================
2465 SMESH::SMESH_MeshEditor::Extrusion_Error
2466 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2467 SMESH::SMESH_Mesh_ptr thePathMesh,
2468 GEOM::GEOM_Object_ptr thePathShape,
2469 CORBA::Long theNodeStart,
2470 CORBA::Boolean theHasAngles,
2471 const SMESH::double_array & theAngles,
2472 CORBA::Boolean theHasRefPoint,
2473 const SMESH::PointStruct & theRefPoint)
2475 if ( !myPreviewMode ) {
2476 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2477 << theObject << ", "
2478 << thePathMesh << ", "
2479 << thePathShape << ", "
2480 << theNodeStart << ", "
2481 << theHasAngles << ", "
2482 << theAngles << ", "
2483 << theHasRefPoint << ", "
2484 << "SMESH.PointStruct( "
2485 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2486 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2487 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2489 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2490 SMESH::long_array_var anElementsId = theObject->GetIDs();
2491 extrusionAlongPath( anElementsId,
2505 //=======================================================================
2506 //function : ExtrusionAlongPathObject2D
2508 //=======================================================================
2509 SMESH::SMESH_MeshEditor::Extrusion_Error
2510 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
2511 SMESH::SMESH_Mesh_ptr thePathMesh,
2512 GEOM::GEOM_Object_ptr thePathShape,
2513 CORBA::Long theNodeStart,
2514 CORBA::Boolean theHasAngles,
2515 const SMESH::double_array & theAngles,
2516 CORBA::Boolean theHasRefPoint,
2517 const SMESH::PointStruct & theRefPoint)
2519 if ( !myPreviewMode ) {
2520 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
2521 << theObject << ", "
2522 << thePathMesh << ", "
2523 << thePathShape << ", "
2524 << theNodeStart << ", "
2525 << theHasAngles << ", "
2526 << theAngles << ", "
2527 << theHasRefPoint << ", "
2528 << "SMESH.PointStruct( "
2529 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2530 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2531 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2533 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2534 SMESH::long_array_var anElementsId = theObject->GetIDs();
2535 extrusionAlongPath( anElementsId,
2550 //=======================================================================
2551 //function : ExtrusionAlongPathMakeGroups
2553 //=======================================================================
2554 SMESH::ListOfGroups*
2555 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
2556 SMESH::SMESH_Mesh_ptr thePathMesh,
2557 GEOM::GEOM_Object_ptr thePathShape,
2558 CORBA::Long theNodeStart,
2559 CORBA::Boolean theHasAngles,
2560 const SMESH::double_array& theAngles,
2561 CORBA::Boolean theHasRefPoint,
2562 const SMESH::PointStruct& theRefPoint,
2563 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2565 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2567 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
2577 if (!myPreviewMode) {
2578 bool isDumpGroups = aGroups && aGroups->length() > 0;
2580 aPythonDump << "(" << aGroups << ", error)";
2582 aPythonDump <<"error";
2584 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
2585 << theIDsOfElements << ", "
2586 << thePathMesh << ", "
2587 << thePathShape << ", "
2588 << theNodeStart << ", "
2589 << theHasAngles << ", "
2590 << theAngles << ", "
2591 << theHasRefPoint << ", "
2592 << "SMESH.PointStruct( "
2593 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2594 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2595 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2600 //=======================================================================
2601 //function : ExtrusionAlongPathObjectMakeGroups
2603 //=======================================================================
2604 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2605 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2606 SMESH::SMESH_Mesh_ptr thePathMesh,
2607 GEOM::GEOM_Object_ptr thePathShape,
2608 CORBA::Long theNodeStart,
2609 CORBA::Boolean theHasAngles,
2610 const SMESH::double_array& theAngles,
2611 CORBA::Boolean theHasRefPoint,
2612 const SMESH::PointStruct& theRefPoint,
2613 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2615 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2617 SMESH::long_array_var anElementsId = theObject->GetIDs();
2618 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2629 if (!myPreviewMode) {
2630 bool isDumpGroups = aGroups && aGroups->length() > 0;
2632 aPythonDump << "(" << aGroups << ", error)";
2634 aPythonDump <<"error";
2636 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
2637 << theObject << ", "
2638 << thePathMesh << ", "
2639 << thePathShape << ", "
2640 << theNodeStart << ", "
2641 << theHasAngles << ", "
2642 << theAngles << ", "
2643 << theHasRefPoint << ", "
2644 << "SMESH.PointStruct( "
2645 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2646 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2647 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2652 //=======================================================================
2653 //function : ExtrusionAlongPathObject1DMakeGroups
2655 //=======================================================================
2656 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2657 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2658 SMESH::SMESH_Mesh_ptr thePathMesh,
2659 GEOM::GEOM_Object_ptr thePathShape,
2660 CORBA::Long theNodeStart,
2661 CORBA::Boolean theHasAngles,
2662 const SMESH::double_array& theAngles,
2663 CORBA::Boolean theHasRefPoint,
2664 const SMESH::PointStruct& theRefPoint,
2665 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2667 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2669 SMESH::long_array_var anElementsId = theObject->GetIDs();
2670 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2682 if (!myPreviewMode) {
2683 bool isDumpGroups = aGroups && aGroups->length() > 0;
2685 aPythonDump << "(" << aGroups << ", error)";
2687 aPythonDump << "error";
2689 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
2690 << theObject << ", "
2691 << thePathMesh << ", "
2692 << thePathShape << ", "
2693 << theNodeStart << ", "
2694 << theHasAngles << ", "
2695 << theAngles << ", "
2696 << theHasRefPoint << ", "
2697 << "SMESH.PointStruct( "
2698 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2699 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2700 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2705 //=======================================================================
2706 //function : ExtrusionAlongPathObject2DMakeGroups
2708 //=======================================================================
2709 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2710 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2711 SMESH::SMESH_Mesh_ptr thePathMesh,
2712 GEOM::GEOM_Object_ptr thePathShape,
2713 CORBA::Long theNodeStart,
2714 CORBA::Boolean theHasAngles,
2715 const SMESH::double_array& theAngles,
2716 CORBA::Boolean theHasRefPoint,
2717 const SMESH::PointStruct& theRefPoint,
2718 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2720 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2722 SMESH::long_array_var anElementsId = theObject->GetIDs();
2723 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2735 if (!myPreviewMode) {
2736 bool isDumpGroups = aGroups && aGroups->length() > 0;
2738 aPythonDump << "(" << aGroups << ", error)";
2740 aPythonDump << "error";
2742 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
2743 << theObject << ", "
2744 << thePathMesh << ", "
2745 << thePathShape << ", "
2746 << theNodeStart << ", "
2747 << theHasAngles << ", "
2748 << theAngles << ", "
2749 << theHasRefPoint << ", "
2750 << "SMESH.PointStruct( "
2751 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2752 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2753 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2759 //=======================================================================
2760 //function : ExtrusionAlongPathObjX
2762 //=======================================================================
2763 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2764 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
2765 SMESH::SMESH_IDSource_ptr Path,
2766 CORBA::Long NodeStart,
2767 CORBA::Boolean HasAngles,
2768 const SMESH::double_array& Angles,
2769 CORBA::Boolean LinearVariation,
2770 CORBA::Boolean HasRefPoint,
2771 const SMESH::PointStruct& RefPoint,
2772 CORBA::Boolean MakeGroups,
2773 SMESH::ElementType ElemType,
2774 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2776 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2778 SMESH::long_array_var anElementsId = Object->GetIDs();
2779 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
2788 (SMDSAbs_ElementType)ElemType,
2791 if (!myPreviewMode) {
2792 bool isDumpGroups = aGroups && aGroups->length() > 0;
2794 aPythonDump << "(" << *aGroups << ", error)";
2796 aPythonDump << "error";
2798 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
2801 << NodeStart << ", "
2802 << HasAngles << ", "
2804 << LinearVariation << ", "
2805 << HasRefPoint << ", "
2806 << "SMESH.PointStruct( "
2807 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2808 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2809 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2810 << MakeGroups << ", "
2811 << ElemType << " )";
2817 //=======================================================================
2818 //function : ExtrusionAlongPathX
2820 //=======================================================================
2821 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2822 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
2823 SMESH::SMESH_IDSource_ptr Path,
2824 CORBA::Long NodeStart,
2825 CORBA::Boolean HasAngles,
2826 const SMESH::double_array& Angles,
2827 CORBA::Boolean LinearVariation,
2828 CORBA::Boolean HasRefPoint,
2829 const SMESH::PointStruct& RefPoint,
2830 CORBA::Boolean MakeGroups,
2831 SMESH::ElementType ElemType,
2832 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2834 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2836 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
2845 (SMDSAbs_ElementType)ElemType,
2848 if (!myPreviewMode) {
2849 bool isDumpGroups = aGroups && aGroups->length() > 0;
2851 aPythonDump << "(" << *aGroups << ", error)";
2853 aPythonDump <<"error";
2855 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
2856 << IDsOfElements << ", "
2858 << NodeStart << ", "
2859 << HasAngles << ", "
2861 << LinearVariation << ", "
2862 << HasRefPoint << ", "
2863 << "SMESH.PointStruct( "
2864 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2865 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2866 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2867 << MakeGroups << ", "
2868 << ElemType << " )";
2874 //================================================================================
2876 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2877 * of given angles along path steps
2878 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2879 * which proceeds the extrusion
2880 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2881 * is used to define the sub-mesh for the path
2883 //================================================================================
2885 SMESH::double_array*
2886 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2887 GEOM::GEOM_Object_ptr thePathShape,
2888 const SMESH::double_array & theAngles)
2890 SMESH::double_array_var aResult = new SMESH::double_array();
2891 int nbAngles = theAngles.length();
2892 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2894 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2895 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2896 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2897 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2898 return aResult._retn();
2899 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2900 if ( nbSteps == nbAngles )
2902 aResult.inout() = theAngles;
2906 aResult->length( nbSteps );
2907 double rAn2St = double( nbAngles ) / double( nbSteps );
2908 double angPrev = 0, angle;
2909 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2911 double angCur = rAn2St * ( iSt+1 );
2912 double angCurFloor = floor( angCur );
2913 double angPrevFloor = floor( angPrev );
2914 if ( angPrevFloor == angCurFloor )
2915 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2918 int iP = int( angPrevFloor );
2919 double angPrevCeil = ceil(angPrev);
2920 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2922 int iC = int( angCurFloor );
2923 if ( iC < nbAngles )
2924 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2926 iP = int( angPrevCeil );
2928 angle += theAngles[ iC ];
2930 aResult[ iSt ] = angle;
2935 // Update Python script
2936 TPythonDump() << "rotAngles = " << theAngles;
2937 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
2938 << thePathMesh << ", "
2939 << thePathShape << ", "
2942 return aResult._retn();
2946 //=======================================================================
2949 //=======================================================================
2951 SMESH::ListOfGroups*
2952 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
2953 const SMESH::AxisStruct & theAxis,
2954 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2955 CORBA::Boolean theCopy,
2957 ::SMESH_Mesh* theTargetMesh)
2961 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
2962 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
2964 if ( theTargetMesh )
2968 switch ( theMirrorType ) {
2969 case SMESH::SMESH_MeshEditor::POINT:
2970 aTrsf.SetMirror( P );
2972 case SMESH::SMESH_MeshEditor::AXIS:
2973 aTrsf.SetMirror( gp_Ax1( P, V ));
2976 aTrsf.SetMirror( gp_Ax2( P, V ));
2979 TIDSortedElemSet copyElements;
2980 TPreviewMesh tmpMesh;
2981 TIDSortedElemSet* workElements = & theElements;
2982 SMESH_Mesh* mesh = myMesh;
2984 if ( myPreviewMode )
2986 tmpMesh.Copy( theElements, copyElements);
2987 if ( !theCopy && !theTargetMesh )
2989 TIDSortedElemSet elemsAround, elemsAroundCopy;
2990 getElementsAround( theElements, GetMeshDS(), elemsAround );
2991 tmpMesh.Copy( elemsAround, elemsAroundCopy);
2994 workElements = & copyElements;
2995 theMakeGroups = false;
2998 ::SMESH_MeshEditor anEditor( mesh );
2999 ::SMESH_MeshEditor::PGroupIDs groupIds =
3000 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3002 if(theCopy || myPreviewMode)
3003 storeResult(anEditor);
3006 myMesh->SetIsModified( true );
3007 myMesh->GetMeshDS()->Modified();
3009 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3012 //=======================================================================
3015 //=======================================================================
3017 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3018 const SMESH::AxisStruct & theAxis,
3019 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3020 CORBA::Boolean theCopy)
3022 if ( !myPreviewMode ) {
3023 TPythonDump() << this << ".Mirror( "
3024 << theIDsOfElements << ", "
3026 << mirrorTypeName(theMirrorType) << ", "
3029 if ( theIDsOfElements.length() > 0 )
3031 TIDSortedElemSet elements;
3032 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3033 mirror(elements, theAxis, theMirrorType, theCopy, false);
3038 //=======================================================================
3039 //function : MirrorObject
3041 //=======================================================================
3043 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3044 const SMESH::AxisStruct & theAxis,
3045 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3046 CORBA::Boolean theCopy)
3048 if ( !myPreviewMode ) {
3049 TPythonDump() << this << ".MirrorObject( "
3050 << theObject << ", "
3052 << mirrorTypeName(theMirrorType) << ", "
3055 TIDSortedElemSet elements;
3057 bool emptyIfIsMesh = myPreviewMode ? false : true;
3059 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3060 mirror(elements, theAxis, theMirrorType, theCopy, false);
3063 //=======================================================================
3064 //function : MirrorMakeGroups
3066 //=======================================================================
3068 SMESH::ListOfGroups*
3069 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3070 const SMESH::AxisStruct& theMirror,
3071 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3073 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3075 SMESH::ListOfGroups * aGroups = 0;
3076 if ( theIDsOfElements.length() > 0 )
3078 TIDSortedElemSet elements;
3079 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3080 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3082 if (!myPreviewMode) {
3083 DumpGroupsList(aPythonDump, aGroups);
3084 aPythonDump << this << ".MirrorMakeGroups( "
3085 << theIDsOfElements << ", "
3086 << theMirror << ", "
3087 << mirrorTypeName(theMirrorType) << " )";
3092 //=======================================================================
3093 //function : MirrorObjectMakeGroups
3095 //=======================================================================
3097 SMESH::ListOfGroups*
3098 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3099 const SMESH::AxisStruct& theMirror,
3100 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3102 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3104 SMESH::ListOfGroups * aGroups = 0;
3105 TIDSortedElemSet elements;
3106 if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3107 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3111 DumpGroupsList(aPythonDump,aGroups);
3112 aPythonDump << this << ".MirrorObjectMakeGroups( "
3113 << theObject << ", "
3114 << theMirror << ", "
3115 << mirrorTypeName(theMirrorType) << " )";
3120 //=======================================================================
3121 //function : MirrorMakeMesh
3123 //=======================================================================
3125 SMESH::SMESH_Mesh_ptr
3126 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3127 const SMESH::AxisStruct& theMirror,
3128 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3129 CORBA::Boolean theCopyGroups,
3130 const char* theMeshName)
3132 SMESH_Mesh_i* mesh_i;
3133 SMESH::SMESH_Mesh_var mesh;
3134 { // open new scope to dump "MakeMesh" command
3135 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3137 TPythonDump pydump; // to prevent dump at mesh creation
3139 mesh = makeMesh( theMeshName );
3140 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3141 if (mesh_i && theIDsOfElements.length() > 0 )
3143 TIDSortedElemSet elements;
3144 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3145 mirror(elements, theMirror, theMirrorType,
3146 false, theCopyGroups, & mesh_i->GetImpl());
3147 mesh_i->CreateGroupServants();
3150 if (!myPreviewMode) {
3151 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3152 << theIDsOfElements << ", "
3153 << theMirror << ", "
3154 << mirrorTypeName(theMirrorType) << ", "
3155 << theCopyGroups << ", '"
3156 << theMeshName << "' )";
3161 if (!myPreviewMode && mesh_i)
3162 mesh_i->GetGroups();
3164 return mesh._retn();
3167 //=======================================================================
3168 //function : MirrorObjectMakeMesh
3170 //=======================================================================
3172 SMESH::SMESH_Mesh_ptr
3173 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3174 const SMESH::AxisStruct& theMirror,
3175 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3176 CORBA::Boolean theCopyGroups,
3177 const char* theMeshName)
3179 SMESH_Mesh_i* mesh_i;
3180 SMESH::SMESH_Mesh_var mesh;
3181 { // open new scope to dump "MakeMesh" command
3182 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3184 TPythonDump pydump; // to prevent dump at mesh creation
3186 mesh = makeMesh( theMeshName );
3187 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3188 TIDSortedElemSet elements;
3190 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3192 mirror(elements, theMirror, theMirrorType,
3193 false, theCopyGroups, & mesh_i->GetImpl());
3194 mesh_i->CreateGroupServants();
3196 if (!myPreviewMode) {
3197 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3198 << theObject << ", "
3199 << theMirror << ", "
3200 << mirrorTypeName(theMirrorType) << ", "
3201 << theCopyGroups << ", '"
3202 << theMeshName << "' )";
3207 if (!myPreviewMode && mesh_i)
3208 mesh_i->GetGroups();
3210 return mesh._retn();
3213 //=======================================================================
3214 //function : translate
3216 //=======================================================================
3218 SMESH::ListOfGroups*
3219 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3220 const SMESH::DirStruct & theVector,
3221 CORBA::Boolean theCopy,
3223 ::SMESH_Mesh* theTargetMesh)
3227 if ( theTargetMesh )
3231 const SMESH::PointStruct * P = &theVector.PS;
3232 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3234 TIDSortedElemSet copyElements;
3235 TIDSortedElemSet* workElements = &theElements;
3236 TPreviewMesh tmpMesh;
3237 SMESH_Mesh* mesh = myMesh;
3239 if ( myPreviewMode )
3241 tmpMesh.Copy( theElements, copyElements);
3242 if ( !theCopy && !theTargetMesh )
3244 TIDSortedElemSet elemsAround, elemsAroundCopy;
3245 getElementsAround( theElements, GetMeshDS(), elemsAround );
3246 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3249 workElements = & copyElements;
3250 theMakeGroups = false;
3253 ::SMESH_MeshEditor anEditor( mesh );
3254 ::SMESH_MeshEditor::PGroupIDs groupIds =
3255 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3257 if(theCopy || myPreviewMode)
3258 storeResult(anEditor);
3261 myMesh->GetMeshDS()->Modified();
3262 myMesh->SetIsModified( true );
3265 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3268 //=======================================================================
3269 //function : Translate
3271 //=======================================================================
3273 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3274 const SMESH::DirStruct & theVector,
3275 CORBA::Boolean theCopy)
3277 if (!myPreviewMode) {
3278 TPythonDump() << this << ".Translate( "
3279 << theIDsOfElements << ", "
3280 << theVector << ", "
3283 if (theIDsOfElements.length()) {
3284 TIDSortedElemSet elements;
3285 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3286 translate(elements, theVector, theCopy, false);
3290 //=======================================================================
3291 //function : TranslateObject
3293 //=======================================================================
3295 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3296 const SMESH::DirStruct & theVector,
3297 CORBA::Boolean theCopy)
3299 if (!myPreviewMode) {
3300 TPythonDump() << this << ".TranslateObject( "
3301 << theObject << ", "
3302 << theVector << ", "
3305 TIDSortedElemSet elements;
3307 bool emptyIfIsMesh = myPreviewMode ? false : true;
3309 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3310 translate(elements, theVector, theCopy, false);
3313 //=======================================================================
3314 //function : TranslateMakeGroups
3316 //=======================================================================
3318 SMESH::ListOfGroups*
3319 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3320 const SMESH::DirStruct& theVector)
3322 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3324 SMESH::ListOfGroups * aGroups = 0;
3325 if (theIDsOfElements.length()) {
3326 TIDSortedElemSet elements;
3327 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3328 aGroups = translate(elements,theVector,true,true);
3330 if (!myPreviewMode) {
3331 DumpGroupsList(aPythonDump, aGroups);
3332 aPythonDump << this << ".TranslateMakeGroups( "
3333 << theIDsOfElements << ", "
3334 << theVector << " )";
3339 //=======================================================================
3340 //function : TranslateObjectMakeGroups
3342 //=======================================================================
3344 SMESH::ListOfGroups*
3345 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3346 const SMESH::DirStruct& theVector)
3348 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3350 SMESH::ListOfGroups * aGroups = 0;
3351 TIDSortedElemSet elements;
3352 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3353 aGroups = translate(elements, theVector, true, true);
3355 if (!myPreviewMode) {
3356 DumpGroupsList(aPythonDump, aGroups);
3357 aPythonDump << this << ".TranslateObjectMakeGroups( "
3358 << theObject << ", "
3359 << theVector << " )";
3364 //=======================================================================
3365 //function : TranslateMakeMesh
3367 //=======================================================================
3369 SMESH::SMESH_Mesh_ptr
3370 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3371 const SMESH::DirStruct& theVector,
3372 CORBA::Boolean theCopyGroups,
3373 const char* theMeshName)
3375 SMESH_Mesh_i* mesh_i;
3376 SMESH::SMESH_Mesh_var mesh;
3378 { // open new scope to dump "MakeMesh" command
3379 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3381 TPythonDump pydump; // to prevent dump at mesh creation
3383 mesh = makeMesh( theMeshName );
3384 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3386 if ( mesh_i && theIDsOfElements.length() )
3388 TIDSortedElemSet elements;
3389 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3390 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3391 mesh_i->CreateGroupServants();
3394 if ( !myPreviewMode ) {
3395 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3396 << theIDsOfElements << ", "
3397 << theVector << ", "
3398 << theCopyGroups << ", '"
3399 << theMeshName << "' )";
3404 if (!myPreviewMode && mesh_i)
3405 mesh_i->GetGroups();
3407 return mesh._retn();
3410 //=======================================================================
3411 //function : TranslateObjectMakeMesh
3413 //=======================================================================
3415 SMESH::SMESH_Mesh_ptr
3416 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3417 const SMESH::DirStruct& theVector,
3418 CORBA::Boolean theCopyGroups,
3419 const char* theMeshName)
3421 SMESH_Mesh_i* mesh_i;
3422 SMESH::SMESH_Mesh_var mesh;
3423 { // open new scope to dump "MakeMesh" command
3424 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3426 TPythonDump pydump; // to prevent dump at mesh creation
3427 mesh = makeMesh( theMeshName );
3428 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3430 TIDSortedElemSet elements;
3432 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3434 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3435 mesh_i->CreateGroupServants();
3437 if ( !myPreviewMode ) {
3438 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3439 << theObject << ", "
3440 << theVector << ", "
3441 << theCopyGroups << ", '"
3442 << theMeshName << "' )";
3447 if (!myPreviewMode && mesh_i)
3448 mesh_i->GetGroups();
3450 return mesh._retn();
3453 //=======================================================================
3456 //=======================================================================
3458 SMESH::ListOfGroups*
3459 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3460 const SMESH::AxisStruct & theAxis,
3461 CORBA::Double theAngle,
3462 CORBA::Boolean theCopy,
3464 ::SMESH_Mesh* theTargetMesh)
3468 if ( theTargetMesh )
3471 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3472 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3475 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3477 TIDSortedElemSet copyElements;
3478 TIDSortedElemSet* workElements = &theElements;
3479 TPreviewMesh tmpMesh;
3480 SMESH_Mesh* mesh = myMesh;
3482 if ( myPreviewMode ) {
3483 tmpMesh.Copy( theElements, copyElements );
3484 if ( !theCopy && !theTargetMesh )
3486 TIDSortedElemSet elemsAround, elemsAroundCopy;
3487 getElementsAround( theElements, GetMeshDS(), elemsAround );
3488 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3491 workElements = ©Elements;
3492 theMakeGroups = false;
3495 ::SMESH_MeshEditor anEditor( mesh );
3496 ::SMESH_MeshEditor::PGroupIDs groupIds =
3497 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3499 if(theCopy || myPreviewMode)
3500 storeResult(anEditor);
3503 myMesh->GetMeshDS()->Modified();
3504 myMesh->SetIsModified( true );
3507 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3510 //=======================================================================
3513 //=======================================================================
3515 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3516 const SMESH::AxisStruct & theAxis,
3517 CORBA::Double theAngle,
3518 CORBA::Boolean theCopy)
3520 if (!myPreviewMode) {
3521 TPythonDump() << this << ".Rotate( "
3522 << theIDsOfElements << ", "
3527 if (theIDsOfElements.length() > 0)
3529 TIDSortedElemSet elements;
3530 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3531 rotate(elements,theAxis,theAngle,theCopy,false);
3535 //=======================================================================
3536 //function : RotateObject
3538 //=======================================================================
3540 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3541 const SMESH::AxisStruct & theAxis,
3542 CORBA::Double theAngle,
3543 CORBA::Boolean theCopy)
3545 if ( !myPreviewMode ) {
3546 TPythonDump() << this << ".RotateObject( "
3547 << theObject << ", "
3552 TIDSortedElemSet elements;
3553 bool emptyIfIsMesh = myPreviewMode ? false : true;
3554 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3555 rotate(elements,theAxis,theAngle,theCopy,false);
3558 //=======================================================================
3559 //function : RotateMakeGroups
3561 //=======================================================================
3563 SMESH::ListOfGroups*
3564 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3565 const SMESH::AxisStruct& theAxis,
3566 CORBA::Double theAngle)
3568 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3570 SMESH::ListOfGroups * aGroups = 0;
3571 if (theIDsOfElements.length() > 0)
3573 TIDSortedElemSet elements;
3574 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3575 aGroups = rotate(elements,theAxis,theAngle,true,true);
3577 if (!myPreviewMode) {
3578 DumpGroupsList(aPythonDump, aGroups);
3579 aPythonDump << this << ".RotateMakeGroups( "
3580 << theIDsOfElements << ", "
3582 << theAngle << " )";
3587 //=======================================================================
3588 //function : RotateObjectMakeGroups
3590 //=======================================================================
3592 SMESH::ListOfGroups*
3593 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3594 const SMESH::AxisStruct& theAxis,
3595 CORBA::Double theAngle)
3597 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3599 SMESH::ListOfGroups * aGroups = 0;
3600 TIDSortedElemSet elements;
3601 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3602 aGroups = rotate(elements, theAxis, theAngle, true, true);
3604 if (!myPreviewMode) {
3605 DumpGroupsList(aPythonDump, aGroups);
3606 aPythonDump << this << ".RotateObjectMakeGroups( "
3607 << theObject << ", "
3609 << theAngle << " )";
3614 //=======================================================================
3615 //function : RotateMakeMesh
3617 //=======================================================================
3619 SMESH::SMESH_Mesh_ptr
3620 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3621 const SMESH::AxisStruct& theAxis,
3622 CORBA::Double theAngleInRadians,
3623 CORBA::Boolean theCopyGroups,
3624 const char* theMeshName)
3626 SMESH::SMESH_Mesh_var mesh;
3627 SMESH_Mesh_i* mesh_i;
3629 { // open new scope to dump "MakeMesh" command
3630 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3632 TPythonDump pydump; // to prevent dump at mesh creation
3634 mesh = makeMesh( theMeshName );
3635 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3637 if ( mesh_i && theIDsOfElements.length() > 0 )
3639 TIDSortedElemSet elements;
3640 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3641 rotate(elements, theAxis, theAngleInRadians,
3642 false, theCopyGroups, & mesh_i->GetImpl());
3643 mesh_i->CreateGroupServants();
3645 if ( !myPreviewMode ) {
3646 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3647 << theIDsOfElements << ", "
3649 << theAngleInRadians << ", "
3650 << theCopyGroups << ", '"
3651 << theMeshName << "' )";
3656 if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3657 mesh_i->GetGroups();
3659 return mesh._retn();
3662 //=======================================================================
3663 //function : RotateObjectMakeMesh
3665 //=======================================================================
3667 SMESH::SMESH_Mesh_ptr
3668 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3669 const SMESH::AxisStruct& theAxis,
3670 CORBA::Double theAngleInRadians,
3671 CORBA::Boolean theCopyGroups,
3672 const char* theMeshName)
3674 SMESH::SMESH_Mesh_var mesh;
3675 SMESH_Mesh_i* mesh_i;
3677 {// open new scope to dump "MakeMesh" command
3678 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3680 TPythonDump pydump; // to prevent dump at mesh creation
3681 mesh = makeMesh( theMeshName );
3682 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3684 TIDSortedElemSet elements;
3686 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3688 rotate(elements, theAxis, theAngleInRadians,
3689 false, theCopyGroups, & mesh_i->GetImpl());
3690 mesh_i->CreateGroupServants();
3692 if ( !myPreviewMode ) {
3693 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3694 << theObject << ", "
3696 << theAngleInRadians << ", "
3697 << theCopyGroups << ", '"
3698 << theMeshName << "' )";
3703 if (!myPreviewMode && mesh_i)
3704 mesh_i->GetGroups();
3706 return mesh._retn();
3709 //=======================================================================
3712 //=======================================================================
3714 SMESH::ListOfGroups*
3715 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3716 const SMESH::PointStruct& thePoint,
3717 const SMESH::double_array& theScaleFact,
3718 CORBA::Boolean theCopy,
3720 ::SMESH_Mesh* theTargetMesh)
3723 if ( theScaleFact.length() < 1 )
3724 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3725 if ( theScaleFact.length() == 2 )
3726 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3728 if ( theTargetMesh )
3731 TIDSortedElemSet elements;
3732 bool emptyIfIsMesh = myPreviewMode ? false : true;
3733 if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3738 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3739 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3741 double tol = std::numeric_limits<double>::max();
3743 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3744 0, S[1], 0, thePoint.y * (1-S[1]),
3745 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3747 TIDSortedElemSet copyElements;
3748 TPreviewMesh tmpMesh;
3749 TIDSortedElemSet* workElements = &elements;
3750 SMESH_Mesh* mesh = myMesh;
3752 if ( myPreviewMode )
3754 tmpMesh.Copy( elements, copyElements);
3755 if ( !theCopy && !theTargetMesh )
3757 TIDSortedElemSet elemsAround, elemsAroundCopy;
3758 getElementsAround( elements, GetMeshDS(), elemsAround );
3759 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3762 workElements = & copyElements;
3763 theMakeGroups = false;
3766 ::SMESH_MeshEditor anEditor( mesh );
3767 ::SMESH_MeshEditor::PGroupIDs groupIds =
3768 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3770 if(theCopy || myPreviewMode )
3771 storeResult(anEditor);
3774 myMesh->GetMeshDS()->Modified();
3775 myMesh->SetIsModified( true );
3777 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3780 //=======================================================================
3783 //=======================================================================
3785 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3786 const SMESH::PointStruct& thePoint,
3787 const SMESH::double_array& theScaleFact,
3788 CORBA::Boolean theCopy)
3790 if ( !myPreviewMode ) {
3791 TPythonDump() << this << ".Scale( "
3792 << theObject << ", "
3793 << "SMESH.PointStruct( " << thePoint.x << ", "
3794 << thePoint.y << ", " << thePoint.z << " ) ,"
3795 << theScaleFact << ", "
3798 scale(theObject, thePoint, theScaleFact, theCopy, false);
3802 //=======================================================================
3803 //function : ScaleMakeGroups
3805 //=======================================================================
3807 SMESH::ListOfGroups*
3808 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3809 const SMESH::PointStruct& thePoint,
3810 const SMESH::double_array& theScaleFact)
3812 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3814 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3815 if (!myPreviewMode) {
3816 DumpGroupsList(aPythonDump, aGroups);
3817 aPythonDump << this << ".Scale("
3819 << "SMESH.PointStruct(" <<thePoint.x << ","
3820 << thePoint.y << "," << thePoint.z << "),"
3821 << theScaleFact << ",True,True)";
3827 //=======================================================================
3828 //function : ScaleMakeMesh
3830 //=======================================================================
3832 SMESH::SMESH_Mesh_ptr
3833 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3834 const SMESH::PointStruct& thePoint,
3835 const SMESH::double_array& theScaleFact,
3836 CORBA::Boolean theCopyGroups,
3837 const char* theMeshName)
3839 SMESH_Mesh_i* mesh_i;
3840 SMESH::SMESH_Mesh_var mesh;
3841 { // open new scope to dump "MakeMesh" command
3842 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3844 TPythonDump pydump; // to prevent dump at mesh creation
3845 mesh = makeMesh( theMeshName );
3846 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3850 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
3851 mesh_i->CreateGroupServants();
3853 if ( !myPreviewMode )
3854 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
3855 << theObject << ", "
3856 << "SMESH.PointStruct( " << thePoint.x << ", "
3857 << thePoint.y << ", " << thePoint.z << " ) ,"
3858 << theScaleFact << ", "
3859 << theCopyGroups << ", '"
3860 << theMeshName << "' )";
3864 if (!myPreviewMode && mesh_i)
3865 mesh_i->GetGroups();
3867 return mesh._retn();
3871 //=======================================================================
3872 //function : FindCoincidentNodes
3874 //=======================================================================
3876 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
3877 SMESH::array_of_long_array_out GroupsOfNodes)
3881 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3882 ::SMESH_MeshEditor anEditor( myMesh );
3883 TIDSortedNodeSet nodes; // no input nodes
3884 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3886 GroupsOfNodes = new SMESH::array_of_long_array;
3887 GroupsOfNodes->length( aListOfListOfNodes.size() );
3888 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3889 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
3890 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3891 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3892 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3893 aGroup.length( aListOfNodes.size() );
3894 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3895 aGroup[ j ] = (*lIt)->GetID();
3897 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
3898 << Tolerance << " )";
3901 //=======================================================================
3902 //function : FindCoincidentNodesOnPart
3904 //=======================================================================
3905 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
3906 CORBA::Double Tolerance,
3907 SMESH::array_of_long_array_out GroupsOfNodes)
3911 TIDSortedNodeSet nodes;
3912 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3914 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3915 ::SMESH_MeshEditor anEditor( myMesh );
3917 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3919 GroupsOfNodes = new SMESH::array_of_long_array;
3920 GroupsOfNodes->length( aListOfListOfNodes.size() );
3921 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3922 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3924 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3925 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3926 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3927 aGroup.length( aListOfNodes.size() );
3928 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3929 aGroup[ j ] = (*lIt)->GetID();
3931 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
3933 << Tolerance << " )";
3936 //================================================================================
3938 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
3939 * ExceptSubMeshOrGroups
3941 //================================================================================
3943 void SMESH_MeshEditor_i::
3944 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
3945 CORBA::Double theTolerance,
3946 SMESH::array_of_long_array_out theGroupsOfNodes,
3947 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
3951 TIDSortedNodeSet nodes;
3952 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3954 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
3956 TIDSortedNodeSet exceptNodes;
3957 idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
3958 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
3959 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
3960 nodes.erase( *avoidNode );
3962 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3963 ::SMESH_MeshEditor anEditor( myMesh );
3965 anEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
3967 theGroupsOfNodes = new SMESH::array_of_long_array;
3968 theGroupsOfNodes->length( aListOfListOfNodes.size() );
3969 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3970 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3972 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3973 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3974 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
3975 aGroup.length( aListOfNodes.size() );
3976 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3977 aGroup[ j ] = (*lIt)->GetID();
3979 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
3981 << theTolerance << ", "
3982 << theExceptSubMeshOrGroups << " )";
3985 //=======================================================================
3986 //function : MergeNodes
3988 //=======================================================================
3990 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
3994 SMESHDS_Mesh* aMesh = GetMeshDS();
3996 TPythonDump aTPythonDump;
3997 aTPythonDump << this << ".MergeNodes([";
3998 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3999 for (int i = 0; i < GroupsOfNodes.length(); i++)
4001 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4002 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4003 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4004 for ( int j = 0; j < aNodeGroup.length(); j++ )
4006 CORBA::Long index = aNodeGroup[ j ];
4007 const SMDS_MeshNode * node = aMesh->FindNode(index);
4009 aListOfNodes.push_back( node );
4011 if ( aListOfNodes.size() < 2 )
4012 aListOfListOfNodes.pop_back();
4014 if ( i > 0 ) aTPythonDump << ", ";
4015 aTPythonDump << aNodeGroup;
4017 ::SMESH_MeshEditor anEditor( myMesh );
4018 anEditor.MergeNodes( aListOfListOfNodes );
4020 aTPythonDump << "])";
4021 myMesh->GetMeshDS()->Modified();
4022 myMesh->SetIsModified( true );
4025 //=======================================================================
4026 //function : FindEqualElements
4028 //=======================================================================
4029 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4030 SMESH::array_of_long_array_out GroupsOfElementsID)
4034 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4035 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4037 typedef list<int> TListOfIDs;
4038 set<const SMDS_MeshElement*> elems;
4039 SMESH::long_array_var aElementsId = theObject->GetIDs();
4040 SMESHDS_Mesh* aMesh = GetMeshDS();
4042 for(int i = 0; i < aElementsId->length(); i++) {
4043 CORBA::Long anID = aElementsId[i];
4044 const SMDS_MeshElement * elem = aMesh->FindElement(anID);
4050 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4051 ::SMESH_MeshEditor anEditor( myMesh );
4052 anEditor.FindEqualElements( elems, aListOfListOfElementsID );
4054 GroupsOfElementsID = new SMESH::array_of_long_array;
4055 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4057 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
4058 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
4059 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4060 TListOfIDs& listOfIDs = *arraysIt;
4061 aGroup.length( listOfIDs.size() );
4062 TListOfIDs::iterator idIt = listOfIDs.begin();
4063 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
4064 aGroup[ k ] = *idIt;
4068 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4073 //=======================================================================
4074 //function : MergeElements
4076 //=======================================================================
4078 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4082 TPythonDump aTPythonDump;
4083 aTPythonDump << this << ".MergeElements( [";
4085 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4087 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4088 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4089 aListOfListOfElementsID.push_back( list< int >() );
4090 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4091 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4092 CORBA::Long id = anElemsIDGroup[ j ];
4093 aListOfElemsID.push_back( id );
4095 if ( aListOfElemsID.size() < 2 )
4096 aListOfListOfElementsID.pop_back();
4097 if ( i > 0 ) aTPythonDump << ", ";
4098 aTPythonDump << anElemsIDGroup;
4101 ::SMESH_MeshEditor anEditor( myMesh );
4102 anEditor.MergeElements(aListOfListOfElementsID);
4103 myMesh->GetMeshDS()->Modified();
4104 myMesh->SetIsModified( true );
4106 aTPythonDump << "] )";
4109 //=======================================================================
4110 //function : MergeEqualElements
4112 //=======================================================================
4114 void SMESH_MeshEditor_i::MergeEqualElements()
4118 ::SMESH_MeshEditor anEditor( myMesh );
4119 anEditor.MergeEqualElements();
4121 TPythonDump() << this << ".MergeEqualElements()";
4124 //=============================================================================
4126 * Move the node to a given point
4128 //=============================================================================
4130 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4135 initData(/*deleteSearchers=*/false);
4137 const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
4141 if ( theNodeSearcher )
4142 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4144 if ( myPreviewMode ) // make preview data
4146 // in a preview mesh, make edges linked to a node
4147 TPreviewMesh tmpMesh;
4148 TIDSortedElemSet linkedNodes;
4149 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4150 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4151 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4152 for ( ; nIt != linkedNodes.end(); ++nIt )
4154 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4155 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4159 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4160 // fill preview data
4161 ::SMESH_MeshEditor anEditor( & tmpMesh );
4162 storeResult( anEditor );
4164 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4165 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4167 GetMeshDS()->MoveNode(node, x, y, z);
4169 if ( !myPreviewMode )
4171 // Update Python script
4172 TPythonDump() << "isDone = " << this << ".MoveNode( "
4173 << NodeID << ", " << x << ", " << y << ", " << z << " )";
4174 myMesh->GetMeshDS()->Modified();
4175 myMesh->SetIsModified( true );
4181 //================================================================================
4183 * \brief Return ID of node closest to a given point
4185 //================================================================================
4187 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4191 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4193 if ( !theNodeSearcher ) {
4194 ::SMESH_MeshEditor anEditor( myMesh );
4195 theNodeSearcher = anEditor.GetNodeSearcher();
4198 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4199 return node->GetID();
4204 //================================================================================
4206 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4207 * move the node closest to the point to point's location and return ID of the node
4209 //================================================================================
4211 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4214 CORBA::Long theNodeID)
4216 // We keep theNodeSearcher until any mesh modification:
4217 // 1) initData() deletes theNodeSearcher at any edition,
4218 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4220 initData(/*deleteSearchers=*/false);
4222 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4224 int nodeID = theNodeID;
4225 const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
4226 if ( !node ) // preview moving node
4228 if ( !theNodeSearcher ) {
4229 ::SMESH_MeshEditor anEditor( myMesh );
4230 theNodeSearcher = anEditor.GetNodeSearcher();
4233 node = theNodeSearcher->FindClosestTo( p );
4236 nodeID = node->GetID();
4237 if ( myPreviewMode ) // make preview data
4239 // in a preview mesh, make edges linked to a node
4240 TPreviewMesh tmpMesh;
4241 TIDSortedElemSet linkedNodes;
4242 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4243 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4244 for ( ; nIt != linkedNodes.end(); ++nIt )
4246 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4247 tmpMesh.Copy( &edge );
4250 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4252 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4253 // fill preview data
4254 ::SMESH_MeshEditor anEditor( & tmpMesh );
4255 storeResult( anEditor );
4257 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4259 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4263 GetMeshDS()->MoveNode(node, x, y, z);
4267 if ( !myPreviewMode )
4269 TPythonDump() << "nodeID = " << this
4270 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4271 << ", " << nodeID << " )";
4273 myMesh->GetMeshDS()->Modified();
4274 myMesh->SetIsModified( true );
4280 //=======================================================================
4282 * Return elements of given type where the given point is IN or ON.
4284 * 'ALL' type means elements of any type excluding nodes
4286 //=======================================================================
4288 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4291 SMESH::ElementType type)
4293 SMESH::long_array_var res = new SMESH::long_array;
4294 vector< const SMDS_MeshElement* > foundElems;
4296 theSearchersDeleter.Set( myMesh );
4297 if ( !theElementSearcher ) {
4298 ::SMESH_MeshEditor anEditor( myMesh );
4299 theElementSearcher = anEditor.GetElementSearcher();
4301 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4302 SMDSAbs_ElementType( type ),
4304 res->length( foundElems.size() );
4305 for ( int i = 0; i < foundElems.size(); ++i )
4306 res[i] = foundElems[i]->GetID();
4308 if ( !myPreviewMode ) // call from tui
4309 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4318 //=======================================================================
4319 //function : FindAmongElementsByPoint
4320 //purpose : Searching among the given elements, return elements of given type
4321 // where the given point is IN or ON.
4322 // 'ALL' type means elements of any type excluding nodes
4323 //=======================================================================
4326 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4330 SMESH::ElementType type)
4332 SMESH::long_array_var res = new SMESH::long_array;
4334 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4335 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4336 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D ) &&
4337 type != types[0] ) // but search of elements of dim > 0
4340 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4341 return FindElementsByPoint( x,y,z, type );
4343 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( elementIDs );
4344 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( elementIDs ))
4345 // take into account passible group modification
4346 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
4347 partIOR += SMESH_Comment( type );
4349 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4351 theSearchersDeleter.Set( myMesh, partIOR );
4352 if ( !theElementSearcher )
4354 // create a searcher from elementIDs
4355 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4356 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4358 if ( !idSourceToSet( elementIDs, meshDS, elements,
4359 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4362 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4363 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4365 ::SMESH_MeshEditor anEditor( myMesh );
4366 theElementSearcher = anEditor.GetElementSearcher(elemsIt);
4369 vector< const SMDS_MeshElement* > foundElems;
4371 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4372 SMDSAbs_ElementType( type ),
4374 res->length( foundElems.size() );
4375 for ( int i = 0; i < foundElems.size(); ++i )
4376 res[i] = foundElems[i]->GetID();
4378 if ( !myPreviewMode ) // call from tui
4379 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4380 << elementIDs << ", "
4389 //=======================================================================
4390 //function : GetPointState
4391 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4392 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4393 //=======================================================================
4395 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4399 theSearchersDeleter.Set( myMesh );
4400 if ( !theElementSearcher ) {
4401 ::SMESH_MeshEditor anEditor( myMesh );
4402 theElementSearcher = anEditor.GetElementSearcher();
4404 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4407 //=======================================================================
4408 //function : convError
4410 //=======================================================================
4412 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4414 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4418 RETCASE( SEW_BORDER1_NOT_FOUND );
4419 RETCASE( SEW_BORDER2_NOT_FOUND );
4420 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4421 RETCASE( SEW_BAD_SIDE_NODES );
4422 RETCASE( SEW_VOLUMES_TO_SPLIT );
4423 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4424 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4425 RETCASE( SEW_BAD_SIDE1_NODES );
4426 RETCASE( SEW_BAD_SIDE2_NODES );
4428 return SMESH::SMESH_MeshEditor::SEW_OK;
4431 //=======================================================================
4432 //function : SewFreeBorders
4434 //=======================================================================
4436 SMESH::SMESH_MeshEditor::Sew_Error
4437 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4438 CORBA::Long SecondNodeID1,
4439 CORBA::Long LastNodeID1,
4440 CORBA::Long FirstNodeID2,
4441 CORBA::Long SecondNodeID2,
4442 CORBA::Long LastNodeID2,
4443 CORBA::Boolean CreatePolygons,
4444 CORBA::Boolean CreatePolyedrs)
4448 SMESHDS_Mesh* aMesh = GetMeshDS();
4450 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4451 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4452 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4453 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4454 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4455 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4457 if (!aBorderFirstNode ||
4458 !aBorderSecondNode||
4460 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4461 if (!aSide2FirstNode ||
4462 !aSide2SecondNode ||
4464 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4466 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4467 << FirstNodeID1 << ", "
4468 << SecondNodeID1 << ", "
4469 << LastNodeID1 << ", "
4470 << FirstNodeID2 << ", "
4471 << SecondNodeID2 << ", "
4472 << LastNodeID2 << ", "
4473 << CreatePolygons<< ", "
4474 << CreatePolyedrs<< " )";
4476 ::SMESH_MeshEditor anEditor( myMesh );
4477 SMESH::SMESH_MeshEditor::Sew_Error error =
4478 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4488 storeResult(anEditor);
4490 myMesh->GetMeshDS()->Modified();
4491 myMesh->SetIsModified( true );
4497 //=======================================================================
4498 //function : SewConformFreeBorders
4500 //=======================================================================
4502 SMESH::SMESH_MeshEditor::Sew_Error
4503 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4504 CORBA::Long SecondNodeID1,
4505 CORBA::Long LastNodeID1,
4506 CORBA::Long FirstNodeID2,
4507 CORBA::Long SecondNodeID2)
4511 SMESHDS_Mesh* aMesh = GetMeshDS();
4513 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4514 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4515 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4516 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4517 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4518 const SMDS_MeshNode* aSide2ThirdNode = 0;
4520 if (!aBorderFirstNode ||
4521 !aBorderSecondNode||
4523 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4524 if (!aSide2FirstNode ||
4526 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4528 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4529 << FirstNodeID1 << ", "
4530 << SecondNodeID1 << ", "
4531 << LastNodeID1 << ", "
4532 << FirstNodeID2 << ", "
4533 << SecondNodeID2 << " )";
4535 ::SMESH_MeshEditor anEditor( myMesh );
4536 SMESH::SMESH_MeshEditor::Sew_Error error =
4537 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4546 storeResult(anEditor);
4548 myMesh->GetMeshDS()->Modified();
4549 myMesh->SetIsModified( true );
4555 //=======================================================================
4556 //function : SewBorderToSide
4558 //=======================================================================
4560 SMESH::SMESH_MeshEditor::Sew_Error
4561 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4562 CORBA::Long SecondNodeIDOnFreeBorder,
4563 CORBA::Long LastNodeIDOnFreeBorder,
4564 CORBA::Long FirstNodeIDOnSide,
4565 CORBA::Long LastNodeIDOnSide,
4566 CORBA::Boolean CreatePolygons,
4567 CORBA::Boolean CreatePolyedrs)
4571 SMESHDS_Mesh* aMesh = GetMeshDS();
4573 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4574 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4575 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4576 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4577 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4578 const SMDS_MeshNode* aSide2ThirdNode = 0;
4580 if (!aBorderFirstNode ||
4581 !aBorderSecondNode||
4583 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4584 if (!aSide2FirstNode ||
4586 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4588 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4589 << FirstNodeIDOnFreeBorder << ", "
4590 << SecondNodeIDOnFreeBorder << ", "
4591 << LastNodeIDOnFreeBorder << ", "
4592 << FirstNodeIDOnSide << ", "
4593 << LastNodeIDOnSide << ", "
4594 << CreatePolygons << ", "
4595 << CreatePolyedrs << ") ";
4597 ::SMESH_MeshEditor anEditor( myMesh );
4598 SMESH::SMESH_MeshEditor::Sew_Error error =
4599 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4609 storeResult(anEditor);
4611 myMesh->GetMeshDS()->Modified();
4612 myMesh->SetIsModified( true );
4618 //=======================================================================
4619 //function : SewSideElements
4621 //=======================================================================
4623 SMESH::SMESH_MeshEditor::Sew_Error
4624 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
4625 const SMESH::long_array& IDsOfSide2Elements,
4626 CORBA::Long NodeID1OfSide1ToMerge,
4627 CORBA::Long NodeID1OfSide2ToMerge,
4628 CORBA::Long NodeID2OfSide1ToMerge,
4629 CORBA::Long NodeID2OfSide2ToMerge)
4633 SMESHDS_Mesh* aMesh = GetMeshDS();
4635 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
4636 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
4637 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
4638 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
4640 if (!aFirstNode1ToMerge ||
4641 !aFirstNode2ToMerge )
4642 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
4643 if (!aSecondNode1ToMerge||
4644 !aSecondNode2ToMerge)
4645 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
4647 TIDSortedElemSet aSide1Elems, aSide2Elems;
4648 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
4649 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
4651 TPythonDump() << "error = " << this << ".SewSideElements( "
4652 << IDsOfSide1Elements << ", "
4653 << IDsOfSide2Elements << ", "
4654 << NodeID1OfSide1ToMerge << ", "
4655 << NodeID1OfSide2ToMerge << ", "
4656 << NodeID2OfSide1ToMerge << ", "
4657 << NodeID2OfSide2ToMerge << ")";
4659 ::SMESH_MeshEditor anEditor( myMesh );
4660 SMESH::SMESH_MeshEditor::Sew_Error error =
4661 convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
4664 aSecondNode1ToMerge,
4665 aSecondNode2ToMerge));
4667 storeResult(anEditor);
4669 myMesh->GetMeshDS()->Modified();
4670 myMesh->SetIsModified( true );
4675 //================================================================================
4677 * \brief Set new nodes for given element
4678 * \param ide - element id
4679 * \param newIDs - new node ids
4680 * \retval CORBA::Boolean - true if result is OK
4682 //================================================================================
4684 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
4685 const SMESH::long_array& newIDs)
4689 const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
4690 if(!elem) return false;
4692 int nbn = newIDs.length();
4694 vector<const SMDS_MeshNode*> aNodes(nbn);
4697 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
4700 aNodes[nbn1] = aNode;
4703 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
4704 << ide << ", " << newIDs << " )";
4706 MESSAGE("ChangeElementNodes");
4707 bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
4709 myMesh->GetMeshDS()->Modified();
4711 myMesh->SetIsModified( true );
4716 //================================================================================
4718 * \brief Update myLastCreated* or myPreviewData
4719 * \param anEditor - it contains last modification results
4721 //================================================================================
4723 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
4725 if ( myPreviewMode ) { // --- MeshPreviewStruct filling ---
4727 list<int> aNodesConnectivity;
4728 typedef map<int, int> TNodesMap;
4731 TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
4732 SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
4734 SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
4735 int nbEdges = aMeshDS->NbEdges();
4736 int nbFaces = aMeshDS->NbFaces();
4737 int nbVolum = aMeshDS->NbVolumes();
4738 switch ( previewType ) {
4739 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
4740 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
4741 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
4744 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
4745 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
4747 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
4749 while ( itMeshElems->more() ) {
4750 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
4751 if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
4754 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
4755 while ( itElemNodes->more() ) {
4756 const SMDS_MeshNode* aMeshNode =
4757 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
4758 int aNodeID = aMeshNode->GetID();
4759 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
4760 if ( anIter == nodesMap.end() ) {
4761 // filling the nodes coordinates
4762 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
4763 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
4764 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
4765 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
4768 aNodesConnectivity.push_back(anIter->second);
4771 // filling the elements types
4772 SMDSAbs_ElementType aType;
4774 /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
4775 aType = SMDSAbs_Node;
4779 aType = aMeshElem->GetType();
4780 isPoly = aMeshElem->IsPoly();
4783 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
4784 myPreviewData->elementTypes[i].isPoly = isPoly;
4785 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
4789 myPreviewData->nodesXYZ.length( j );
4791 // filling the elements connectivities
4792 list<int>::iterator aConnIter = aNodesConnectivity.begin();
4793 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
4794 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
4795 myPreviewData->elementConnectivities[i] = *aConnIter;
4801 // append new nodes into myLastCreatedNodes
4802 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
4803 int j = myLastCreatedNodes->length();
4804 int newLen = j + aSeq.Length();
4805 myLastCreatedNodes->length( newLen );
4806 for(int i=0; j<newLen; i++,j++)
4807 myLastCreatedNodes[j] = aSeq.Value(i+1)->GetID();
4810 // append new elements into myLastCreatedElems
4811 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
4812 int j = myLastCreatedElems->length();
4813 int newLen = j + aSeq.Length();
4814 myLastCreatedElems->length( newLen );
4815 for(int i=0; j<newLen; i++,j++)
4816 myLastCreatedElems[j] = aSeq.Value(i+1)->GetID();
4820 //================================================================================
4822 * Return data of mesh edition preview
4824 //================================================================================
4826 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
4828 return myPreviewData._retn();
4831 //================================================================================
4833 * \brief Returns list of it's IDs of created nodes
4834 * \retval SMESH::long_array* - list of node ID
4836 //================================================================================
4838 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
4840 return myLastCreatedNodes._retn();
4843 //================================================================================
4845 * \brief Returns list of it's IDs of created elements
4846 * \retval SMESH::long_array* - list of elements' ID
4848 //================================================================================
4850 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
4852 return myLastCreatedElems._retn();
4855 //=======================================================================
4856 //function : ConvertToQuadratic
4858 //=======================================================================
4860 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
4862 ::SMESH_MeshEditor anEditor( myMesh );
4863 anEditor.ConvertToQuadratic(theForce3d);
4864 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
4865 myMesh->GetMeshDS()->Modified();
4866 myMesh->SetIsModified( true );
4869 //=======================================================================
4870 //function : ConvertFromQuadratic
4872 //=======================================================================
4874 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
4876 ::SMESH_MeshEditor anEditor( myMesh );
4877 CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
4878 TPythonDump() << this << ".ConvertFromQuadratic()";
4879 myMesh->GetMeshDS()->Modified();
4881 myMesh->SetIsModified( true );
4884 //================================================================================
4886 * \brief Makes a part of the mesh quadratic
4888 //================================================================================
4890 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
4891 SMESH::SMESH_IDSource_ptr theObject)
4892 throw (SALOME::SALOME_Exception)
4894 Unexpect aCatch(SALOME_SalomeException);
4896 TIDSortedElemSet elems;
4897 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4899 if ( elems.empty() )
4901 ConvertToQuadratic( theForce3d );
4903 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4905 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4909 ::SMESH_MeshEditor anEditor( myMesh );
4910 anEditor.ConvertToQuadratic(theForce3d, elems);
4913 myMesh->GetMeshDS()->Modified();
4914 myMesh->SetIsModified( true );
4916 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
4919 //================================================================================
4921 * \brief Makes a part of the mesh linear
4923 //================================================================================
4925 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
4926 throw (SALOME::SALOME_Exception)
4928 Unexpect aCatch(SALOME_SalomeException);
4930 TIDSortedElemSet elems;
4931 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4933 if ( elems.empty() )
4935 ConvertFromQuadratic();
4937 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4939 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4943 ::SMESH_MeshEditor anEditor( myMesh );
4944 anEditor.ConvertFromQuadratic(elems);
4947 myMesh->GetMeshDS()->Modified();
4948 myMesh->SetIsModified( true );
4950 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
4953 //=======================================================================
4954 //function : makeMesh
4955 //purpose : create a named imported mesh
4956 //=======================================================================
4958 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
4960 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
4961 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
4962 SALOMEDS::Study_var study = gen->GetCurrentStudy();
4963 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
4964 gen->SetName( meshSO, theMeshName, "Mesh" );
4965 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
4967 return mesh._retn();
4970 //=======================================================================
4971 //function : DumpGroupsList
4973 //=======================================================================
4974 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
4975 const SMESH::ListOfGroups * theGroupList)
4977 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
4978 if(isDumpGroupList) {
4979 theDumpPython << theGroupList << " = ";
4983 //================================================================================
4985 \brief Generates the unique group name.
4986 \param thePrefix name prefix
4989 //================================================================================
4990 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
4992 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
4993 set<string> groupNames;
4995 // Get existing group names
4996 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
4997 SMESH::SMESH_GroupBase_var aGroup = groups[i];
4998 if (CORBA::is_nil(aGroup))
5001 groupNames.insert(aGroup->GetName());
5005 string name = thePrefix;
5008 while (!groupNames.insert(name).second) {
5013 TCollection_AsciiString nbStr(index+1);
5014 name.resize( name.rfind('_')+1 );
5015 name += nbStr.ToCString();
5023 //================================================================================
5025 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5026 \param theNodes - identifiers of nodes to be doubled
5027 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5028 nodes. If list of element identifiers is empty then nodes are doubled but
5029 they not assigned to elements
5030 \return TRUE if operation has been completed successfully, FALSE otherwise
5031 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5033 //================================================================================
5035 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5036 const SMESH::long_array& theModifiedElems )
5040 ::SMESH_MeshEditor aMeshEditor( myMesh );
5041 list< int > aListOfNodes;
5043 for ( i = 0, n = theNodes.length(); i < n; i++ )
5044 aListOfNodes.push_back( theNodes[ i ] );
5046 list< int > aListOfElems;
5047 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5048 aListOfElems.push_back( theModifiedElems[ i ] );
5050 bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
5052 myMesh->GetMeshDS()->Modified();
5053 storeResult( aMeshEditor) ;
5055 myMesh->SetIsModified( true );
5057 // Update Python script
5058 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5063 //================================================================================
5065 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5066 This method provided for convenience works as DoubleNodes() described above.
5067 \param theNodeId - identifier of node to be doubled.
5068 \param theModifiedElems - identifiers of elements to be updated.
5069 \return TRUE if operation has been completed successfully, FALSE otherwise
5070 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5072 //================================================================================
5074 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5075 const SMESH::long_array& theModifiedElems )
5077 SMESH::long_array_var aNodes = new SMESH::long_array;
5078 aNodes->length( 1 );
5079 aNodes[ 0 ] = theNodeId;
5081 TPythonDump pyDump; // suppress dump by the next line
5083 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5085 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5090 //================================================================================
5092 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5093 This method provided for convenience works as DoubleNodes() described above.
5094 \param theNodes - group of nodes to be doubled.
5095 \param theModifiedElems - group of elements to be updated.
5096 \return TRUE if operation has been completed successfully, FALSE otherwise
5097 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5099 //================================================================================
5101 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5102 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5104 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5107 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5108 SMESH::long_array_var aModifiedElems;
5109 if ( !CORBA::is_nil( theModifiedElems ) )
5110 aModifiedElems = theModifiedElems->GetListOfID();
5113 aModifiedElems = new SMESH::long_array;
5114 aModifiedElems->length( 0 );
5117 TPythonDump pyDump; // suppress dump by the next line
5119 bool done = DoubleNodes( aNodes, aModifiedElems );
5121 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5127 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5128 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5129 * \param theNodes - group of nodes to be doubled.
5130 * \param theModifiedElems - group of elements to be updated.
5131 * \return a new group with newly created nodes
5132 * \sa DoubleNodeGroup()
5134 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5135 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5137 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5140 SMESH::SMESH_Group_var aNewGroup;
5143 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5144 SMESH::long_array_var aModifiedElems;
5145 if ( !CORBA::is_nil( theModifiedElems ) )
5146 aModifiedElems = theModifiedElems->GetListOfID();
5148 aModifiedElems = new SMESH::long_array;
5149 aModifiedElems->length( 0 );
5152 TPythonDump pyDump; // suppress dump by the next line
5154 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5158 // Create group with newly created nodes
5159 SMESH::long_array_var anIds = GetLastCreatedNodes();
5160 if (anIds->length() > 0) {
5161 string anUnindexedName (theNodes->GetName());
5162 string aNewName = generateGroupName(anUnindexedName + "_double");
5163 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5164 aNewGroup->Add(anIds);
5168 pyDump << "createdNodes = " << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5169 << theModifiedElems << " )";
5171 return aNewGroup._retn();
5174 //================================================================================
5176 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5177 This method provided for convenience works as DoubleNodes() described above.
5178 \param theNodes - list of groups of nodes to be doubled
5179 \param theModifiedElems - list of groups of elements to be updated.
5180 \return TRUE if operation has been completed successfully, FALSE otherwise
5181 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5183 //================================================================================
5185 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5186 const SMESH::ListOfGroups& theModifiedElems )
5190 ::SMESH_MeshEditor aMeshEditor( myMesh );
5192 std::list< int > aNodes;
5194 for ( i = 0, n = theNodes.length(); i < n; i++ )
5196 SMESH::SMESH_GroupBase_var aGrp = theNodes[ 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 aNodes.push_back( aCurr[ j ] );
5205 std::list< int > anElems;
5206 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5208 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5209 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5211 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5212 for ( j = 0, m = aCurr->length(); j < m; j++ )
5213 anElems.push_back( aCurr[ j ] );
5217 bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
5219 storeResult( aMeshEditor) ;
5221 myMesh->GetMeshDS()->Modified();
5223 myMesh->SetIsModified( true );
5226 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5231 //================================================================================
5233 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5234 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5235 * \param theNodes - group of nodes to be doubled.
5236 * \param theModifiedElems - group of elements to be updated.
5237 * \return a new group with newly created nodes
5238 * \sa DoubleNodeGroups()
5240 //================================================================================
5242 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5243 const SMESH::ListOfGroups& theModifiedElems )
5245 SMESH::SMESH_Group_var aNewGroup;
5247 TPythonDump pyDump; // suppress dump by the next line
5249 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5253 // Create group with newly created nodes
5254 SMESH::long_array_var anIds = GetLastCreatedNodes();
5255 if (anIds->length() > 0) {
5256 string anUnindexedName (theNodes[0]->GetName());
5257 string aNewName = generateGroupName(anUnindexedName + "_double");
5258 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5259 aNewGroup->Add(anIds);
5263 pyDump << "createdNodes = " << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5264 << theModifiedElems << " )";
5266 return aNewGroup._retn();
5270 //================================================================================
5272 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5273 \param theElems - the list of elements (edges or faces) to be replicated
5274 The nodes for duplication could be found from these elements
5275 \param theNodesNot - list of nodes to NOT replicate
5276 \param theAffectedElems - the list of elements (cells and edges) to which the
5277 replicated nodes should be associated to.
5278 \return TRUE if operation has been completed successfully, FALSE otherwise
5279 \sa DoubleNodeGroup(), DoubleNodeGroups()
5281 //================================================================================
5283 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5284 const SMESH::long_array& theNodesNot,
5285 const SMESH::long_array& theAffectedElems )
5290 ::SMESH_MeshEditor aMeshEditor( myMesh );
5292 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5293 TIDSortedElemSet anElems, aNodes, anAffected;
5294 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5295 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5296 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5298 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5300 storeResult( aMeshEditor) ;
5302 myMesh->GetMeshDS()->Modified();
5304 myMesh->SetIsModified( true );
5306 // Update Python script
5307 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5308 << theNodesNot << ", " << theAffectedElems << " )";
5312 //================================================================================
5314 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5315 \param theElems - the list of elements (edges or faces) to be replicated
5316 The nodes for duplication could be found from these elements
5317 \param theNodesNot - list of nodes to NOT replicate
5318 \param theShape - shape to detect affected elements (element which geometric center
5319 located on or inside shape).
5320 The replicated nodes should be associated to affected elements.
5321 \return TRUE if operation has been completed successfully, FALSE otherwise
5322 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5324 //================================================================================
5326 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5327 const SMESH::long_array& theNodesNot,
5328 GEOM::GEOM_Object_ptr theShape )
5333 ::SMESH_MeshEditor aMeshEditor( myMesh );
5335 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5336 TIDSortedElemSet anElems, aNodes;
5337 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5338 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5340 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5341 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5343 storeResult( aMeshEditor) ;
5345 myMesh->GetMeshDS()->Modified();
5347 myMesh->SetIsModified( true );
5349 // Update Python script
5350 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5351 << theNodesNot << ", " << theShape << " )";
5355 //================================================================================
5357 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5358 \param theElems - group of of elements (edges or faces) to be replicated
5359 \param theNodesNot - group of nodes not to replicated
5360 \param theAffectedElems - group of elements to which the replicated nodes
5361 should be associated to.
5362 \return TRUE if operation has been completed successfully, FALSE otherwise
5363 \sa DoubleNodes(), DoubleNodeGroups()
5365 //================================================================================
5367 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5368 SMESH::SMESH_GroupBase_ptr theNodesNot,
5369 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5371 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5376 ::SMESH_MeshEditor aMeshEditor( myMesh );
5378 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5379 TIDSortedElemSet anElems, aNodes, anAffected;
5380 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5381 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5382 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5384 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5386 storeResult( aMeshEditor) ;
5388 myMesh->GetMeshDS()->Modified();
5390 myMesh->SetIsModified( true );
5392 // Update Python script
5393 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5394 << theNodesNot << ", " << theAffectedElems << " )";
5399 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5400 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5401 * \param theElems - group of of elements (edges or faces) to be replicated
5402 * \param theNodesNot - group of nodes not to replicated
5403 * \param theAffectedElems - group of elements to which the replicated nodes
5404 * should be associated to.
5405 * \return a new group with newly created elements
5406 * \sa DoubleNodeElemGroup()
5408 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5409 SMESH::SMESH_GroupBase_ptr theNodesNot,
5410 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5412 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5415 SMESH::SMESH_Group_var aNewGroup;
5419 ::SMESH_MeshEditor aMeshEditor( myMesh );
5421 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5422 TIDSortedElemSet anElems, aNodes, anAffected;
5423 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5424 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5425 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5428 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5430 storeResult( aMeshEditor) ;
5433 myMesh->SetIsModified( true );
5435 // Create group with newly created elements
5436 SMESH::long_array_var anIds = GetLastCreatedElems();
5437 if (anIds->length() > 0) {
5438 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5439 string anUnindexedName (theElems->GetName());
5440 string aNewName = generateGroupName(anUnindexedName + "_double");
5441 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5442 aNewGroup->Add(anIds);
5446 // Update Python script
5447 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupNew( " << theElems << ", "
5448 << theNodesNot << ", " << theAffectedElems << " )";
5449 return aNewGroup._retn();
5452 //================================================================================
5454 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5455 \param theElems - group of of elements (edges or faces) to be replicated
5456 \param theNodesNot - group of nodes not to replicated
5457 \param theShape - shape to detect affected elements (element which geometric center
5458 located on or inside shape).
5459 The replicated nodes should be associated to affected elements.
5460 \return TRUE if operation has been completed successfully, FALSE otherwise
5461 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5463 //================================================================================
5465 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5466 SMESH::SMESH_GroupBase_ptr theNodesNot,
5467 GEOM::GEOM_Object_ptr theShape )
5470 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5475 ::SMESH_MeshEditor aMeshEditor( myMesh );
5477 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5478 TIDSortedElemSet anElems, aNodes, anAffected;
5479 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5480 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5482 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5483 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5485 storeResult( aMeshEditor) ;
5487 myMesh->GetMeshDS()->Modified();
5489 myMesh->SetIsModified( true );
5491 // Update Python script
5492 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5493 << theNodesNot << ", " << theShape << " )";
5497 //================================================================================
5499 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5500 This method provided for convenience works as DoubleNodes() described above.
5501 \param theElems - list of groups of elements (edges or faces) to be replicated
5502 \param theNodesNot - list of groups of nodes not to replicated
5503 \param theAffectedElems - group of elements to which the replicated nodes
5504 should be associated to.
5505 \return TRUE if operation has been completed successfully, FALSE otherwise
5506 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5508 //================================================================================
5510 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5511 SMESHDS_Mesh* theMeshDS,
5512 TIDSortedElemSet& theElemSet,
5513 const bool theIsNodeGrp)
5515 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5517 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5518 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5519 : aGrp->GetType() != SMESH::NODE ) )
5521 SMESH::long_array_var anIDs = aGrp->GetIDs();
5522 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5527 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5528 const SMESH::ListOfGroups& theNodesNot,
5529 const SMESH::ListOfGroups& theAffectedElems)
5533 ::SMESH_MeshEditor aMeshEditor( myMesh );
5535 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5536 TIDSortedElemSet anElems, aNodes, anAffected;
5537 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5538 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5539 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5541 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5543 storeResult( aMeshEditor) ;
5545 myMesh->GetMeshDS()->Modified();
5547 myMesh->SetIsModified( true );
5549 // Update Python script
5550 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5551 << &theNodesNot << ", " << &theAffectedElems << " )";
5555 //================================================================================
5557 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5558 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5559 \param theElems - list of groups of elements (edges or faces) to be replicated
5560 \param theNodesNot - list of groups of nodes not to replicated
5561 \param theAffectedElems - group of elements to which the replicated nodes
5562 should be associated to.
5563 * \return a new group with newly created elements
5564 * \sa DoubleNodeElemGroups()
5566 //================================================================================
5568 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5569 const SMESH::ListOfGroups& theNodesNot,
5570 const SMESH::ListOfGroups& theAffectedElems)
5572 SMESH::SMESH_Group_var aNewGroup;
5576 ::SMESH_MeshEditor aMeshEditor( myMesh );
5578 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5579 TIDSortedElemSet anElems, aNodes, anAffected;
5580 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5581 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5582 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5584 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5586 storeResult( aMeshEditor) ;
5588 myMesh->GetMeshDS()->Modified();
5590 myMesh->SetIsModified( true );
5592 // Create group with newly created elements
5593 SMESH::long_array_var anIds = GetLastCreatedElems();
5594 if (anIds->length() > 0) {
5595 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5596 string anUnindexedName (theElems[0]->GetName());
5597 string aNewName = generateGroupName(anUnindexedName + "_double");
5598 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5599 aNewGroup->Add(anIds);
5603 // Update Python script
5604 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupsNew( " << &theElems << ", "
5605 << &theNodesNot << ", " << &theAffectedElems << " )";
5606 return aNewGroup._retn();
5609 //================================================================================
5611 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5612 This method provided for convenience works as DoubleNodes() described above.
5613 \param theElems - list of groups of elements (edges or faces) to be replicated
5614 \param theNodesNot - list of groups of nodes not to replicated
5615 \param theShape - shape to detect affected elements (element which geometric center
5616 located on or inside shape).
5617 The replicated nodes should be associated to affected elements.
5618 \return TRUE if operation has been completed successfully, FALSE otherwise
5619 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
5621 //================================================================================
5624 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
5625 const SMESH::ListOfGroups& theNodesNot,
5626 GEOM::GEOM_Object_ptr theShape )
5630 ::SMESH_MeshEditor aMeshEditor( myMesh );
5632 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5633 TIDSortedElemSet anElems, aNodes;
5634 listOfGroupToSet(theElems, aMeshDS, anElems,false );
5635 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5637 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5638 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5640 storeResult( aMeshEditor) ;
5642 myMesh->GetMeshDS()->Modified();
5644 myMesh->SetIsModified( true );
5646 // Update Python script
5647 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
5648 << &theNodesNot << ", " << theShape << " )";
5652 //================================================================================
5654 \brief Generated skin mesh (containing 2D cells) from 3D mesh
5655 The created 2D mesh elements based on nodes of free faces of boundary volumes
5656 \return TRUE if operation has been completed successfully, FALSE otherwise
5658 //================================================================================
5660 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
5664 ::SMESH_MeshEditor aMeshEditor( myMesh );
5665 bool aResult = aMeshEditor.Make2DMeshFrom3D();
5666 storeResult( aMeshEditor) ;
5667 myMesh->GetMeshDS()->Modified();
5668 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
5672 //================================================================================
5674 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
5675 * The list of groups must describe a partition of the mesh volumes.
5676 * The nodes of the internal faces at the boundaries of the groups are doubled.
5677 * In option, the internal faces are replaced by flat elements.
5678 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5679 * The flat elements are stored in groups of volumes.
5680 * @param theDomains - list of groups of volumes
5681 * @param createJointElems - if TRUE, create the elements
5682 * @return TRUE if operation has been completed successfully, FALSE otherwise
5684 //================================================================================
5686 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
5687 CORBA::Boolean createJointElems )
5688 throw (SALOME::SALOME_Exception)
5692 ::SMESH_MeshEditor aMeshEditor( myMesh );
5694 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5696 vector<TIDSortedElemSet> domains;
5699 for ( int i = 0, n = theDomains.length(); i < n; i++ )
5701 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
5702 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
5704 if ( aGrp->GetType() != SMESH::VOLUME )
5705 THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
5706 TIDSortedElemSet domain;
5708 domains.push_back(domain);
5709 SMESH::long_array_var anIDs = aGrp->GetIDs();
5710 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
5714 bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
5715 // TODO publish the groups of flat elements in study
5717 storeResult( aMeshEditor) ;
5718 myMesh->GetMeshDS()->Modified();
5720 // Update Python script
5721 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
5722 << ", " << createJointElems << " )";
5726 //================================================================================
5728 * \brief Double nodes on some external faces and create flat elements.
5729 * Flat elements are mainly used by some types of mechanic calculations.
5731 * Each group of the list must be constituted of faces.
5732 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5733 * @param theGroupsOfFaces - list of groups of faces
5734 * @return TRUE if operation has been completed successfully, FALSE otherwise
5736 //================================================================================
5738 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
5742 ::SMESH_MeshEditor aMeshEditor( myMesh );
5744 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5746 vector<TIDSortedElemSet> faceGroups;
5749 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
5751 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
5752 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
5754 TIDSortedElemSet faceGroup;
5756 faceGroups.push_back(faceGroup);
5757 SMESH::long_array_var anIDs = aGrp->GetIDs();
5758 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
5762 bool aResult = aMeshEditor.CreateFlatElementsOnFacesGroups( faceGroups );
5763 // TODO publish the groups of flat elements in study
5765 storeResult( aMeshEditor) ;
5766 myMesh->GetMeshDS()->Modified();
5768 // Update Python script
5769 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
5773 // issue 20749 ===================================================================
5775 * \brief Creates missing boundary elements
5776 * \param elements - elements whose boundary is to be checked
5777 * \param dimension - defines type of boundary elements to create
5778 * \param groupName - a name of group to store created boundary elements in,
5779 * "" means not to create the group
5780 * \param meshName - a name of new mesh to store created boundary elements in,
5781 * "" means not to create the new mesh
5782 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
5783 * \param toCopyExistingBondary - if true, not only new but also pre-existing
5784 * boundary elements will be copied into the new mesh
5785 * \param group - returns the create group, if any
5786 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
5788 // ================================================================================
5790 SMESH::SMESH_Mesh_ptr
5791 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
5792 SMESH::Bnd_Dimension dim,
5793 const char* groupName,
5794 const char* meshName,
5795 CORBA::Boolean toCopyElements,
5796 CORBA::Boolean toCopyExistingBondary,
5797 SMESH::SMESH_Group_out group)
5801 if ( dim > SMESH::BND_1DFROM2D )
5802 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5804 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5806 SMESH::SMESH_Mesh_var mesh_var;
5807 SMESH::SMESH_Group_var group_var;
5811 TIDSortedElemSet elements;
5812 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
5813 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
5817 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
5818 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5820 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
5822 // group of new boundary elements
5823 SMESH_Group* smesh_group = 0;
5824 if ( strlen(groupName) )
5826 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
5827 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5828 smesh_group = group_i->GetSmeshGroup();
5832 ::SMESH_MeshEditor aMeshEditor( myMesh );
5833 aMeshEditor.MakeBoundaryMesh( elements,
5834 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5838 toCopyExistingBondary);
5839 storeResult( aMeshEditor );
5842 smesh_mesh->GetMeshDS()->Modified();
5845 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
5847 // result of MakeBoundaryMesh() is a tuple (mesh, group)
5848 if ( mesh_var->_is_nil() )
5849 pyDump << myMesh_i->_this() << ", ";
5851 pyDump << mesh_var << ", ";
5852 if ( group_var->_is_nil() )
5853 pyDump << "_NoneGroup = "; // assignment to None is forbiden
5855 pyDump << group_var << " = ";
5856 pyDump << this << ".MakeBoundaryMesh( "
5858 << "SMESH." << dimName[int(dim)] << ", "
5859 << "'" << groupName << "', "
5860 << "'" << meshName<< "', "
5861 << toCopyElements << ", "
5862 << toCopyExistingBondary << ")";
5864 group = group_var._retn();
5865 return mesh_var._retn();
5868 //================================================================================
5870 * \brief Creates missing boundary elements
5871 * \param dimension - defines type of boundary elements to create
5872 * \param groupName - a name of group to store all boundary elements in,
5873 * "" means not to create the group
5874 * \param meshName - a name of a new mesh, which is a copy of the initial
5875 * mesh + created boundary elements; "" means not to create the new mesh
5876 * \param toCopyAll - if true, the whole initial mesh will be copied into
5877 * the new mesh else only boundary elements will be copied into the new mesh
5878 * \param groups - optional groups of elements to make boundary around
5879 * \param mesh - returns the mesh where elements were added to
5880 * \param group - returns the created group, if any
5881 * \retval long - number of added boundary elements
5883 //================================================================================
5885 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
5886 const char* groupName,
5887 const char* meshName,
5888 CORBA::Boolean toCopyAll,
5889 const SMESH::ListOfIDSources& groups,
5890 SMESH::SMESH_Mesh_out mesh,
5891 SMESH::SMESH_Group_out group)
5892 throw (SALOME::SALOME_Exception)
5894 Unexpect aCatch(SALOME_SalomeException);
5898 if ( dim > SMESH::BND_1DFROM2D )
5899 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5901 // separate groups belonging to this and other mesh
5902 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
5903 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
5904 groupsOfThisMesh->length( groups.length() );
5905 groupsOfOtherMesh->length( groups.length() );
5906 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
5907 for ( int i = 0; i < groups.length(); ++i )
5909 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
5910 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
5911 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
5913 groupsOfThisMesh[ nbGroups++ ] = groups[i];
5914 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
5915 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
5917 groupsOfThisMesh->length( nbGroups );
5918 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
5923 if ( nbGroupsOfOtherMesh > 0 )
5925 // process groups belonging to another mesh
5926 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
5927 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
5928 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
5929 groupsOfOtherMesh, mesh, group );
5932 SMESH::SMESH_Mesh_var mesh_var;
5933 SMESH::SMESH_Group_var group_var;
5936 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
5937 const bool toCopyMesh = ( strlen( meshName ) > 0 );
5941 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
5943 /*toCopyGroups=*/false,
5944 /*toKeepIDs=*/true);
5946 mesh_var = makeMesh(meshName);
5948 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5949 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
5952 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
5953 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
5955 // group of boundary elements
5956 SMESH_Group* smesh_group = 0;
5957 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
5958 if ( strlen(groupName) )
5960 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
5961 group_var = mesh_i->CreateGroup( groupType, groupName );
5962 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5963 smesh_group = group_i->GetSmeshGroup();
5966 TIDSortedElemSet elements;
5968 if ( groups.length() > 0 )
5970 for ( int i = 0; i < nbGroups; ++i )
5973 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
5975 SMESH::Bnd_Dimension bdim =
5976 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
5977 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5978 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5979 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
5982 /*toCopyElements=*/false,
5983 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
5984 /*toAddExistingBondary=*/true,
5985 /*aroundElements=*/true);
5986 storeResult( aMeshEditor );
5992 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5993 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5994 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5997 /*toCopyElements=*/false,
5998 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
5999 /*toAddExistingBondary=*/true);
6000 storeResult( aMeshEditor );
6002 tgtMesh->GetMeshDS()->Modified();
6004 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6006 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6007 pyDump << "nbAdded, ";
6008 if ( mesh_var->_is_nil() )
6009 pyDump << myMesh_i->_this() << ", ";
6011 pyDump << mesh_var << ", ";
6012 if ( group_var->_is_nil() )
6013 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6015 pyDump << group_var << " = ";
6016 pyDump << this << ".MakeBoundaryElements( "
6017 << "SMESH." << dimName[int(dim)] << ", "
6018 << "'" << groupName << "', "
6019 << "'" << meshName<< "', "
6020 << toCopyAll << ", "
6023 mesh = mesh_var._retn();
6024 group = group_var._retn();