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;
437 return types._retn();
441 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
442 SMESH::ElementType type)
444 _IDSource* anIDSource = new _IDSource;
445 anIDSource->_ids = ids;
446 anIDSource->_type = type;
447 anIDSource->_mesh = myMesh_i->_this();
448 SMESH::SMESH_IDSource_var anIDSourceVar = anIDSource->_this();
450 return anIDSourceVar._retn();
453 //=============================================================================
457 //=============================================================================
460 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
464 ::SMESH_MeshEditor anEditor( myMesh );
467 for (int i = 0; i < IDsOfElements.length(); i++)
468 IdList.push_back( IDsOfElements[i] );
470 // Update Python script
471 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
474 bool ret = anEditor.Remove( IdList, false );
475 myMesh->GetMeshDS()->Modified();
476 if ( IDsOfElements.length() )
477 myMesh->SetIsModified( true ); // issue 0020693
481 //=============================================================================
485 //=============================================================================
487 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
491 ::SMESH_MeshEditor anEditor( myMesh );
493 for (int i = 0; i < IDsOfNodes.length(); i++)
494 IdList.push_back( IDsOfNodes[i] );
496 // Update Python script
497 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
499 bool ret = anEditor.Remove( IdList, true );
500 myMesh->GetMeshDS()->Modified();
501 if ( IDsOfNodes.length() )
502 myMesh->SetIsModified( true ); // issue 0020693
506 //=============================================================================
510 //=============================================================================
512 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
516 ::SMESH_MeshEditor anEditor( myMesh );
518 // Update Python script
519 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
521 // Create filter to find all orphan nodes
522 SMESH::Controls::Filter::TIdSequence seq;
523 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
524 SMESH::Controls::Filter::GetElementsId( GetMeshDS(), predicate, seq );
526 // remove orphan nodes (if there are any)
528 for ( int i = 0; i < seq.size(); i++ )
529 IdList.push_back( seq[i] );
531 bool ret = anEditor.Remove( IdList, true );
532 myMesh->GetMeshDS()->Modified();
534 myMesh->SetIsModified( true );
539 //=============================================================================
543 //=============================================================================
545 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
546 CORBA::Double y, CORBA::Double z)
550 const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
552 // Update Python script
553 TPythonDump() << "nodeID = " << this << ".AddNode( "
554 << x << ", " << y << ", " << z << " )";
556 myMesh->GetMeshDS()->Modified();
557 myMesh->SetIsModified( true ); // issue 0020693
561 //=============================================================================
565 //=============================================================================
566 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
570 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
571 SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode);
573 // Update Python script
574 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
576 myMesh->GetMeshDS()->Modified();
577 myMesh->SetIsModified( true ); // issue 0020693
580 return elem->GetID();
585 //=============================================================================
589 //=============================================================================
591 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
595 int NbNodes = IDsOfNodes.length();
596 SMDS_MeshElement* elem = 0;
599 CORBA::Long index1 = IDsOfNodes[0];
600 CORBA::Long index2 = IDsOfNodes[1];
601 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
603 // Update Python script
604 TPythonDump() << "edge = " << this << ".AddEdge([ "
605 << index1 << ", " << index2 <<" ])";
608 CORBA::Long n1 = IDsOfNodes[0];
609 CORBA::Long n2 = IDsOfNodes[1];
610 CORBA::Long n12 = IDsOfNodes[2];
611 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
612 GetMeshDS()->FindNode(n2),
613 GetMeshDS()->FindNode(n12));
614 // Update Python script
615 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
616 <<n1<<", "<<n2<<", "<<n12<<" ])";
619 myMesh->GetMeshDS()->Modified();
621 return myMesh->SetIsModified( true ), elem->GetID();
626 //=============================================================================
630 //=============================================================================
632 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
636 int NbNodes = IDsOfNodes.length();
642 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
643 for (int i = 0; i < NbNodes; i++)
644 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
646 SMDS_MeshElement* elem = 0;
648 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
650 else if (NbNodes == 4) {
651 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
653 else if (NbNodes == 6) {
654 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
657 else if (NbNodes == 8) {
658 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
659 nodes[4], nodes[5], nodes[6], nodes[7]);
661 else if (NbNodes > 2) {
662 elem = GetMeshDS()->AddPolygonalFace(nodes);
665 // Update Python script
666 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
668 myMesh->GetMeshDS()->Modified();
670 return myMesh->SetIsModified( true ), elem->GetID();
675 //=============================================================================
679 //=============================================================================
680 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
684 int NbNodes = IDsOfNodes.length();
685 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
686 for (int i = 0; i < NbNodes; i++)
687 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
689 const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
691 // Update Python script
692 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
694 myMesh->GetMeshDS()->Modified();
695 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
698 //=============================================================================
702 //=============================================================================
704 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
708 int NbNodes = IDsOfNodes.length();
709 vector< const SMDS_MeshNode*> n(NbNodes);
710 for(int i=0;i<NbNodes;i++)
711 n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
713 SMDS_MeshElement* elem = 0;
716 case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
717 case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
718 case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
719 case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
720 case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
721 n[6],n[7],n[8],n[9]);
723 case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
724 n[7],n[8],n[9],n[10],n[11],n[12]);
726 case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
727 n[9],n[10],n[11],n[12],n[13],n[14]);
729 case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
730 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
731 n[15],n[16],n[17],n[18],n[19]);
735 // Update Python script
736 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
738 myMesh->GetMeshDS()->Modified();
740 return myMesh->SetIsModified( true ), elem->GetID();
745 //=============================================================================
747 * AddPolyhedralVolume
749 //=============================================================================
750 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
751 const SMESH::long_array & Quantities)
755 int NbNodes = IDsOfNodes.length();
756 std::vector<const SMDS_MeshNode*> n (NbNodes);
757 for (int i = 0; i < NbNodes; i++)
759 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
760 if (!aNode) return 0;
764 int NbFaces = Quantities.length();
765 std::vector<int> q (NbFaces);
766 for (int j = 0; j < NbFaces; j++)
767 q[j] = Quantities[j];
769 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
771 // Update Python script
772 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
773 << IDsOfNodes << ", " << Quantities << " )";
774 myMesh->GetMeshDS()->Modified();
776 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
779 //=============================================================================
781 * AddPolyhedralVolumeByFaces
783 //=============================================================================
784 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
788 int NbFaces = IdsOfFaces.length();
789 std::vector<const SMDS_MeshNode*> poly_nodes;
790 std::vector<int> quantities (NbFaces);
792 for (int i = 0; i < NbFaces; i++) {
793 const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
794 quantities[i] = aFace->NbNodes();
796 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
798 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
802 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
804 // Update Python script
805 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
806 << IdsOfFaces << " )";
807 myMesh->GetMeshDS()->Modified();
809 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
812 //=============================================================================
814 * \brief Bind a node to a vertex
815 * \param NodeID - node ID
816 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
817 * \retval boolean - false if NodeID or VertexID is invalid
819 //=============================================================================
821 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
822 throw (SALOME::SALOME_Exception)
824 Unexpect aCatch(SALOME_SalomeException);
826 SMESHDS_Mesh * mesh = GetMeshDS();
827 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
829 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
831 if ( mesh->MaxShapeIndex() < VertexID )
832 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
834 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
835 if ( shape.ShapeType() != TopAbs_VERTEX )
836 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
838 mesh->SetNodeOnVertex( node, VertexID );
840 myMesh->SetIsModified( true );
843 //=============================================================================
845 * \brief Store node position on an edge
846 * \param NodeID - node ID
847 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
848 * \param paramOnEdge - parameter on edge where the node is located
849 * \retval boolean - false if any parameter is invalid
851 //=============================================================================
853 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
854 CORBA::Double paramOnEdge)
855 throw (SALOME::SALOME_Exception)
857 Unexpect aCatch(SALOME_SalomeException);
859 SMESHDS_Mesh * mesh = GetMeshDS();
860 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
862 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
864 if ( mesh->MaxShapeIndex() < EdgeID )
865 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
867 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
868 if ( shape.ShapeType() != TopAbs_EDGE )
869 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
872 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
873 if ( paramOnEdge < f || paramOnEdge > l )
874 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
876 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
878 myMesh->SetIsModified( true );
881 //=============================================================================
883 * \brief Store node position on a face
884 * \param NodeID - node ID
885 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
886 * \param u - U parameter on face where the node is located
887 * \param v - V parameter on face where the node is located
888 * \retval boolean - false if any parameter is invalid
890 //=============================================================================
892 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
893 CORBA::Double u, CORBA::Double v)
894 throw (SALOME::SALOME_Exception)
896 Unexpect aCatch(SALOME_SalomeException);
898 SMESHDS_Mesh * mesh = GetMeshDS();
899 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
901 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
903 if ( mesh->MaxShapeIndex() < FaceID )
904 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
906 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
907 if ( shape.ShapeType() != TopAbs_FACE )
908 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
910 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
911 bool isOut = ( u < surf.FirstUParameter() ||
912 u > surf.LastUParameter() ||
913 v < surf.FirstVParameter() ||
914 v > surf.LastVParameter() );
918 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
919 << " u( " << surf.FirstUParameter()
920 << "," << surf.LastUParameter()
921 << ") v( " << surf.FirstVParameter()
922 << "," << surf.LastVParameter() << ")" );
924 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
927 mesh->SetNodeOnFace( node, FaceID, u, v );
928 myMesh->SetIsModified( true );
931 //=============================================================================
933 * \brief Bind a node to a solid
934 * \param NodeID - node ID
935 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
936 * \retval boolean - false if NodeID or SolidID is invalid
938 //=============================================================================
940 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
941 throw (SALOME::SALOME_Exception)
943 Unexpect aCatch(SALOME_SalomeException);
945 SMESHDS_Mesh * mesh = GetMeshDS();
946 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
948 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
950 if ( mesh->MaxShapeIndex() < SolidID )
951 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
953 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
954 if ( shape.ShapeType() != TopAbs_SOLID &&
955 shape.ShapeType() != TopAbs_SHELL)
956 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
958 mesh->SetNodeInVolume( node, SolidID );
960 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
963 //=============================================================================
965 * \brief Bind an element to a shape
966 * \param ElementID - element ID
967 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
968 * \retval boolean - false if ElementID or ShapeID is invalid
970 //=============================================================================
972 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
974 throw (SALOME::SALOME_Exception)
976 Unexpect aCatch(SALOME_SalomeException);
978 SMESHDS_Mesh * mesh = GetMeshDS();
979 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
981 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
983 if ( mesh->MaxShapeIndex() < ShapeID )
984 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
986 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
987 if ( shape.ShapeType() != TopAbs_EDGE &&
988 shape.ShapeType() != TopAbs_FACE &&
989 shape.ShapeType() != TopAbs_SOLID &&
990 shape.ShapeType() != TopAbs_SHELL )
991 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
993 mesh->SetMeshElementOnShape( elem, ShapeID );
995 myMesh->SetIsModified( true );
998 //=============================================================================
1002 //=============================================================================
1004 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1005 CORBA::Long NodeID2)
1009 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1010 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1014 // Update Python script
1015 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1016 << NodeID1 << ", " << NodeID2 << " )";
1019 ::SMESH_MeshEditor aMeshEditor( myMesh );
1020 int ret = aMeshEditor.InverseDiag ( n1, n2 );
1021 myMesh->GetMeshDS()->Modified();
1022 myMesh->SetIsModified( true );
1026 //=============================================================================
1030 //=============================================================================
1032 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1033 CORBA::Long NodeID2)
1037 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1038 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1042 // Update Python script
1043 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1044 << NodeID1 << ", " << NodeID2 << " )";
1046 ::SMESH_MeshEditor aMeshEditor( myMesh );
1048 bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
1050 myMesh->GetMeshDS()->Modified();
1052 myMesh->SetIsModified( true ); // issue 0020693
1054 storeResult(aMeshEditor);
1059 //=============================================================================
1063 //=============================================================================
1065 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1069 ::SMESH_MeshEditor anEditor( myMesh );
1070 for (int i = 0; i < IDsOfElements.length(); i++)
1072 CORBA::Long index = IDsOfElements[i];
1073 const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
1075 anEditor.Reorient( elem );
1077 // Update Python script
1078 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1080 myMesh->GetMeshDS()->Modified();
1081 if ( IDsOfElements.length() )
1082 myMesh->SetIsModified( true ); // issue 0020693
1088 //=============================================================================
1092 //=============================================================================
1094 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1098 TPythonDump aTPythonDump; // suppress dump in Reorient()
1100 SMESH::long_array_var anElementsId = theObject->GetIDs();
1101 CORBA::Boolean isDone = Reorient(anElementsId);
1103 // Update Python script
1104 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1109 //=============================================================================
1113 //=============================================================================
1114 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1115 SMESH::NumericalFunctor_ptr Criterion,
1116 CORBA::Double MaxAngle)
1120 SMESHDS_Mesh* aMesh = GetMeshDS();
1121 TIDSortedElemSet faces;
1122 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1124 SMESH::NumericalFunctor_i* aNumericalFunctor =
1125 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1126 SMESH::Controls::NumericalFunctorPtr aCrit;
1127 if ( !aNumericalFunctor )
1128 aCrit.reset( new SMESH::Controls::AspectRatio() );
1130 aCrit = aNumericalFunctor->GetNumericalFunctor();
1132 // Update Python script
1133 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1134 << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1136 ::SMESH_MeshEditor anEditor( myMesh );
1138 bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
1139 myMesh->GetMeshDS()->Modified();
1141 myMesh->SetIsModified( true ); // issue 0020693
1143 storeResult(anEditor);
1149 //=============================================================================
1153 //=============================================================================
1154 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1155 SMESH::NumericalFunctor_ptr Criterion,
1156 CORBA::Double MaxAngle)
1160 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1161 SMESH::long_array_var anElementsId = theObject->GetIDs();
1162 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1164 SMESH::NumericalFunctor_i* aNumericalFunctor =
1165 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1167 // Update Python script
1168 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1169 << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1175 //=============================================================================
1179 //=============================================================================
1180 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1181 SMESH::NumericalFunctor_ptr Criterion)
1185 SMESHDS_Mesh* aMesh = GetMeshDS();
1186 TIDSortedElemSet faces;
1187 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1189 SMESH::NumericalFunctor_i* aNumericalFunctor =
1190 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1191 SMESH::Controls::NumericalFunctorPtr aCrit;
1192 if ( !aNumericalFunctor )
1193 aCrit.reset( new SMESH::Controls::AspectRatio() );
1195 aCrit = aNumericalFunctor->GetNumericalFunctor();
1198 // Update Python script
1199 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1201 ::SMESH_MeshEditor anEditor( myMesh );
1202 CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
1203 myMesh->GetMeshDS()->Modified();
1205 myMesh->SetIsModified( true ); // issue 0020693
1207 storeResult(anEditor);
1213 //=============================================================================
1217 //=============================================================================
1218 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1219 SMESH::NumericalFunctor_ptr Criterion)
1223 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1225 SMESH::long_array_var anElementsId = theObject->GetIDs();
1226 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1228 SMESH::NumericalFunctor_i* aNumericalFunctor =
1229 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1231 // Update Python script
1232 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1238 //=============================================================================
1242 //=============================================================================
1243 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1244 CORBA::Boolean Diag13)
1248 SMESHDS_Mesh* aMesh = GetMeshDS();
1249 TIDSortedElemSet faces;
1250 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1252 // Update Python script
1253 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1254 << IDsOfElements << ", " << Diag13 << " )";
1256 ::SMESH_MeshEditor anEditor( myMesh );
1257 CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
1258 myMesh->GetMeshDS()->Modified();
1260 myMesh->SetIsModified( true ); // issue 0020693
1263 storeResult(anEditor);
1269 //=============================================================================
1273 //=============================================================================
1274 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1275 CORBA::Boolean Diag13)
1279 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1281 SMESH::long_array_var anElementsId = theObject->GetIDs();
1282 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1284 // Update Python script
1285 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1286 << theObject << ", " << Diag13 << " )";
1292 //=============================================================================
1296 //=============================================================================
1297 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1298 SMESH::NumericalFunctor_ptr Criterion)
1302 const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1303 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1305 SMESH::NumericalFunctor_i* aNumericalFunctor =
1306 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1307 SMESH::Controls::NumericalFunctorPtr aCrit;
1308 if (aNumericalFunctor)
1309 aCrit = aNumericalFunctor->GetNumericalFunctor();
1311 aCrit.reset(new SMESH::Controls::AspectRatio());
1313 ::SMESH_MeshEditor anEditor (myMesh);
1314 return anEditor.BestSplit(quad, aCrit);
1319 //================================================================================
1321 * \brief Split volumic elements into tetrahedrons
1323 //================================================================================
1325 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1326 CORBA::Short methodFlags)
1327 throw (SALOME::SALOME_Exception)
1329 Unexpect aCatch(SALOME_SalomeException);
1333 SMESH::long_array_var anElementsId = elems->GetIDs();
1334 TIDSortedElemSet elemSet;
1335 arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume );
1337 ::SMESH_MeshEditor anEditor (myMesh);
1338 anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1339 myMesh->GetMeshDS()->Modified();
1341 storeResult(anEditor);
1343 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1344 // myMesh->SetIsModified( true ); // issue 0020693
1346 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1347 << elems << ", " << methodFlags << " )";
1350 //=======================================================================
1353 //=======================================================================
1356 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1357 const SMESH::long_array & IDsOfFixedNodes,
1358 CORBA::Long MaxNbOfIterations,
1359 CORBA::Double MaxAspectRatio,
1360 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1362 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1363 MaxAspectRatio, Method, false );
1367 //=======================================================================
1368 //function : SmoothParametric
1370 //=======================================================================
1373 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1374 const SMESH::long_array & IDsOfFixedNodes,
1375 CORBA::Long MaxNbOfIterations,
1376 CORBA::Double MaxAspectRatio,
1377 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1379 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1380 MaxAspectRatio, Method, true );
1384 //=======================================================================
1385 //function : SmoothObject
1387 //=======================================================================
1390 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1391 const SMESH::long_array & IDsOfFixedNodes,
1392 CORBA::Long MaxNbOfIterations,
1393 CORBA::Double MaxAspectRatio,
1394 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1396 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1397 MaxAspectRatio, Method, false);
1401 //=======================================================================
1402 //function : SmoothParametricObject
1404 //=======================================================================
1407 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1408 const SMESH::long_array & IDsOfFixedNodes,
1409 CORBA::Long MaxNbOfIterations,
1410 CORBA::Double MaxAspectRatio,
1411 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1413 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1414 MaxAspectRatio, Method, true);
1418 //=============================================================================
1422 //=============================================================================
1425 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1426 const SMESH::long_array & IDsOfFixedNodes,
1427 CORBA::Long MaxNbOfIterations,
1428 CORBA::Double MaxAspectRatio,
1429 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1434 SMESHDS_Mesh* aMesh = GetMeshDS();
1436 TIDSortedElemSet elements;
1437 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1439 set<const SMDS_MeshNode*> fixedNodes;
1440 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1441 CORBA::Long index = IDsOfFixedNodes[i];
1442 const SMDS_MeshNode * node = aMesh->FindNode(index);
1444 fixedNodes.insert( node );
1446 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1447 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1448 method = ::SMESH_MeshEditor::CENTROIDAL;
1450 ::SMESH_MeshEditor anEditor( myMesh );
1451 anEditor.Smooth(elements, fixedNodes, method,
1452 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1454 myMesh->GetMeshDS()->Modified();
1455 myMesh->SetIsModified( true ); // issue 0020693
1457 storeResult(anEditor);
1459 // Update Python script
1460 TPythonDump() << "isDone = " << this << "."
1461 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1462 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1463 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1464 << "SMESH.SMESH_MeshEditor."
1465 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1466 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1472 //=============================================================================
1476 //=============================================================================
1479 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1480 const SMESH::long_array & IDsOfFixedNodes,
1481 CORBA::Long MaxNbOfIterations,
1482 CORBA::Double MaxAspectRatio,
1483 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1488 TPythonDump aTPythonDump; // suppress dump in smooth()
1490 SMESH::long_array_var anElementsId = theObject->GetIDs();
1491 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1492 MaxAspectRatio, Method, IsParametric);
1494 // Update Python script
1495 aTPythonDump << "isDone = " << this << "."
1496 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1497 << theObject << ", " << IDsOfFixedNodes << ", "
1498 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1499 << "SMESH.SMESH_MeshEditor."
1500 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1501 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1507 //=============================================================================
1511 //=============================================================================
1513 void SMESH_MeshEditor_i::RenumberNodes()
1515 // Update Python script
1516 TPythonDump() << this << ".RenumberNodes()";
1518 GetMeshDS()->Renumber( true );
1522 //=============================================================================
1526 //=============================================================================
1528 void SMESH_MeshEditor_i::RenumberElements()
1530 // Update Python script
1531 TPythonDump() << this << ".RenumberElements()";
1533 GetMeshDS()->Renumber( false );
1536 //=======================================================================
1538 * \brief Return groups by their IDs
1540 //=======================================================================
1542 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1546 myMesh_i->CreateGroupServants();
1547 return myMesh_i->GetGroups( *groupIDs );
1550 //=======================================================================
1551 //function : rotationSweep
1553 //=======================================================================
1555 SMESH::ListOfGroups*
1556 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1557 const SMESH::AxisStruct & theAxis,
1558 CORBA::Double theAngleInRadians,
1559 CORBA::Long theNbOfSteps,
1560 CORBA::Double theTolerance,
1561 const bool theMakeGroups,
1562 const SMDSAbs_ElementType theElementType)
1566 TIDSortedElemSet inElements, copyElements;
1567 arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
1569 TIDSortedElemSet* workElements = & inElements;
1570 TPreviewMesh tmpMesh( SMDSAbs_Face );
1571 SMESH_Mesh* mesh = 0;
1572 bool makeWalls=true;
1573 if ( myPreviewMode )
1575 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1576 tmpMesh.Copy( inElements, copyElements, select, avoid );
1578 workElements = & copyElements;
1579 //makeWalls = false;
1586 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
1587 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1589 ::SMESH_MeshEditor anEditor( mesh );
1590 ::SMESH_MeshEditor::PGroupIDs groupIds =
1591 anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1592 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
1593 storeResult(anEditor);
1594 myMesh->GetMeshDS()->Modified();
1596 // myMesh->SetIsModified( true ); -- it does not influence Compute()
1598 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1601 //=======================================================================
1602 //function : RotationSweep
1604 //=======================================================================
1606 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1607 const SMESH::AxisStruct & theAxis,
1608 CORBA::Double theAngleInRadians,
1609 CORBA::Long theNbOfSteps,
1610 CORBA::Double theTolerance)
1612 if ( !myPreviewMode ) {
1613 TPythonDump() << this << ".RotationSweep( "
1614 << theIDsOfElements << ", "
1616 << theAngleInRadians << ", "
1617 << theNbOfSteps << ", "
1618 << theTolerance << " )";
1620 rotationSweep(theIDsOfElements,
1628 //=======================================================================
1629 //function : RotationSweepMakeGroups
1631 //=======================================================================
1633 SMESH::ListOfGroups*
1634 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1635 const SMESH::AxisStruct& theAxis,
1636 CORBA::Double theAngleInRadians,
1637 CORBA::Long theNbOfSteps,
1638 CORBA::Double theTolerance)
1640 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1642 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
1648 if (!myPreviewMode) {
1649 DumpGroupsList(aPythonDump, aGroups);
1650 aPythonDump << this << ".RotationSweepMakeGroups( "
1651 << theIDsOfElements << ", "
1653 << theAngleInRadians << ", "
1654 << theNbOfSteps << ", "
1655 << theTolerance << " )";
1660 //=======================================================================
1661 //function : RotationSweepObject
1663 //=======================================================================
1665 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1666 const SMESH::AxisStruct & theAxis,
1667 CORBA::Double theAngleInRadians,
1668 CORBA::Long theNbOfSteps,
1669 CORBA::Double theTolerance)
1671 if ( !myPreviewMode ) {
1672 TPythonDump() << this << ".RotationSweepObject( "
1673 << theObject << ", "
1675 << theAngleInRadians << ", "
1676 << theNbOfSteps << ", "
1677 << theTolerance << " )";
1679 SMESH::long_array_var anElementsId = theObject->GetIDs();
1680 rotationSweep(anElementsId,
1688 //=======================================================================
1689 //function : RotationSweepObject1D
1691 //=======================================================================
1693 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1694 const SMESH::AxisStruct & theAxis,
1695 CORBA::Double theAngleInRadians,
1696 CORBA::Long theNbOfSteps,
1697 CORBA::Double theTolerance)
1699 if ( !myPreviewMode ) {
1700 TPythonDump() << this << ".RotationSweepObject1D( "
1701 << theObject << ", "
1703 << theAngleInRadians << ", "
1704 << theNbOfSteps << ", "
1705 << theTolerance << " )";
1707 SMESH::long_array_var anElementsId = theObject->GetIDs();
1708 rotationSweep(anElementsId,
1717 //=======================================================================
1718 //function : RotationSweepObject2D
1720 //=======================================================================
1722 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1723 const SMESH::AxisStruct & theAxis,
1724 CORBA::Double theAngleInRadians,
1725 CORBA::Long theNbOfSteps,
1726 CORBA::Double theTolerance)
1728 if ( !myPreviewMode ) {
1729 TPythonDump() << this << ".RotationSweepObject2D( "
1730 << theObject << ", "
1732 << theAngleInRadians << ", "
1733 << theNbOfSteps << ", "
1734 << theTolerance << " )";
1736 SMESH::long_array_var anElementsId = theObject->GetIDs();
1737 rotationSweep(anElementsId,
1746 //=======================================================================
1747 //function : RotationSweepObjectMakeGroups
1749 //=======================================================================
1751 SMESH::ListOfGroups*
1752 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1753 const SMESH::AxisStruct& theAxis,
1754 CORBA::Double theAngleInRadians,
1755 CORBA::Long theNbOfSteps,
1756 CORBA::Double theTolerance)
1758 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1760 SMESH::long_array_var anElementsId = theObject->GetIDs();
1761 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1767 if (!myPreviewMode) {
1768 DumpGroupsList(aPythonDump, aGroups);
1769 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
1770 << theObject << ", "
1772 << theAngleInRadians << ", "
1773 << theNbOfSteps << ", "
1774 << theTolerance << " )";
1779 //=======================================================================
1780 //function : RotationSweepObject1DMakeGroups
1782 //=======================================================================
1784 SMESH::ListOfGroups*
1785 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1786 const SMESH::AxisStruct& theAxis,
1787 CORBA::Double theAngleInRadians,
1788 CORBA::Long theNbOfSteps,
1789 CORBA::Double theTolerance)
1791 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1793 SMESH::long_array_var anElementsId = theObject->GetIDs();
1794 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1801 if (!myPreviewMode) {
1802 DumpGroupsList(aPythonDump, aGroups);
1803 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
1804 << theObject << ", "
1806 << theAngleInRadians << ", "
1807 << theNbOfSteps << ", "
1808 << theTolerance << " )";
1813 //=======================================================================
1814 //function : RotationSweepObject2DMakeGroups
1816 //=======================================================================
1818 SMESH::ListOfGroups*
1819 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1820 const SMESH::AxisStruct& theAxis,
1821 CORBA::Double theAngleInRadians,
1822 CORBA::Long theNbOfSteps,
1823 CORBA::Double theTolerance)
1825 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1827 SMESH::long_array_var anElementsId = theObject->GetIDs();
1828 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1835 if (!myPreviewMode) {
1836 DumpGroupsList(aPythonDump, aGroups);
1837 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
1838 << theObject << ", "
1840 << theAngleInRadians << ", "
1841 << theNbOfSteps << ", "
1842 << theTolerance << " )";
1848 //=======================================================================
1849 //function : extrusionSweep
1851 //=======================================================================
1853 SMESH::ListOfGroups*
1854 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
1855 const SMESH::DirStruct & theStepVector,
1856 CORBA::Long theNbOfSteps,
1858 const SMDSAbs_ElementType theElementType)
1866 TIDSortedElemSet elements, copyElements;
1867 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
1869 const SMESH::PointStruct * P = &theStepVector.PS;
1870 gp_Vec stepVec( P->x, P->y, P->z );
1872 TIDSortedElemSet* workElements = & elements;
1873 TPreviewMesh tmpMesh( SMDSAbs_Face );
1874 SMESH_Mesh* mesh = myMesh;
1876 if ( myPreviewMode ) {
1877 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1878 tmpMesh.Copy( elements, copyElements, select, avoid );
1880 workElements = & copyElements;
1881 theMakeGroups = false;
1884 TElemOfElemListMap aHystory;
1885 ::SMESH_MeshEditor anEditor( mesh );
1886 ::SMESH_MeshEditor::PGroupIDs groupIds =
1887 anEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
1889 myMesh->GetMeshDS()->Modified();
1890 storeResult(anEditor);
1892 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1894 } catch(Standard_Failure) {
1895 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1896 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
1901 //=======================================================================
1902 //function : ExtrusionSweep
1904 //=======================================================================
1906 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
1907 const SMESH::DirStruct & theStepVector,
1908 CORBA::Long theNbOfSteps)
1910 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
1911 if (!myPreviewMode) {
1912 TPythonDump() << this << ".ExtrusionSweep( "
1913 << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
1918 //=======================================================================
1919 //function : ExtrusionSweepObject
1921 //=======================================================================
1923 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1924 const SMESH::DirStruct & theStepVector,
1925 CORBA::Long theNbOfSteps)
1927 SMESH::long_array_var anElementsId = theObject->GetIDs();
1928 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
1929 if (!myPreviewMode) {
1930 TPythonDump() << this << ".ExtrusionSweepObject( "
1931 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1935 //=======================================================================
1936 //function : ExtrusionSweepObject1D
1938 //=======================================================================
1940 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1941 const SMESH::DirStruct & theStepVector,
1942 CORBA::Long theNbOfSteps)
1944 SMESH::long_array_var anElementsId = theObject->GetIDs();
1945 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
1946 if ( !myPreviewMode ) {
1947 TPythonDump() << this << ".ExtrusionSweepObject1D( "
1948 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1952 //=======================================================================
1953 //function : ExtrusionSweepObject2D
1955 //=======================================================================
1957 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1958 const SMESH::DirStruct & theStepVector,
1959 CORBA::Long theNbOfSteps)
1961 SMESH::long_array_var anElementsId = theObject->GetIDs();
1962 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
1963 if ( !myPreviewMode ) {
1964 TPythonDump() << this << ".ExtrusionSweepObject2D( "
1965 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1969 //=======================================================================
1970 //function : ExtrusionSweepMakeGroups
1972 //=======================================================================
1974 SMESH::ListOfGroups*
1975 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1976 const SMESH::DirStruct& theStepVector,
1977 CORBA::Long theNbOfSteps)
1979 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1981 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
1983 if (!myPreviewMode) {
1984 DumpGroupsList(aPythonDump, aGroups);
1985 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
1986 << ", " << theStepVector <<", " << theNbOfSteps << " )";
1991 //=======================================================================
1992 //function : ExtrusionSweepObjectMakeGroups
1994 //=======================================================================
1996 SMESH::ListOfGroups*
1997 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1998 const SMESH::DirStruct& theStepVector,
1999 CORBA::Long theNbOfSteps)
2001 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2003 SMESH::long_array_var anElementsId = theObject->GetIDs();
2004 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2006 if (!myPreviewMode) {
2007 DumpGroupsList(aPythonDump, aGroups);
2008 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2009 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2014 //=======================================================================
2015 //function : ExtrusionSweepObject1DMakeGroups
2017 //=======================================================================
2019 SMESH::ListOfGroups*
2020 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2021 const SMESH::DirStruct& theStepVector,
2022 CORBA::Long theNbOfSteps)
2024 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2026 SMESH::long_array_var anElementsId = theObject->GetIDs();
2027 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2028 theNbOfSteps, true, SMDSAbs_Edge);
2029 if (!myPreviewMode) {
2030 DumpGroupsList(aPythonDump, aGroups);
2031 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2032 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2037 //=======================================================================
2038 //function : ExtrusionSweepObject2DMakeGroups
2040 //=======================================================================
2042 SMESH::ListOfGroups*
2043 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2044 const SMESH::DirStruct& theStepVector,
2045 CORBA::Long theNbOfSteps)
2047 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2049 SMESH::long_array_var anElementsId = theObject->GetIDs();
2050 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2051 theNbOfSteps, true, SMDSAbs_Face);
2052 if (!myPreviewMode) {
2053 DumpGroupsList(aPythonDump, aGroups);
2054 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2055 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2061 //=======================================================================
2062 //function : advancedExtrusion
2064 //=======================================================================
2066 SMESH::ListOfGroups*
2067 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2068 const SMESH::DirStruct & theStepVector,
2069 CORBA::Long theNbOfSteps,
2070 CORBA::Long theExtrFlags,
2071 CORBA::Double theSewTolerance,
2072 const bool theMakeGroups)
2076 TIDSortedElemSet elements;
2077 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2079 const SMESH::PointStruct * P = &theStepVector.PS;
2080 gp_Vec stepVec( P->x, P->y, P->z );
2082 ::SMESH_MeshEditor anEditor( myMesh );
2083 TElemOfElemListMap aHystory;
2084 ::SMESH_MeshEditor::PGroupIDs groupIds =
2085 anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2086 theMakeGroups, theExtrFlags, theSewTolerance);
2087 storeResult(anEditor);
2089 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2092 //=======================================================================
2093 //function : AdvancedExtrusion
2095 //=======================================================================
2097 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2098 const SMESH::DirStruct & theStepVector,
2099 CORBA::Long theNbOfSteps,
2100 CORBA::Long theExtrFlags,
2101 CORBA::Double theSewTolerance)
2103 if ( !myPreviewMode ) {
2104 TPythonDump() << "stepVector = " << theStepVector;
2105 TPythonDump() << this << ".AdvancedExtrusion("
2108 << theNbOfSteps << ","
2109 << theExtrFlags << ", "
2110 << theSewTolerance << " )";
2112 advancedExtrusion( theIDsOfElements,
2120 //=======================================================================
2121 //function : AdvancedExtrusionMakeGroups
2123 //=======================================================================
2124 SMESH::ListOfGroups*
2125 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2126 const SMESH::DirStruct& theStepVector,
2127 CORBA::Long theNbOfSteps,
2128 CORBA::Long theExtrFlags,
2129 CORBA::Double theSewTolerance)
2131 if (!myPreviewMode) {
2132 TPythonDump() << "stepVector = " << theStepVector;
2134 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2136 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2143 if (!myPreviewMode) {
2144 DumpGroupsList(aPythonDump, aGroups);
2145 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2148 << theNbOfSteps << ","
2149 << theExtrFlags << ", "
2150 << theSewTolerance << " )";
2156 //================================================================================
2158 * \brief Convert extrusion error to IDL enum
2160 //================================================================================
2162 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2164 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2168 RETCASE( EXTR_NO_ELEMENTS );
2169 RETCASE( EXTR_PATH_NOT_EDGE );
2170 RETCASE( EXTR_BAD_PATH_SHAPE );
2171 RETCASE( EXTR_BAD_STARTING_NODE );
2172 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2173 RETCASE( EXTR_CANT_GET_TANGENT );
2175 return SMESH::SMESH_MeshEditor::EXTR_OK;
2179 //=======================================================================
2180 //function : extrusionAlongPath
2182 //=======================================================================
2183 SMESH::ListOfGroups*
2184 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2185 SMESH::SMESH_Mesh_ptr thePathMesh,
2186 GEOM::GEOM_Object_ptr thePathShape,
2187 CORBA::Long theNodeStart,
2188 CORBA::Boolean theHasAngles,
2189 const SMESH::double_array & theAngles,
2190 CORBA::Boolean theHasRefPoint,
2191 const SMESH::PointStruct & theRefPoint,
2192 const bool theMakeGroups,
2193 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2194 const SMDSAbs_ElementType theElementType)
2196 MESSAGE("extrusionAlongPath");
2199 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2200 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2203 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2205 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2206 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2208 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2209 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2213 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2215 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2219 TIDSortedElemSet elements;
2220 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2222 list<double> angles;
2223 for (int i = 0; i < theAngles.length(); i++) {
2224 angles.push_back( theAngles[i] );
2227 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2229 int nbOldGroups = myMesh->NbGroup();
2231 ::SMESH_MeshEditor anEditor( myMesh );
2232 ::SMESH_MeshEditor::Extrusion_Error error =
2233 anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2234 theHasAngles, angles, false,
2235 theHasRefPoint, refPnt, theMakeGroups );
2236 myMesh->GetMeshDS()->Modified();
2237 storeResult(anEditor);
2238 theError = convExtrError( error );
2240 if ( theMakeGroups ) {
2241 list<int> groupIDs = myMesh->GetGroupIds();
2242 list<int>::iterator newBegin = groupIDs.begin();
2243 std::advance( newBegin, nbOldGroups ); // skip old groups
2244 groupIDs.erase( groupIDs.begin(), newBegin );
2245 return getGroups( & groupIDs );
2251 //=======================================================================
2252 //function : extrusionAlongPathX
2254 //=======================================================================
2255 SMESH::ListOfGroups*
2256 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2257 SMESH::SMESH_IDSource_ptr Path,
2258 CORBA::Long NodeStart,
2259 CORBA::Boolean HasAngles,
2260 const SMESH::double_array& Angles,
2261 CORBA::Boolean LinearVariation,
2262 CORBA::Boolean HasRefPoint,
2263 const SMESH::PointStruct& RefPoint,
2265 const SMDSAbs_ElementType ElementType,
2266 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2268 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2272 list<double> angles;
2273 for (int i = 0; i < Angles.length(); i++) {
2274 angles.push_back( Angles[i] );
2276 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2277 int nbOldGroups = myMesh->NbGroup();
2279 if ( Path->_is_nil() ) {
2280 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2284 TIDSortedElemSet elements, copyElements;
2285 arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
2287 TIDSortedElemSet* workElements = &elements;
2288 TPreviewMesh tmpMesh( SMDSAbs_Face );
2289 SMESH_Mesh* mesh = myMesh;
2291 if ( myPreviewMode )
2293 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2294 tmpMesh.Copy( elements, copyElements, select, avoid );
2296 workElements = & copyElements;
2300 ::SMESH_MeshEditor anEditor( mesh );
2301 ::SMESH_MeshEditor::Extrusion_Error error;
2303 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2306 SMDS_MeshNode* aNodeStart =
2307 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2308 if ( !aNodeStart ) {
2309 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2312 error = anEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2313 HasAngles, angles, LinearVariation,
2314 HasRefPoint, refPnt, MakeGroups );
2315 myMesh->GetMeshDS()->Modified();
2317 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2320 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2321 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2322 SMDS_MeshNode* aNodeStart =
2323 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2324 if ( !aNodeStart ) {
2325 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2328 SMESH_subMesh* aSubMesh =
2329 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2330 error = anEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2331 HasAngles, angles, LinearVariation,
2332 HasRefPoint, refPnt, MakeGroups );
2333 myMesh->GetMeshDS()->Modified();
2335 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2337 // path as group of 1D elements
2343 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2347 storeResult(anEditor);
2348 Error = convExtrError( error );
2351 list<int> groupIDs = myMesh->GetGroupIds();
2352 list<int>::iterator newBegin = groupIDs.begin();
2353 std::advance( newBegin, nbOldGroups ); // skip old groups
2354 groupIDs.erase( groupIDs.begin(), newBegin );
2355 return getGroups( & groupIDs );
2361 //=======================================================================
2362 //function : ExtrusionAlongPath
2364 //=======================================================================
2365 SMESH::SMESH_MeshEditor::Extrusion_Error
2366 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2367 SMESH::SMESH_Mesh_ptr thePathMesh,
2368 GEOM::GEOM_Object_ptr thePathShape,
2369 CORBA::Long theNodeStart,
2370 CORBA::Boolean theHasAngles,
2371 const SMESH::double_array & theAngles,
2372 CORBA::Boolean theHasRefPoint,
2373 const SMESH::PointStruct & theRefPoint)
2375 MESSAGE("ExtrusionAlongPath");
2376 if ( !myPreviewMode ) {
2377 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2378 << theIDsOfElements << ", "
2379 << thePathMesh << ", "
2380 << thePathShape << ", "
2381 << theNodeStart << ", "
2382 << theHasAngles << ", "
2383 << theAngles << ", "
2384 << theHasRefPoint << ", "
2385 << "SMESH.PointStruct( "
2386 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2387 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2388 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2390 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2391 extrusionAlongPath( theIDsOfElements,
2404 //=======================================================================
2405 //function : ExtrusionAlongPathObject
2407 //=======================================================================
2408 SMESH::SMESH_MeshEditor::Extrusion_Error
2409 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2410 SMESH::SMESH_Mesh_ptr thePathMesh,
2411 GEOM::GEOM_Object_ptr thePathShape,
2412 CORBA::Long theNodeStart,
2413 CORBA::Boolean theHasAngles,
2414 const SMESH::double_array & theAngles,
2415 CORBA::Boolean theHasRefPoint,
2416 const SMESH::PointStruct & theRefPoint)
2418 if ( !myPreviewMode ) {
2419 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2420 << theObject << ", "
2421 << thePathMesh << ", "
2422 << thePathShape << ", "
2423 << theNodeStart << ", "
2424 << theHasAngles << ", "
2425 << theAngles << ", "
2426 << theHasRefPoint << ", "
2427 << "SMESH.PointStruct( "
2428 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2429 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2430 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2432 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2433 SMESH::long_array_var anElementsId = theObject->GetIDs();
2434 extrusionAlongPath( anElementsId,
2447 //=======================================================================
2448 //function : ExtrusionAlongPathObject1D
2450 //=======================================================================
2451 SMESH::SMESH_MeshEditor::Extrusion_Error
2452 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2453 SMESH::SMESH_Mesh_ptr thePathMesh,
2454 GEOM::GEOM_Object_ptr thePathShape,
2455 CORBA::Long theNodeStart,
2456 CORBA::Boolean theHasAngles,
2457 const SMESH::double_array & theAngles,
2458 CORBA::Boolean theHasRefPoint,
2459 const SMESH::PointStruct & theRefPoint)
2461 if ( !myPreviewMode ) {
2462 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2463 << theObject << ", "
2464 << thePathMesh << ", "
2465 << thePathShape << ", "
2466 << theNodeStart << ", "
2467 << theHasAngles << ", "
2468 << theAngles << ", "
2469 << theHasRefPoint << ", "
2470 << "SMESH.PointStruct( "
2471 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2472 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2473 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2475 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2476 SMESH::long_array_var anElementsId = theObject->GetIDs();
2477 extrusionAlongPath( anElementsId,
2491 //=======================================================================
2492 //function : ExtrusionAlongPathObject2D
2494 //=======================================================================
2495 SMESH::SMESH_MeshEditor::Extrusion_Error
2496 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
2497 SMESH::SMESH_Mesh_ptr thePathMesh,
2498 GEOM::GEOM_Object_ptr thePathShape,
2499 CORBA::Long theNodeStart,
2500 CORBA::Boolean theHasAngles,
2501 const SMESH::double_array & theAngles,
2502 CORBA::Boolean theHasRefPoint,
2503 const SMESH::PointStruct & theRefPoint)
2505 if ( !myPreviewMode ) {
2506 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
2507 << theObject << ", "
2508 << thePathMesh << ", "
2509 << thePathShape << ", "
2510 << theNodeStart << ", "
2511 << theHasAngles << ", "
2512 << theAngles << ", "
2513 << theHasRefPoint << ", "
2514 << "SMESH.PointStruct( "
2515 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2516 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2517 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2519 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2520 SMESH::long_array_var anElementsId = theObject->GetIDs();
2521 extrusionAlongPath( anElementsId,
2536 //=======================================================================
2537 //function : ExtrusionAlongPathMakeGroups
2539 //=======================================================================
2540 SMESH::ListOfGroups*
2541 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
2542 SMESH::SMESH_Mesh_ptr thePathMesh,
2543 GEOM::GEOM_Object_ptr thePathShape,
2544 CORBA::Long theNodeStart,
2545 CORBA::Boolean theHasAngles,
2546 const SMESH::double_array& theAngles,
2547 CORBA::Boolean theHasRefPoint,
2548 const SMESH::PointStruct& theRefPoint,
2549 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2551 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2553 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
2563 if (!myPreviewMode) {
2564 bool isDumpGroups = aGroups && aGroups->length() > 0;
2566 aPythonDump << "(" << aGroups << ", error)";
2568 aPythonDump <<"error";
2570 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
2571 << theIDsOfElements << ", "
2572 << thePathMesh << ", "
2573 << thePathShape << ", "
2574 << theNodeStart << ", "
2575 << theHasAngles << ", "
2576 << theAngles << ", "
2577 << theHasRefPoint << ", "
2578 << "SMESH.PointStruct( "
2579 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2580 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2581 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2586 //=======================================================================
2587 //function : ExtrusionAlongPathObjectMakeGroups
2589 //=======================================================================
2590 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2591 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2592 SMESH::SMESH_Mesh_ptr thePathMesh,
2593 GEOM::GEOM_Object_ptr thePathShape,
2594 CORBA::Long theNodeStart,
2595 CORBA::Boolean theHasAngles,
2596 const SMESH::double_array& theAngles,
2597 CORBA::Boolean theHasRefPoint,
2598 const SMESH::PointStruct& theRefPoint,
2599 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2601 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2603 SMESH::long_array_var anElementsId = theObject->GetIDs();
2604 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2615 if (!myPreviewMode) {
2616 bool isDumpGroups = aGroups && aGroups->length() > 0;
2618 aPythonDump << "(" << aGroups << ", error)";
2620 aPythonDump <<"error";
2622 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
2623 << theObject << ", "
2624 << thePathMesh << ", "
2625 << thePathShape << ", "
2626 << theNodeStart << ", "
2627 << theHasAngles << ", "
2628 << theAngles << ", "
2629 << theHasRefPoint << ", "
2630 << "SMESH.PointStruct( "
2631 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2632 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2633 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2638 //=======================================================================
2639 //function : ExtrusionAlongPathObject1DMakeGroups
2641 //=======================================================================
2642 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2643 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2644 SMESH::SMESH_Mesh_ptr thePathMesh,
2645 GEOM::GEOM_Object_ptr thePathShape,
2646 CORBA::Long theNodeStart,
2647 CORBA::Boolean theHasAngles,
2648 const SMESH::double_array& theAngles,
2649 CORBA::Boolean theHasRefPoint,
2650 const SMESH::PointStruct& theRefPoint,
2651 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2653 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2655 SMESH::long_array_var anElementsId = theObject->GetIDs();
2656 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2668 if (!myPreviewMode) {
2669 bool isDumpGroups = aGroups && aGroups->length() > 0;
2671 aPythonDump << "(" << aGroups << ", error)";
2673 aPythonDump << "error";
2675 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
2676 << theObject << ", "
2677 << thePathMesh << ", "
2678 << thePathShape << ", "
2679 << theNodeStart << ", "
2680 << theHasAngles << ", "
2681 << theAngles << ", "
2682 << theHasRefPoint << ", "
2683 << "SMESH.PointStruct( "
2684 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2685 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2686 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2691 //=======================================================================
2692 //function : ExtrusionAlongPathObject2DMakeGroups
2694 //=======================================================================
2695 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2696 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2697 SMESH::SMESH_Mesh_ptr thePathMesh,
2698 GEOM::GEOM_Object_ptr thePathShape,
2699 CORBA::Long theNodeStart,
2700 CORBA::Boolean theHasAngles,
2701 const SMESH::double_array& theAngles,
2702 CORBA::Boolean theHasRefPoint,
2703 const SMESH::PointStruct& theRefPoint,
2704 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2706 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2708 SMESH::long_array_var anElementsId = theObject->GetIDs();
2709 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2721 if (!myPreviewMode) {
2722 bool isDumpGroups = aGroups && aGroups->length() > 0;
2724 aPythonDump << "(" << aGroups << ", error)";
2726 aPythonDump << "error";
2728 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
2729 << theObject << ", "
2730 << thePathMesh << ", "
2731 << thePathShape << ", "
2732 << theNodeStart << ", "
2733 << theHasAngles << ", "
2734 << theAngles << ", "
2735 << theHasRefPoint << ", "
2736 << "SMESH.PointStruct( "
2737 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2738 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2739 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2745 //=======================================================================
2746 //function : ExtrusionAlongPathObjX
2748 //=======================================================================
2749 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2750 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
2751 SMESH::SMESH_IDSource_ptr Path,
2752 CORBA::Long NodeStart,
2753 CORBA::Boolean HasAngles,
2754 const SMESH::double_array& Angles,
2755 CORBA::Boolean LinearVariation,
2756 CORBA::Boolean HasRefPoint,
2757 const SMESH::PointStruct& RefPoint,
2758 CORBA::Boolean MakeGroups,
2759 SMESH::ElementType ElemType,
2760 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2762 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2764 SMESH::long_array_var anElementsId = Object->GetIDs();
2765 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
2774 (SMDSAbs_ElementType)ElemType,
2777 if (!myPreviewMode) {
2778 bool isDumpGroups = aGroups && aGroups->length() > 0;
2780 aPythonDump << "(" << *aGroups << ", error)";
2782 aPythonDump << "error";
2784 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
2787 << NodeStart << ", "
2788 << HasAngles << ", "
2790 << LinearVariation << ", "
2791 << HasRefPoint << ", "
2792 << "SMESH.PointStruct( "
2793 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2794 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2795 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2796 << MakeGroups << ", "
2797 << ElemType << " )";
2803 //=======================================================================
2804 //function : ExtrusionAlongPathX
2806 //=======================================================================
2807 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2808 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
2809 SMESH::SMESH_IDSource_ptr Path,
2810 CORBA::Long NodeStart,
2811 CORBA::Boolean HasAngles,
2812 const SMESH::double_array& Angles,
2813 CORBA::Boolean LinearVariation,
2814 CORBA::Boolean HasRefPoint,
2815 const SMESH::PointStruct& RefPoint,
2816 CORBA::Boolean MakeGroups,
2817 SMESH::ElementType ElemType,
2818 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2820 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2822 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
2831 (SMDSAbs_ElementType)ElemType,
2834 if (!myPreviewMode) {
2835 bool isDumpGroups = aGroups && aGroups->length() > 0;
2837 aPythonDump << "(" << *aGroups << ", error)";
2839 aPythonDump <<"error";
2841 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
2842 << IDsOfElements << ", "
2844 << NodeStart << ", "
2845 << HasAngles << ", "
2847 << LinearVariation << ", "
2848 << HasRefPoint << ", "
2849 << "SMESH.PointStruct( "
2850 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2851 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2852 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2853 << MakeGroups << ", "
2854 << ElemType << " )";
2860 //================================================================================
2862 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2863 * of given angles along path steps
2864 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2865 * which proceeds the extrusion
2866 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2867 * is used to define the sub-mesh for the path
2869 //================================================================================
2871 SMESH::double_array*
2872 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2873 GEOM::GEOM_Object_ptr thePathShape,
2874 const SMESH::double_array & theAngles)
2876 SMESH::double_array_var aResult = new SMESH::double_array();
2877 int nbAngles = theAngles.length();
2878 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2880 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2881 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2882 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2883 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2884 return aResult._retn();
2885 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2886 if ( nbSteps == nbAngles )
2888 aResult.inout() = theAngles;
2892 aResult->length( nbSteps );
2893 double rAn2St = double( nbAngles ) / double( nbSteps );
2894 double angPrev = 0, angle;
2895 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2897 double angCur = rAn2St * ( iSt+1 );
2898 double angCurFloor = floor( angCur );
2899 double angPrevFloor = floor( angPrev );
2900 if ( angPrevFloor == angCurFloor )
2901 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2904 int iP = int( angPrevFloor );
2905 double angPrevCeil = ceil(angPrev);
2906 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2908 int iC = int( angCurFloor );
2909 if ( iC < nbAngles )
2910 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2912 iP = int( angPrevCeil );
2914 angle += theAngles[ iC ];
2916 aResult[ iSt ] = angle;
2921 // Update Python script
2922 TPythonDump() << "rotAngles = " << theAngles;
2923 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
2924 << thePathMesh << ", "
2925 << thePathShape << ", "
2928 return aResult._retn();
2932 //=======================================================================
2935 //=======================================================================
2937 SMESH::ListOfGroups*
2938 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
2939 const SMESH::AxisStruct & theAxis,
2940 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2941 CORBA::Boolean theCopy,
2943 ::SMESH_Mesh* theTargetMesh)
2947 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
2948 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
2950 if ( theTargetMesh )
2954 switch ( theMirrorType ) {
2955 case SMESH::SMESH_MeshEditor::POINT:
2956 aTrsf.SetMirror( P );
2958 case SMESH::SMESH_MeshEditor::AXIS:
2959 aTrsf.SetMirror( gp_Ax1( P, V ));
2962 aTrsf.SetMirror( gp_Ax2( P, V ));
2965 TIDSortedElemSet copyElements;
2966 TPreviewMesh tmpMesh;
2967 TIDSortedElemSet* workElements = & theElements;
2968 SMESH_Mesh* mesh = myMesh;
2970 if ( myPreviewMode )
2972 tmpMesh.Copy( theElements, copyElements);
2973 if ( !theCopy && !theTargetMesh )
2975 TIDSortedElemSet elemsAround, elemsAroundCopy;
2976 getElementsAround( theElements, GetMeshDS(), elemsAround );
2977 tmpMesh.Copy( elemsAround, elemsAroundCopy);
2980 workElements = & copyElements;
2981 theMakeGroups = false;
2984 ::SMESH_MeshEditor anEditor( mesh );
2985 ::SMESH_MeshEditor::PGroupIDs groupIds =
2986 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
2988 if(theCopy || myPreviewMode)
2989 storeResult(anEditor);
2992 myMesh->SetIsModified( true );
2993 myMesh->GetMeshDS()->Modified();
2995 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2998 //=======================================================================
3001 //=======================================================================
3003 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3004 const SMESH::AxisStruct & theAxis,
3005 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3006 CORBA::Boolean theCopy)
3008 if ( !myPreviewMode ) {
3009 TPythonDump() << this << ".Mirror( "
3010 << theIDsOfElements << ", "
3012 << mirrorTypeName(theMirrorType) << ", "
3015 if ( theIDsOfElements.length() > 0 )
3017 TIDSortedElemSet elements;
3018 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3019 mirror(elements, theAxis, theMirrorType, theCopy, false);
3024 //=======================================================================
3025 //function : MirrorObject
3027 //=======================================================================
3029 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3030 const SMESH::AxisStruct & theAxis,
3031 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3032 CORBA::Boolean theCopy)
3034 if ( !myPreviewMode ) {
3035 TPythonDump() << this << ".MirrorObject( "
3036 << theObject << ", "
3038 << mirrorTypeName(theMirrorType) << ", "
3041 TIDSortedElemSet elements;
3043 bool emptyIfIsMesh = myPreviewMode ? false : true;
3045 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3046 mirror(elements, theAxis, theMirrorType, theCopy, false);
3049 //=======================================================================
3050 //function : MirrorMakeGroups
3052 //=======================================================================
3054 SMESH::ListOfGroups*
3055 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3056 const SMESH::AxisStruct& theMirror,
3057 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3059 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3061 SMESH::ListOfGroups * aGroups = 0;
3062 if ( theIDsOfElements.length() > 0 )
3064 TIDSortedElemSet elements;
3065 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3066 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3068 if (!myPreviewMode) {
3069 DumpGroupsList(aPythonDump, aGroups);
3070 aPythonDump << this << ".MirrorMakeGroups( "
3071 << theIDsOfElements << ", "
3072 << theMirror << ", "
3073 << mirrorTypeName(theMirrorType) << " )";
3078 //=======================================================================
3079 //function : MirrorObjectMakeGroups
3081 //=======================================================================
3083 SMESH::ListOfGroups*
3084 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3085 const SMESH::AxisStruct& theMirror,
3086 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3088 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3090 SMESH::ListOfGroups * aGroups = 0;
3091 TIDSortedElemSet elements;
3092 if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3093 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3097 DumpGroupsList(aPythonDump,aGroups);
3098 aPythonDump << this << ".MirrorObjectMakeGroups( "
3099 << theObject << ", "
3100 << theMirror << ", "
3101 << mirrorTypeName(theMirrorType) << " )";
3106 //=======================================================================
3107 //function : MirrorMakeMesh
3109 //=======================================================================
3111 SMESH::SMESH_Mesh_ptr
3112 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3113 const SMESH::AxisStruct& theMirror,
3114 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3115 CORBA::Boolean theCopyGroups,
3116 const char* theMeshName)
3118 SMESH_Mesh_i* mesh_i;
3119 SMESH::SMESH_Mesh_var mesh;
3120 { // open new scope to dump "MakeMesh" command
3121 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3123 TPythonDump pydump; // to prevent dump at mesh creation
3125 mesh = makeMesh( theMeshName );
3126 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3127 if (mesh_i && theIDsOfElements.length() > 0 )
3129 TIDSortedElemSet elements;
3130 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3131 mirror(elements, theMirror, theMirrorType,
3132 false, theCopyGroups, & mesh_i->GetImpl());
3133 mesh_i->CreateGroupServants();
3136 if (!myPreviewMode) {
3137 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3138 << theIDsOfElements << ", "
3139 << theMirror << ", "
3140 << mirrorTypeName(theMirrorType) << ", "
3141 << theCopyGroups << ", '"
3142 << theMeshName << "' )";
3147 if (!myPreviewMode && mesh_i)
3148 mesh_i->GetGroups();
3150 return mesh._retn();
3153 //=======================================================================
3154 //function : MirrorObjectMakeMesh
3156 //=======================================================================
3158 SMESH::SMESH_Mesh_ptr
3159 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3160 const SMESH::AxisStruct& theMirror,
3161 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3162 CORBA::Boolean theCopyGroups,
3163 const char* theMeshName)
3165 SMESH_Mesh_i* mesh_i;
3166 SMESH::SMESH_Mesh_var mesh;
3167 { // open new scope to dump "MakeMesh" command
3168 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3170 TPythonDump pydump; // to prevent dump at mesh creation
3172 mesh = makeMesh( theMeshName );
3173 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3174 TIDSortedElemSet elements;
3176 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3178 mirror(elements, theMirror, theMirrorType,
3179 false, theCopyGroups, & mesh_i->GetImpl());
3180 mesh_i->CreateGroupServants();
3182 if (!myPreviewMode) {
3183 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3184 << theObject << ", "
3185 << theMirror << ", "
3186 << mirrorTypeName(theMirrorType) << ", "
3187 << theCopyGroups << ", '"
3188 << theMeshName << "' )";
3193 if (!myPreviewMode && mesh_i)
3194 mesh_i->GetGroups();
3196 return mesh._retn();
3199 //=======================================================================
3200 //function : translate
3202 //=======================================================================
3204 SMESH::ListOfGroups*
3205 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3206 const SMESH::DirStruct & theVector,
3207 CORBA::Boolean theCopy,
3209 ::SMESH_Mesh* theTargetMesh)
3213 if ( theTargetMesh )
3217 const SMESH::PointStruct * P = &theVector.PS;
3218 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3220 TIDSortedElemSet copyElements;
3221 TIDSortedElemSet* workElements = &theElements;
3222 TPreviewMesh tmpMesh;
3223 SMESH_Mesh* mesh = myMesh;
3225 if ( myPreviewMode )
3227 tmpMesh.Copy( theElements, copyElements);
3228 if ( !theCopy && !theTargetMesh )
3230 TIDSortedElemSet elemsAround, elemsAroundCopy;
3231 getElementsAround( theElements, GetMeshDS(), elemsAround );
3232 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3235 workElements = & copyElements;
3236 theMakeGroups = false;
3239 ::SMESH_MeshEditor anEditor( mesh );
3240 ::SMESH_MeshEditor::PGroupIDs groupIds =
3241 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3243 if(theCopy || myPreviewMode)
3244 storeResult(anEditor);
3247 myMesh->GetMeshDS()->Modified();
3248 myMesh->SetIsModified( true );
3251 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3254 //=======================================================================
3255 //function : Translate
3257 //=======================================================================
3259 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3260 const SMESH::DirStruct & theVector,
3261 CORBA::Boolean theCopy)
3263 if (!myPreviewMode) {
3264 TPythonDump() << this << ".Translate( "
3265 << theIDsOfElements << ", "
3266 << theVector << ", "
3269 if (theIDsOfElements.length()) {
3270 TIDSortedElemSet elements;
3271 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3272 translate(elements, theVector, theCopy, false);
3276 //=======================================================================
3277 //function : TranslateObject
3279 //=======================================================================
3281 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3282 const SMESH::DirStruct & theVector,
3283 CORBA::Boolean theCopy)
3285 if (!myPreviewMode) {
3286 TPythonDump() << this << ".TranslateObject( "
3287 << theObject << ", "
3288 << theVector << ", "
3291 TIDSortedElemSet elements;
3293 bool emptyIfIsMesh = myPreviewMode ? false : true;
3295 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3296 translate(elements, theVector, theCopy, false);
3299 //=======================================================================
3300 //function : TranslateMakeGroups
3302 //=======================================================================
3304 SMESH::ListOfGroups*
3305 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3306 const SMESH::DirStruct& theVector)
3308 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3310 SMESH::ListOfGroups * aGroups = 0;
3311 if (theIDsOfElements.length()) {
3312 TIDSortedElemSet elements;
3313 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3314 aGroups = translate(elements,theVector,true,true);
3316 if (!myPreviewMode) {
3317 DumpGroupsList(aPythonDump, aGroups);
3318 aPythonDump << this << ".TranslateMakeGroups( "
3319 << theIDsOfElements << ", "
3320 << theVector << " )";
3325 //=======================================================================
3326 //function : TranslateObjectMakeGroups
3328 //=======================================================================
3330 SMESH::ListOfGroups*
3331 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3332 const SMESH::DirStruct& theVector)
3334 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3336 SMESH::ListOfGroups * aGroups = 0;
3337 TIDSortedElemSet elements;
3338 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3339 aGroups = translate(elements, theVector, true, true);
3341 if (!myPreviewMode) {
3342 DumpGroupsList(aPythonDump, aGroups);
3343 aPythonDump << this << ".TranslateObjectMakeGroups( "
3344 << theObject << ", "
3345 << theVector << " )";
3350 //=======================================================================
3351 //function : TranslateMakeMesh
3353 //=======================================================================
3355 SMESH::SMESH_Mesh_ptr
3356 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3357 const SMESH::DirStruct& theVector,
3358 CORBA::Boolean theCopyGroups,
3359 const char* theMeshName)
3361 SMESH_Mesh_i* mesh_i;
3362 SMESH::SMESH_Mesh_var mesh;
3364 { // open new scope to dump "MakeMesh" command
3365 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3367 TPythonDump pydump; // to prevent dump at mesh creation
3369 mesh = makeMesh( theMeshName );
3370 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3372 if ( mesh_i && theIDsOfElements.length() )
3374 TIDSortedElemSet elements;
3375 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3376 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3377 mesh_i->CreateGroupServants();
3380 if ( !myPreviewMode ) {
3381 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3382 << theIDsOfElements << ", "
3383 << theVector << ", "
3384 << theCopyGroups << ", '"
3385 << theMeshName << "' )";
3390 if (!myPreviewMode && mesh_i)
3391 mesh_i->GetGroups();
3393 return mesh._retn();
3396 //=======================================================================
3397 //function : TranslateObjectMakeMesh
3399 //=======================================================================
3401 SMESH::SMESH_Mesh_ptr
3402 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3403 const SMESH::DirStruct& theVector,
3404 CORBA::Boolean theCopyGroups,
3405 const char* theMeshName)
3407 SMESH_Mesh_i* mesh_i;
3408 SMESH::SMESH_Mesh_var mesh;
3409 { // open new scope to dump "MakeMesh" command
3410 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3412 TPythonDump pydump; // to prevent dump at mesh creation
3413 mesh = makeMesh( theMeshName );
3414 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3416 TIDSortedElemSet elements;
3418 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3420 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3421 mesh_i->CreateGroupServants();
3423 if ( !myPreviewMode ) {
3424 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3425 << theObject << ", "
3426 << theVector << ", "
3427 << theCopyGroups << ", '"
3428 << theMeshName << "' )";
3433 if (!myPreviewMode && mesh_i)
3434 mesh_i->GetGroups();
3436 return mesh._retn();
3439 //=======================================================================
3442 //=======================================================================
3444 SMESH::ListOfGroups*
3445 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3446 const SMESH::AxisStruct & theAxis,
3447 CORBA::Double theAngle,
3448 CORBA::Boolean theCopy,
3450 ::SMESH_Mesh* theTargetMesh)
3454 if ( theTargetMesh )
3457 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3458 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3461 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3463 TIDSortedElemSet copyElements;
3464 TIDSortedElemSet* workElements = &theElements;
3465 TPreviewMesh tmpMesh;
3466 SMESH_Mesh* mesh = myMesh;
3468 if ( myPreviewMode ) {
3469 tmpMesh.Copy( theElements, copyElements );
3470 if ( !theCopy && !theTargetMesh )
3472 TIDSortedElemSet elemsAround, elemsAroundCopy;
3473 getElementsAround( theElements, GetMeshDS(), elemsAround );
3474 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3477 workElements = ©Elements;
3478 theMakeGroups = false;
3481 ::SMESH_MeshEditor anEditor( mesh );
3482 ::SMESH_MeshEditor::PGroupIDs groupIds =
3483 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3485 if(theCopy || myPreviewMode)
3486 storeResult(anEditor);
3489 myMesh->GetMeshDS()->Modified();
3490 myMesh->SetIsModified( true );
3493 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3496 //=======================================================================
3499 //=======================================================================
3501 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3502 const SMESH::AxisStruct & theAxis,
3503 CORBA::Double theAngle,
3504 CORBA::Boolean theCopy)
3506 if (!myPreviewMode) {
3507 TPythonDump() << this << ".Rotate( "
3508 << theIDsOfElements << ", "
3513 if (theIDsOfElements.length() > 0)
3515 TIDSortedElemSet elements;
3516 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3517 rotate(elements,theAxis,theAngle,theCopy,false);
3521 //=======================================================================
3522 //function : RotateObject
3524 //=======================================================================
3526 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3527 const SMESH::AxisStruct & theAxis,
3528 CORBA::Double theAngle,
3529 CORBA::Boolean theCopy)
3531 if ( !myPreviewMode ) {
3532 TPythonDump() << this << ".RotateObject( "
3533 << theObject << ", "
3538 TIDSortedElemSet elements;
3539 bool emptyIfIsMesh = myPreviewMode ? false : true;
3540 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3541 rotate(elements,theAxis,theAngle,theCopy,false);
3544 //=======================================================================
3545 //function : RotateMakeGroups
3547 //=======================================================================
3549 SMESH::ListOfGroups*
3550 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3551 const SMESH::AxisStruct& theAxis,
3552 CORBA::Double theAngle)
3554 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3556 SMESH::ListOfGroups * aGroups = 0;
3557 if (theIDsOfElements.length() > 0)
3559 TIDSortedElemSet elements;
3560 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3561 aGroups = rotate(elements,theAxis,theAngle,true,true);
3563 if (!myPreviewMode) {
3564 DumpGroupsList(aPythonDump, aGroups);
3565 aPythonDump << this << ".RotateMakeGroups( "
3566 << theIDsOfElements << ", "
3568 << theAngle << " )";
3573 //=======================================================================
3574 //function : RotateObjectMakeGroups
3576 //=======================================================================
3578 SMESH::ListOfGroups*
3579 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3580 const SMESH::AxisStruct& theAxis,
3581 CORBA::Double theAngle)
3583 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3585 SMESH::ListOfGroups * aGroups = 0;
3586 TIDSortedElemSet elements;
3587 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3588 aGroups = rotate(elements, theAxis, theAngle, true, true);
3590 if (!myPreviewMode) {
3591 DumpGroupsList(aPythonDump, aGroups);
3592 aPythonDump << this << ".RotateObjectMakeGroups( "
3593 << theObject << ", "
3595 << theAngle << " )";
3600 //=======================================================================
3601 //function : RotateMakeMesh
3603 //=======================================================================
3605 SMESH::SMESH_Mesh_ptr
3606 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3607 const SMESH::AxisStruct& theAxis,
3608 CORBA::Double theAngleInRadians,
3609 CORBA::Boolean theCopyGroups,
3610 const char* theMeshName)
3612 SMESH::SMESH_Mesh_var mesh;
3613 SMESH_Mesh_i* mesh_i;
3615 { // open new scope to dump "MakeMesh" command
3616 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3618 TPythonDump pydump; // to prevent dump at mesh creation
3620 mesh = makeMesh( theMeshName );
3621 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3623 if ( mesh_i && theIDsOfElements.length() > 0 )
3625 TIDSortedElemSet elements;
3626 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3627 rotate(elements, theAxis, theAngleInRadians,
3628 false, theCopyGroups, & mesh_i->GetImpl());
3629 mesh_i->CreateGroupServants();
3631 if ( !myPreviewMode ) {
3632 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3633 << theIDsOfElements << ", "
3635 << theAngleInRadians << ", "
3636 << theCopyGroups << ", '"
3637 << theMeshName << "' )";
3642 if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3643 mesh_i->GetGroups();
3645 return mesh._retn();
3648 //=======================================================================
3649 //function : RotateObjectMakeMesh
3651 //=======================================================================
3653 SMESH::SMESH_Mesh_ptr
3654 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3655 const SMESH::AxisStruct& theAxis,
3656 CORBA::Double theAngleInRadians,
3657 CORBA::Boolean theCopyGroups,
3658 const char* theMeshName)
3660 SMESH::SMESH_Mesh_var mesh;
3661 SMESH_Mesh_i* mesh_i;
3663 {// open new scope to dump "MakeMesh" command
3664 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3666 TPythonDump pydump; // to prevent dump at mesh creation
3667 mesh = makeMesh( theMeshName );
3668 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3670 TIDSortedElemSet elements;
3672 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3674 rotate(elements, theAxis, theAngleInRadians,
3675 false, theCopyGroups, & mesh_i->GetImpl());
3676 mesh_i->CreateGroupServants();
3678 if ( !myPreviewMode ) {
3679 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3680 << theObject << ", "
3682 << theAngleInRadians << ", "
3683 << theCopyGroups << ", '"
3684 << theMeshName << "' )";
3689 if (!myPreviewMode && mesh_i)
3690 mesh_i->GetGroups();
3692 return mesh._retn();
3695 //=======================================================================
3698 //=======================================================================
3700 SMESH::ListOfGroups*
3701 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3702 const SMESH::PointStruct& thePoint,
3703 const SMESH::double_array& theScaleFact,
3704 CORBA::Boolean theCopy,
3706 ::SMESH_Mesh* theTargetMesh)
3709 if ( theScaleFact.length() < 1 )
3710 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3711 if ( theScaleFact.length() == 2 )
3712 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3714 if ( theTargetMesh )
3717 TIDSortedElemSet elements;
3718 bool emptyIfIsMesh = myPreviewMode ? false : true;
3719 if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3724 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3725 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3727 double tol = std::numeric_limits<double>::max();
3729 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3730 0, S[1], 0, thePoint.y * (1-S[1]),
3731 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3733 TIDSortedElemSet copyElements;
3734 TPreviewMesh tmpMesh;
3735 TIDSortedElemSet* workElements = &elements;
3736 SMESH_Mesh* mesh = myMesh;
3738 if ( myPreviewMode )
3740 tmpMesh.Copy( elements, copyElements);
3741 if ( !theCopy && !theTargetMesh )
3743 TIDSortedElemSet elemsAround, elemsAroundCopy;
3744 getElementsAround( elements, GetMeshDS(), elemsAround );
3745 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3748 workElements = & copyElements;
3749 theMakeGroups = false;
3752 ::SMESH_MeshEditor anEditor( mesh );
3753 ::SMESH_MeshEditor::PGroupIDs groupIds =
3754 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3756 if(theCopy || myPreviewMode )
3757 storeResult(anEditor);
3760 myMesh->GetMeshDS()->Modified();
3761 myMesh->SetIsModified( true );
3763 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3766 //=======================================================================
3769 //=======================================================================
3771 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3772 const SMESH::PointStruct& thePoint,
3773 const SMESH::double_array& theScaleFact,
3774 CORBA::Boolean theCopy)
3776 if ( !myPreviewMode ) {
3777 TPythonDump() << this << ".Scale( "
3778 << theObject << ", "
3779 << "SMESH.PointStruct( " << thePoint.x << ", "
3780 << thePoint.y << ", " << thePoint.z << " ) ,"
3781 << theScaleFact << ", "
3784 scale(theObject, thePoint, theScaleFact, theCopy, false);
3788 //=======================================================================
3789 //function : ScaleMakeGroups
3791 //=======================================================================
3793 SMESH::ListOfGroups*
3794 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3795 const SMESH::PointStruct& thePoint,
3796 const SMESH::double_array& theScaleFact)
3798 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3800 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3801 if (!myPreviewMode) {
3802 DumpGroupsList(aPythonDump, aGroups);
3803 aPythonDump << this << ".Scale("
3805 << "SMESH.PointStruct(" <<thePoint.x << ","
3806 << thePoint.y << "," << thePoint.z << "),"
3807 << theScaleFact << ",True,True)";
3813 //=======================================================================
3814 //function : ScaleMakeMesh
3816 //=======================================================================
3818 SMESH::SMESH_Mesh_ptr
3819 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3820 const SMESH::PointStruct& thePoint,
3821 const SMESH::double_array& theScaleFact,
3822 CORBA::Boolean theCopyGroups,
3823 const char* theMeshName)
3825 SMESH_Mesh_i* mesh_i;
3826 SMESH::SMESH_Mesh_var mesh;
3827 { // open new scope to dump "MakeMesh" command
3828 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3830 TPythonDump pydump; // to prevent dump at mesh creation
3831 mesh = makeMesh( theMeshName );
3832 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3836 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
3837 mesh_i->CreateGroupServants();
3839 if ( !myPreviewMode )
3840 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
3841 << theObject << ", "
3842 << "SMESH.PointStruct( " << thePoint.x << ", "
3843 << thePoint.y << ", " << thePoint.z << " ) ,"
3844 << theScaleFact << ", "
3845 << theCopyGroups << ", '"
3846 << theMeshName << "' )";
3850 if (!myPreviewMode && mesh_i)
3851 mesh_i->GetGroups();
3853 return mesh._retn();
3857 //=======================================================================
3858 //function : FindCoincidentNodes
3860 //=======================================================================
3862 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
3863 SMESH::array_of_long_array_out GroupsOfNodes)
3867 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3868 ::SMESH_MeshEditor anEditor( myMesh );
3869 TIDSortedNodeSet nodes; // no input nodes
3870 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3872 GroupsOfNodes = new SMESH::array_of_long_array;
3873 GroupsOfNodes->length( aListOfListOfNodes.size() );
3874 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3875 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
3876 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3877 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3878 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3879 aGroup.length( aListOfNodes.size() );
3880 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3881 aGroup[ j ] = (*lIt)->GetID();
3883 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
3884 << Tolerance << " )";
3887 //=======================================================================
3888 //function : FindCoincidentNodesOnPart
3890 //=======================================================================
3891 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
3892 CORBA::Double Tolerance,
3893 SMESH::array_of_long_array_out GroupsOfNodes)
3897 TIDSortedNodeSet nodes;
3898 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3900 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3901 ::SMESH_MeshEditor anEditor( myMesh );
3903 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3905 GroupsOfNodes = new SMESH::array_of_long_array;
3906 GroupsOfNodes->length( aListOfListOfNodes.size() );
3907 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3908 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3910 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3911 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3912 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3913 aGroup.length( aListOfNodes.size() );
3914 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3915 aGroup[ j ] = (*lIt)->GetID();
3917 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
3919 << Tolerance << " )";
3922 //================================================================================
3924 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
3925 * ExceptSubMeshOrGroups
3927 //================================================================================
3929 void SMESH_MeshEditor_i::
3930 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
3931 CORBA::Double theTolerance,
3932 SMESH::array_of_long_array_out theGroupsOfNodes,
3933 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
3937 TIDSortedNodeSet nodes;
3938 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3940 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
3942 TIDSortedNodeSet exceptNodes;
3943 idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
3944 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
3945 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
3946 nodes.erase( *avoidNode );
3948 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3949 ::SMESH_MeshEditor anEditor( myMesh );
3951 anEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
3953 theGroupsOfNodes = new SMESH::array_of_long_array;
3954 theGroupsOfNodes->length( aListOfListOfNodes.size() );
3955 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3956 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3958 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3959 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3960 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
3961 aGroup.length( aListOfNodes.size() );
3962 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3963 aGroup[ j ] = (*lIt)->GetID();
3965 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
3967 << theTolerance << ", "
3968 << theExceptSubMeshOrGroups << " )";
3971 //=======================================================================
3972 //function : MergeNodes
3974 //=======================================================================
3976 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
3980 SMESHDS_Mesh* aMesh = GetMeshDS();
3982 TPythonDump aTPythonDump;
3983 aTPythonDump << this << ".MergeNodes([";
3984 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3985 for (int i = 0; i < GroupsOfNodes.length(); i++)
3987 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
3988 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
3989 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
3990 for ( int j = 0; j < aNodeGroup.length(); j++ )
3992 CORBA::Long index = aNodeGroup[ j ];
3993 const SMDS_MeshNode * node = aMesh->FindNode(index);
3995 aListOfNodes.push_back( node );
3997 if ( aListOfNodes.size() < 2 )
3998 aListOfListOfNodes.pop_back();
4000 if ( i > 0 ) aTPythonDump << ", ";
4001 aTPythonDump << aNodeGroup;
4003 ::SMESH_MeshEditor anEditor( myMesh );
4004 anEditor.MergeNodes( aListOfListOfNodes );
4006 aTPythonDump << "])";
4007 myMesh->GetMeshDS()->Modified();
4008 myMesh->SetIsModified( true );
4011 //=======================================================================
4012 //function : FindEqualElements
4014 //=======================================================================
4015 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4016 SMESH::array_of_long_array_out GroupsOfElementsID)
4020 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4021 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4023 typedef list<int> TListOfIDs;
4024 set<const SMDS_MeshElement*> elems;
4025 SMESH::long_array_var aElementsId = theObject->GetIDs();
4026 SMESHDS_Mesh* aMesh = GetMeshDS();
4028 for(int i = 0; i < aElementsId->length(); i++) {
4029 CORBA::Long anID = aElementsId[i];
4030 const SMDS_MeshElement * elem = aMesh->FindElement(anID);
4036 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4037 ::SMESH_MeshEditor anEditor( myMesh );
4038 anEditor.FindEqualElements( elems, aListOfListOfElementsID );
4040 GroupsOfElementsID = new SMESH::array_of_long_array;
4041 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4043 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
4044 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
4045 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4046 TListOfIDs& listOfIDs = *arraysIt;
4047 aGroup.length( listOfIDs.size() );
4048 TListOfIDs::iterator idIt = listOfIDs.begin();
4049 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
4050 aGroup[ k ] = *idIt;
4054 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4059 //=======================================================================
4060 //function : MergeElements
4062 //=======================================================================
4064 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4068 TPythonDump aTPythonDump;
4069 aTPythonDump << this << ".MergeElements( [";
4071 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4073 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4074 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4075 aListOfListOfElementsID.push_back( list< int >() );
4076 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4077 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4078 CORBA::Long id = anElemsIDGroup[ j ];
4079 aListOfElemsID.push_back( id );
4081 if ( aListOfElemsID.size() < 2 )
4082 aListOfListOfElementsID.pop_back();
4083 if ( i > 0 ) aTPythonDump << ", ";
4084 aTPythonDump << anElemsIDGroup;
4087 ::SMESH_MeshEditor anEditor( myMesh );
4088 anEditor.MergeElements(aListOfListOfElementsID);
4089 myMesh->GetMeshDS()->Modified();
4090 myMesh->SetIsModified( true );
4092 aTPythonDump << "] )";
4095 //=======================================================================
4096 //function : MergeEqualElements
4098 //=======================================================================
4100 void SMESH_MeshEditor_i::MergeEqualElements()
4104 ::SMESH_MeshEditor anEditor( myMesh );
4105 anEditor.MergeEqualElements();
4107 TPythonDump() << this << ".MergeEqualElements()";
4110 //=============================================================================
4112 * Move the node to a given point
4114 //=============================================================================
4116 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4121 initData(/*deleteSearchers=*/false);
4123 const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
4127 if ( theNodeSearcher )
4128 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4130 if ( myPreviewMode ) // make preview data
4132 // in a preview mesh, make edges linked to a node
4133 TPreviewMesh tmpMesh;
4134 TIDSortedElemSet linkedNodes;
4135 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4136 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4137 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4138 for ( ; nIt != linkedNodes.end(); ++nIt )
4140 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4141 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4145 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4146 // fill preview data
4147 ::SMESH_MeshEditor anEditor( & tmpMesh );
4148 storeResult( anEditor );
4150 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4151 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4153 GetMeshDS()->MoveNode(node, x, y, z);
4155 if ( !myPreviewMode )
4157 // Update Python script
4158 TPythonDump() << "isDone = " << this << ".MoveNode( "
4159 << NodeID << ", " << x << ", " << y << ", " << z << " )";
4160 myMesh->GetMeshDS()->Modified();
4161 myMesh->SetIsModified( true );
4167 //================================================================================
4169 * \brief Return ID of node closest to a given point
4171 //================================================================================
4173 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4177 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4179 if ( !theNodeSearcher ) {
4180 ::SMESH_MeshEditor anEditor( myMesh );
4181 theNodeSearcher = anEditor.GetNodeSearcher();
4184 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4185 return node->GetID();
4190 //================================================================================
4192 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4193 * move the node closest to the point to point's location and return ID of the node
4195 //================================================================================
4197 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4200 CORBA::Long theNodeID)
4202 // We keep theNodeSearcher until any mesh modification:
4203 // 1) initData() deletes theNodeSearcher at any edition,
4204 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4206 initData(/*deleteSearchers=*/false);
4208 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4210 int nodeID = theNodeID;
4211 const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
4212 if ( !node ) // preview moving node
4214 if ( !theNodeSearcher ) {
4215 ::SMESH_MeshEditor anEditor( myMesh );
4216 theNodeSearcher = anEditor.GetNodeSearcher();
4219 node = theNodeSearcher->FindClosestTo( p );
4222 nodeID = node->GetID();
4223 if ( myPreviewMode ) // make preview data
4225 // in a preview mesh, make edges linked to a node
4226 TPreviewMesh tmpMesh;
4227 TIDSortedElemSet linkedNodes;
4228 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4229 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4230 for ( ; nIt != linkedNodes.end(); ++nIt )
4232 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4233 tmpMesh.Copy( &edge );
4236 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4238 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4239 // fill preview data
4240 ::SMESH_MeshEditor anEditor( & tmpMesh );
4241 storeResult( anEditor );
4243 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4245 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4249 GetMeshDS()->MoveNode(node, x, y, z);
4253 if ( !myPreviewMode )
4255 TPythonDump() << "nodeID = " << this
4256 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4257 << ", " << nodeID << " )";
4259 myMesh->GetMeshDS()->Modified();
4260 myMesh->SetIsModified( true );
4266 //=======================================================================
4268 * Return elements of given type where the given point is IN or ON.
4270 * 'ALL' type means elements of any type excluding nodes
4272 //=======================================================================
4274 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4277 SMESH::ElementType type)
4279 SMESH::long_array_var res = new SMESH::long_array;
4280 vector< const SMDS_MeshElement* > foundElems;
4282 theSearchersDeleter.Set( myMesh );
4283 if ( !theElementSearcher ) {
4284 ::SMESH_MeshEditor anEditor( myMesh );
4285 theElementSearcher = anEditor.GetElementSearcher();
4287 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4288 SMDSAbs_ElementType( type ),
4290 res->length( foundElems.size() );
4291 for ( int i = 0; i < foundElems.size(); ++i )
4292 res[i] = foundElems[i]->GetID();
4294 if ( !myPreviewMode ) // call from tui
4295 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4304 //=======================================================================
4305 //function : FindAmongElementsByPoint
4306 //purpose : Searching among the given elements, return elements of given type
4307 // where the given point is IN or ON.
4308 // 'ALL' type means elements of any type excluding nodes
4309 //=======================================================================
4312 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4316 SMESH::ElementType type)
4318 SMESH::long_array_var res = new SMESH::long_array;
4320 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4321 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4322 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D ) &&
4323 type != types[0] ) // but search of elements of dim > 0
4326 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4327 return FindElementsByPoint( x,y,z, type );
4329 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( elementIDs );
4330 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( elementIDs ))
4331 // take into account passible group modification
4332 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
4333 partIOR += SMESH_Comment( type );
4335 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4337 theSearchersDeleter.Set( myMesh, partIOR );
4338 if ( !theElementSearcher )
4340 // create a searcher from elementIDs
4341 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4342 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4344 if ( !idSourceToSet( elementIDs, meshDS, elements,
4345 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4348 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4349 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4351 ::SMESH_MeshEditor anEditor( myMesh );
4352 theElementSearcher = anEditor.GetElementSearcher(elemsIt);
4355 vector< const SMDS_MeshElement* > foundElems;
4357 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4358 SMDSAbs_ElementType( type ),
4360 res->length( foundElems.size() );
4361 for ( int i = 0; i < foundElems.size(); ++i )
4362 res[i] = foundElems[i]->GetID();
4364 if ( !myPreviewMode ) // call from tui
4365 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4366 << elementIDs << ", "
4375 //=======================================================================
4376 //function : GetPointState
4377 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4378 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4379 //=======================================================================
4381 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4385 theSearchersDeleter.Set( myMesh );
4386 if ( !theElementSearcher ) {
4387 ::SMESH_MeshEditor anEditor( myMesh );
4388 theElementSearcher = anEditor.GetElementSearcher();
4390 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4393 //=======================================================================
4394 //function : convError
4396 //=======================================================================
4398 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4400 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4404 RETCASE( SEW_BORDER1_NOT_FOUND );
4405 RETCASE( SEW_BORDER2_NOT_FOUND );
4406 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4407 RETCASE( SEW_BAD_SIDE_NODES );
4408 RETCASE( SEW_VOLUMES_TO_SPLIT );
4409 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4410 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4411 RETCASE( SEW_BAD_SIDE1_NODES );
4412 RETCASE( SEW_BAD_SIDE2_NODES );
4414 return SMESH::SMESH_MeshEditor::SEW_OK;
4417 //=======================================================================
4418 //function : SewFreeBorders
4420 //=======================================================================
4422 SMESH::SMESH_MeshEditor::Sew_Error
4423 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4424 CORBA::Long SecondNodeID1,
4425 CORBA::Long LastNodeID1,
4426 CORBA::Long FirstNodeID2,
4427 CORBA::Long SecondNodeID2,
4428 CORBA::Long LastNodeID2,
4429 CORBA::Boolean CreatePolygons,
4430 CORBA::Boolean CreatePolyedrs)
4434 SMESHDS_Mesh* aMesh = GetMeshDS();
4436 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4437 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4438 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4439 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4440 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4441 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4443 if (!aBorderFirstNode ||
4444 !aBorderSecondNode||
4446 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4447 if (!aSide2FirstNode ||
4448 !aSide2SecondNode ||
4450 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4452 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4453 << FirstNodeID1 << ", "
4454 << SecondNodeID1 << ", "
4455 << LastNodeID1 << ", "
4456 << FirstNodeID2 << ", "
4457 << SecondNodeID2 << ", "
4458 << LastNodeID2 << ", "
4459 << CreatePolygons<< ", "
4460 << CreatePolyedrs<< " )";
4462 ::SMESH_MeshEditor anEditor( myMesh );
4463 SMESH::SMESH_MeshEditor::Sew_Error error =
4464 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4474 storeResult(anEditor);
4476 myMesh->GetMeshDS()->Modified();
4477 myMesh->SetIsModified( true );
4483 //=======================================================================
4484 //function : SewConformFreeBorders
4486 //=======================================================================
4488 SMESH::SMESH_MeshEditor::Sew_Error
4489 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4490 CORBA::Long SecondNodeID1,
4491 CORBA::Long LastNodeID1,
4492 CORBA::Long FirstNodeID2,
4493 CORBA::Long SecondNodeID2)
4497 SMESHDS_Mesh* aMesh = GetMeshDS();
4499 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4500 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4501 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4502 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4503 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4504 const SMDS_MeshNode* aSide2ThirdNode = 0;
4506 if (!aBorderFirstNode ||
4507 !aBorderSecondNode||
4509 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4510 if (!aSide2FirstNode ||
4512 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4514 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4515 << FirstNodeID1 << ", "
4516 << SecondNodeID1 << ", "
4517 << LastNodeID1 << ", "
4518 << FirstNodeID2 << ", "
4519 << SecondNodeID2 << " )";
4521 ::SMESH_MeshEditor anEditor( myMesh );
4522 SMESH::SMESH_MeshEditor::Sew_Error error =
4523 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4532 storeResult(anEditor);
4534 myMesh->GetMeshDS()->Modified();
4535 myMesh->SetIsModified( true );
4541 //=======================================================================
4542 //function : SewBorderToSide
4544 //=======================================================================
4546 SMESH::SMESH_MeshEditor::Sew_Error
4547 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4548 CORBA::Long SecondNodeIDOnFreeBorder,
4549 CORBA::Long LastNodeIDOnFreeBorder,
4550 CORBA::Long FirstNodeIDOnSide,
4551 CORBA::Long LastNodeIDOnSide,
4552 CORBA::Boolean CreatePolygons,
4553 CORBA::Boolean CreatePolyedrs)
4557 SMESHDS_Mesh* aMesh = GetMeshDS();
4559 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4560 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4561 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4562 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4563 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4564 const SMDS_MeshNode* aSide2ThirdNode = 0;
4566 if (!aBorderFirstNode ||
4567 !aBorderSecondNode||
4569 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4570 if (!aSide2FirstNode ||
4572 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4574 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4575 << FirstNodeIDOnFreeBorder << ", "
4576 << SecondNodeIDOnFreeBorder << ", "
4577 << LastNodeIDOnFreeBorder << ", "
4578 << FirstNodeIDOnSide << ", "
4579 << LastNodeIDOnSide << ", "
4580 << CreatePolygons << ", "
4581 << CreatePolyedrs << ") ";
4583 ::SMESH_MeshEditor anEditor( myMesh );
4584 SMESH::SMESH_MeshEditor::Sew_Error error =
4585 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4595 storeResult(anEditor);
4597 myMesh->GetMeshDS()->Modified();
4598 myMesh->SetIsModified( true );
4604 //=======================================================================
4605 //function : SewSideElements
4607 //=======================================================================
4609 SMESH::SMESH_MeshEditor::Sew_Error
4610 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
4611 const SMESH::long_array& IDsOfSide2Elements,
4612 CORBA::Long NodeID1OfSide1ToMerge,
4613 CORBA::Long NodeID1OfSide2ToMerge,
4614 CORBA::Long NodeID2OfSide1ToMerge,
4615 CORBA::Long NodeID2OfSide2ToMerge)
4619 SMESHDS_Mesh* aMesh = GetMeshDS();
4621 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
4622 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
4623 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
4624 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
4626 if (!aFirstNode1ToMerge ||
4627 !aFirstNode2ToMerge )
4628 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
4629 if (!aSecondNode1ToMerge||
4630 !aSecondNode2ToMerge)
4631 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
4633 TIDSortedElemSet aSide1Elems, aSide2Elems;
4634 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
4635 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
4637 TPythonDump() << "error = " << this << ".SewSideElements( "
4638 << IDsOfSide1Elements << ", "
4639 << IDsOfSide2Elements << ", "
4640 << NodeID1OfSide1ToMerge << ", "
4641 << NodeID1OfSide2ToMerge << ", "
4642 << NodeID2OfSide1ToMerge << ", "
4643 << NodeID2OfSide2ToMerge << ")";
4645 ::SMESH_MeshEditor anEditor( myMesh );
4646 SMESH::SMESH_MeshEditor::Sew_Error error =
4647 convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
4650 aSecondNode1ToMerge,
4651 aSecondNode2ToMerge));
4653 storeResult(anEditor);
4655 myMesh->GetMeshDS()->Modified();
4656 myMesh->SetIsModified( true );
4661 //================================================================================
4663 * \brief Set new nodes for given element
4664 * \param ide - element id
4665 * \param newIDs - new node ids
4666 * \retval CORBA::Boolean - true if result is OK
4668 //================================================================================
4670 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
4671 const SMESH::long_array& newIDs)
4675 const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
4676 if(!elem) return false;
4678 int nbn = newIDs.length();
4680 vector<const SMDS_MeshNode*> aNodes(nbn);
4683 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
4686 aNodes[nbn1] = aNode;
4689 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
4690 << ide << ", " << newIDs << " )";
4692 MESSAGE("ChangeElementNodes");
4693 bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
4695 myMesh->GetMeshDS()->Modified();
4697 myMesh->SetIsModified( true );
4702 //================================================================================
4704 * \brief Update myLastCreated* or myPreviewData
4705 * \param anEditor - it contains last modification results
4707 //================================================================================
4709 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
4711 if ( myPreviewMode ) { // --- MeshPreviewStruct filling ---
4713 list<int> aNodesConnectivity;
4714 typedef map<int, int> TNodesMap;
4717 TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
4718 SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
4720 SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
4721 int nbEdges = aMeshDS->NbEdges();
4722 int nbFaces = aMeshDS->NbFaces();
4723 int nbVolum = aMeshDS->NbVolumes();
4724 switch ( previewType ) {
4725 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
4726 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
4727 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
4730 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
4731 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
4733 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
4735 while ( itMeshElems->more() ) {
4736 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
4737 if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
4740 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
4741 while ( itElemNodes->more() ) {
4742 const SMDS_MeshNode* aMeshNode =
4743 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
4744 int aNodeID = aMeshNode->GetID();
4745 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
4746 if ( anIter == nodesMap.end() ) {
4747 // filling the nodes coordinates
4748 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
4749 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
4750 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
4751 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
4754 aNodesConnectivity.push_back(anIter->second);
4757 // filling the elements types
4758 SMDSAbs_ElementType aType;
4760 /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
4761 aType = SMDSAbs_Node;
4765 aType = aMeshElem->GetType();
4766 isPoly = aMeshElem->IsPoly();
4769 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
4770 myPreviewData->elementTypes[i].isPoly = isPoly;
4771 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
4775 myPreviewData->nodesXYZ.length( j );
4777 // filling the elements connectivities
4778 list<int>::iterator aConnIter = aNodesConnectivity.begin();
4779 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
4780 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
4781 myPreviewData->elementConnectivities[i] = *aConnIter;
4787 // append new nodes into myLastCreatedNodes
4788 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
4789 int j = myLastCreatedNodes->length();
4790 int newLen = j + aSeq.Length();
4791 myLastCreatedNodes->length( newLen );
4792 for(int i=0; j<newLen; i++,j++)
4793 myLastCreatedNodes[j] = aSeq.Value(i+1)->GetID();
4796 // append new elements into myLastCreatedElems
4797 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
4798 int j = myLastCreatedElems->length();
4799 int newLen = j + aSeq.Length();
4800 myLastCreatedElems->length( newLen );
4801 for(int i=0; j<newLen; i++,j++)
4802 myLastCreatedElems[j] = aSeq.Value(i+1)->GetID();
4806 //================================================================================
4808 * Return data of mesh edition preview
4810 //================================================================================
4812 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
4814 return myPreviewData._retn();
4817 //================================================================================
4819 * \brief Returns list of it's IDs of created nodes
4820 * \retval SMESH::long_array* - list of node ID
4822 //================================================================================
4824 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
4826 return myLastCreatedNodes._retn();
4829 //================================================================================
4831 * \brief Returns list of it's IDs of created elements
4832 * \retval SMESH::long_array* - list of elements' ID
4834 //================================================================================
4836 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
4838 return myLastCreatedElems._retn();
4841 //=======================================================================
4842 //function : ConvertToQuadratic
4844 //=======================================================================
4846 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
4848 ::SMESH_MeshEditor anEditor( myMesh );
4849 anEditor.ConvertToQuadratic(theForce3d);
4850 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
4851 myMesh->GetMeshDS()->Modified();
4852 myMesh->SetIsModified( true );
4855 //=======================================================================
4856 //function : ConvertFromQuadratic
4858 //=======================================================================
4860 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
4862 ::SMESH_MeshEditor anEditor( myMesh );
4863 CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
4864 TPythonDump() << this << ".ConvertFromQuadratic()";
4865 myMesh->GetMeshDS()->Modified();
4867 myMesh->SetIsModified( true );
4870 //================================================================================
4872 * \brief Makes a part of the mesh quadratic
4874 //================================================================================
4876 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
4877 SMESH::SMESH_IDSource_ptr theObject)
4878 throw (SALOME::SALOME_Exception)
4880 Unexpect aCatch(SALOME_SalomeException);
4882 TIDSortedElemSet elems;
4883 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4885 if ( elems.empty() )
4887 ConvertToQuadratic( theForce3d );
4889 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4891 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4895 ::SMESH_MeshEditor anEditor( myMesh );
4896 anEditor.ConvertToQuadratic(theForce3d, elems);
4899 myMesh->GetMeshDS()->Modified();
4900 myMesh->SetIsModified( true );
4902 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
4905 //================================================================================
4907 * \brief Makes a part of the mesh linear
4909 //================================================================================
4911 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
4912 throw (SALOME::SALOME_Exception)
4914 Unexpect aCatch(SALOME_SalomeException);
4916 TIDSortedElemSet elems;
4917 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4919 if ( elems.empty() )
4921 ConvertFromQuadratic();
4923 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4925 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4929 ::SMESH_MeshEditor anEditor( myMesh );
4930 anEditor.ConvertFromQuadratic(elems);
4933 myMesh->GetMeshDS()->Modified();
4934 myMesh->SetIsModified( true );
4936 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
4939 //=======================================================================
4940 //function : makeMesh
4941 //purpose : create a named imported mesh
4942 //=======================================================================
4944 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
4946 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
4947 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
4948 SALOMEDS::Study_var study = gen->GetCurrentStudy();
4949 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
4950 gen->SetName( meshSO, theMeshName, "Mesh" );
4951 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
4953 return mesh._retn();
4956 //=======================================================================
4957 //function : DumpGroupsList
4959 //=======================================================================
4960 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
4961 const SMESH::ListOfGroups * theGroupList)
4963 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
4964 if(isDumpGroupList) {
4965 theDumpPython << theGroupList << " = ";
4969 //================================================================================
4971 \brief Generates the unique group name.
4972 \param thePrefix name prefix
4975 //================================================================================
4976 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
4978 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
4979 set<string> groupNames;
4981 // Get existing group names
4982 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
4983 SMESH::SMESH_GroupBase_var aGroup = groups[i];
4984 if (CORBA::is_nil(aGroup))
4987 groupNames.insert(aGroup->GetName());
4991 string name = thePrefix;
4994 while (!groupNames.insert(name).second) {
4999 TCollection_AsciiString nbStr(index+1);
5000 name.resize( name.rfind('_')+1 );
5001 name += nbStr.ToCString();
5009 //================================================================================
5011 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5012 \param theNodes - identifiers of nodes to be doubled
5013 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5014 nodes. If list of element identifiers is empty then nodes are doubled but
5015 they not assigned to elements
5016 \return TRUE if operation has been completed successfully, FALSE otherwise
5017 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5019 //================================================================================
5021 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5022 const SMESH::long_array& theModifiedElems )
5026 ::SMESH_MeshEditor aMeshEditor( myMesh );
5027 list< int > aListOfNodes;
5029 for ( i = 0, n = theNodes.length(); i < n; i++ )
5030 aListOfNodes.push_back( theNodes[ i ] );
5032 list< int > aListOfElems;
5033 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5034 aListOfElems.push_back( theModifiedElems[ i ] );
5036 bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
5038 myMesh->GetMeshDS()->Modified();
5039 storeResult( aMeshEditor) ;
5041 myMesh->SetIsModified( true );
5043 // Update Python script
5044 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5049 //================================================================================
5051 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5052 This method provided for convenience works as DoubleNodes() described above.
5053 \param theNodeId - identifier of node to be doubled.
5054 \param theModifiedElems - identifiers of elements to be updated.
5055 \return TRUE if operation has been completed successfully, FALSE otherwise
5056 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5058 //================================================================================
5060 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5061 const SMESH::long_array& theModifiedElems )
5063 SMESH::long_array_var aNodes = new SMESH::long_array;
5064 aNodes->length( 1 );
5065 aNodes[ 0 ] = theNodeId;
5067 TPythonDump pyDump; // suppress dump by the next line
5069 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5071 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5076 //================================================================================
5078 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5079 This method provided for convenience works as DoubleNodes() described above.
5080 \param theNodes - group of nodes to be doubled.
5081 \param theModifiedElems - group of elements to be updated.
5082 \return TRUE if operation has been completed successfully, FALSE otherwise
5083 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5085 //================================================================================
5087 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5088 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5090 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5093 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5094 SMESH::long_array_var aModifiedElems;
5095 if ( !CORBA::is_nil( theModifiedElems ) )
5096 aModifiedElems = theModifiedElems->GetListOfID();
5099 aModifiedElems = new SMESH::long_array;
5100 aModifiedElems->length( 0 );
5103 TPythonDump pyDump; // suppress dump by the next line
5105 bool done = DoubleNodes( aNodes, aModifiedElems );
5107 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5113 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5114 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5115 * \param theNodes - group of nodes to be doubled.
5116 * \param theModifiedElems - group of elements to be updated.
5117 * \return a new group with newly created nodes
5118 * \sa DoubleNodeGroup()
5120 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5121 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5123 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5126 SMESH::SMESH_Group_var aNewGroup;
5129 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5130 SMESH::long_array_var aModifiedElems;
5131 if ( !CORBA::is_nil( theModifiedElems ) )
5132 aModifiedElems = theModifiedElems->GetListOfID();
5134 aModifiedElems = new SMESH::long_array;
5135 aModifiedElems->length( 0 );
5138 TPythonDump pyDump; // suppress dump by the next line
5140 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5144 // Create group with newly created nodes
5145 SMESH::long_array_var anIds = GetLastCreatedNodes();
5146 if (anIds->length() > 0) {
5147 string anUnindexedName (theNodes->GetName());
5148 string aNewName = generateGroupName(anUnindexedName + "_double");
5149 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5150 aNewGroup->Add(anIds);
5154 pyDump << "createdNodes = " << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5155 << theModifiedElems << " )";
5157 return aNewGroup._retn();
5160 //================================================================================
5162 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5163 This method provided for convenience works as DoubleNodes() described above.
5164 \param theNodes - list of groups of nodes to be doubled
5165 \param theModifiedElems - list of groups of elements to be updated.
5166 \return TRUE if operation has been completed successfully, FALSE otherwise
5167 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5169 //================================================================================
5171 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5172 const SMESH::ListOfGroups& theModifiedElems )
5176 ::SMESH_MeshEditor aMeshEditor( myMesh );
5178 std::list< int > aNodes;
5180 for ( i = 0, n = theNodes.length(); i < n; i++ )
5182 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5183 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5185 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5186 for ( j = 0, m = aCurr->length(); j < m; j++ )
5187 aNodes.push_back( aCurr[ j ] );
5191 std::list< int > anElems;
5192 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5194 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5195 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5197 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5198 for ( j = 0, m = aCurr->length(); j < m; j++ )
5199 anElems.push_back( aCurr[ j ] );
5203 bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
5205 storeResult( aMeshEditor) ;
5207 myMesh->GetMeshDS()->Modified();
5209 myMesh->SetIsModified( true );
5212 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5217 //================================================================================
5219 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5220 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5221 * \param theNodes - group of nodes to be doubled.
5222 * \param theModifiedElems - group of elements to be updated.
5223 * \return a new group with newly created nodes
5224 * \sa DoubleNodeGroups()
5226 //================================================================================
5228 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5229 const SMESH::ListOfGroups& theModifiedElems )
5231 SMESH::SMESH_Group_var aNewGroup;
5233 TPythonDump pyDump; // suppress dump by the next line
5235 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5239 // Create group with newly created nodes
5240 SMESH::long_array_var anIds = GetLastCreatedNodes();
5241 if (anIds->length() > 0) {
5242 string anUnindexedName (theNodes[0]->GetName());
5243 string aNewName = generateGroupName(anUnindexedName + "_double");
5244 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5245 aNewGroup->Add(anIds);
5249 pyDump << "createdNodes = " << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5250 << theModifiedElems << " )";
5252 return aNewGroup._retn();
5256 //================================================================================
5258 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5259 \param theElems - the list of elements (edges or faces) to be replicated
5260 The nodes for duplication could be found from these elements
5261 \param theNodesNot - list of nodes to NOT replicate
5262 \param theAffectedElems - the list of elements (cells and edges) to which the
5263 replicated nodes should be associated to.
5264 \return TRUE if operation has been completed successfully, FALSE otherwise
5265 \sa DoubleNodeGroup(), DoubleNodeGroups()
5267 //================================================================================
5269 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5270 const SMESH::long_array& theNodesNot,
5271 const SMESH::long_array& theAffectedElems )
5276 ::SMESH_MeshEditor aMeshEditor( myMesh );
5278 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5279 TIDSortedElemSet anElems, aNodes, anAffected;
5280 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5281 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5282 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5284 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5286 storeResult( aMeshEditor) ;
5288 myMesh->GetMeshDS()->Modified();
5290 myMesh->SetIsModified( true );
5292 // Update Python script
5293 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5294 << theNodesNot << ", " << theAffectedElems << " )";
5298 //================================================================================
5300 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5301 \param theElems - the list of elements (edges or faces) to be replicated
5302 The nodes for duplication could be found from these elements
5303 \param theNodesNot - list of nodes to NOT replicate
5304 \param theShape - shape to detect affected elements (element which geometric center
5305 located on or inside shape).
5306 The replicated nodes should be associated to affected elements.
5307 \return TRUE if operation has been completed successfully, FALSE otherwise
5308 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5310 //================================================================================
5312 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5313 const SMESH::long_array& theNodesNot,
5314 GEOM::GEOM_Object_ptr theShape )
5319 ::SMESH_MeshEditor aMeshEditor( myMesh );
5321 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5322 TIDSortedElemSet anElems, aNodes;
5323 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5324 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5326 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5327 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5329 storeResult( aMeshEditor) ;
5331 myMesh->GetMeshDS()->Modified();
5333 myMesh->SetIsModified( true );
5335 // Update Python script
5336 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5337 << theNodesNot << ", " << theShape << " )";
5341 //================================================================================
5343 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5344 \param theElems - group of of elements (edges or faces) to be replicated
5345 \param theNodesNot - group of nodes not to replicated
5346 \param theAffectedElems - group of elements to which the replicated nodes
5347 should be associated to.
5348 \return TRUE if operation has been completed successfully, FALSE otherwise
5349 \sa DoubleNodes(), DoubleNodeGroups()
5351 //================================================================================
5353 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5354 SMESH::SMESH_GroupBase_ptr theNodesNot,
5355 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5357 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5362 ::SMESH_MeshEditor aMeshEditor( myMesh );
5364 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5365 TIDSortedElemSet anElems, aNodes, anAffected;
5366 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5367 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5368 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5370 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5372 storeResult( aMeshEditor) ;
5374 myMesh->GetMeshDS()->Modified();
5376 myMesh->SetIsModified( true );
5378 // Update Python script
5379 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5380 << theNodesNot << ", " << theAffectedElems << " )";
5385 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5386 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5387 * \param theElems - group of of elements (edges or faces) to be replicated
5388 * \param theNodesNot - group of nodes not to replicated
5389 * \param theAffectedElems - group of elements to which the replicated nodes
5390 * should be associated to.
5391 * \return a new group with newly created elements
5392 * \sa DoubleNodeElemGroup()
5394 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5395 SMESH::SMESH_GroupBase_ptr theNodesNot,
5396 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5398 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5401 SMESH::SMESH_Group_var aNewGroup;
5405 ::SMESH_MeshEditor aMeshEditor( myMesh );
5407 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5408 TIDSortedElemSet anElems, aNodes, anAffected;
5409 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5410 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5411 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5414 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5416 storeResult( aMeshEditor) ;
5419 myMesh->SetIsModified( true );
5421 // Create group with newly created elements
5422 SMESH::long_array_var anIds = GetLastCreatedElems();
5423 if (anIds->length() > 0) {
5424 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5425 string anUnindexedName (theElems->GetName());
5426 string aNewName = generateGroupName(anUnindexedName + "_double");
5427 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5428 aNewGroup->Add(anIds);
5432 // Update Python script
5433 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupNew( " << theElems << ", "
5434 << theNodesNot << ", " << theAffectedElems << " )";
5435 return aNewGroup._retn();
5438 //================================================================================
5440 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5441 \param theElems - group of of elements (edges or faces) to be replicated
5442 \param theNodesNot - group of nodes not to replicated
5443 \param theShape - shape to detect affected elements (element which geometric center
5444 located on or inside shape).
5445 The replicated nodes should be associated to affected elements.
5446 \return TRUE if operation has been completed successfully, FALSE otherwise
5447 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5449 //================================================================================
5451 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5452 SMESH::SMESH_GroupBase_ptr theNodesNot,
5453 GEOM::GEOM_Object_ptr theShape )
5456 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5461 ::SMESH_MeshEditor aMeshEditor( myMesh );
5463 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5464 TIDSortedElemSet anElems, aNodes, anAffected;
5465 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5466 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5468 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5469 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5471 storeResult( aMeshEditor) ;
5473 myMesh->GetMeshDS()->Modified();
5475 myMesh->SetIsModified( true );
5477 // Update Python script
5478 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5479 << theNodesNot << ", " << theShape << " )";
5483 //================================================================================
5485 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5486 This method provided for convenience works as DoubleNodes() described above.
5487 \param theElems - list of groups of elements (edges or faces) to be replicated
5488 \param theNodesNot - list of groups of nodes not to replicated
5489 \param theAffectedElems - group of elements to which the replicated nodes
5490 should be associated to.
5491 \return TRUE if operation has been completed successfully, FALSE otherwise
5492 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5494 //================================================================================
5496 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5497 SMESHDS_Mesh* theMeshDS,
5498 TIDSortedElemSet& theElemSet,
5499 const bool theIsNodeGrp)
5501 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5503 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5504 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5505 : aGrp->GetType() != SMESH::NODE ) )
5507 SMESH::long_array_var anIDs = aGrp->GetIDs();
5508 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5513 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5514 const SMESH::ListOfGroups& theNodesNot,
5515 const SMESH::ListOfGroups& theAffectedElems)
5519 ::SMESH_MeshEditor aMeshEditor( myMesh );
5521 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5522 TIDSortedElemSet anElems, aNodes, anAffected;
5523 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5524 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5525 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5527 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5529 storeResult( aMeshEditor) ;
5531 myMesh->GetMeshDS()->Modified();
5533 myMesh->SetIsModified( true );
5535 // Update Python script
5536 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5537 << &theNodesNot << ", " << &theAffectedElems << " )";
5541 //================================================================================
5543 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5544 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5545 \param theElems - list of groups of elements (edges or faces) to be replicated
5546 \param theNodesNot - list of groups of nodes not to replicated
5547 \param theAffectedElems - group of elements to which the replicated nodes
5548 should be associated to.
5549 * \return a new group with newly created elements
5550 * \sa DoubleNodeElemGroups()
5552 //================================================================================
5554 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5555 const SMESH::ListOfGroups& theNodesNot,
5556 const SMESH::ListOfGroups& theAffectedElems)
5558 SMESH::SMESH_Group_var aNewGroup;
5562 ::SMESH_MeshEditor aMeshEditor( myMesh );
5564 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5565 TIDSortedElemSet anElems, aNodes, anAffected;
5566 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5567 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5568 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5570 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5572 storeResult( aMeshEditor) ;
5574 myMesh->GetMeshDS()->Modified();
5576 myMesh->SetIsModified( true );
5578 // Create group with newly created elements
5579 SMESH::long_array_var anIds = GetLastCreatedElems();
5580 if (anIds->length() > 0) {
5581 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5582 string anUnindexedName (theElems[0]->GetName());
5583 string aNewName = generateGroupName(anUnindexedName + "_double");
5584 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5585 aNewGroup->Add(anIds);
5589 // Update Python script
5590 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupsNew( " << &theElems << ", "
5591 << &theNodesNot << ", " << &theAffectedElems << " )";
5592 return aNewGroup._retn();
5595 //================================================================================
5597 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5598 This method provided for convenience works as DoubleNodes() described above.
5599 \param theElems - list of groups of elements (edges or faces) to be replicated
5600 \param theNodesNot - list of groups of nodes not to replicated
5601 \param theShape - shape to detect affected elements (element which geometric center
5602 located on or inside shape).
5603 The replicated nodes should be associated to affected elements.
5604 \return TRUE if operation has been completed successfully, FALSE otherwise
5605 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
5607 //================================================================================
5610 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
5611 const SMESH::ListOfGroups& theNodesNot,
5612 GEOM::GEOM_Object_ptr theShape )
5616 ::SMESH_MeshEditor aMeshEditor( myMesh );
5618 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5619 TIDSortedElemSet anElems, aNodes;
5620 listOfGroupToSet(theElems, aMeshDS, anElems,false );
5621 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5623 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5624 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5626 storeResult( aMeshEditor) ;
5628 myMesh->GetMeshDS()->Modified();
5630 myMesh->SetIsModified( true );
5632 // Update Python script
5633 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
5634 << &theNodesNot << ", " << theShape << " )";
5638 //================================================================================
5640 \brief Generated skin mesh (containing 2D cells) from 3D mesh
5641 The created 2D mesh elements based on nodes of free faces of boundary volumes
5642 \return TRUE if operation has been completed successfully, FALSE otherwise
5644 //================================================================================
5646 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
5650 ::SMESH_MeshEditor aMeshEditor( myMesh );
5651 bool aResult = aMeshEditor.Make2DMeshFrom3D();
5652 storeResult( aMeshEditor) ;
5653 myMesh->GetMeshDS()->Modified();
5654 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
5658 //================================================================================
5660 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
5661 * The list of groups must describe a partition of the mesh volumes.
5662 * The nodes of the internal faces at the boundaries of the groups are doubled.
5663 * In option, the internal faces are replaced by flat elements.
5664 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5665 * The flat elements are stored in groups of volumes.
5666 * @param theDomains - list of groups of volumes
5667 * @param createJointElems - if TRUE, create the elements
5668 * @return TRUE if operation has been completed successfully, FALSE otherwise
5670 //================================================================================
5672 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
5673 CORBA::Boolean createJointElems )
5677 ::SMESH_MeshEditor aMeshEditor( myMesh );
5679 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5681 vector<TIDSortedElemSet> domains;
5684 for ( int i = 0, n = theDomains.length(); i < n; i++ )
5686 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
5687 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
5689 TIDSortedElemSet domain;
5691 domains.push_back(domain);
5692 SMESH::long_array_var anIDs = aGrp->GetIDs();
5693 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
5697 bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
5698 // TODO publish the groups of flat elements in study
5700 storeResult( aMeshEditor) ;
5701 myMesh->GetMeshDS()->Modified();
5703 // Update Python script
5704 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
5705 << ", " << createJointElems << " )";
5709 //================================================================================
5711 * \brief Double nodes on some external faces and create flat elements.
5712 * Flat elements are mainly used by some types of mechanic calculations.
5714 * Each group of the list must be constituted of faces.
5715 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5716 * @param theGroupsOfFaces - list of groups of faces
5717 * @return TRUE if operation has been completed successfully, FALSE otherwise
5719 //================================================================================
5721 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
5725 ::SMESH_MeshEditor aMeshEditor( myMesh );
5727 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5729 vector<TIDSortedElemSet> faceGroups;
5732 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
5734 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
5735 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
5737 TIDSortedElemSet faceGroup;
5739 faceGroups.push_back(faceGroup);
5740 SMESH::long_array_var anIDs = aGrp->GetIDs();
5741 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
5745 bool aResult = aMeshEditor.CreateFlatElementsOnFacesGroups( faceGroups );
5746 // TODO publish the groups of flat elements in study
5748 storeResult( aMeshEditor) ;
5749 myMesh->GetMeshDS()->Modified();
5751 // Update Python script
5752 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
5756 // issue 20749 ===================================================================
5758 * \brief Creates missing boundary elements
5759 * \param elements - elements whose boundary is to be checked
5760 * \param dimension - defines type of boundary elements to create
5761 * \param groupName - a name of group to store created boundary elements in,
5762 * "" means not to create the group
5763 * \param meshName - a name of new mesh to store created boundary elements in,
5764 * "" means not to create the new mesh
5765 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
5766 * \param toCopyExistingBondary - if true, not only new but also pre-existing
5767 * boundary elements will be copied into the new mesh
5768 * \param group - returns the create group, if any
5769 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
5771 // ================================================================================
5773 SMESH::SMESH_Mesh_ptr
5774 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
5775 SMESH::Bnd_Dimension dim,
5776 const char* groupName,
5777 const char* meshName,
5778 CORBA::Boolean toCopyElements,
5779 CORBA::Boolean toCopyExistingBondary,
5780 SMESH::SMESH_Group_out group)
5784 if ( dim > SMESH::BND_1DFROM2D )
5785 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5787 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5789 SMESH::SMESH_Mesh_var mesh_var;
5790 SMESH::SMESH_Group_var group_var;
5794 TIDSortedElemSet elements;
5795 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
5796 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
5800 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
5801 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5803 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
5805 // group of new boundary elements
5806 SMESH_Group* smesh_group = 0;
5807 if ( strlen(groupName) )
5809 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
5810 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5811 smesh_group = group_i->GetSmeshGroup();
5815 ::SMESH_MeshEditor aMeshEditor( myMesh );
5816 aMeshEditor.MakeBoundaryMesh( elements,
5817 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5821 toCopyExistingBondary);
5822 storeResult( aMeshEditor );
5825 smesh_mesh->GetMeshDS()->Modified();
5828 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
5830 // result of MakeBoundaryMesh() is a tuple (mesh, group)
5831 if ( mesh_var->_is_nil() )
5832 pyDump << myMesh_i->_this() << ", ";
5834 pyDump << mesh_var << ", ";
5835 if ( group_var->_is_nil() )
5836 pyDump << "_NoneGroup = "; // assignment to None is forbiden
5838 pyDump << group_var << " = ";
5839 pyDump << this << ".MakeBoundaryMesh( "
5841 << "SMESH." << dimName[int(dim)] << ", "
5842 << "'" << groupName << "', "
5843 << "'" << meshName<< "', "
5844 << toCopyElements << ", "
5845 << toCopyExistingBondary << ")";
5847 group = group_var._retn();
5848 return mesh_var._retn();
5851 //================================================================================
5853 * \brief Creates missing boundary elements
5854 * \param dimension - defines type of boundary elements to create
5855 * \param groupName - a name of group to store all boundary elements in,
5856 * "" means not to create the group
5857 * \param meshName - a name of a new mesh, which is a copy of the initial
5858 * mesh + created boundary elements; "" means not to create the new mesh
5859 * \param toCopyAll - if true, the whole initial mesh will be copied into
5860 * the new mesh else only boundary elements will be copied into the new mesh
5861 * \param groups - optional groups of elements to make boundary around
5862 * \param mesh - returns the mesh where elements were added to
5863 * \param group - returns the created group, if any
5864 * \retval long - number of added boundary elements
5866 //================================================================================
5868 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
5869 const char* groupName,
5870 const char* meshName,
5871 CORBA::Boolean toCopyAll,
5872 const SMESH::ListOfIDSources& groups,
5873 SMESH::SMESH_Mesh_out mesh,
5874 SMESH::SMESH_Group_out group)
5875 throw (SALOME::SALOME_Exception)
5877 Unexpect aCatch(SALOME_SalomeException);
5881 if ( dim > SMESH::BND_1DFROM2D )
5882 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5884 // check that groups belongs to to this mesh and is not this mesh
5885 const int nbGroups = groups.length();
5886 for ( int i = 0; i < nbGroups; ++i )
5888 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
5889 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
5890 THROW_SALOME_CORBA_EXCEPTION("group does not belong to this mesh", SALOME::BAD_PARAM);
5891 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
5892 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
5898 SMESH::SMESH_Mesh_var mesh_var;
5899 SMESH::SMESH_Group_var group_var;
5902 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
5903 const bool toCopyMesh = ( strlen( meshName ) > 0 );
5907 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
5909 /*toCopyGroups=*/false,
5910 /*toKeepIDs=*/true);
5912 mesh_var = makeMesh(meshName);
5914 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5915 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
5918 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
5919 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
5921 // group of boundary elements
5922 SMESH_Group* smesh_group = 0;
5923 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
5924 if ( strlen(groupName) )
5926 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
5927 group_var = mesh_i->CreateGroup( groupType, groupName );
5928 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5929 smesh_group = group_i->GetSmeshGroup();
5932 TIDSortedElemSet elements;
5936 for ( int i = 0; i < nbGroups; ++i )
5939 if ( idSourceToSet( groups[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/false ))
5941 SMESH::Bnd_Dimension bdim =
5942 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
5943 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5944 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5945 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
5948 /*toCopyElements=*/false,
5949 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
5950 /*toAddExistingBondary=*/true,
5951 /*aroundElements=*/true);
5952 storeResult( aMeshEditor );
5958 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5959 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5960 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5963 /*toCopyElements=*/false,
5964 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
5965 /*toAddExistingBondary=*/true);
5966 storeResult( aMeshEditor );
5968 tgtMesh->GetMeshDS()->Modified();
5970 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
5972 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
5973 pyDump << "nbAdded, ";
5974 if ( mesh_var->_is_nil() )
5975 pyDump << myMesh_i->_this() << ", ";
5977 pyDump << mesh_var << ", ";
5978 if ( group_var->_is_nil() )
5979 pyDump << "_NoneGroup = "; // assignment to None is forbiden
5981 pyDump << group_var << " = ";
5982 pyDump << this << ".MakeBoundaryElements( "
5983 << "SMESH." << dimName[int(dim)] << ", "
5984 << "'" << groupName << "', "
5985 << "'" << meshName<< "', "
5986 << toCopyAll << ", "
5989 mesh = mesh_var._retn();
5990 group = group_var._retn();