1 // Copyright (C) 2007-2012 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;
82 //=============================================================================
84 * \brief Mesh to apply modifications for preview purposes
86 //=============================================================================
88 struct TPreviewMesh: public SMESH_Mesh
90 SMDSAbs_ElementType myPreviewType; // type to show
92 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
93 _isShapeToMesh = (_id =_studyId =_idDoc = 0);
94 _myMeshDS = new SMESHDS_Mesh( _id, true );
95 myPreviewType = previewElements;
98 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
99 //!< Copy a set of elements
100 void Copy(const TIDSortedElemSet & theElements,
101 TIDSortedElemSet& theCopyElements,
102 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
103 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
105 // loop on theIDsOfElements
106 TIDSortedElemSet::const_iterator eIt = theElements.begin();
107 for ( ; eIt != theElements.end(); ++eIt )
109 const SMDS_MeshElement* anElem = *eIt;
110 if ( !anElem ) continue;
111 SMDSAbs_ElementType type = anElem->GetType();
112 if ( type == theAvoidType ||
113 ( theSelectType != SMDSAbs_All && type != theSelectType ))
115 const SMDS_MeshElement* anElemCopy;
116 if ( type == SMDSAbs_Node)
117 anElemCopy = Copy( cast2Node(anElem) );
119 anElemCopy = Copy( anElem );
121 theCopyElements.insert( theCopyElements.end(), anElemCopy );
125 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
127 // copy element nodes
128 int anElemNbNodes = anElem->NbNodes();
129 vector< int > anElemNodesID( anElemNbNodes ) ;
130 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
131 for ( int i = 0; itElemNodes->more(); i++)
133 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
135 anElemNodesID[i] = anElemNode->GetID();
138 // creates a corresponding element on copied nodes
139 SMDS_MeshElement* anElemCopy = 0;
140 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
142 const SMDS_VtkVolume* ph =
143 dynamic_cast<const SMDS_VtkVolume*> (anElem);
145 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
146 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
149 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
156 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
158 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
159 anElemNode->GetID());
161 };// struct TPreviewMesh
163 static SMESH_NodeSearcher * theNodeSearcher = 0;
164 static SMESH_ElementSearcher * theElementSearcher = 0;
166 //=============================================================================
168 * \brief Deleter of theNodeSearcher at any compute event occured
170 //=============================================================================
172 struct TSearchersDeleter : public SMESH_subMeshEventListener
175 string myMeshPartIOR;
177 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
178 "SMESH_MeshEditor_i::TSearchersDeleter"),
180 //!< Delete theNodeSearcher
183 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
184 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
186 typedef map < int, SMESH_subMesh * > TDependsOnMap;
187 //!< The meshod called by submesh: do my main job
188 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
189 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
191 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
193 Unset( sm->GetFather() );
196 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
197 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
199 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
206 myMeshPartIOR = meshPartIOR;
207 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
208 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
209 TDependsOnMap::const_iterator sm;
210 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
211 sm->second->SetEventListener( this, 0, sm->second );
215 //!< delete self from all submeshes
216 void Unset(SMESH_Mesh* mesh)
218 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
219 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
220 TDependsOnMap::const_iterator sm;
221 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
222 sm->second->DeleteEventListener( this );
227 } theSearchersDeleter;
229 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
231 TCollection_AsciiString typeStr;
232 switch ( theMirrorType ) {
233 case SMESH::SMESH_MeshEditor::POINT:
234 typeStr = "SMESH.SMESH_MeshEditor.POINT";
236 case SMESH::SMESH_MeshEditor::AXIS:
237 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
240 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
244 //================================================================================
246 * \brief function for conversion of long_array to TIDSortedElemSet
247 * \param IDs - array of IDs
248 * \param aMesh - mesh
249 * \param aMap - collection to fill
250 * \param aType - element type
252 //================================================================================
254 void arrayToSet(const SMESH::long_array & IDs,
255 const SMESHDS_Mesh* aMesh,
256 TIDSortedElemSet& aMap,
257 const SMDSAbs_ElementType aType = SMDSAbs_All )
259 for (int i=0; i<IDs.length(); i++) {
260 CORBA::Long ind = IDs[i];
261 const SMDS_MeshElement * elem =
262 (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
263 if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
267 //================================================================================
269 * \brief Retrieve elements of given type from SMESH_IDSource
271 //================================================================================
273 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
274 const SMESHDS_Mesh* theMeshDS,
275 TIDSortedElemSet& theElemSet,
276 const SMDSAbs_ElementType theType,
277 const bool emptyIfIsMesh=false)
280 if ( CORBA::is_nil( theIDSource ) )
282 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
285 SMESH::long_array_var anIDs = theIDSource->GetIDs();
286 if ( anIDs->length() == 0 )
288 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
289 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
291 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
292 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
298 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
299 return bool(anIDs->length()) == bool(theElemSet.size());
303 //================================================================================
305 * \brief Retrieve nodes from SMESH_IDSource
307 //================================================================================
309 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
310 const SMESHDS_Mesh* theMeshDS,
311 TIDSortedNodeSet& theNodeSet)
314 if ( CORBA::is_nil( theObject ) )
316 SMESH::array_of_ElementType_var types = theObject->GetTypes();
317 SMESH::long_array_var aElementsId = theObject->GetIDs();
318 if ( types->length() == 1 && types[0] == SMESH::NODE)
320 for(int i = 0; i < aElementsId->length(); i++)
321 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
322 theNodeSet.insert( theNodeSet.end(), n);
324 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
326 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
327 while ( nIt->more( ))
328 if( const SMDS_MeshElement * elem = nIt->next() )
329 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
333 for(int i = 0; i < aElementsId->length(); i++)
334 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
335 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
339 //================================================================================
341 * \brief Returns elements connected to the given elements
343 //================================================================================
345 void getElementsAround(const TIDSortedElemSet& theElements,
346 const SMESHDS_Mesh* theMeshDS,
347 TIDSortedElemSet& theElementsAround)
349 if ( theElements.empty() ) return;
351 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
352 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
354 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
355 return; // all the elements are in theElements
358 elemType = SMDSAbs_All;
360 TIDSortedElemSet visitedNodes;
361 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
362 for ( ; elemIt != theElements.end(); ++elemIt )
364 const SMDS_MeshElement* e = *elemIt;
365 int i = e->NbCornerNodes();
368 const SMDS_MeshNode* n = e->GetNode( i );
369 if ( visitedNodes.insert( n ).second )
371 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
372 while ( invIt->more() )
374 const SMDS_MeshElement* elemAround = invIt->next();
375 if ( !theElements.count( elemAround ))
376 theElementsAround.insert( elemAround );
383 //================================================================================
385 * \brief Return a string used to detect change of mesh part on which theElementSearcher
386 * is going to be used
388 //================================================================================
390 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
392 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
393 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
394 // take into account passible group modification
395 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
396 partIOR += SMESH_Comment( type );
402 //=============================================================================
406 //=============================================================================
408 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview)
411 myMesh = & theMesh->GetImpl();
412 myPreviewMode = isPreview;
415 //================================================================================
419 //================================================================================
421 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
425 //================================================================================
427 * \brief Clear members
429 //================================================================================
431 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
433 if ( myPreviewMode ) {
434 myPreviewData = new SMESH::MeshPreviewStruct();
437 myLastCreatedElems = new SMESH::long_array();
438 myLastCreatedNodes = new SMESH::long_array();
439 if ( deleteSearchers )
440 TSearchersDeleter::Delete();
444 //=======================================================================
445 //function : MakeIDSource
446 //purpose : Wrap a sequence of ids in a SMESH_IDSource
447 //=======================================================================
449 struct _IDSource : public POA_SMESH::SMESH_IDSource
451 SMESH::long_array _ids;
452 SMESH::ElementType _type;
453 SMESH::SMESH_Mesh_ptr _mesh;
454 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
455 SMESH::long_array* GetMeshInfo() { return 0; }
456 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
457 bool IsMeshInfoCorrect() { return true; }
458 SMESH::array_of_ElementType* GetTypes()
460 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
461 if ( _ids.length() > 0 ) {
465 return types._retn();
469 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
470 SMESH::ElementType type)
472 _IDSource* anIDSource = new _IDSource;
473 anIDSource->_ids = ids;
474 anIDSource->_type = type;
475 anIDSource->_mesh = myMesh_i->_this();
476 SMESH::SMESH_IDSource_var anIDSourceVar = anIDSource->_this();
478 return anIDSourceVar._retn();
481 //=============================================================================
485 //=============================================================================
488 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
492 ::SMESH_MeshEditor anEditor( myMesh );
495 for (int i = 0; i < IDsOfElements.length(); i++)
496 IdList.push_back( IDsOfElements[i] );
498 // Update Python script
499 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
502 bool ret = anEditor.Remove( IdList, false );
503 myMesh->GetMeshDS()->Modified();
504 if ( IDsOfElements.length() )
505 myMesh->SetIsModified( true ); // issue 0020693
509 //=============================================================================
513 //=============================================================================
515 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
519 ::SMESH_MeshEditor anEditor( myMesh );
521 for (int i = 0; i < IDsOfNodes.length(); i++)
522 IdList.push_back( IDsOfNodes[i] );
524 // Update Python script
525 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
527 bool ret = anEditor.Remove( IdList, true );
528 myMesh->GetMeshDS()->Modified();
529 if ( IDsOfNodes.length() )
530 myMesh->SetIsModified( true ); // issue 0020693
534 //=============================================================================
538 //=============================================================================
540 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
544 ::SMESH_MeshEditor anEditor( myMesh );
546 // Update Python script
547 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
549 // Create filter to find all orphan nodes
550 SMESH::Controls::Filter::TIdSequence seq;
551 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
552 SMESH::Controls::Filter::GetElementsId( GetMeshDS(), predicate, seq );
554 // remove orphan nodes (if there are any)
556 for ( int i = 0; i < seq.size(); i++ )
557 IdList.push_back( seq[i] );
559 int nbNodesBefore = myMesh->NbNodes();
560 anEditor.Remove( IdList, true );
561 myMesh->GetMeshDS()->Modified();
563 myMesh->SetIsModified( true );
564 int nbNodesAfter = myMesh->NbNodes();
566 return nbNodesBefore - nbNodesAfter;
569 //=============================================================================
573 //=============================================================================
575 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
576 CORBA::Double y, CORBA::Double z)
580 const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
582 // Update Python script
583 TPythonDump() << "nodeID = " << this << ".AddNode( "
584 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
586 myMesh->GetMeshDS()->Modified();
587 myMesh->SetIsModified( true ); // issue 0020693
591 //=============================================================================
595 //=============================================================================
596 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
600 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
601 SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode);
603 // Update Python script
604 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
606 myMesh->GetMeshDS()->Modified();
607 myMesh->SetIsModified( true ); // issue 0020693
610 return elem->GetID();
615 //=============================================================================
619 //=============================================================================
621 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
625 int NbNodes = IDsOfNodes.length();
626 SMDS_MeshElement* elem = 0;
629 CORBA::Long index1 = IDsOfNodes[0];
630 CORBA::Long index2 = IDsOfNodes[1];
631 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
633 // Update Python script
634 TPythonDump() << "edge = " << this << ".AddEdge([ "
635 << index1 << ", " << index2 <<" ])";
638 CORBA::Long n1 = IDsOfNodes[0];
639 CORBA::Long n2 = IDsOfNodes[1];
640 CORBA::Long n12 = IDsOfNodes[2];
641 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
642 GetMeshDS()->FindNode(n2),
643 GetMeshDS()->FindNode(n12));
644 // Update Python script
645 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
646 <<n1<<", "<<n2<<", "<<n12<<" ])";
649 myMesh->GetMeshDS()->Modified();
651 return myMesh->SetIsModified( true ), elem->GetID();
656 //=============================================================================
660 //=============================================================================
662 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
666 int NbNodes = IDsOfNodes.length();
672 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
673 for (int i = 0; i < NbNodes; i++)
674 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
676 SMDS_MeshElement* elem = 0;
678 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
680 else if (NbNodes == 4) {
681 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
683 else if (NbNodes == 6) {
684 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
687 else if (NbNodes == 8) {
688 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
689 nodes[4], nodes[5], nodes[6], nodes[7]);
691 else if (NbNodes == 9) {
692 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
693 nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
695 else if (NbNodes > 2) {
696 elem = GetMeshDS()->AddPolygonalFace(nodes);
699 // Update Python script
700 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
702 myMesh->GetMeshDS()->Modified();
704 return myMesh->SetIsModified( true ), elem->GetID();
709 //=============================================================================
713 //=============================================================================
714 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
718 int NbNodes = IDsOfNodes.length();
719 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
720 for (int i = 0; i < NbNodes; i++)
721 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
723 const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
725 // Update Python script
726 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
728 myMesh->GetMeshDS()->Modified();
729 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
732 //=============================================================================
736 //=============================================================================
738 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
742 int NbNodes = IDsOfNodes.length();
743 vector< const SMDS_MeshNode*> n(NbNodes);
744 for(int i=0;i<NbNodes;i++)
745 n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
747 SMDS_MeshElement* elem = 0;
750 case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
751 case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
752 case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
753 case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
754 case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
755 n[6],n[7],n[8],n[9]);
757 case 12:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
758 n[6],n[7],n[8],n[9],n[10],n[11]);
760 case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
761 n[7],n[8],n[9],n[10],n[11],n[12]);
763 case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
764 n[9],n[10],n[11],n[12],n[13],n[14]);
766 case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
767 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
768 n[15],n[16],n[17],n[18],n[19]);
770 case 27:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
771 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
772 n[15],n[16],n[17],n[18],n[19],
773 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
777 // Update Python script
778 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
780 myMesh->GetMeshDS()->Modified();
782 return myMesh->SetIsModified( true ), elem->GetID();
787 //=============================================================================
789 * AddPolyhedralVolume
791 //=============================================================================
792 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
793 const SMESH::long_array & Quantities)
797 int NbNodes = IDsOfNodes.length();
798 std::vector<const SMDS_MeshNode*> n (NbNodes);
799 for (int i = 0; i < NbNodes; i++)
801 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
802 if (!aNode) return 0;
806 int NbFaces = Quantities.length();
807 std::vector<int> q (NbFaces);
808 for (int j = 0; j < NbFaces; j++)
809 q[j] = Quantities[j];
811 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
813 // Update Python script
814 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
815 << IDsOfNodes << ", " << Quantities << " )";
816 myMesh->GetMeshDS()->Modified();
818 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
821 //=============================================================================
823 * AddPolyhedralVolumeByFaces
825 //=============================================================================
826 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
830 int NbFaces = IdsOfFaces.length();
831 std::vector<const SMDS_MeshNode*> poly_nodes;
832 std::vector<int> quantities (NbFaces);
834 for (int i = 0; i < NbFaces; i++) {
835 const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
836 quantities[i] = aFace->NbNodes();
838 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
840 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
844 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
846 // Update Python script
847 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
848 << IdsOfFaces << " )";
849 myMesh->GetMeshDS()->Modified();
851 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
854 //=============================================================================
856 * \brief Bind a node to a vertex
857 * \param NodeID - node ID
858 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
859 * \retval boolean - false if NodeID or VertexID is invalid
861 //=============================================================================
863 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
864 throw (SALOME::SALOME_Exception)
866 Unexpect aCatch(SALOME_SalomeException);
868 SMESHDS_Mesh * mesh = GetMeshDS();
869 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
871 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
873 if ( mesh->MaxShapeIndex() < VertexID )
874 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
876 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
877 if ( shape.ShapeType() != TopAbs_VERTEX )
878 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
880 mesh->SetNodeOnVertex( node, VertexID );
882 myMesh->SetIsModified( true );
885 //=============================================================================
887 * \brief Store node position on an edge
888 * \param NodeID - node ID
889 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
890 * \param paramOnEdge - parameter on edge where the node is located
891 * \retval boolean - false if any parameter is invalid
893 //=============================================================================
895 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
896 CORBA::Double paramOnEdge)
897 throw (SALOME::SALOME_Exception)
899 Unexpect aCatch(SALOME_SalomeException);
901 SMESHDS_Mesh * mesh = GetMeshDS();
902 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
904 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
906 if ( mesh->MaxShapeIndex() < EdgeID )
907 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
909 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
910 if ( shape.ShapeType() != TopAbs_EDGE )
911 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
914 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
915 if ( paramOnEdge < f || paramOnEdge > l )
916 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
918 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
920 myMesh->SetIsModified( true );
923 //=============================================================================
925 * \brief Store node position on a face
926 * \param NodeID - node ID
927 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
928 * \param u - U parameter on face where the node is located
929 * \param v - V parameter on face where the node is located
930 * \retval boolean - false if any parameter is invalid
932 //=============================================================================
934 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
935 CORBA::Double u, CORBA::Double v)
936 throw (SALOME::SALOME_Exception)
938 Unexpect aCatch(SALOME_SalomeException);
940 SMESHDS_Mesh * mesh = GetMeshDS();
941 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
943 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
945 if ( mesh->MaxShapeIndex() < FaceID )
946 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
948 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
949 if ( shape.ShapeType() != TopAbs_FACE )
950 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
952 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
953 bool isOut = ( u < surf.FirstUParameter() ||
954 u > surf.LastUParameter() ||
955 v < surf.FirstVParameter() ||
956 v > surf.LastVParameter() );
960 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
961 << " u( " << surf.FirstUParameter()
962 << "," << surf.LastUParameter()
963 << ") v( " << surf.FirstVParameter()
964 << "," << surf.LastVParameter() << ")" );
966 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
969 mesh->SetNodeOnFace( node, FaceID, u, v );
970 myMesh->SetIsModified( true );
973 //=============================================================================
975 * \brief Bind a node to a solid
976 * \param NodeID - node ID
977 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
978 * \retval boolean - false if NodeID or SolidID is invalid
980 //=============================================================================
982 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
983 throw (SALOME::SALOME_Exception)
985 Unexpect aCatch(SALOME_SalomeException);
987 SMESHDS_Mesh * mesh = GetMeshDS();
988 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
990 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
992 if ( mesh->MaxShapeIndex() < SolidID )
993 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
995 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
996 if ( shape.ShapeType() != TopAbs_SOLID &&
997 shape.ShapeType() != TopAbs_SHELL)
998 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1000 mesh->SetNodeInVolume( node, SolidID );
1002 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
1005 //=============================================================================
1007 * \brief Bind an element to a shape
1008 * \param ElementID - element ID
1009 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1010 * \retval boolean - false if ElementID or ShapeID is invalid
1012 //=============================================================================
1014 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1015 CORBA::Long ShapeID)
1016 throw (SALOME::SALOME_Exception)
1018 Unexpect aCatch(SALOME_SalomeException);
1020 SMESHDS_Mesh * mesh = GetMeshDS();
1021 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1023 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1025 if ( mesh->MaxShapeIndex() < ShapeID )
1026 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1028 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1029 if ( shape.ShapeType() != TopAbs_EDGE &&
1030 shape.ShapeType() != TopAbs_FACE &&
1031 shape.ShapeType() != TopAbs_SOLID &&
1032 shape.ShapeType() != TopAbs_SHELL )
1033 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1035 mesh->SetMeshElementOnShape( elem, ShapeID );
1037 myMesh->SetIsModified( true );
1040 //=============================================================================
1044 //=============================================================================
1046 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1047 CORBA::Long NodeID2)
1051 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1052 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1056 // Update Python script
1057 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1058 << NodeID1 << ", " << NodeID2 << " )";
1061 ::SMESH_MeshEditor aMeshEditor( myMesh );
1062 int ret = aMeshEditor.InverseDiag ( n1, n2 );
1063 myMesh->GetMeshDS()->Modified();
1064 myMesh->SetIsModified( true );
1068 //=============================================================================
1072 //=============================================================================
1074 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1075 CORBA::Long NodeID2)
1079 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1080 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1084 // Update Python script
1085 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1086 << NodeID1 << ", " << NodeID2 << " )";
1088 ::SMESH_MeshEditor aMeshEditor( myMesh );
1090 bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
1092 myMesh->GetMeshDS()->Modified();
1094 myMesh->SetIsModified( true ); // issue 0020693
1096 storeResult(aMeshEditor);
1101 //=============================================================================
1105 //=============================================================================
1107 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1111 ::SMESH_MeshEditor anEditor( myMesh );
1112 for (int i = 0; i < IDsOfElements.length(); i++)
1114 CORBA::Long index = IDsOfElements[i];
1115 const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
1117 anEditor.Reorient( elem );
1119 // Update Python script
1120 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1122 myMesh->GetMeshDS()->Modified();
1123 if ( IDsOfElements.length() )
1124 myMesh->SetIsModified( true ); // issue 0020693
1130 //=============================================================================
1134 //=============================================================================
1136 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1140 TPythonDump aTPythonDump; // suppress dump in Reorient()
1142 SMESH::long_array_var anElementsId = theObject->GetIDs();
1143 CORBA::Boolean isDone = Reorient(anElementsId);
1145 // Update Python script
1146 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1151 //=======================================================================
1152 //function : Reorient2D
1153 //purpose : Reorient faces contained in \a the2Dgroup.
1154 // the2Dgroup - the mesh or its part to reorient
1155 // theDirection - desired direction of normal of \a theFace
1156 // theFace - ID of face whose orientation is checked.
1157 // It can be < 1 then \a thePoint is used to find a face.
1158 // thePoint - is used to find a face if \a theFace < 1.
1159 // return number of reoriented elements.
1160 //=======================================================================
1162 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1163 const SMESH::DirStruct& theDirection,
1164 CORBA::Long theFace,
1165 const SMESH::PointStruct& thePoint)
1166 throw (SALOME::SALOME_Exception)
1168 Unexpect aCatch(SALOME_SalomeException);
1170 initData(/*deleteSearchers=*/false);
1172 TIDSortedElemSet elements;
1173 if ( !idSourceToSet( the2Dgroup, GetMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1174 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1176 ::SMESH_MeshEditor anEditor( myMesh );
1178 const SMDS_MeshElement* face = 0;
1181 face = GetMeshDS()->FindElement( theFace );
1183 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1184 if ( face->GetType() != SMDSAbs_Face )
1185 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1189 // create theElementSearcher if needed
1190 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1191 if ( !theElementSearcher )
1193 if ( elements.empty() ) // search in the whole mesh
1195 if ( myMesh->NbFaces() == 0 )
1196 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1198 theElementSearcher = anEditor.GetElementSearcher();
1202 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1203 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1205 theElementSearcher = anEditor.GetElementSearcher(elemsIt);
1209 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1210 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1213 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1214 if ( !elements.empty() && !elements.count( face ))
1215 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1218 const SMESH::PointStruct * P = &theDirection.PS;
1219 gp_Vec dirVec( P->x, P->y, P->z );
1220 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1221 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1223 int nbReori = anEditor.Reorient2D( elements, dirVec, face );
1224 storeResult(anEditor);
1227 myMesh->SetIsModified( true );
1228 myMesh->GetMeshDS()->Modified();
1230 TPythonDump() << this << ".Reorient2D( "
1231 << the2Dgroup << ", "
1232 << theDirection << ", "
1234 << thePoint << " )";
1239 //=============================================================================
1243 //=============================================================================
1244 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1245 SMESH::NumericalFunctor_ptr Criterion,
1246 CORBA::Double MaxAngle)
1250 SMESHDS_Mesh* aMesh = GetMeshDS();
1251 TIDSortedElemSet faces;
1252 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1254 SMESH::NumericalFunctor_i* aNumericalFunctor =
1255 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1256 SMESH::Controls::NumericalFunctorPtr aCrit;
1257 if ( !aNumericalFunctor )
1258 aCrit.reset( new SMESH::Controls::AspectRatio() );
1260 aCrit = aNumericalFunctor->GetNumericalFunctor();
1262 // Update Python script
1263 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1264 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1266 ::SMESH_MeshEditor anEditor( myMesh );
1268 bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
1269 myMesh->GetMeshDS()->Modified();
1271 myMesh->SetIsModified( true ); // issue 0020693
1273 storeResult(anEditor);
1279 //=============================================================================
1283 //=============================================================================
1284 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1285 SMESH::NumericalFunctor_ptr Criterion,
1286 CORBA::Double MaxAngle)
1290 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1291 SMESH::long_array_var anElementsId = theObject->GetIDs();
1292 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1294 SMESH::NumericalFunctor_i* aNumericalFunctor =
1295 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1297 // Update Python script
1298 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1299 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1305 //=============================================================================
1309 //=============================================================================
1310 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1311 SMESH::NumericalFunctor_ptr Criterion)
1315 SMESHDS_Mesh* aMesh = GetMeshDS();
1316 TIDSortedElemSet faces;
1317 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1319 SMESH::NumericalFunctor_i* aNumericalFunctor =
1320 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1321 SMESH::Controls::NumericalFunctorPtr aCrit;
1322 if ( !aNumericalFunctor )
1323 aCrit.reset( new SMESH::Controls::AspectRatio() );
1325 aCrit = aNumericalFunctor->GetNumericalFunctor();
1328 // Update Python script
1329 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1331 ::SMESH_MeshEditor anEditor( myMesh );
1332 CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
1333 myMesh->GetMeshDS()->Modified();
1335 myMesh->SetIsModified( true ); // issue 0020693
1337 storeResult(anEditor);
1343 //=============================================================================
1347 //=============================================================================
1348 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1349 SMESH::NumericalFunctor_ptr Criterion)
1353 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1355 SMESH::long_array_var anElementsId = theObject->GetIDs();
1356 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1358 SMESH::NumericalFunctor_i* aNumericalFunctor =
1359 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1361 // Update Python script
1362 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1368 //=============================================================================
1372 //=============================================================================
1373 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1374 CORBA::Boolean Diag13)
1378 SMESHDS_Mesh* aMesh = GetMeshDS();
1379 TIDSortedElemSet faces;
1380 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1382 // Update Python script
1383 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1384 << IDsOfElements << ", " << Diag13 << " )";
1386 ::SMESH_MeshEditor anEditor( myMesh );
1387 CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
1388 myMesh->GetMeshDS()->Modified();
1390 myMesh->SetIsModified( true ); // issue 0020693
1393 storeResult(anEditor);
1399 //=============================================================================
1403 //=============================================================================
1404 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1405 CORBA::Boolean Diag13)
1409 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1411 SMESH::long_array_var anElementsId = theObject->GetIDs();
1412 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1414 // Update Python script
1415 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1416 << theObject << ", " << Diag13 << " )";
1422 //=============================================================================
1426 //=============================================================================
1427 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1428 SMESH::NumericalFunctor_ptr Criterion)
1432 const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1433 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1435 SMESH::NumericalFunctor_i* aNumericalFunctor =
1436 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1437 SMESH::Controls::NumericalFunctorPtr aCrit;
1438 if (aNumericalFunctor)
1439 aCrit = aNumericalFunctor->GetNumericalFunctor();
1441 aCrit.reset(new SMESH::Controls::AspectRatio());
1443 ::SMESH_MeshEditor anEditor (myMesh);
1444 return anEditor.BestSplit(quad, aCrit);
1449 //================================================================================
1451 * \brief Split volumic elements into tetrahedrons
1453 //================================================================================
1455 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1456 CORBA::Short methodFlags)
1457 throw (SALOME::SALOME_Exception)
1459 Unexpect aCatch(SALOME_SalomeException);
1463 SMESH::long_array_var anElementsId = elems->GetIDs();
1464 TIDSortedElemSet elemSet;
1465 arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume );
1467 ::SMESH_MeshEditor anEditor (myMesh);
1468 anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1469 myMesh->GetMeshDS()->Modified();
1471 storeResult(anEditor);
1473 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1474 // myMesh->SetIsModified( true ); // issue 0020693
1476 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1477 << elems << ", " << methodFlags << " )";
1480 //=======================================================================
1483 //=======================================================================
1486 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1487 const SMESH::long_array & IDsOfFixedNodes,
1488 CORBA::Long MaxNbOfIterations,
1489 CORBA::Double MaxAspectRatio,
1490 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1492 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1493 MaxAspectRatio, Method, false );
1497 //=======================================================================
1498 //function : SmoothParametric
1500 //=======================================================================
1503 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1504 const SMESH::long_array & IDsOfFixedNodes,
1505 CORBA::Long MaxNbOfIterations,
1506 CORBA::Double MaxAspectRatio,
1507 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1509 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1510 MaxAspectRatio, Method, true );
1514 //=======================================================================
1515 //function : SmoothObject
1517 //=======================================================================
1520 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1521 const SMESH::long_array & IDsOfFixedNodes,
1522 CORBA::Long MaxNbOfIterations,
1523 CORBA::Double MaxAspectRatio,
1524 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1526 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1527 MaxAspectRatio, Method, false);
1531 //=======================================================================
1532 //function : SmoothParametricObject
1534 //=======================================================================
1537 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1538 const SMESH::long_array & IDsOfFixedNodes,
1539 CORBA::Long MaxNbOfIterations,
1540 CORBA::Double MaxAspectRatio,
1541 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1543 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1544 MaxAspectRatio, Method, true);
1548 //=============================================================================
1552 //=============================================================================
1555 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1556 const SMESH::long_array & IDsOfFixedNodes,
1557 CORBA::Long MaxNbOfIterations,
1558 CORBA::Double MaxAspectRatio,
1559 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1564 SMESHDS_Mesh* aMesh = GetMeshDS();
1566 TIDSortedElemSet elements;
1567 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1569 set<const SMDS_MeshNode*> fixedNodes;
1570 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1571 CORBA::Long index = IDsOfFixedNodes[i];
1572 const SMDS_MeshNode * node = aMesh->FindNode(index);
1574 fixedNodes.insert( node );
1576 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1577 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1578 method = ::SMESH_MeshEditor::CENTROIDAL;
1580 ::SMESH_MeshEditor anEditor( myMesh );
1581 anEditor.Smooth(elements, fixedNodes, method,
1582 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1584 myMesh->GetMeshDS()->Modified();
1585 myMesh->SetIsModified( true ); // issue 0020693
1587 storeResult(anEditor);
1589 // Update Python script
1590 TPythonDump() << "isDone = " << this << "."
1591 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1592 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1593 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1594 << "SMESH.SMESH_MeshEditor."
1595 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1596 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1602 //=============================================================================
1606 //=============================================================================
1609 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1610 const SMESH::long_array & IDsOfFixedNodes,
1611 CORBA::Long MaxNbOfIterations,
1612 CORBA::Double MaxAspectRatio,
1613 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1618 TPythonDump aTPythonDump; // suppress dump in smooth()
1620 SMESH::long_array_var anElementsId = theObject->GetIDs();
1621 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1622 MaxAspectRatio, Method, IsParametric);
1624 // Update Python script
1625 aTPythonDump << "isDone = " << this << "."
1626 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1627 << theObject << ", " << IDsOfFixedNodes << ", "
1628 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1629 << "SMESH.SMESH_MeshEditor."
1630 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1631 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1637 //=============================================================================
1641 //=============================================================================
1643 void SMESH_MeshEditor_i::RenumberNodes()
1645 // Update Python script
1646 TPythonDump() << this << ".RenumberNodes()";
1648 GetMeshDS()->Renumber( true );
1652 //=============================================================================
1656 //=============================================================================
1658 void SMESH_MeshEditor_i::RenumberElements()
1660 // Update Python script
1661 TPythonDump() << this << ".RenumberElements()";
1663 GetMeshDS()->Renumber( false );
1666 //=======================================================================
1668 * \brief Return groups by their IDs
1670 //=======================================================================
1672 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1676 myMesh_i->CreateGroupServants();
1677 return myMesh_i->GetGroups( *groupIDs );
1680 //=======================================================================
1681 //function : rotationSweep
1683 //=======================================================================
1685 SMESH::ListOfGroups*
1686 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1687 const SMESH::AxisStruct & theAxis,
1688 CORBA::Double theAngleInRadians,
1689 CORBA::Long theNbOfSteps,
1690 CORBA::Double theTolerance,
1691 const bool theMakeGroups,
1692 const SMDSAbs_ElementType theElementType)
1696 TIDSortedElemSet inElements, copyElements;
1697 arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
1699 TIDSortedElemSet* workElements = & inElements;
1700 TPreviewMesh tmpMesh( SMDSAbs_Face );
1701 SMESH_Mesh* mesh = 0;
1702 bool makeWalls=true;
1703 if ( myPreviewMode )
1705 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1706 tmpMesh.Copy( inElements, copyElements, select, avoid );
1708 workElements = & copyElements;
1709 //makeWalls = false;
1716 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
1717 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1719 ::SMESH_MeshEditor anEditor( mesh );
1720 ::SMESH_MeshEditor::PGroupIDs groupIds =
1721 anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1722 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
1723 storeResult(anEditor);
1724 myMesh->GetMeshDS()->Modified();
1726 // myMesh->SetIsModified( true ); -- it does not influence Compute()
1728 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1731 //=======================================================================
1732 //function : RotationSweep
1734 //=======================================================================
1736 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1737 const SMESH::AxisStruct & theAxis,
1738 CORBA::Double theAngleInRadians,
1739 CORBA::Long theNbOfSteps,
1740 CORBA::Double theTolerance)
1742 if ( !myPreviewMode ) {
1743 TPythonDump() << this << ".RotationSweep( "
1744 << theIDsOfElements << ", "
1746 << TVar( theAngleInRadians ) << ", "
1747 << TVar( theNbOfSteps ) << ", "
1748 << TVar( theTolerance ) << " )";
1750 rotationSweep(theIDsOfElements,
1758 //=======================================================================
1759 //function : RotationSweepMakeGroups
1761 //=======================================================================
1763 SMESH::ListOfGroups*
1764 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1765 const SMESH::AxisStruct& theAxis,
1766 CORBA::Double theAngleInRadians,
1767 CORBA::Long theNbOfSteps,
1768 CORBA::Double theTolerance)
1770 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1772 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
1778 if (!myPreviewMode) {
1779 DumpGroupsList(aPythonDump, aGroups);
1780 aPythonDump << this << ".RotationSweepMakeGroups( "
1781 << theIDsOfElements << ", "
1783 << TVar( theAngleInRadians ) << ", "
1784 << TVar( theNbOfSteps ) << ", "
1785 << TVar( theTolerance ) << " )";
1790 //=======================================================================
1791 //function : RotationSweepObject
1793 //=======================================================================
1795 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1796 const SMESH::AxisStruct & theAxis,
1797 CORBA::Double theAngleInRadians,
1798 CORBA::Long theNbOfSteps,
1799 CORBA::Double theTolerance)
1801 if ( !myPreviewMode ) {
1802 TPythonDump() << this << ".RotationSweepObject( "
1803 << theObject << ", "
1805 << theAngleInRadians << ", "
1806 << theNbOfSteps << ", "
1807 << theTolerance << " )";
1809 SMESH::long_array_var anElementsId = theObject->GetIDs();
1810 rotationSweep(anElementsId,
1818 //=======================================================================
1819 //function : RotationSweepObject1D
1821 //=======================================================================
1823 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1824 const SMESH::AxisStruct & theAxis,
1825 CORBA::Double theAngleInRadians,
1826 CORBA::Long theNbOfSteps,
1827 CORBA::Double theTolerance)
1829 if ( !myPreviewMode ) {
1830 TPythonDump() << this << ".RotationSweepObject1D( "
1831 << theObject << ", "
1833 << TVar( theAngleInRadians ) << ", "
1834 << TVar( theNbOfSteps ) << ", "
1835 << TVar( theTolerance ) << " )";
1837 SMESH::long_array_var anElementsId = theObject->GetIDs();
1838 rotationSweep(anElementsId,
1847 //=======================================================================
1848 //function : RotationSweepObject2D
1850 //=======================================================================
1852 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1853 const SMESH::AxisStruct & theAxis,
1854 CORBA::Double theAngleInRadians,
1855 CORBA::Long theNbOfSteps,
1856 CORBA::Double theTolerance)
1858 if ( !myPreviewMode ) {
1859 TPythonDump() << this << ".RotationSweepObject2D( "
1860 << theObject << ", "
1862 << TVar( theAngleInRadians ) << ", "
1863 << TVar( theNbOfSteps ) << ", "
1864 << TVar( theTolerance ) << " )";
1866 SMESH::long_array_var anElementsId = theObject->GetIDs();
1867 rotationSweep(anElementsId,
1876 //=======================================================================
1877 //function : RotationSweepObjectMakeGroups
1879 //=======================================================================
1881 SMESH::ListOfGroups*
1882 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1883 const SMESH::AxisStruct& theAxis,
1884 CORBA::Double theAngleInRadians,
1885 CORBA::Long theNbOfSteps,
1886 CORBA::Double theTolerance)
1888 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1890 SMESH::long_array_var anElementsId = theObject->GetIDs();
1891 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1897 if (!myPreviewMode) {
1898 DumpGroupsList(aPythonDump, aGroups);
1899 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
1900 << theObject << ", "
1902 << theAngleInRadians << ", "
1903 << theNbOfSteps << ", "
1904 << theTolerance << " )";
1909 //=======================================================================
1910 //function : RotationSweepObject1DMakeGroups
1912 //=======================================================================
1914 SMESH::ListOfGroups*
1915 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1916 const SMESH::AxisStruct& theAxis,
1917 CORBA::Double theAngleInRadians,
1918 CORBA::Long theNbOfSteps,
1919 CORBA::Double theTolerance)
1921 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1923 SMESH::long_array_var anElementsId = theObject->GetIDs();
1924 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1931 if (!myPreviewMode) {
1932 DumpGroupsList(aPythonDump, aGroups);
1933 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
1934 << theObject << ", "
1936 << TVar( theAngleInRadians ) << ", "
1937 << TVar( theNbOfSteps ) << ", "
1938 << TVar( theTolerance ) << " )";
1943 //=======================================================================
1944 //function : RotationSweepObject2DMakeGroups
1946 //=======================================================================
1948 SMESH::ListOfGroups*
1949 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1950 const SMESH::AxisStruct& theAxis,
1951 CORBA::Double theAngleInRadians,
1952 CORBA::Long theNbOfSteps,
1953 CORBA::Double theTolerance)
1955 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1957 SMESH::long_array_var anElementsId = theObject->GetIDs();
1958 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1965 if (!myPreviewMode) {
1966 DumpGroupsList(aPythonDump, aGroups);
1967 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
1968 << theObject << ", "
1970 << TVar( theAngleInRadians ) << ", "
1971 << TVar( theNbOfSteps ) << ", "
1972 << TVar( theTolerance ) << " )";
1978 //=======================================================================
1979 //function : extrusionSweep
1981 //=======================================================================
1983 SMESH::ListOfGroups*
1984 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
1985 const SMESH::DirStruct & theStepVector,
1986 CORBA::Long theNbOfSteps,
1988 const SMDSAbs_ElementType theElementType)
1996 TIDSortedElemSet elements, copyElements;
1997 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
1999 const SMESH::PointStruct * P = &theStepVector.PS;
2000 gp_Vec stepVec( P->x, P->y, P->z );
2002 TIDSortedElemSet* workElements = & elements;
2004 SMDSAbs_ElementType aType = SMDSAbs_Face;
2005 //::SMESH_MeshEditor::ExtrusionFlags aFlag = ::SMESH_MeshEditor::ExtrusionFlags::EXTRUSION_FLAG_BOUNDARY;
2006 if (theElementType == SMDSAbs_Node)
2008 aType = SMDSAbs_Edge;
2009 //aFlag = ::SMESH_MeshEditor::ExtrusionFlags::EXTRUSION_FLAG_SEW;
2011 TPreviewMesh tmpMesh( aType );
2012 SMESH_Mesh* mesh = myMesh;
2014 if ( myPreviewMode ) {
2015 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2016 tmpMesh.Copy( elements, copyElements, select, avoid );
2018 workElements = & copyElements;
2019 theMakeGroups = false;
2022 TElemOfElemListMap aHystory;
2023 ::SMESH_MeshEditor anEditor( mesh );
2024 ::SMESH_MeshEditor::PGroupIDs groupIds =
2025 anEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2027 myMesh->GetMeshDS()->Modified();
2028 storeResult(anEditor);
2030 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2032 } catch(Standard_Failure) {
2033 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2034 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
2039 //=======================================================================
2040 //function : ExtrusionSweep
2042 //=======================================================================
2044 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2045 const SMESH::DirStruct & theStepVector,
2046 CORBA::Long theNbOfSteps)
2048 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2049 if (!myPreviewMode) {
2050 TPythonDump() << this << ".ExtrusionSweep( "
2051 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2055 //=======================================================================
2056 //function : ExtrusionSweep0D
2058 //=======================================================================
2060 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2061 const SMESH::DirStruct & theStepVector,
2062 CORBA::Long theNbOfSteps)
2064 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2065 if (!myPreviewMode) {
2066 TPythonDump() << this << ".ExtrusionSweep0D( "
2067 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2071 //=======================================================================
2072 //function : ExtrusionSweepObject
2074 //=======================================================================
2076 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2077 const SMESH::DirStruct & theStepVector,
2078 CORBA::Long theNbOfSteps)
2080 SMESH::long_array_var anElementsId = theObject->GetIDs();
2081 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2082 if (!myPreviewMode) {
2083 TPythonDump() << this << ".ExtrusionSweepObject( "
2084 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2088 //=======================================================================
2089 //function : ExtrusionSweepObject0D
2091 //=======================================================================
2093 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2094 const SMESH::DirStruct & theStepVector,
2095 CORBA::Long theNbOfSteps)
2097 SMESH::long_array_var anElementsId = theObject->GetIDs();
2098 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2099 if ( !myPreviewMode ) {
2100 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2101 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2105 //=======================================================================
2106 //function : ExtrusionSweepObject1D
2108 //=======================================================================
2110 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2111 const SMESH::DirStruct & theStepVector,
2112 CORBA::Long theNbOfSteps)
2114 SMESH::long_array_var anElementsId = theObject->GetIDs();
2115 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2116 if ( !myPreviewMode ) {
2117 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2118 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2122 //=======================================================================
2123 //function : ExtrusionSweepObject2D
2125 //=======================================================================
2127 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2128 const SMESH::DirStruct & theStepVector,
2129 CORBA::Long theNbOfSteps)
2131 SMESH::long_array_var anElementsId = theObject->GetIDs();
2132 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2133 if ( !myPreviewMode ) {
2134 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2135 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2139 //=======================================================================
2140 //function : ExtrusionSweepMakeGroups
2142 //=======================================================================
2144 SMESH::ListOfGroups*
2145 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2146 const SMESH::DirStruct& theStepVector,
2147 CORBA::Long theNbOfSteps)
2149 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2151 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2153 if (!myPreviewMode) {
2154 DumpGroupsList(aPythonDump, aGroups);
2155 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2156 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2161 //=======================================================================
2162 //function : ExtrusionSweepMakeGroups0D
2164 //=======================================================================
2166 SMESH::ListOfGroups*
2167 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2168 const SMESH::DirStruct& theStepVector,
2169 CORBA::Long theNbOfSteps)
2171 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2173 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2175 if (!myPreviewMode) {
2176 DumpGroupsList(aPythonDump, aGroups);
2177 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2178 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2183 //=======================================================================
2184 //function : ExtrusionSweepObjectMakeGroups
2186 //=======================================================================
2188 SMESH::ListOfGroups*
2189 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2190 const SMESH::DirStruct& theStepVector,
2191 CORBA::Long theNbOfSteps)
2193 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2195 SMESH::long_array_var anElementsId = theObject->GetIDs();
2196 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2198 if (!myPreviewMode) {
2199 DumpGroupsList(aPythonDump, aGroups);
2200 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2201 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2206 //=======================================================================
2207 //function : ExtrusionSweepObject0DMakeGroups
2209 //=======================================================================
2211 SMESH::ListOfGroups*
2212 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2213 const SMESH::DirStruct& theStepVector,
2214 CORBA::Long theNbOfSteps)
2216 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2218 SMESH::long_array_var anElementsId = theObject->GetIDs();
2219 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2220 theNbOfSteps, true, SMDSAbs_Node);
2221 if (!myPreviewMode) {
2222 DumpGroupsList(aPythonDump, aGroups);
2223 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2224 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2229 //=======================================================================
2230 //function : ExtrusionSweepObject1DMakeGroups
2232 //=======================================================================
2234 SMESH::ListOfGroups*
2235 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2236 const SMESH::DirStruct& theStepVector,
2237 CORBA::Long theNbOfSteps)
2239 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2241 SMESH::long_array_var anElementsId = theObject->GetIDs();
2242 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2243 theNbOfSteps, true, SMDSAbs_Edge);
2244 if (!myPreviewMode) {
2245 DumpGroupsList(aPythonDump, aGroups);
2246 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2247 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2252 //=======================================================================
2253 //function : ExtrusionSweepObject2DMakeGroups
2255 //=======================================================================
2257 SMESH::ListOfGroups*
2258 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2259 const SMESH::DirStruct& theStepVector,
2260 CORBA::Long theNbOfSteps)
2262 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2264 SMESH::long_array_var anElementsId = theObject->GetIDs();
2265 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2266 theNbOfSteps, true, SMDSAbs_Face);
2267 if (!myPreviewMode) {
2268 DumpGroupsList(aPythonDump, aGroups);
2269 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2270 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2276 //=======================================================================
2277 //function : advancedExtrusion
2279 //=======================================================================
2281 SMESH::ListOfGroups*
2282 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2283 const SMESH::DirStruct & theStepVector,
2284 CORBA::Long theNbOfSteps,
2285 CORBA::Long theExtrFlags,
2286 CORBA::Double theSewTolerance,
2287 const bool theMakeGroups)
2291 TIDSortedElemSet elements;
2292 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2294 const SMESH::PointStruct * P = &theStepVector.PS;
2295 gp_Vec stepVec( P->x, P->y, P->z );
2297 ::SMESH_MeshEditor anEditor( myMesh );
2298 TElemOfElemListMap aHystory;
2299 ::SMESH_MeshEditor::PGroupIDs groupIds =
2300 anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2301 theMakeGroups, theExtrFlags, theSewTolerance);
2302 storeResult(anEditor);
2304 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2307 //=======================================================================
2308 //function : AdvancedExtrusion
2310 //=======================================================================
2312 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2313 const SMESH::DirStruct & theStepVector,
2314 CORBA::Long theNbOfSteps,
2315 CORBA::Long theExtrFlags,
2316 CORBA::Double theSewTolerance)
2318 if ( !myPreviewMode ) {
2319 TPythonDump() << "stepVector = " << theStepVector;
2320 TPythonDump() << this << ".AdvancedExtrusion("
2323 << theNbOfSteps << ","
2324 << theExtrFlags << ", "
2325 << theSewTolerance << " )";
2327 advancedExtrusion( theIDsOfElements,
2335 //=======================================================================
2336 //function : AdvancedExtrusionMakeGroups
2338 //=======================================================================
2339 SMESH::ListOfGroups*
2340 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2341 const SMESH::DirStruct& theStepVector,
2342 CORBA::Long theNbOfSteps,
2343 CORBA::Long theExtrFlags,
2344 CORBA::Double theSewTolerance)
2346 if (!myPreviewMode) {
2347 TPythonDump() << "stepVector = " << theStepVector;
2349 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2351 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2358 if (!myPreviewMode) {
2359 DumpGroupsList(aPythonDump, aGroups);
2360 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2363 << theNbOfSteps << ","
2364 << theExtrFlags << ", "
2365 << theSewTolerance << " )";
2371 //================================================================================
2373 * \brief Convert extrusion error to IDL enum
2375 //================================================================================
2377 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2379 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2383 RETCASE( EXTR_NO_ELEMENTS );
2384 RETCASE( EXTR_PATH_NOT_EDGE );
2385 RETCASE( EXTR_BAD_PATH_SHAPE );
2386 RETCASE( EXTR_BAD_STARTING_NODE );
2387 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2388 RETCASE( EXTR_CANT_GET_TANGENT );
2390 return SMESH::SMESH_MeshEditor::EXTR_OK;
2394 //=======================================================================
2395 //function : extrusionAlongPath
2397 //=======================================================================
2398 SMESH::ListOfGroups*
2399 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2400 SMESH::SMESH_Mesh_ptr thePathMesh,
2401 GEOM::GEOM_Object_ptr thePathShape,
2402 CORBA::Long theNodeStart,
2403 CORBA::Boolean theHasAngles,
2404 const SMESH::double_array & theAngles,
2405 CORBA::Boolean theHasRefPoint,
2406 const SMESH::PointStruct & theRefPoint,
2407 const bool theMakeGroups,
2408 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2409 const SMDSAbs_ElementType theElementType)
2411 MESSAGE("extrusionAlongPath");
2414 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2415 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2418 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2420 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2421 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2423 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2424 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2428 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2430 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2434 TIDSortedElemSet elements;
2435 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2437 list<double> angles;
2438 for (int i = 0; i < theAngles.length(); i++) {
2439 angles.push_back( theAngles[i] );
2442 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2444 int nbOldGroups = myMesh->NbGroup();
2446 ::SMESH_MeshEditor anEditor( myMesh );
2447 ::SMESH_MeshEditor::Extrusion_Error error =
2448 anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2449 theHasAngles, angles, false,
2450 theHasRefPoint, refPnt, theMakeGroups );
2451 myMesh->GetMeshDS()->Modified();
2452 storeResult(anEditor);
2453 theError = convExtrError( error );
2455 if ( theMakeGroups ) {
2456 list<int> groupIDs = myMesh->GetGroupIds();
2457 list<int>::iterator newBegin = groupIDs.begin();
2458 std::advance( newBegin, nbOldGroups ); // skip old groups
2459 groupIDs.erase( groupIDs.begin(), newBegin );
2460 return getGroups( & groupIDs );
2466 //=======================================================================
2467 //function : extrusionAlongPathX
2469 //=======================================================================
2470 SMESH::ListOfGroups*
2471 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2472 SMESH::SMESH_IDSource_ptr Path,
2473 CORBA::Long NodeStart,
2474 CORBA::Boolean HasAngles,
2475 const SMESH::double_array& Angles,
2476 CORBA::Boolean LinearVariation,
2477 CORBA::Boolean HasRefPoint,
2478 const SMESH::PointStruct& RefPoint,
2480 const SMDSAbs_ElementType ElementType,
2481 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2483 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2487 list<double> angles;
2488 for (int i = 0; i < Angles.length(); i++) {
2489 angles.push_back( Angles[i] );
2491 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2492 int nbOldGroups = myMesh->NbGroup();
2494 if ( Path->_is_nil() ) {
2495 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2499 TIDSortedElemSet elements, copyElements;
2500 arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
2502 TIDSortedElemSet* workElements = &elements;
2503 TPreviewMesh tmpMesh( SMDSAbs_Face );
2504 SMESH_Mesh* mesh = myMesh;
2506 if ( myPreviewMode )
2508 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2509 tmpMesh.Copy( elements, copyElements, select, avoid );
2511 workElements = & copyElements;
2515 ::SMESH_MeshEditor anEditor( mesh );
2516 ::SMESH_MeshEditor::Extrusion_Error error;
2518 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2521 SMDS_MeshNode* aNodeStart =
2522 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2523 if ( !aNodeStart ) {
2524 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2527 error = anEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2528 HasAngles, angles, LinearVariation,
2529 HasRefPoint, refPnt, MakeGroups );
2530 myMesh->GetMeshDS()->Modified();
2532 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2535 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2536 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2537 SMDS_MeshNode* aNodeStart =
2538 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2539 if ( !aNodeStart ) {
2540 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2543 SMESH_subMesh* aSubMesh =
2544 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2545 error = anEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2546 HasAngles, angles, LinearVariation,
2547 HasRefPoint, refPnt, MakeGroups );
2548 myMesh->GetMeshDS()->Modified();
2550 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2552 // path as group of 1D elements
2558 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2562 storeResult(anEditor);
2563 Error = convExtrError( error );
2566 list<int> groupIDs = myMesh->GetGroupIds();
2567 list<int>::iterator newBegin = groupIDs.begin();
2568 std::advance( newBegin, nbOldGroups ); // skip old groups
2569 groupIDs.erase( groupIDs.begin(), newBegin );
2570 return getGroups( & groupIDs );
2576 //=======================================================================
2577 //function : ExtrusionAlongPath
2579 //=======================================================================
2580 SMESH::SMESH_MeshEditor::Extrusion_Error
2581 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2582 SMESH::SMESH_Mesh_ptr thePathMesh,
2583 GEOM::GEOM_Object_ptr thePathShape,
2584 CORBA::Long theNodeStart,
2585 CORBA::Boolean theHasAngles,
2586 const SMESH::double_array & theAngles,
2587 CORBA::Boolean theHasRefPoint,
2588 const SMESH::PointStruct & theRefPoint)
2590 MESSAGE("ExtrusionAlongPath");
2591 if ( !myPreviewMode ) {
2592 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2593 << theIDsOfElements << ", "
2594 << thePathMesh << ", "
2595 << thePathShape << ", "
2596 << theNodeStart << ", "
2597 << theHasAngles << ", "
2598 << theAngles << ", "
2599 << theHasRefPoint << ", "
2600 << "SMESH.PointStruct( "
2601 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2602 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2603 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2605 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2606 extrusionAlongPath( theIDsOfElements,
2619 //=======================================================================
2620 //function : ExtrusionAlongPathObject
2622 //=======================================================================
2623 SMESH::SMESH_MeshEditor::Extrusion_Error
2624 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2625 SMESH::SMESH_Mesh_ptr thePathMesh,
2626 GEOM::GEOM_Object_ptr thePathShape,
2627 CORBA::Long theNodeStart,
2628 CORBA::Boolean theHasAngles,
2629 const SMESH::double_array & theAngles,
2630 CORBA::Boolean theHasRefPoint,
2631 const SMESH::PointStruct & theRefPoint)
2633 if ( !myPreviewMode ) {
2634 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2635 << theObject << ", "
2636 << thePathMesh << ", "
2637 << thePathShape << ", "
2638 << theNodeStart << ", "
2639 << theHasAngles << ", "
2640 << theAngles << ", "
2641 << theHasRefPoint << ", "
2642 << "SMESH.PointStruct( "
2643 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2644 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2645 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2647 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2648 SMESH::long_array_var anElementsId = theObject->GetIDs();
2649 extrusionAlongPath( anElementsId,
2662 //=======================================================================
2663 //function : ExtrusionAlongPathObject1D
2665 //=======================================================================
2666 SMESH::SMESH_MeshEditor::Extrusion_Error
2667 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2668 SMESH::SMESH_Mesh_ptr thePathMesh,
2669 GEOM::GEOM_Object_ptr thePathShape,
2670 CORBA::Long theNodeStart,
2671 CORBA::Boolean theHasAngles,
2672 const SMESH::double_array & theAngles,
2673 CORBA::Boolean theHasRefPoint,
2674 const SMESH::PointStruct & theRefPoint)
2676 if ( !myPreviewMode ) {
2677 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2678 << theObject << ", "
2679 << thePathMesh << ", "
2680 << thePathShape << ", "
2681 << theNodeStart << ", "
2682 << theHasAngles << ", "
2683 << theAngles << ", "
2684 << theHasRefPoint << ", "
2685 << "SMESH.PointStruct( "
2686 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2687 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2688 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2690 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2691 SMESH::long_array_var anElementsId = theObject->GetIDs();
2692 extrusionAlongPath( anElementsId,
2706 //=======================================================================
2707 //function : ExtrusionAlongPathObject2D
2709 //=======================================================================
2710 SMESH::SMESH_MeshEditor::Extrusion_Error
2711 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
2712 SMESH::SMESH_Mesh_ptr thePathMesh,
2713 GEOM::GEOM_Object_ptr thePathShape,
2714 CORBA::Long theNodeStart,
2715 CORBA::Boolean theHasAngles,
2716 const SMESH::double_array & theAngles,
2717 CORBA::Boolean theHasRefPoint,
2718 const SMESH::PointStruct & theRefPoint)
2720 if ( !myPreviewMode ) {
2721 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
2722 << theObject << ", "
2723 << thePathMesh << ", "
2724 << thePathShape << ", "
2725 << theNodeStart << ", "
2726 << theHasAngles << ", "
2727 << theAngles << ", "
2728 << theHasRefPoint << ", "
2729 << "SMESH.PointStruct( "
2730 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2731 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2732 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2734 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2735 SMESH::long_array_var anElementsId = theObject->GetIDs();
2736 extrusionAlongPath( anElementsId,
2751 //=======================================================================
2752 //function : ExtrusionAlongPathMakeGroups
2754 //=======================================================================
2755 SMESH::ListOfGroups*
2756 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
2757 SMESH::SMESH_Mesh_ptr thePathMesh,
2758 GEOM::GEOM_Object_ptr thePathShape,
2759 CORBA::Long theNodeStart,
2760 CORBA::Boolean theHasAngles,
2761 const SMESH::double_array& theAngles,
2762 CORBA::Boolean theHasRefPoint,
2763 const SMESH::PointStruct& theRefPoint,
2764 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2766 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2768 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
2778 if (!myPreviewMode) {
2779 bool isDumpGroups = aGroups && aGroups->length() > 0;
2781 aPythonDump << "(" << aGroups << ", error)";
2783 aPythonDump <<"error";
2785 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
2786 << theIDsOfElements << ", "
2787 << thePathMesh << ", "
2788 << thePathShape << ", "
2789 << theNodeStart << ", "
2790 << theHasAngles << ", "
2791 << theAngles << ", "
2792 << theHasRefPoint << ", "
2793 << "SMESH.PointStruct( "
2794 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2795 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2796 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2801 //=======================================================================
2802 //function : ExtrusionAlongPathObjectMakeGroups
2804 //=======================================================================
2805 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2806 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2807 SMESH::SMESH_Mesh_ptr thePathMesh,
2808 GEOM::GEOM_Object_ptr thePathShape,
2809 CORBA::Long theNodeStart,
2810 CORBA::Boolean theHasAngles,
2811 const SMESH::double_array& theAngles,
2812 CORBA::Boolean theHasRefPoint,
2813 const SMESH::PointStruct& theRefPoint,
2814 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2816 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2818 SMESH::long_array_var anElementsId = theObject->GetIDs();
2819 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2830 if (!myPreviewMode) {
2831 bool isDumpGroups = aGroups && aGroups->length() > 0;
2833 aPythonDump << "(" << aGroups << ", error)";
2835 aPythonDump <<"error";
2837 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
2838 << theObject << ", "
2839 << thePathMesh << ", "
2840 << thePathShape << ", "
2841 << theNodeStart << ", "
2842 << theHasAngles << ", "
2843 << theAngles << ", "
2844 << theHasRefPoint << ", "
2845 << "SMESH.PointStruct( "
2846 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2847 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2848 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2853 //=======================================================================
2854 //function : ExtrusionAlongPathObject1DMakeGroups
2856 //=======================================================================
2857 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2858 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2859 SMESH::SMESH_Mesh_ptr thePathMesh,
2860 GEOM::GEOM_Object_ptr thePathShape,
2861 CORBA::Long theNodeStart,
2862 CORBA::Boolean theHasAngles,
2863 const SMESH::double_array& theAngles,
2864 CORBA::Boolean theHasRefPoint,
2865 const SMESH::PointStruct& theRefPoint,
2866 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2868 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2870 SMESH::long_array_var anElementsId = theObject->GetIDs();
2871 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2883 if (!myPreviewMode) {
2884 bool isDumpGroups = aGroups && aGroups->length() > 0;
2886 aPythonDump << "(" << aGroups << ", error)";
2888 aPythonDump << "error";
2890 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
2891 << theObject << ", "
2892 << thePathMesh << ", "
2893 << thePathShape << ", "
2894 << theNodeStart << ", "
2895 << theHasAngles << ", "
2896 << theAngles << ", "
2897 << theHasRefPoint << ", "
2898 << "SMESH.PointStruct( "
2899 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2900 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2901 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2906 //=======================================================================
2907 //function : ExtrusionAlongPathObject2DMakeGroups
2909 //=======================================================================
2910 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2911 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2912 SMESH::SMESH_Mesh_ptr thePathMesh,
2913 GEOM::GEOM_Object_ptr thePathShape,
2914 CORBA::Long theNodeStart,
2915 CORBA::Boolean theHasAngles,
2916 const SMESH::double_array& theAngles,
2917 CORBA::Boolean theHasRefPoint,
2918 const SMESH::PointStruct& theRefPoint,
2919 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2921 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2923 SMESH::long_array_var anElementsId = theObject->GetIDs();
2924 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2936 if (!myPreviewMode) {
2937 bool isDumpGroups = aGroups && aGroups->length() > 0;
2939 aPythonDump << "(" << aGroups << ", error)";
2941 aPythonDump << "error";
2943 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
2944 << theObject << ", "
2945 << thePathMesh << ", "
2946 << thePathShape << ", "
2947 << theNodeStart << ", "
2948 << theHasAngles << ", "
2949 << theAngles << ", "
2950 << theHasRefPoint << ", "
2951 << "SMESH.PointStruct( "
2952 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2953 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2954 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2960 //=======================================================================
2961 //function : ExtrusionAlongPathObjX
2963 //=======================================================================
2964 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2965 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
2966 SMESH::SMESH_IDSource_ptr Path,
2967 CORBA::Long NodeStart,
2968 CORBA::Boolean HasAngles,
2969 const SMESH::double_array& Angles,
2970 CORBA::Boolean LinearVariation,
2971 CORBA::Boolean HasRefPoint,
2972 const SMESH::PointStruct& RefPoint,
2973 CORBA::Boolean MakeGroups,
2974 SMESH::ElementType ElemType,
2975 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2977 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2979 SMESH::long_array_var anElementsId = Object->GetIDs();
2980 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
2989 (SMDSAbs_ElementType)ElemType,
2992 if (!myPreviewMode) {
2993 bool isDumpGroups = aGroups && aGroups->length() > 0;
2995 aPythonDump << "(" << *aGroups << ", error)";
2997 aPythonDump << "error";
2999 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3002 << NodeStart << ", "
3003 << HasAngles << ", "
3004 << TVar( Angles ) << ", "
3005 << LinearVariation << ", "
3006 << HasRefPoint << ", "
3007 << "SMESH.PointStruct( "
3008 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3009 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3010 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3011 << MakeGroups << ", "
3012 << ElemType << " )";
3018 //=======================================================================
3019 //function : ExtrusionAlongPathX
3021 //=======================================================================
3022 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3023 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3024 SMESH::SMESH_IDSource_ptr Path,
3025 CORBA::Long NodeStart,
3026 CORBA::Boolean HasAngles,
3027 const SMESH::double_array& Angles,
3028 CORBA::Boolean LinearVariation,
3029 CORBA::Boolean HasRefPoint,
3030 const SMESH::PointStruct& RefPoint,
3031 CORBA::Boolean MakeGroups,
3032 SMESH::ElementType ElemType,
3033 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3035 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3037 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3046 (SMDSAbs_ElementType)ElemType,
3049 if (!myPreviewMode) {
3050 bool isDumpGroups = aGroups && aGroups->length() > 0;
3052 aPythonDump << "(" << *aGroups << ", error)";
3054 aPythonDump <<"error";
3056 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3057 << IDsOfElements << ", "
3059 << NodeStart << ", "
3060 << HasAngles << ", "
3061 << TVar( Angles ) << ", "
3062 << LinearVariation << ", "
3063 << HasRefPoint << ", "
3064 << "SMESH.PointStruct( "
3065 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3066 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3067 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3068 << MakeGroups << ", "
3069 << ElemType << " )";
3075 //================================================================================
3077 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3078 * of given angles along path steps
3079 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3080 * which proceeds the extrusion
3081 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3082 * is used to define the sub-mesh for the path
3084 //================================================================================
3086 SMESH::double_array*
3087 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3088 GEOM::GEOM_Object_ptr thePathShape,
3089 const SMESH::double_array & theAngles)
3091 SMESH::double_array_var aResult = new SMESH::double_array();
3092 int nbAngles = theAngles.length();
3093 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3095 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3096 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3097 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3098 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3099 return aResult._retn();
3100 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3101 if ( nbSteps == nbAngles )
3103 aResult.inout() = theAngles;
3107 aResult->length( nbSteps );
3108 double rAn2St = double( nbAngles ) / double( nbSteps );
3109 double angPrev = 0, angle;
3110 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3112 double angCur = rAn2St * ( iSt+1 );
3113 double angCurFloor = floor( angCur );
3114 double angPrevFloor = floor( angPrev );
3115 if ( angPrevFloor == angCurFloor )
3116 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3119 int iP = int( angPrevFloor );
3120 double angPrevCeil = ceil(angPrev);
3121 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3123 int iC = int( angCurFloor );
3124 if ( iC < nbAngles )
3125 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3127 iP = int( angPrevCeil );
3129 angle += theAngles[ iC ];
3131 aResult[ iSt ] = angle;
3136 // Update Python script
3137 TPythonDump() << "rotAngles = " << theAngles;
3138 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3139 << thePathMesh << ", "
3140 << thePathShape << ", "
3143 return aResult._retn();
3147 //=======================================================================
3150 //=======================================================================
3152 SMESH::ListOfGroups*
3153 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3154 const SMESH::AxisStruct & theAxis,
3155 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3156 CORBA::Boolean theCopy,
3158 ::SMESH_Mesh* theTargetMesh)
3162 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3163 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3165 if ( theTargetMesh )
3169 switch ( theMirrorType ) {
3170 case SMESH::SMESH_MeshEditor::POINT:
3171 aTrsf.SetMirror( P );
3173 case SMESH::SMESH_MeshEditor::AXIS:
3174 aTrsf.SetMirror( gp_Ax1( P, V ));
3177 aTrsf.SetMirror( gp_Ax2( P, V ));
3180 TIDSortedElemSet copyElements;
3181 TPreviewMesh tmpMesh;
3182 TIDSortedElemSet* workElements = & theElements;
3183 SMESH_Mesh* mesh = myMesh;
3185 if ( myPreviewMode )
3187 tmpMesh.Copy( theElements, copyElements);
3188 if ( !theCopy && !theTargetMesh )
3190 TIDSortedElemSet elemsAround, elemsAroundCopy;
3191 getElementsAround( theElements, GetMeshDS(), elemsAround );
3192 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3195 workElements = & copyElements;
3196 theMakeGroups = false;
3199 ::SMESH_MeshEditor anEditor( mesh );
3200 ::SMESH_MeshEditor::PGroupIDs groupIds =
3201 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3203 if(theCopy || myPreviewMode)
3204 storeResult(anEditor); // store preview data or new elements
3206 if ( !myPreviewMode )
3208 if ( theTargetMesh )
3210 theTargetMesh->GetMeshDS()->Modified();
3214 myMesh->GetMeshDS()->Modified();
3215 myMesh->SetIsModified( true );
3218 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3221 //=======================================================================
3224 //=======================================================================
3226 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3227 const SMESH::AxisStruct & theAxis,
3228 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3229 CORBA::Boolean theCopy)
3231 if ( !myPreviewMode ) {
3232 TPythonDump() << this << ".Mirror( "
3233 << theIDsOfElements << ", "
3235 << mirrorTypeName(theMirrorType) << ", "
3238 if ( theIDsOfElements.length() > 0 )
3240 TIDSortedElemSet elements;
3241 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3242 mirror(elements, theAxis, theMirrorType, theCopy, false);
3247 //=======================================================================
3248 //function : MirrorObject
3250 //=======================================================================
3252 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3253 const SMESH::AxisStruct & theAxis,
3254 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3255 CORBA::Boolean theCopy)
3257 if ( !myPreviewMode ) {
3258 TPythonDump() << this << ".MirrorObject( "
3259 << theObject << ", "
3261 << mirrorTypeName(theMirrorType) << ", "
3264 TIDSortedElemSet elements;
3266 bool emptyIfIsMesh = myPreviewMode ? false : true;
3268 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3269 mirror(elements, theAxis, theMirrorType, theCopy, false);
3272 //=======================================================================
3273 //function : MirrorMakeGroups
3275 //=======================================================================
3277 SMESH::ListOfGroups*
3278 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3279 const SMESH::AxisStruct& theMirror,
3280 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3282 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3284 SMESH::ListOfGroups * aGroups = 0;
3285 if ( theIDsOfElements.length() > 0 )
3287 TIDSortedElemSet elements;
3288 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3289 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3291 if (!myPreviewMode) {
3292 DumpGroupsList(aPythonDump, aGroups);
3293 aPythonDump << this << ".MirrorMakeGroups( "
3294 << theIDsOfElements << ", "
3295 << theMirror << ", "
3296 << mirrorTypeName(theMirrorType) << " )";
3301 //=======================================================================
3302 //function : MirrorObjectMakeGroups
3304 //=======================================================================
3306 SMESH::ListOfGroups*
3307 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3308 const SMESH::AxisStruct& theMirror,
3309 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3311 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3313 SMESH::ListOfGroups * aGroups = 0;
3314 TIDSortedElemSet elements;
3315 if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3316 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3320 DumpGroupsList(aPythonDump,aGroups);
3321 aPythonDump << this << ".MirrorObjectMakeGroups( "
3322 << theObject << ", "
3323 << theMirror << ", "
3324 << mirrorTypeName(theMirrorType) << " )";
3329 //=======================================================================
3330 //function : MirrorMakeMesh
3332 //=======================================================================
3334 SMESH::SMESH_Mesh_ptr
3335 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3336 const SMESH::AxisStruct& theMirror,
3337 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3338 CORBA::Boolean theCopyGroups,
3339 const char* theMeshName)
3341 SMESH_Mesh_i* mesh_i;
3342 SMESH::SMESH_Mesh_var mesh;
3343 { // open new scope to dump "MakeMesh" command
3344 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3346 TPythonDump pydump; // to prevent dump at mesh creation
3348 mesh = makeMesh( theMeshName );
3349 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3350 if (mesh_i && theIDsOfElements.length() > 0 )
3352 TIDSortedElemSet elements;
3353 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3354 mirror(elements, theMirror, theMirrorType,
3355 false, theCopyGroups, & mesh_i->GetImpl());
3356 mesh_i->CreateGroupServants();
3359 if (!myPreviewMode) {
3360 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3361 << theIDsOfElements << ", "
3362 << theMirror << ", "
3363 << mirrorTypeName(theMirrorType) << ", "
3364 << theCopyGroups << ", '"
3365 << theMeshName << "' )";
3370 if (!myPreviewMode && mesh_i)
3371 mesh_i->GetGroups();
3373 return mesh._retn();
3376 //=======================================================================
3377 //function : MirrorObjectMakeMesh
3379 //=======================================================================
3381 SMESH::SMESH_Mesh_ptr
3382 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3383 const SMESH::AxisStruct& theMirror,
3384 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3385 CORBA::Boolean theCopyGroups,
3386 const char* theMeshName)
3388 SMESH_Mesh_i* mesh_i;
3389 SMESH::SMESH_Mesh_var mesh;
3390 { // open new scope to dump "MakeMesh" command
3391 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3393 TPythonDump pydump; // to prevent dump at mesh creation
3395 mesh = makeMesh( theMeshName );
3396 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3397 TIDSortedElemSet elements;
3399 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3401 mirror(elements, theMirror, theMirrorType,
3402 false, theCopyGroups, & mesh_i->GetImpl());
3403 mesh_i->CreateGroupServants();
3405 if (!myPreviewMode) {
3406 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3407 << theObject << ", "
3408 << theMirror << ", "
3409 << mirrorTypeName(theMirrorType) << ", "
3410 << theCopyGroups << ", '"
3411 << theMeshName << "' )";
3416 if (!myPreviewMode && mesh_i)
3417 mesh_i->GetGroups();
3419 return mesh._retn();
3422 //=======================================================================
3423 //function : translate
3425 //=======================================================================
3427 SMESH::ListOfGroups*
3428 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3429 const SMESH::DirStruct & theVector,
3430 CORBA::Boolean theCopy,
3432 ::SMESH_Mesh* theTargetMesh)
3436 if ( theTargetMesh )
3440 const SMESH::PointStruct * P = &theVector.PS;
3441 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3443 TIDSortedElemSet copyElements;
3444 TIDSortedElemSet* workElements = &theElements;
3445 TPreviewMesh tmpMesh;
3446 SMESH_Mesh* mesh = myMesh;
3448 if ( myPreviewMode )
3450 tmpMesh.Copy( theElements, copyElements);
3451 if ( !theCopy && !theTargetMesh )
3453 TIDSortedElemSet elemsAround, elemsAroundCopy;
3454 getElementsAround( theElements, GetMeshDS(), elemsAround );
3455 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3458 workElements = & copyElements;
3459 theMakeGroups = false;
3462 ::SMESH_MeshEditor anEditor( mesh );
3463 ::SMESH_MeshEditor::PGroupIDs groupIds =
3464 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3466 if(theCopy || myPreviewMode)
3467 storeResult(anEditor);
3469 if ( !myPreviewMode )
3471 if ( theTargetMesh )
3473 theTargetMesh->GetMeshDS()->Modified();
3477 myMesh->GetMeshDS()->Modified();
3478 myMesh->SetIsModified( true );
3482 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3485 //=======================================================================
3486 //function : Translate
3488 //=======================================================================
3490 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3491 const SMESH::DirStruct & theVector,
3492 CORBA::Boolean theCopy)
3494 if (!myPreviewMode) {
3495 TPythonDump() << this << ".Translate( "
3496 << theIDsOfElements << ", "
3497 << theVector << ", "
3500 if (theIDsOfElements.length()) {
3501 TIDSortedElemSet elements;
3502 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3503 translate(elements, theVector, theCopy, false);
3507 //=======================================================================
3508 //function : TranslateObject
3510 //=======================================================================
3512 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3513 const SMESH::DirStruct & theVector,
3514 CORBA::Boolean theCopy)
3516 if (!myPreviewMode) {
3517 TPythonDump() << this << ".TranslateObject( "
3518 << theObject << ", "
3519 << theVector << ", "
3522 TIDSortedElemSet elements;
3524 bool emptyIfIsMesh = myPreviewMode ? false : true;
3526 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3527 translate(elements, theVector, theCopy, false);
3530 //=======================================================================
3531 //function : TranslateMakeGroups
3533 //=======================================================================
3535 SMESH::ListOfGroups*
3536 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3537 const SMESH::DirStruct& theVector)
3539 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3541 SMESH::ListOfGroups * aGroups = 0;
3542 if (theIDsOfElements.length()) {
3543 TIDSortedElemSet elements;
3544 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3545 aGroups = translate(elements,theVector,true,true);
3547 if (!myPreviewMode) {
3548 DumpGroupsList(aPythonDump, aGroups);
3549 aPythonDump << this << ".TranslateMakeGroups( "
3550 << theIDsOfElements << ", "
3551 << theVector << " )";
3556 //=======================================================================
3557 //function : TranslateObjectMakeGroups
3559 //=======================================================================
3561 SMESH::ListOfGroups*
3562 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3563 const SMESH::DirStruct& theVector)
3565 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3567 SMESH::ListOfGroups * aGroups = 0;
3568 TIDSortedElemSet elements;
3569 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3570 aGroups = translate(elements, theVector, true, true);
3572 if (!myPreviewMode) {
3573 DumpGroupsList(aPythonDump, aGroups);
3574 aPythonDump << this << ".TranslateObjectMakeGroups( "
3575 << theObject << ", "
3576 << theVector << " )";
3581 //=======================================================================
3582 //function : TranslateMakeMesh
3584 //=======================================================================
3586 SMESH::SMESH_Mesh_ptr
3587 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3588 const SMESH::DirStruct& theVector,
3589 CORBA::Boolean theCopyGroups,
3590 const char* theMeshName)
3592 SMESH_Mesh_i* mesh_i;
3593 SMESH::SMESH_Mesh_var mesh;
3595 { // open new scope to dump "MakeMesh" command
3596 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3598 TPythonDump pydump; // to prevent dump at mesh creation
3600 mesh = makeMesh( theMeshName );
3601 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3603 if ( mesh_i && theIDsOfElements.length() )
3605 TIDSortedElemSet elements;
3606 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3607 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3608 mesh_i->CreateGroupServants();
3611 if ( !myPreviewMode ) {
3612 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3613 << theIDsOfElements << ", "
3614 << theVector << ", "
3615 << theCopyGroups << ", '"
3616 << theMeshName << "' )";
3621 if (!myPreviewMode && mesh_i)
3622 mesh_i->GetGroups();
3624 return mesh._retn();
3627 //=======================================================================
3628 //function : TranslateObjectMakeMesh
3630 //=======================================================================
3632 SMESH::SMESH_Mesh_ptr
3633 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3634 const SMESH::DirStruct& theVector,
3635 CORBA::Boolean theCopyGroups,
3636 const char* theMeshName)
3638 SMESH_Mesh_i* mesh_i;
3639 SMESH::SMESH_Mesh_var mesh;
3640 { // open new scope to dump "MakeMesh" command
3641 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3643 TPythonDump pydump; // to prevent dump at mesh creation
3644 mesh = makeMesh( theMeshName );
3645 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3647 TIDSortedElemSet elements;
3649 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3651 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3652 mesh_i->CreateGroupServants();
3654 if ( !myPreviewMode ) {
3655 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3656 << theObject << ", "
3657 << theVector << ", "
3658 << theCopyGroups << ", '"
3659 << theMeshName << "' )";
3664 if (!myPreviewMode && mesh_i)
3665 mesh_i->GetGroups();
3667 return mesh._retn();
3670 //=======================================================================
3673 //=======================================================================
3675 SMESH::ListOfGroups*
3676 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3677 const SMESH::AxisStruct & theAxis,
3678 CORBA::Double theAngle,
3679 CORBA::Boolean theCopy,
3681 ::SMESH_Mesh* theTargetMesh)
3685 if ( theTargetMesh )
3688 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3689 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3692 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3694 TIDSortedElemSet copyElements;
3695 TIDSortedElemSet* workElements = &theElements;
3696 TPreviewMesh tmpMesh;
3697 SMESH_Mesh* mesh = myMesh;
3699 if ( myPreviewMode ) {
3700 tmpMesh.Copy( theElements, copyElements );
3701 if ( !theCopy && !theTargetMesh )
3703 TIDSortedElemSet elemsAround, elemsAroundCopy;
3704 getElementsAround( theElements, GetMeshDS(), elemsAround );
3705 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3708 workElements = ©Elements;
3709 theMakeGroups = false;
3712 ::SMESH_MeshEditor anEditor( mesh );
3713 ::SMESH_MeshEditor::PGroupIDs groupIds =
3714 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3716 if(theCopy || myPreviewMode)
3717 storeResult(anEditor);
3719 if ( !myPreviewMode )
3721 if ( theTargetMesh )
3723 theTargetMesh->GetMeshDS()->Modified();
3727 myMesh->GetMeshDS()->Modified();
3728 myMesh->SetIsModified( true );
3732 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3735 //=======================================================================
3738 //=======================================================================
3740 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3741 const SMESH::AxisStruct & theAxis,
3742 CORBA::Double theAngle,
3743 CORBA::Boolean theCopy)
3745 if (!myPreviewMode) {
3746 TPythonDump() << this << ".Rotate( "
3747 << theIDsOfElements << ", "
3749 << TVar( theAngle ) << ", "
3752 if (theIDsOfElements.length() > 0)
3754 TIDSortedElemSet elements;
3755 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3756 rotate(elements,theAxis,theAngle,theCopy,false);
3760 //=======================================================================
3761 //function : RotateObject
3763 //=======================================================================
3765 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3766 const SMESH::AxisStruct & theAxis,
3767 CORBA::Double theAngle,
3768 CORBA::Boolean theCopy)
3770 if ( !myPreviewMode ) {
3771 TPythonDump() << this << ".RotateObject( "
3772 << theObject << ", "
3774 << TVar( theAngle ) << ", "
3777 TIDSortedElemSet elements;
3778 bool emptyIfIsMesh = myPreviewMode ? false : true;
3779 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3780 rotate(elements,theAxis,theAngle,theCopy,false);
3783 //=======================================================================
3784 //function : RotateMakeGroups
3786 //=======================================================================
3788 SMESH::ListOfGroups*
3789 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3790 const SMESH::AxisStruct& theAxis,
3791 CORBA::Double theAngle)
3793 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3795 SMESH::ListOfGroups * aGroups = 0;
3796 if (theIDsOfElements.length() > 0)
3798 TIDSortedElemSet elements;
3799 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3800 aGroups = rotate(elements,theAxis,theAngle,true,true);
3802 if (!myPreviewMode) {
3803 DumpGroupsList(aPythonDump, aGroups);
3804 aPythonDump << this << ".RotateMakeGroups( "
3805 << theIDsOfElements << ", "
3807 << TVar( theAngle ) << " )";
3812 //=======================================================================
3813 //function : RotateObjectMakeGroups
3815 //=======================================================================
3817 SMESH::ListOfGroups*
3818 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3819 const SMESH::AxisStruct& theAxis,
3820 CORBA::Double theAngle)
3822 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3824 SMESH::ListOfGroups * aGroups = 0;
3825 TIDSortedElemSet elements;
3826 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3827 aGroups = rotate(elements, theAxis, theAngle, true, true);
3829 if (!myPreviewMode) {
3830 DumpGroupsList(aPythonDump, aGroups);
3831 aPythonDump << this << ".RotateObjectMakeGroups( "
3832 << theObject << ", "
3834 << TVar( theAngle ) << " )";
3839 //=======================================================================
3840 //function : RotateMakeMesh
3842 //=======================================================================
3844 SMESH::SMESH_Mesh_ptr
3845 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3846 const SMESH::AxisStruct& theAxis,
3847 CORBA::Double theAngleInRadians,
3848 CORBA::Boolean theCopyGroups,
3849 const char* theMeshName)
3851 SMESH::SMESH_Mesh_var mesh;
3852 SMESH_Mesh_i* mesh_i;
3854 { // open new scope to dump "MakeMesh" command
3855 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3857 TPythonDump pydump; // to prevent dump at mesh creation
3859 mesh = makeMesh( theMeshName );
3860 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3862 if ( mesh_i && theIDsOfElements.length() > 0 )
3864 TIDSortedElemSet elements;
3865 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3866 rotate(elements, theAxis, theAngleInRadians,
3867 false, theCopyGroups, & mesh_i->GetImpl());
3868 mesh_i->CreateGroupServants();
3870 if ( !myPreviewMode ) {
3871 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3872 << theIDsOfElements << ", "
3874 << TVar( theAngleInRadians ) << ", "
3875 << theCopyGroups << ", '"
3876 << theMeshName << "' )";
3881 if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3882 mesh_i->GetGroups();
3884 return mesh._retn();
3887 //=======================================================================
3888 //function : RotateObjectMakeMesh
3890 //=======================================================================
3892 SMESH::SMESH_Mesh_ptr
3893 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3894 const SMESH::AxisStruct& theAxis,
3895 CORBA::Double theAngleInRadians,
3896 CORBA::Boolean theCopyGroups,
3897 const char* theMeshName)
3899 SMESH::SMESH_Mesh_var mesh;
3900 SMESH_Mesh_i* mesh_i;
3902 {// open new scope to dump "MakeMesh" command
3903 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3905 TPythonDump pydump; // to prevent dump at mesh creation
3906 mesh = makeMesh( theMeshName );
3907 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3909 TIDSortedElemSet elements;
3911 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3913 rotate(elements, theAxis, theAngleInRadians,
3914 false, theCopyGroups, & mesh_i->GetImpl());
3915 mesh_i->CreateGroupServants();
3917 if ( !myPreviewMode ) {
3918 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3919 << theObject << ", "
3921 << TVar( theAngleInRadians ) << ", "
3922 << theCopyGroups << ", '"
3923 << theMeshName << "' )";
3928 if (!myPreviewMode && mesh_i)
3929 mesh_i->GetGroups();
3931 return mesh._retn();
3934 //=======================================================================
3937 //=======================================================================
3939 SMESH::ListOfGroups*
3940 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3941 const SMESH::PointStruct& thePoint,
3942 const SMESH::double_array& theScaleFact,
3943 CORBA::Boolean theCopy,
3945 ::SMESH_Mesh* theTargetMesh)
3948 if ( theScaleFact.length() < 1 )
3949 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3950 if ( theScaleFact.length() == 2 )
3951 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3953 if ( theTargetMesh )
3956 TIDSortedElemSet elements;
3957 bool emptyIfIsMesh = myPreviewMode ? false : true;
3958 if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3963 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3964 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3966 double tol = std::numeric_limits<double>::max();
3968 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3969 0, S[1], 0, thePoint.y * (1-S[1]),
3970 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3972 TIDSortedElemSet copyElements;
3973 TPreviewMesh tmpMesh;
3974 TIDSortedElemSet* workElements = &elements;
3975 SMESH_Mesh* mesh = myMesh;
3977 if ( myPreviewMode )
3979 tmpMesh.Copy( elements, copyElements);
3980 if ( !theCopy && !theTargetMesh )
3982 TIDSortedElemSet elemsAround, elemsAroundCopy;
3983 getElementsAround( elements, GetMeshDS(), elemsAround );
3984 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3987 workElements = & copyElements;
3988 theMakeGroups = false;
3991 ::SMESH_MeshEditor anEditor( mesh );
3992 ::SMESH_MeshEditor::PGroupIDs groupIds =
3993 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3995 if(theCopy || myPreviewMode )
3996 storeResult(anEditor);
3998 if ( !myPreviewMode )
4000 if ( theTargetMesh )
4002 theTargetMesh->GetMeshDS()->Modified();
4006 myMesh->GetMeshDS()->Modified();
4007 myMesh->SetIsModified( true );
4011 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4014 //=======================================================================
4017 //=======================================================================
4019 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4020 const SMESH::PointStruct& thePoint,
4021 const SMESH::double_array& theScaleFact,
4022 CORBA::Boolean theCopy)
4024 if ( !myPreviewMode ) {
4025 TPythonDump() << this << ".Scale( "
4026 << theObject << ", "
4028 << TVar( theScaleFact ) << ", "
4031 scale(theObject, thePoint, theScaleFact, theCopy, false);
4035 //=======================================================================
4036 //function : ScaleMakeGroups
4038 //=======================================================================
4040 SMESH::ListOfGroups*
4041 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4042 const SMESH::PointStruct& thePoint,
4043 const SMESH::double_array& theScaleFact)
4045 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4047 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4048 if (!myPreviewMode) {
4049 DumpGroupsList(aPythonDump, aGroups);
4050 aPythonDump << this << ".Scale("
4053 << TVar( theScaleFact ) << ",True,True)";
4059 //=======================================================================
4060 //function : ScaleMakeMesh
4062 //=======================================================================
4064 SMESH::SMESH_Mesh_ptr
4065 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4066 const SMESH::PointStruct& thePoint,
4067 const SMESH::double_array& theScaleFact,
4068 CORBA::Boolean theCopyGroups,
4069 const char* theMeshName)
4071 SMESH_Mesh_i* mesh_i;
4072 SMESH::SMESH_Mesh_var mesh;
4073 { // open new scope to dump "MakeMesh" command
4074 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4076 TPythonDump pydump; // to prevent dump at mesh creation
4077 mesh = makeMesh( theMeshName );
4078 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4082 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4083 mesh_i->CreateGroupServants();
4085 if ( !myPreviewMode )
4086 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4087 << theObject << ", "
4089 << TVar( theScaleFact ) << ", "
4090 << theCopyGroups << ", '"
4091 << theMeshName << "' )";
4095 if (!myPreviewMode && mesh_i)
4096 mesh_i->GetGroups();
4098 return mesh._retn();
4102 //=======================================================================
4103 //function : FindCoincidentNodes
4105 //=======================================================================
4107 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4108 SMESH::array_of_long_array_out GroupsOfNodes)
4112 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4113 ::SMESH_MeshEditor anEditor( myMesh );
4114 TIDSortedNodeSet nodes; // no input nodes
4115 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4117 GroupsOfNodes = new SMESH::array_of_long_array;
4118 GroupsOfNodes->length( aListOfListOfNodes.size() );
4119 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4120 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4121 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4122 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4123 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4124 aGroup.length( aListOfNodes.size() );
4125 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4126 aGroup[ j ] = (*lIt)->GetID();
4128 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4129 << Tolerance << " )";
4132 //=======================================================================
4133 //function : FindCoincidentNodesOnPart
4135 //=======================================================================
4136 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4137 CORBA::Double Tolerance,
4138 SMESH::array_of_long_array_out GroupsOfNodes)
4142 TIDSortedNodeSet nodes;
4143 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
4145 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4146 ::SMESH_MeshEditor anEditor( myMesh );
4148 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4150 GroupsOfNodes = new SMESH::array_of_long_array;
4151 GroupsOfNodes->length( aListOfListOfNodes.size() );
4152 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4153 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4155 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4156 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4157 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4158 aGroup.length( aListOfNodes.size() );
4159 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4160 aGroup[ j ] = (*lIt)->GetID();
4162 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4164 << Tolerance << " )";
4167 //================================================================================
4169 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4170 * ExceptSubMeshOrGroups
4172 //================================================================================
4174 void SMESH_MeshEditor_i::
4175 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4176 CORBA::Double theTolerance,
4177 SMESH::array_of_long_array_out theGroupsOfNodes,
4178 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4182 TIDSortedNodeSet nodes;
4183 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
4185 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4187 TIDSortedNodeSet exceptNodes;
4188 idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
4189 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4190 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4191 nodes.erase( *avoidNode );
4193 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4194 ::SMESH_MeshEditor anEditor( myMesh );
4196 anEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4198 theGroupsOfNodes = new SMESH::array_of_long_array;
4199 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4200 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4201 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4203 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4204 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4205 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4206 aGroup.length( aListOfNodes.size() );
4207 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4208 aGroup[ j ] = (*lIt)->GetID();
4210 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4212 << theTolerance << ", "
4213 << theExceptSubMeshOrGroups << " )";
4216 //=======================================================================
4217 //function : MergeNodes
4219 //=======================================================================
4221 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4225 SMESHDS_Mesh* aMesh = GetMeshDS();
4227 TPythonDump aTPythonDump;
4228 aTPythonDump << this << ".MergeNodes([";
4229 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4230 for (int i = 0; i < GroupsOfNodes.length(); i++)
4232 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4233 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4234 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4235 for ( int j = 0; j < aNodeGroup.length(); j++ )
4237 CORBA::Long index = aNodeGroup[ j ];
4238 const SMDS_MeshNode * node = aMesh->FindNode(index);
4240 aListOfNodes.push_back( node );
4242 if ( aListOfNodes.size() < 2 )
4243 aListOfListOfNodes.pop_back();
4245 if ( i > 0 ) aTPythonDump << ", ";
4246 aTPythonDump << aNodeGroup;
4248 ::SMESH_MeshEditor anEditor( myMesh );
4249 anEditor.MergeNodes( aListOfListOfNodes );
4251 aTPythonDump << "])";
4252 myMesh->GetMeshDS()->Modified();
4253 myMesh->SetIsModified( true );
4256 //=======================================================================
4257 //function : FindEqualElements
4259 //=======================================================================
4260 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4261 SMESH::array_of_long_array_out GroupsOfElementsID)
4265 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4266 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4268 typedef list<int> TListOfIDs;
4269 set<const SMDS_MeshElement*> elems;
4270 SMESH::long_array_var aElementsId = theObject->GetIDs();
4271 SMESHDS_Mesh* aMesh = GetMeshDS();
4273 for(int i = 0; i < aElementsId->length(); i++) {
4274 CORBA::Long anID = aElementsId[i];
4275 const SMDS_MeshElement * elem = aMesh->FindElement(anID);
4281 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4282 ::SMESH_MeshEditor anEditor( myMesh );
4283 anEditor.FindEqualElements( elems, aListOfListOfElementsID );
4285 GroupsOfElementsID = new SMESH::array_of_long_array;
4286 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4288 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
4289 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
4290 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4291 TListOfIDs& listOfIDs = *arraysIt;
4292 aGroup.length( listOfIDs.size() );
4293 TListOfIDs::iterator idIt = listOfIDs.begin();
4294 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
4295 aGroup[ k ] = *idIt;
4299 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4304 //=======================================================================
4305 //function : MergeElements
4307 //=======================================================================
4309 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4313 TPythonDump aTPythonDump;
4314 aTPythonDump << this << ".MergeElements( [";
4316 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4318 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4319 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4320 aListOfListOfElementsID.push_back( list< int >() );
4321 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4322 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4323 CORBA::Long id = anElemsIDGroup[ j ];
4324 aListOfElemsID.push_back( id );
4326 if ( aListOfElemsID.size() < 2 )
4327 aListOfListOfElementsID.pop_back();
4328 if ( i > 0 ) aTPythonDump << ", ";
4329 aTPythonDump << anElemsIDGroup;
4332 ::SMESH_MeshEditor anEditor( myMesh );
4333 anEditor.MergeElements(aListOfListOfElementsID);
4334 myMesh->GetMeshDS()->Modified();
4335 myMesh->SetIsModified( true );
4337 aTPythonDump << "] )";
4340 //=======================================================================
4341 //function : MergeEqualElements
4343 //=======================================================================
4345 void SMESH_MeshEditor_i::MergeEqualElements()
4349 ::SMESH_MeshEditor anEditor( myMesh );
4350 anEditor.MergeEqualElements();
4352 myMesh->GetMeshDS()->Modified();
4354 TPythonDump() << this << ".MergeEqualElements()";
4357 //=============================================================================
4359 * Move the node to a given point
4361 //=============================================================================
4363 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4368 initData(/*deleteSearchers=*/false);
4370 const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
4374 if ( theNodeSearcher )
4375 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4377 if ( myPreviewMode ) // make preview data
4379 // in a preview mesh, make edges linked to a node
4380 TPreviewMesh tmpMesh;
4381 TIDSortedElemSet linkedNodes;
4382 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4383 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4384 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4385 for ( ; nIt != linkedNodes.end(); ++nIt )
4387 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4388 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4392 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4393 // fill preview data
4394 ::SMESH_MeshEditor anEditor( & tmpMesh );
4395 storeResult( anEditor );
4397 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4398 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4400 GetMeshDS()->MoveNode(node, x, y, z);
4402 if ( !myPreviewMode )
4404 // Update Python script
4405 TPythonDump() << "isDone = " << this << ".MoveNode( "
4406 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4407 myMesh->GetMeshDS()->Modified();
4408 myMesh->SetIsModified( true );
4414 //================================================================================
4416 * \brief Return ID of node closest to a given point
4418 //================================================================================
4420 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4424 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4426 if ( !theNodeSearcher ) {
4427 ::SMESH_MeshEditor anEditor( myMesh );
4428 theNodeSearcher = anEditor.GetNodeSearcher();
4431 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4432 return node->GetID();
4437 //================================================================================
4439 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4440 * move the node closest to the point to point's location and return ID of the node
4442 //================================================================================
4444 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4447 CORBA::Long theNodeID)
4449 // We keep theNodeSearcher until any mesh modification:
4450 // 1) initData() deletes theNodeSearcher at any edition,
4451 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4453 initData(/*deleteSearchers=*/false);
4455 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4457 int nodeID = theNodeID;
4458 const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
4459 if ( !node ) // preview moving node
4461 if ( !theNodeSearcher ) {
4462 ::SMESH_MeshEditor anEditor( myMesh );
4463 theNodeSearcher = anEditor.GetNodeSearcher();
4466 node = theNodeSearcher->FindClosestTo( p );
4469 nodeID = node->GetID();
4470 if ( myPreviewMode ) // make preview data
4472 // in a preview mesh, make edges linked to a node
4473 TPreviewMesh tmpMesh;
4474 TIDSortedElemSet linkedNodes;
4475 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4476 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4477 for ( ; nIt != linkedNodes.end(); ++nIt )
4479 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4480 tmpMesh.Copy( &edge );
4483 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4485 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4486 // fill preview data
4487 ::SMESH_MeshEditor anEditor( & tmpMesh );
4488 storeResult( anEditor );
4490 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4492 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4496 GetMeshDS()->MoveNode(node, x, y, z);
4500 if ( !myPreviewMode )
4502 TPythonDump() << "nodeID = " << this
4503 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4504 << ", " << nodeID << " )";
4506 myMesh->GetMeshDS()->Modified();
4507 myMesh->SetIsModified( true );
4513 //=======================================================================
4515 * Return elements of given type where the given point is IN or ON.
4517 * 'ALL' type means elements of any type excluding nodes
4519 //=======================================================================
4521 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4524 SMESH::ElementType type)
4526 SMESH::long_array_var res = new SMESH::long_array;
4527 vector< const SMDS_MeshElement* > foundElems;
4529 theSearchersDeleter.Set( myMesh );
4530 if ( !theElementSearcher ) {
4531 ::SMESH_MeshEditor anEditor( myMesh );
4532 theElementSearcher = anEditor.GetElementSearcher();
4534 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4535 SMDSAbs_ElementType( type ),
4537 res->length( foundElems.size() );
4538 for ( int i = 0; i < foundElems.size(); ++i )
4539 res[i] = foundElems[i]->GetID();
4541 if ( !myPreviewMode ) // call from tui
4542 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4551 //=======================================================================
4552 //function : FindAmongElementsByPoint
4553 //purpose : Searching among the given elements, return elements of given type
4554 // where the given point is IN or ON.
4555 // 'ALL' type means elements of any type excluding nodes
4556 //=======================================================================
4559 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4563 SMESH::ElementType type)
4565 SMESH::long_array_var res = new SMESH::long_array;
4567 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4568 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4569 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D ) &&
4570 type != types[0] ) // but search of elements of dim > 0
4573 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4574 return FindElementsByPoint( x,y,z, type );
4576 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4578 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4579 if ( !theElementSearcher )
4581 // create a searcher from elementIDs
4582 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4583 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4585 if ( !idSourceToSet( elementIDs, meshDS, elements,
4586 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4589 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4590 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4592 ::SMESH_MeshEditor anEditor( myMesh );
4593 theElementSearcher = anEditor.GetElementSearcher(elemsIt);
4596 vector< const SMDS_MeshElement* > foundElems;
4598 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4599 SMDSAbs_ElementType( type ),
4601 res->length( foundElems.size() );
4602 for ( int i = 0; i < foundElems.size(); ++i )
4603 res[i] = foundElems[i]->GetID();
4605 if ( !myPreviewMode ) // call from tui
4606 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4607 << elementIDs << ", "
4616 //=======================================================================
4617 //function : GetPointState
4618 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4619 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4620 //=======================================================================
4622 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4626 theSearchersDeleter.Set( myMesh );
4627 if ( !theElementSearcher ) {
4628 ::SMESH_MeshEditor anEditor( myMesh );
4629 theElementSearcher = anEditor.GetElementSearcher();
4631 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4634 //=======================================================================
4635 //function : convError
4637 //=======================================================================
4639 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4641 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4645 RETCASE( SEW_BORDER1_NOT_FOUND );
4646 RETCASE( SEW_BORDER2_NOT_FOUND );
4647 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4648 RETCASE( SEW_BAD_SIDE_NODES );
4649 RETCASE( SEW_VOLUMES_TO_SPLIT );
4650 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4651 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4652 RETCASE( SEW_BAD_SIDE1_NODES );
4653 RETCASE( SEW_BAD_SIDE2_NODES );
4655 return SMESH::SMESH_MeshEditor::SEW_OK;
4658 //=======================================================================
4659 //function : SewFreeBorders
4661 //=======================================================================
4663 SMESH::SMESH_MeshEditor::Sew_Error
4664 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4665 CORBA::Long SecondNodeID1,
4666 CORBA::Long LastNodeID1,
4667 CORBA::Long FirstNodeID2,
4668 CORBA::Long SecondNodeID2,
4669 CORBA::Long LastNodeID2,
4670 CORBA::Boolean CreatePolygons,
4671 CORBA::Boolean CreatePolyedrs)
4675 SMESHDS_Mesh* aMesh = GetMeshDS();
4677 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4678 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4679 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4680 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4681 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4682 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4684 if (!aBorderFirstNode ||
4685 !aBorderSecondNode||
4687 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4688 if (!aSide2FirstNode ||
4689 !aSide2SecondNode ||
4691 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4693 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4694 << FirstNodeID1 << ", "
4695 << SecondNodeID1 << ", "
4696 << LastNodeID1 << ", "
4697 << FirstNodeID2 << ", "
4698 << SecondNodeID2 << ", "
4699 << LastNodeID2 << ", "
4700 << CreatePolygons<< ", "
4701 << CreatePolyedrs<< " )";
4703 ::SMESH_MeshEditor anEditor( myMesh );
4704 SMESH::SMESH_MeshEditor::Sew_Error error =
4705 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4715 storeResult(anEditor);
4717 myMesh->GetMeshDS()->Modified();
4718 myMesh->SetIsModified( true );
4724 //=======================================================================
4725 //function : SewConformFreeBorders
4727 //=======================================================================
4729 SMESH::SMESH_MeshEditor::Sew_Error
4730 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4731 CORBA::Long SecondNodeID1,
4732 CORBA::Long LastNodeID1,
4733 CORBA::Long FirstNodeID2,
4734 CORBA::Long SecondNodeID2)
4738 SMESHDS_Mesh* aMesh = GetMeshDS();
4740 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4741 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4742 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4743 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4744 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4745 const SMDS_MeshNode* aSide2ThirdNode = 0;
4747 if (!aBorderFirstNode ||
4748 !aBorderSecondNode||
4750 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4751 if (!aSide2FirstNode ||
4753 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4755 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4756 << FirstNodeID1 << ", "
4757 << SecondNodeID1 << ", "
4758 << LastNodeID1 << ", "
4759 << FirstNodeID2 << ", "
4760 << SecondNodeID2 << " )";
4762 ::SMESH_MeshEditor anEditor( myMesh );
4763 SMESH::SMESH_MeshEditor::Sew_Error error =
4764 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4773 storeResult(anEditor);
4775 myMesh->GetMeshDS()->Modified();
4776 myMesh->SetIsModified( true );
4782 //=======================================================================
4783 //function : SewBorderToSide
4785 //=======================================================================
4787 SMESH::SMESH_MeshEditor::Sew_Error
4788 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4789 CORBA::Long SecondNodeIDOnFreeBorder,
4790 CORBA::Long LastNodeIDOnFreeBorder,
4791 CORBA::Long FirstNodeIDOnSide,
4792 CORBA::Long LastNodeIDOnSide,
4793 CORBA::Boolean CreatePolygons,
4794 CORBA::Boolean CreatePolyedrs)
4798 SMESHDS_Mesh* aMesh = GetMeshDS();
4800 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4801 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4802 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4803 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4804 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4805 const SMDS_MeshNode* aSide2ThirdNode = 0;
4807 if (!aBorderFirstNode ||
4808 !aBorderSecondNode||
4810 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4811 if (!aSide2FirstNode ||
4813 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4815 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4816 << FirstNodeIDOnFreeBorder << ", "
4817 << SecondNodeIDOnFreeBorder << ", "
4818 << LastNodeIDOnFreeBorder << ", "
4819 << FirstNodeIDOnSide << ", "
4820 << LastNodeIDOnSide << ", "
4821 << CreatePolygons << ", "
4822 << CreatePolyedrs << ") ";
4824 ::SMESH_MeshEditor anEditor( myMesh );
4825 SMESH::SMESH_MeshEditor::Sew_Error error =
4826 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4836 storeResult(anEditor);
4838 myMesh->GetMeshDS()->Modified();
4839 myMesh->SetIsModified( true );
4845 //=======================================================================
4846 //function : SewSideElements
4848 //=======================================================================
4850 SMESH::SMESH_MeshEditor::Sew_Error
4851 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
4852 const SMESH::long_array& IDsOfSide2Elements,
4853 CORBA::Long NodeID1OfSide1ToMerge,
4854 CORBA::Long NodeID1OfSide2ToMerge,
4855 CORBA::Long NodeID2OfSide1ToMerge,
4856 CORBA::Long NodeID2OfSide2ToMerge)
4860 SMESHDS_Mesh* aMesh = GetMeshDS();
4862 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
4863 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
4864 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
4865 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
4867 if (!aFirstNode1ToMerge ||
4868 !aFirstNode2ToMerge )
4869 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
4870 if (!aSecondNode1ToMerge||
4871 !aSecondNode2ToMerge)
4872 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
4874 TIDSortedElemSet aSide1Elems, aSide2Elems;
4875 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
4876 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
4878 TPythonDump() << "error = " << this << ".SewSideElements( "
4879 << IDsOfSide1Elements << ", "
4880 << IDsOfSide2Elements << ", "
4881 << NodeID1OfSide1ToMerge << ", "
4882 << NodeID1OfSide2ToMerge << ", "
4883 << NodeID2OfSide1ToMerge << ", "
4884 << NodeID2OfSide2ToMerge << ")";
4886 ::SMESH_MeshEditor anEditor( myMesh );
4887 SMESH::SMESH_MeshEditor::Sew_Error error =
4888 convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
4891 aSecondNode1ToMerge,
4892 aSecondNode2ToMerge));
4894 storeResult(anEditor);
4896 myMesh->GetMeshDS()->Modified();
4897 myMesh->SetIsModified( true );
4902 //================================================================================
4904 * \brief Set new nodes for given element
4905 * \param ide - element id
4906 * \param newIDs - new node ids
4907 * \retval CORBA::Boolean - true if result is OK
4909 //================================================================================
4911 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
4912 const SMESH::long_array& newIDs)
4916 const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
4917 if(!elem) return false;
4919 int nbn = newIDs.length();
4921 vector<const SMDS_MeshNode*> aNodes(nbn);
4924 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
4927 aNodes[nbn1] = aNode;
4930 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
4931 << ide << ", " << newIDs << " )";
4933 MESSAGE("ChangeElementNodes");
4934 bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
4936 myMesh->GetMeshDS()->Modified();
4938 myMesh->SetIsModified( true );
4943 //================================================================================
4945 * \brief Update myLastCreated* or myPreviewData
4946 * \param anEditor - it contains last modification results
4948 //================================================================================
4950 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
4952 if ( myPreviewMode ) { // --- MeshPreviewStruct filling ---
4954 list<int> aNodesConnectivity;
4955 typedef map<int, int> TNodesMap;
4958 TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
4959 SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
4961 SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
4962 int nbEdges = aMeshDS->NbEdges();
4963 int nbFaces = aMeshDS->NbFaces();
4964 int nbVolum = aMeshDS->NbVolumes();
4965 switch ( previewType ) {
4966 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
4967 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
4968 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
4971 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
4972 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
4974 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
4976 while ( itMeshElems->more() ) {
4977 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
4978 if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
4981 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
4982 while ( itElemNodes->more() ) {
4983 const SMDS_MeshNode* aMeshNode =
4984 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
4985 int aNodeID = aMeshNode->GetID();
4986 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
4987 if ( anIter == nodesMap.end() ) {
4988 // filling the nodes coordinates
4989 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
4990 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
4991 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
4992 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
4995 aNodesConnectivity.push_back(anIter->second);
4998 // filling the elements types
4999 SMDSAbs_ElementType aType;
5001 /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
5002 aType = SMDSAbs_Node;
5006 aType = aMeshElem->GetType();
5007 isPoly = aMeshElem->IsPoly();
5010 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
5011 myPreviewData->elementTypes[i].isPoly = isPoly;
5012 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
5016 myPreviewData->nodesXYZ.length( j );
5018 // filling the elements connectivities
5019 list<int>::iterator aConnIter = aNodesConnectivity.begin();
5020 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
5021 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
5022 myPreviewData->elementConnectivities[i] = *aConnIter;
5028 // append new nodes into myLastCreatedNodes
5029 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
5030 int j = myLastCreatedNodes->length();
5031 int newLen = j + aSeq.Length();
5032 myLastCreatedNodes->length( newLen );
5033 for(int i=0; j<newLen; i++,j++)
5034 myLastCreatedNodes[j] = aSeq.Value(i+1)->GetID();
5037 // append new elements into myLastCreatedElems
5038 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
5039 int j = myLastCreatedElems->length();
5040 int newLen = j + aSeq.Length();
5041 myLastCreatedElems->length( newLen );
5042 for(int i=0; j<newLen; i++,j++)
5043 myLastCreatedElems[j] = aSeq.Value(i+1)->GetID();
5047 //================================================================================
5049 * Return data of mesh edition preview
5051 //================================================================================
5053 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
5055 return myPreviewData._retn();
5058 //================================================================================
5060 * \brief Returns list of it's IDs of created nodes
5061 * \retval SMESH::long_array* - list of node ID
5063 //================================================================================
5065 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
5067 return myLastCreatedNodes._retn();
5070 //================================================================================
5072 * \brief Returns list of it's IDs of created elements
5073 * \retval SMESH::long_array* - list of elements' ID
5075 //================================================================================
5077 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
5079 return myLastCreatedElems._retn();
5082 //=======================================================================
5083 //function : ConvertToQuadratic
5085 //=======================================================================
5087 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5089 ::SMESH_MeshEditor anEditor( myMesh );
5090 anEditor.ConvertToQuadratic(theForce3d);
5091 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
5092 myMesh->GetMeshDS()->Modified();
5093 myMesh->SetIsModified( true );
5096 //=======================================================================
5097 //function : ConvertFromQuadratic
5099 //=======================================================================
5101 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5103 ::SMESH_MeshEditor anEditor( myMesh );
5104 CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
5105 TPythonDump() << this << ".ConvertFromQuadratic()";
5106 myMesh->GetMeshDS()->Modified();
5108 myMesh->SetIsModified( true );
5111 //================================================================================
5113 * \brief Makes a part of the mesh quadratic
5115 //================================================================================
5117 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5118 SMESH::SMESH_IDSource_ptr theObject)
5119 throw (SALOME::SALOME_Exception)
5121 Unexpect aCatch(SALOME_SalomeException);
5123 TIDSortedElemSet elems;
5124 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5126 if ( elems.empty() )
5128 ConvertToQuadratic( theForce3d );
5130 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5132 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5136 ::SMESH_MeshEditor anEditor( myMesh );
5137 anEditor.ConvertToQuadratic(theForce3d, elems);
5140 myMesh->GetMeshDS()->Modified();
5141 myMesh->SetIsModified( true );
5143 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
5146 //================================================================================
5148 * \brief Makes a part of the mesh linear
5150 //================================================================================
5152 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5153 throw (SALOME::SALOME_Exception)
5155 Unexpect aCatch(SALOME_SalomeException);
5157 TIDSortedElemSet elems;
5158 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5160 if ( elems.empty() )
5162 ConvertFromQuadratic();
5164 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5166 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5170 ::SMESH_MeshEditor anEditor( myMesh );
5171 anEditor.ConvertFromQuadratic(elems);
5174 myMesh->GetMeshDS()->Modified();
5175 myMesh->SetIsModified( true );
5177 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5180 //=======================================================================
5181 //function : makeMesh
5182 //purpose : create a named imported mesh
5183 //=======================================================================
5185 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5187 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5188 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5189 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5190 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
5191 gen->SetName( meshSO, theMeshName, "Mesh" );
5192 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5194 return mesh._retn();
5197 //=======================================================================
5198 //function : DumpGroupsList
5200 //=======================================================================
5201 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
5202 const SMESH::ListOfGroups * theGroupList)
5204 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
5205 if(isDumpGroupList) {
5206 theDumpPython << theGroupList << " = ";
5210 //================================================================================
5212 \brief Generates the unique group name.
5213 \param thePrefix name prefix
5216 //================================================================================
5217 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5219 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5220 set<string> groupNames;
5222 // Get existing group names
5223 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5224 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5225 if (CORBA::is_nil(aGroup))
5228 groupNames.insert(aGroup->GetName());
5232 string name = thePrefix;
5235 while (!groupNames.insert(name).second) {
5240 TCollection_AsciiString nbStr(index+1);
5241 name.resize( name.rfind('_')+1 );
5242 name += nbStr.ToCString();
5250 //================================================================================
5252 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5253 \param theNodes - identifiers of nodes to be doubled
5254 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5255 nodes. If list of element identifiers is empty then nodes are doubled but
5256 they not assigned to elements
5257 \return TRUE if operation has been completed successfully, FALSE otherwise
5258 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5260 //================================================================================
5262 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5263 const SMESH::long_array& theModifiedElems )
5267 ::SMESH_MeshEditor aMeshEditor( myMesh );
5268 list< int > aListOfNodes;
5270 for ( i = 0, n = theNodes.length(); i < n; i++ )
5271 aListOfNodes.push_back( theNodes[ i ] );
5273 list< int > aListOfElems;
5274 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5275 aListOfElems.push_back( theModifiedElems[ i ] );
5277 bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
5279 myMesh->GetMeshDS()->Modified();
5280 storeResult( aMeshEditor) ;
5282 myMesh->SetIsModified( true );
5284 // Update Python script
5285 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5290 //================================================================================
5292 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5293 This method provided for convenience works as DoubleNodes() described above.
5294 \param theNodeId - identifier of node to be doubled.
5295 \param theModifiedElems - identifiers of elements to be updated.
5296 \return TRUE if operation has been completed successfully, FALSE otherwise
5297 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5299 //================================================================================
5301 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5302 const SMESH::long_array& theModifiedElems )
5304 SMESH::long_array_var aNodes = new SMESH::long_array;
5305 aNodes->length( 1 );
5306 aNodes[ 0 ] = theNodeId;
5308 TPythonDump pyDump; // suppress dump by the next line
5310 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5312 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5317 //================================================================================
5319 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5320 This method provided for convenience works as DoubleNodes() described above.
5321 \param theNodes - group of nodes to be doubled.
5322 \param theModifiedElems - group of elements to be updated.
5323 \return TRUE if operation has been completed successfully, FALSE otherwise
5324 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5326 //================================================================================
5328 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5329 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5331 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5334 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5335 SMESH::long_array_var aModifiedElems;
5336 if ( !CORBA::is_nil( theModifiedElems ) )
5337 aModifiedElems = theModifiedElems->GetListOfID();
5340 aModifiedElems = new SMESH::long_array;
5341 aModifiedElems->length( 0 );
5344 TPythonDump pyDump; // suppress dump by the next line
5346 bool done = DoubleNodes( aNodes, aModifiedElems );
5348 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5354 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5355 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5356 * \param theNodes - group of nodes to be doubled.
5357 * \param theModifiedElems - group of elements to be updated.
5358 * \return a new group with newly created nodes
5359 * \sa DoubleNodeGroup()
5361 SMESH::SMESH_Group_ptr
5362 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5363 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5365 SMESH::SMESH_Group_var aNewGroup;
5367 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5368 return aNewGroup._retn();
5371 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5372 SMESH::long_array_var aModifiedElems;
5373 if ( !CORBA::is_nil( theModifiedElems ) )
5374 aModifiedElems = theModifiedElems->GetListOfID();
5376 aModifiedElems = new SMESH::long_array;
5377 aModifiedElems->length( 0 );
5380 TPythonDump pyDump; // suppress dump by the next line
5382 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5385 // Create group with newly created nodes
5386 SMESH::long_array_var anIds = GetLastCreatedNodes();
5387 if (anIds->length() > 0) {
5388 string anUnindexedName (theNodes->GetName());
5389 string aNewName = generateGroupName(anUnindexedName + "_double");
5390 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5391 aNewGroup->Add(anIds);
5392 pyDump << aNewGroup << " = ";
5396 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5397 << theModifiedElems << " )";
5399 return aNewGroup._retn();
5402 //================================================================================
5404 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5405 This method provided for convenience works as DoubleNodes() described above.
5406 \param theNodes - list of groups of nodes to be doubled
5407 \param theModifiedElems - list of groups of elements to be updated.
5408 \return TRUE if operation has been completed successfully, FALSE otherwise
5409 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5411 //================================================================================
5413 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5414 const SMESH::ListOfGroups& theModifiedElems )
5418 ::SMESH_MeshEditor aMeshEditor( myMesh );
5420 std::list< int > aNodes;
5422 for ( i = 0, n = theNodes.length(); i < n; i++ )
5424 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5425 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5427 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5428 for ( j = 0, m = aCurr->length(); j < m; j++ )
5429 aNodes.push_back( aCurr[ j ] );
5433 std::list< int > anElems;
5434 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5436 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5437 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5439 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5440 for ( j = 0, m = aCurr->length(); j < m; j++ )
5441 anElems.push_back( aCurr[ j ] );
5445 bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
5447 storeResult( aMeshEditor) ;
5449 myMesh->GetMeshDS()->Modified();
5451 myMesh->SetIsModified( true );
5454 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5459 //================================================================================
5461 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5462 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5463 * \param theNodes - group of nodes to be doubled.
5464 * \param theModifiedElems - group of elements to be updated.
5465 * \return a new group with newly created nodes
5466 * \sa DoubleNodeGroups()
5468 //================================================================================
5470 SMESH::SMESH_Group_ptr
5471 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5472 const SMESH::ListOfGroups& theModifiedElems )
5474 SMESH::SMESH_Group_var aNewGroup;
5476 TPythonDump pyDump; // suppress dump by the next line
5478 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5482 // Create group with newly created nodes
5483 SMESH::long_array_var anIds = GetLastCreatedNodes();
5484 if (anIds->length() > 0) {
5485 string anUnindexedName (theNodes[0]->GetName());
5486 string aNewName = generateGroupName(anUnindexedName + "_double");
5487 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5488 aNewGroup->Add(anIds);
5489 pyDump << aNewGroup << " = ";
5493 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5494 << theModifiedElems << " )";
5496 return aNewGroup._retn();
5500 //================================================================================
5502 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5503 \param theElems - the list of elements (edges or faces) to be replicated
5504 The nodes for duplication could be found from these elements
5505 \param theNodesNot - list of nodes to NOT replicate
5506 \param theAffectedElems - the list of elements (cells and edges) to which the
5507 replicated nodes should be associated to.
5508 \return TRUE if operation has been completed successfully, FALSE otherwise
5509 \sa DoubleNodeGroup(), DoubleNodeGroups()
5511 //================================================================================
5513 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5514 const SMESH::long_array& theNodesNot,
5515 const SMESH::long_array& theAffectedElems )
5520 ::SMESH_MeshEditor aMeshEditor( myMesh );
5522 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5523 TIDSortedElemSet anElems, aNodes, anAffected;
5524 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5525 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5526 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5528 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5530 storeResult( aMeshEditor) ;
5532 myMesh->GetMeshDS()->Modified();
5534 myMesh->SetIsModified( true );
5536 // Update Python script
5537 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5538 << theNodesNot << ", " << theAffectedElems << " )";
5542 //================================================================================
5544 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5545 \param theElems - the list of elements (edges or faces) to be replicated
5546 The nodes for duplication could be found from these elements
5547 \param theNodesNot - list of nodes to NOT replicate
5548 \param theShape - shape to detect affected elements (element which geometric center
5549 located on or inside shape).
5550 The replicated nodes should be associated to affected elements.
5551 \return TRUE if operation has been completed successfully, FALSE otherwise
5552 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5554 //================================================================================
5556 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5557 const SMESH::long_array& theNodesNot,
5558 GEOM::GEOM_Object_ptr theShape )
5563 ::SMESH_MeshEditor aMeshEditor( myMesh );
5565 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5566 TIDSortedElemSet anElems, aNodes;
5567 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5568 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5570 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5571 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5573 storeResult( aMeshEditor) ;
5575 myMesh->GetMeshDS()->Modified();
5577 myMesh->SetIsModified( true );
5579 // Update Python script
5580 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5581 << theNodesNot << ", " << theShape << " )";
5585 //================================================================================
5587 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5588 \param theElems - group of of elements (edges or faces) to be replicated
5589 \param theNodesNot - group of nodes not to replicated
5590 \param theAffectedElems - group of elements to which the replicated nodes
5591 should be associated to.
5592 \return TRUE if operation has been completed successfully, FALSE otherwise
5593 \sa DoubleNodes(), DoubleNodeGroups()
5595 //================================================================================
5597 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5598 SMESH::SMESH_GroupBase_ptr theNodesNot,
5599 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5601 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5606 ::SMESH_MeshEditor aMeshEditor( myMesh );
5608 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5609 TIDSortedElemSet anElems, aNodes, anAffected;
5610 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5611 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5612 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5614 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5616 storeResult( aMeshEditor) ;
5618 myMesh->GetMeshDS()->Modified();
5620 myMesh->SetIsModified( true );
5622 // Update Python script
5623 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5624 << theNodesNot << ", " << theAffectedElems << " )";
5629 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5630 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5631 * \param theElems - group of of elements (edges or faces) to be replicated
5632 * \param theNodesNot - group of nodes not to replicated
5633 * \param theAffectedElems - group of elements to which the replicated nodes
5634 * should be associated to.
5635 * \return a new group with newly created elements
5636 * \sa DoubleNodeElemGroup()
5638 SMESH::SMESH_Group_ptr
5639 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5640 SMESH::SMESH_GroupBase_ptr theNodesNot,
5641 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5644 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5648 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5649 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5651 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5653 << theNodesNot << ", "
5654 << theAffectedElems << " )";
5656 return elemGroup._retn();
5659 SMESH::ListOfGroups*
5660 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5661 SMESH::SMESH_GroupBase_ptr theNodesNot,
5662 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5663 CORBA::Boolean theElemGroupNeeded,
5664 CORBA::Boolean theNodeGroupNeeded)
5666 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5667 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5668 aTwoGroups->length( 2 );
5670 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5671 return aTwoGroups._retn();
5675 ::SMESH_MeshEditor aMeshEditor( myMesh );
5677 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5678 TIDSortedElemSet anElems, aNodes, anAffected;
5679 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5680 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5681 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5684 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5686 storeResult( aMeshEditor) ;
5687 myMesh->GetMeshDS()->Modified();
5693 myMesh->SetIsModified( true );
5695 // Create group with newly created elements
5696 CORBA::String_var elemGroupName = theElems->GetName();
5697 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5698 if ( !aMeshEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5700 SMESH::long_array_var anIds = GetLastCreatedElems();
5701 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5702 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5703 aNewElemGroup->Add(anIds);
5705 if ( !aMeshEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5707 SMESH::long_array_var anIds = GetLastCreatedNodes();
5708 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5709 aNewNodeGroup->Add(anIds);
5713 // Update Python script
5716 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5717 else pyDump << aNewElemGroup << ", ";
5718 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5719 else pyDump << aNewNodeGroup << " ] = ";
5721 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5722 << theNodesNot << ", "
5723 << theAffectedElems << ", "
5724 << theElemGroupNeeded << ", "
5725 << theNodeGroupNeeded <<" )";
5727 aTwoGroups[0] = aNewElemGroup._retn();
5728 aTwoGroups[1] = aNewNodeGroup._retn();
5729 return aTwoGroups._retn();
5732 //================================================================================
5734 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5735 \param theElems - group of of elements (edges or faces) to be replicated
5736 \param theNodesNot - group of nodes not to replicated
5737 \param theShape - shape to detect affected elements (element which geometric center
5738 located on or inside shape).
5739 The replicated nodes should be associated to affected elements.
5740 \return TRUE if operation has been completed successfully, FALSE otherwise
5741 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5743 //================================================================================
5745 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5746 SMESH::SMESH_GroupBase_ptr theNodesNot,
5747 GEOM::GEOM_Object_ptr theShape )
5750 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5755 ::SMESH_MeshEditor aMeshEditor( myMesh );
5757 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5758 TIDSortedElemSet anElems, aNodes, anAffected;
5759 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5760 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5762 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5763 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5765 storeResult( aMeshEditor) ;
5767 myMesh->GetMeshDS()->Modified();
5769 myMesh->SetIsModified( true );
5771 // Update Python script
5772 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5773 << theNodesNot << ", " << theShape << " )";
5777 //================================================================================
5779 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5780 This method provided for convenience works as DoubleNodes() described above.
5781 \param theElems - list of groups of elements (edges or faces) to be replicated
5782 \param theNodesNot - list of groups of nodes not to replicated
5783 \param theAffectedElems - group of elements to which the replicated nodes
5784 should be associated to.
5785 \return TRUE if operation has been completed successfully, FALSE otherwise
5786 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5788 //================================================================================
5790 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5791 SMESHDS_Mesh* theMeshDS,
5792 TIDSortedElemSet& theElemSet,
5793 const bool theIsNodeGrp)
5795 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5797 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5798 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5799 : aGrp->GetType() != SMESH::NODE ) )
5801 SMESH::long_array_var anIDs = aGrp->GetIDs();
5802 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5807 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5808 const SMESH::ListOfGroups& theNodesNot,
5809 const SMESH::ListOfGroups& theAffectedElems)
5813 ::SMESH_MeshEditor aMeshEditor( myMesh );
5815 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5816 TIDSortedElemSet anElems, aNodes, anAffected;
5817 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5818 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5819 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5821 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5823 storeResult( aMeshEditor) ;
5825 myMesh->GetMeshDS()->Modified();
5827 myMesh->SetIsModified( true );
5829 // Update Python script
5830 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5831 << &theNodesNot << ", " << &theAffectedElems << " )";
5835 //================================================================================
5837 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5838 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5839 \param theElems - list of groups of elements (edges or faces) to be replicated
5840 \param theNodesNot - list of groups of nodes not to replicated
5841 \param theAffectedElems - group of elements to which the replicated nodes
5842 should be associated to.
5843 * \return a new group with newly created elements
5844 * \sa DoubleNodeElemGroups()
5846 //================================================================================
5848 SMESH::SMESH_Group_ptr
5849 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5850 const SMESH::ListOfGroups& theNodesNot,
5851 const SMESH::ListOfGroups& theAffectedElems)
5854 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
5858 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5859 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5861 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
5863 << theNodesNot << ", "
5864 << theAffectedElems << " )";
5866 return elemGroup._retn();
5869 SMESH::ListOfGroups*
5870 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
5871 const SMESH::ListOfGroups& theNodesNot,
5872 const SMESH::ListOfGroups& theAffectedElems,
5873 CORBA::Boolean theElemGroupNeeded,
5874 CORBA::Boolean theNodeGroupNeeded)
5876 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5877 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5878 aTwoGroups->length( 2 );
5882 ::SMESH_MeshEditor aMeshEditor( myMesh );
5884 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5885 TIDSortedElemSet anElems, aNodes, anAffected;
5886 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5887 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5888 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5890 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5892 storeResult( aMeshEditor) ;
5894 myMesh->GetMeshDS()->Modified();
5898 myMesh->SetIsModified( true );
5900 // Create group with newly created elements
5901 CORBA::String_var elemGroupName = theElems[0]->GetName();
5902 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5903 if ( !aMeshEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5905 SMESH::long_array_var anIds = GetLastCreatedElems();
5906 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5907 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5908 aNewElemGroup->Add(anIds);
5910 if ( !aMeshEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5912 SMESH::long_array_var anIds = GetLastCreatedNodes();
5913 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5914 aNewNodeGroup->Add(anIds);
5918 // Update Python script
5921 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5922 else pyDump << aNewElemGroup << ", ";
5923 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5924 else pyDump << aNewNodeGroup << " ] = ";
5926 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
5927 << &theNodesNot << ", "
5928 << &theAffectedElems << ", "
5929 << theElemGroupNeeded << ", "
5930 << theNodeGroupNeeded << " )";
5932 aTwoGroups[0] = aNewElemGroup._retn();
5933 aTwoGroups[1] = aNewNodeGroup._retn();
5934 return aTwoGroups._retn();
5937 //================================================================================
5939 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5940 This method provided for convenience works as DoubleNodes() described above.
5941 \param theElems - list of groups of elements (edges or faces) to be replicated
5942 \param theNodesNot - list of groups of nodes not to replicated
5943 \param theShape - shape to detect affected elements (element which geometric center
5944 located on or inside shape).
5945 The replicated nodes should be associated to affected elements.
5946 \return TRUE if operation has been completed successfully, FALSE otherwise
5947 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
5949 //================================================================================
5952 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
5953 const SMESH::ListOfGroups& theNodesNot,
5954 GEOM::GEOM_Object_ptr theShape )
5958 ::SMESH_MeshEditor aMeshEditor( myMesh );
5960 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5961 TIDSortedElemSet anElems, aNodes;
5962 listOfGroupToSet(theElems, aMeshDS, anElems,false );
5963 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5965 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5966 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5968 storeResult( aMeshEditor) ;
5970 myMesh->GetMeshDS()->Modified();
5972 myMesh->SetIsModified( true );
5974 // Update Python script
5975 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
5976 << &theNodesNot << ", " << theShape << " )";
5980 //================================================================================
5982 \brief Generated skin mesh (containing 2D cells) from 3D mesh
5983 The created 2D mesh elements based on nodes of free faces of boundary volumes
5984 \return TRUE if operation has been completed successfully, FALSE otherwise
5986 //================================================================================
5988 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
5992 ::SMESH_MeshEditor aMeshEditor( myMesh );
5993 bool aResult = aMeshEditor.Make2DMeshFrom3D();
5994 storeResult( aMeshEditor) ;
5995 myMesh->GetMeshDS()->Modified();
5996 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6000 //================================================================================
6002 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6003 * The list of groups must describe a partition of the mesh volumes.
6004 * The nodes of the internal faces at the boundaries of the groups are doubled.
6005 * In option, the internal faces are replaced by flat elements.
6006 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6007 * The flat elements are stored in groups of volumes.
6008 * @param theDomains - list of groups of volumes
6009 * @param createJointElems - if TRUE, create the elements
6010 * @return TRUE if operation has been completed successfully, FALSE otherwise
6012 //================================================================================
6014 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6015 CORBA::Boolean createJointElems )
6016 throw (SALOME::SALOME_Exception)
6020 ::SMESH_MeshEditor aMeshEditor( myMesh );
6022 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6024 vector<TIDSortedElemSet> domains;
6027 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6029 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6030 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6032 // if ( aGrp->GetType() != SMESH::VOLUME )
6033 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6034 TIDSortedElemSet domain;
6036 domains.push_back(domain);
6037 SMESH::long_array_var anIDs = aGrp->GetIDs();
6038 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6042 bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
6043 // TODO publish the groups of flat elements in study
6045 storeResult( aMeshEditor) ;
6046 myMesh->GetMeshDS()->Modified();
6048 // Update Python script
6049 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6050 << ", " << createJointElems << " )";
6054 //================================================================================
6056 * \brief Double nodes on some external faces and create flat elements.
6057 * Flat elements are mainly used by some types of mechanic calculations.
6059 * Each group of the list must be constituted of faces.
6060 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6061 * @param theGroupsOfFaces - list of groups of faces
6062 * @return TRUE if operation has been completed successfully, FALSE otherwise
6064 //================================================================================
6066 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6070 ::SMESH_MeshEditor aMeshEditor( myMesh );
6072 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6074 vector<TIDSortedElemSet> faceGroups;
6077 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6079 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6080 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6082 TIDSortedElemSet faceGroup;
6084 faceGroups.push_back(faceGroup);
6085 SMESH::long_array_var anIDs = aGrp->GetIDs();
6086 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6090 bool aResult = aMeshEditor.CreateFlatElementsOnFacesGroups( faceGroups );
6091 // TODO publish the groups of flat elements in study
6093 storeResult( aMeshEditor) ;
6094 myMesh->GetMeshDS()->Modified();
6096 // Update Python script
6097 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6101 // issue 20749 ===================================================================
6103 * \brief Creates missing boundary elements
6104 * \param elements - elements whose boundary is to be checked
6105 * \param dimension - defines type of boundary elements to create
6106 * \param groupName - a name of group to store created boundary elements in,
6107 * "" means not to create the group
6108 * \param meshName - a name of new mesh to store created boundary elements in,
6109 * "" means not to create the new mesh
6110 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6111 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6112 * boundary elements will be copied into the new mesh
6113 * \param group - returns the create group, if any
6114 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6116 // ================================================================================
6118 SMESH::SMESH_Mesh_ptr
6119 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6120 SMESH::Bnd_Dimension dim,
6121 const char* groupName,
6122 const char* meshName,
6123 CORBA::Boolean toCopyElements,
6124 CORBA::Boolean toCopyExistingBondary,
6125 SMESH::SMESH_Group_out group)
6129 if ( dim > SMESH::BND_1DFROM2D )
6130 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6132 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6134 SMESH::SMESH_Mesh_var mesh_var;
6135 SMESH::SMESH_Group_var group_var;
6139 TIDSortedElemSet elements;
6140 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6141 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6145 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6146 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6148 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6150 // group of new boundary elements
6151 SMESH_Group* smesh_group = 0;
6152 if ( strlen(groupName) )
6154 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6155 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6156 smesh_group = group_i->GetSmeshGroup();
6160 ::SMESH_MeshEditor aMeshEditor( myMesh );
6161 aMeshEditor.MakeBoundaryMesh( elements,
6162 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6166 toCopyExistingBondary);
6167 storeResult( aMeshEditor );
6170 smesh_mesh->GetMeshDS()->Modified();
6173 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6175 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6176 if ( mesh_var->_is_nil() )
6177 pyDump << myMesh_i->_this() << ", ";
6179 pyDump << mesh_var << ", ";
6180 if ( group_var->_is_nil() )
6181 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6183 pyDump << group_var << " = ";
6184 pyDump << this << ".MakeBoundaryMesh( "
6186 << "SMESH." << dimName[int(dim)] << ", "
6187 << "'" << groupName << "', "
6188 << "'" << meshName<< "', "
6189 << toCopyElements << ", "
6190 << toCopyExistingBondary << ")";
6192 group = group_var._retn();
6193 return mesh_var._retn();
6196 //================================================================================
6198 * \brief Creates missing boundary elements
6199 * \param dimension - defines type of boundary elements to create
6200 * \param groupName - a name of group to store all boundary elements in,
6201 * "" means not to create the group
6202 * \param meshName - a name of a new mesh, which is a copy of the initial
6203 * mesh + created boundary elements; "" means not to create the new mesh
6204 * \param toCopyAll - if true, the whole initial mesh will be copied into
6205 * the new mesh else only boundary elements will be copied into the new mesh
6206 * \param groups - optional groups of elements to make boundary around
6207 * \param mesh - returns the mesh where elements were added to
6208 * \param group - returns the created group, if any
6209 * \retval long - number of added boundary elements
6211 //================================================================================
6213 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6214 const char* groupName,
6215 const char* meshName,
6216 CORBA::Boolean toCopyAll,
6217 const SMESH::ListOfIDSources& groups,
6218 SMESH::SMESH_Mesh_out mesh,
6219 SMESH::SMESH_Group_out group)
6220 throw (SALOME::SALOME_Exception)
6222 Unexpect aCatch(SALOME_SalomeException);
6226 if ( dim > SMESH::BND_1DFROM2D )
6227 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6229 // separate groups belonging to this and other mesh
6230 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6231 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6232 groupsOfThisMesh->length( groups.length() );
6233 groupsOfOtherMesh->length( groups.length() );
6234 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6235 for ( int i = 0; i < groups.length(); ++i )
6237 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6238 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6239 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6241 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6242 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6243 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6245 groupsOfThisMesh->length( nbGroups );
6246 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6251 if ( nbGroupsOfOtherMesh > 0 )
6253 // process groups belonging to another mesh
6254 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6255 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6256 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6257 groupsOfOtherMesh, mesh, group );
6260 SMESH::SMESH_Mesh_var mesh_var;
6261 SMESH::SMESH_Group_var group_var;
6264 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6265 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6269 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6271 /*toCopyGroups=*/false,
6272 /*toKeepIDs=*/true);
6274 mesh_var = makeMesh(meshName);
6276 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6277 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6280 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6281 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6283 // group of boundary elements
6284 SMESH_Group* smesh_group = 0;
6285 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6286 if ( strlen(groupName) )
6288 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6289 group_var = mesh_i->CreateGroup( groupType, groupName );
6290 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6291 smesh_group = group_i->GetSmeshGroup();
6294 TIDSortedElemSet elements;
6296 if ( groups.length() > 0 )
6298 for ( int i = 0; i < nbGroups; ++i )
6301 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6303 SMESH::Bnd_Dimension bdim =
6304 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6305 ::SMESH_MeshEditor aMeshEditor( srcMesh );
6306 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
6307 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6310 /*toCopyElements=*/false,
6311 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6312 /*toAddExistingBondary=*/true,
6313 /*aroundElements=*/true);
6314 storeResult( aMeshEditor );
6320 ::SMESH_MeshEditor aMeshEditor( srcMesh );
6321 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
6322 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6325 /*toCopyElements=*/false,
6326 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6327 /*toAddExistingBondary=*/true);
6328 storeResult( aMeshEditor );
6330 tgtMesh->GetMeshDS()->Modified();
6332 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6334 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6335 pyDump << "nbAdded, ";
6336 if ( mesh_var->_is_nil() )
6337 pyDump << myMesh_i->_this() << ", ";
6339 pyDump << mesh_var << ", ";
6340 if ( group_var->_is_nil() )
6341 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6343 pyDump << group_var << " = ";
6344 pyDump << this << ".MakeBoundaryElements( "
6345 << "SMESH." << dimName[int(dim)] << ", "
6346 << "'" << groupName << "', "
6347 << "'" << meshName<< "', "
6348 << toCopyAll << ", "
6351 mesh = mesh_var._retn();
6352 group = group_var._retn();