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 "DriverMED_R_SMESHDS_Mesh.h"
33 #include "DriverMED_W_SMESHDS_Mesh.h"
34 #include "SMDS_EdgePosition.hxx"
35 #include "SMDS_ElemIterator.hxx"
36 #include "SMDS_FacePosition.hxx"
37 #include "SMDS_IteratorOnIterators.hxx"
38 #include "SMDS_LinearEdge.hxx"
39 #include "SMDS_Mesh0DElement.hxx"
40 #include "SMDS_MeshFace.hxx"
41 #include "SMDS_MeshVolume.hxx"
42 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
43 #include "SMDS_SetIterator.hxx"
44 #include "SMDS_SetIterator.hxx"
45 #include "SMDS_VolumeTool.hxx"
46 #include "SMESHDS_Command.hxx"
47 #include "SMESHDS_CommandType.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Filter_i.hxx"
53 #include "SMESH_Gen_i.hxx"
54 #include "SMESH_Gen_i.hxx"
55 #include "SMESH_Group.hxx"
56 #include "SMESH_Group_i.hxx"
57 #include "SMESH_Group_i.hxx"
58 #include "SMESH_MEDMesh_i.hxx"
59 #include "SMESH_MeshEditor.hxx"
60 #include "SMESH_MeshPartDS.hxx"
61 #include "SMESH_MesherHelper.hxx"
62 #include "SMESH_PreMeshInfo.hxx"
63 #include "SMESH_PythonDump.hxx"
64 #include "SMESH_PythonDump.hxx"
65 #include "SMESH_subMeshEventListener.hxx"
66 #include "SMESH_subMesh_i.hxx"
67 #include "SMESH_subMesh_i.hxx"
69 #include "utilities.h"
70 #include "Utils_ExceptHandlers.hxx"
71 #include "Utils_CorbaException.hxx"
73 #include <BRepAdaptor_Surface.hxx>
74 #include <BRep_Tool.hxx>
75 #include <TopExp_Explorer.hxx>
77 #include <TopoDS_Edge.hxx>
78 #include <TopoDS_Face.hxx>
83 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
87 #include <Standard_Failure.hxx>
90 #include <Standard_ErrorHandler.hxx>
96 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
99 using SMESH::TPythonDump;
104 //=============================================================================
106 * \brief Mesh to apply modifications for preview purposes
108 //=============================================================================
110 struct TPreviewMesh: public SMESH_Mesh
112 SMDSAbs_ElementType myPreviewType; // type to show
114 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
115 _isShapeToMesh = (_id =_studyId =_idDoc = 0);
116 _myMeshDS = new SMESHDS_Mesh( _id, true );
117 myPreviewType = previewElements;
120 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
121 //!< Copy a set of elements
122 void Copy(const TIDSortedElemSet & theElements,
123 TIDSortedElemSet& theCopyElements,
124 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
125 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
127 // loop on theIDsOfElements
128 TIDSortedElemSet::const_iterator eIt = theElements.begin();
129 for ( ; eIt != theElements.end(); ++eIt )
131 const SMDS_MeshElement* anElem = *eIt;
132 if ( !anElem ) continue;
133 SMDSAbs_ElementType type = anElem->GetType();
134 if ( type == theAvoidType ||
135 ( theSelectType != SMDSAbs_All && type != theSelectType ))
137 const SMDS_MeshElement* anElemCopy;
138 if ( type == SMDSAbs_Node)
139 anElemCopy = Copy( cast2Node(anElem) );
141 anElemCopy = Copy( anElem );
143 theCopyElements.insert( theCopyElements.end(), anElemCopy );
147 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
149 // copy element nodes
150 int anElemNbNodes = anElem->NbNodes();
151 vector< int > anElemNodesID( anElemNbNodes ) ;
152 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
153 for ( int i = 0; itElemNodes->more(); i++)
155 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
157 anElemNodesID[i] = anElemNode->GetID();
160 // creates a corresponding element on copied nodes
161 SMDS_MeshElement* anElemCopy = 0;
162 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
164 const SMDS_VtkVolume* ph =
165 dynamic_cast<const SMDS_VtkVolume*> (anElem);
167 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
168 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
171 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
178 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
180 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
181 anElemNode->GetID());
183 };// struct TPreviewMesh
185 static SMESH_NodeSearcher * theNodeSearcher = 0;
186 static SMESH_ElementSearcher * theElementSearcher = 0;
188 //=============================================================================
190 * \brief Deleter of theNodeSearcher at any compute event occured
192 //=============================================================================
194 struct TSearchersDeleter : public SMESH_subMeshEventListener
197 string myMeshPartIOR;
199 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
200 "SMESH_MeshEditor_i::TSearchersDeleter"),
202 //!< Delete theNodeSearcher
205 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
206 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
208 typedef map < int, SMESH_subMesh * > TDependsOnMap;
209 //!< The meshod called by submesh: do my main job
210 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
211 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
213 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
215 Unset( sm->GetFather() );
218 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
219 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
221 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
228 myMeshPartIOR = meshPartIOR;
229 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
230 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
231 TDependsOnMap::const_iterator sm;
232 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
233 sm->second->SetEventListener( this, 0, sm->second );
237 //!< delete self from all submeshes
238 void Unset(SMESH_Mesh* mesh)
240 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
241 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
242 TDependsOnMap::const_iterator sm;
243 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
244 sm->second->DeleteEventListener( this );
249 } theSearchersDeleter;
251 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
253 TCollection_AsciiString typeStr;
254 switch ( theMirrorType ) {
255 case SMESH::SMESH_MeshEditor::POINT:
256 typeStr = "SMESH.SMESH_MeshEditor.POINT";
258 case SMESH::SMESH_MeshEditor::AXIS:
259 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
262 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
266 //================================================================================
268 * \brief function for conversion of long_array to TIDSortedElemSet
269 * \param IDs - array of IDs
270 * \param aMesh - mesh
271 * \param aMap - collection to fill
272 * \param aType - element type
274 //================================================================================
276 void arrayToSet(const SMESH::long_array & IDs,
277 const SMESHDS_Mesh* aMesh,
278 TIDSortedElemSet& aMap,
279 const SMDSAbs_ElementType aType = SMDSAbs_All )
281 for (int i=0; i<IDs.length(); i++) {
282 CORBA::Long ind = IDs[i];
283 const SMDS_MeshElement * elem =
284 (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
285 if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
289 //================================================================================
291 * \brief Retrieve elements of given type from SMESH_IDSource
293 //================================================================================
295 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
296 const SMESHDS_Mesh* theMeshDS,
297 TIDSortedElemSet& theElemSet,
298 const SMDSAbs_ElementType theType,
299 const bool emptyIfIsMesh=false)
302 if ( CORBA::is_nil( theIDSource ) )
304 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
307 SMESH::long_array_var anIDs = theIDSource->GetIDs();
308 if ( anIDs->length() == 0 )
310 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
311 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
313 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
314 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
320 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
321 return bool(anIDs->length()) == bool(theElemSet.size());
325 //================================================================================
327 * \brief Retrieve nodes from SMESH_IDSource
329 //================================================================================
331 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
332 const SMESHDS_Mesh* theMeshDS,
333 TIDSortedNodeSet& theNodeSet)
336 if ( CORBA::is_nil( theObject ) )
338 SMESH::array_of_ElementType_var types = theObject->GetTypes();
339 SMESH::long_array_var aElementsId = theObject->GetIDs();
340 if ( types->length() == 1 && types[0] == SMESH::NODE)
342 for(int i = 0; i < aElementsId->length(); i++)
343 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
344 theNodeSet.insert( theNodeSet.end(), n);
346 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
348 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
349 while ( nIt->more( ))
350 if( const SMDS_MeshElement * elem = nIt->next() )
351 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
355 for(int i = 0; i < aElementsId->length(); i++)
356 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
357 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
361 //================================================================================
363 * \brief Returns elements connected to the given elements
365 //================================================================================
367 void getElementsAround(const TIDSortedElemSet& theElements,
368 const SMESHDS_Mesh* theMeshDS,
369 TIDSortedElemSet& theElementsAround)
371 if ( theElements.empty() ) return;
373 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
374 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
376 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
377 return; // all the elements are in theElements
380 elemType = SMDSAbs_All;
382 TIDSortedElemSet visitedNodes;
383 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
384 for ( ; elemIt != theElements.end(); ++elemIt )
386 const SMDS_MeshElement* e = *elemIt;
387 int i = e->NbCornerNodes();
390 const SMDS_MeshNode* n = e->GetNode( i );
391 if ( visitedNodes.insert( n ).second )
393 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
394 while ( invIt->more() )
396 const SMDS_MeshElement* elemAround = invIt->next();
397 if ( !theElements.count( elemAround ))
398 theElementsAround.insert( elemAround );
405 //================================================================================
407 * \brief Return a string used to detect change of mesh part on which theElementSearcher
408 * is going to be used
410 //================================================================================
412 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
414 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
415 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
416 // take into account passible group modification
417 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
418 partIOR += SMESH_Comment( type );
424 //=============================================================================
428 //=============================================================================
430 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
432 myMesh( &theMesh->GetImpl() ),
434 myPreviewMode ( isPreview )
438 //================================================================================
442 //================================================================================
444 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
448 //================================================================================
450 * \brief Clear members
452 //================================================================================
454 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
456 if ( myPreviewMode ) {
457 //myPreviewData = new SMESH::MeshPreviewStruct();
460 if ( deleteSearchers )
461 TSearchersDeleter::Delete();
463 myEditor.GetError().reset();
466 //================================================================================
468 * \brief Now does nothing
470 //================================================================================
472 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& )
476 //================================================================================
478 * Return data of mesh edition preview
480 //================================================================================
482 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
484 const bool hasBadElems = ( myEditor.GetError() && myEditor.GetError()->HasBadElems() );
486 if ( myPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
488 list<int> aNodesConnectivity;
489 typedef map<int, int> TNodesMap;
492 SMESHDS_Mesh* aMeshDS;
493 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
495 aMeshPartDS.reset( new SMESH_MeshPartDS( myEditor.GetError()->myBadElements ));
496 aMeshDS = aMeshPartDS.get();
499 aMeshDS = myEditor.GetMeshDS();
501 int nbEdges = aMeshDS->NbEdges();
502 int nbFaces = aMeshDS->NbFaces();
503 int nbVolum = aMeshDS->NbVolumes();
504 myPreviewData = new SMESH::MeshPreviewStruct();
505 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
508 SMDSAbs_ElementType previewType = SMDSAbs_All;
510 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( myEditor.GetMesh() )) {
511 previewType = aPreviewMesh->myPreviewType;
512 switch ( previewType ) {
513 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
514 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
515 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
520 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
522 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
524 while ( itMeshElems->more() ) {
525 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
526 if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
529 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
530 while ( itElemNodes->more() ) {
531 const SMDS_MeshNode* aMeshNode =
532 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
533 int aNodeID = aMeshNode->GetID();
534 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
535 if ( anIter == nodesMap.end() ) {
536 // filling the nodes coordinates
537 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
538 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
539 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
540 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
543 aNodesConnectivity.push_back(anIter->second);
546 // filling the elements types
547 SMDSAbs_ElementType aType = aMeshElem->GetType();
548 bool isPoly = aMeshElem->IsPoly();
550 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
551 myPreviewData->elementTypes[i].isPoly = isPoly;
552 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
556 myPreviewData->nodesXYZ.length( j );
558 // filling the elements connectivities
559 list<int>::iterator aConnIter = aNodesConnectivity.begin();
560 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
561 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
562 myPreviewData->elementConnectivities[i] = *aConnIter;
565 return myPreviewData._retn();
568 //================================================================================
570 * \brief Returns list of it's IDs of created nodes
571 * \retval SMESH::long_array* - list of node ID
573 //================================================================================
575 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
577 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
578 const SMESH_SequenceOfElemPtr& aSeq = myEditor.GetLastCreatedNodes();
579 myLastCreatedNodes->length( aSeq.Length() );
580 for (int i = 1; i <= aSeq.Length(); i++)
581 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
582 return myLastCreatedNodes._retn();
585 //================================================================================
587 * \brief Returns list of it's IDs of created elements
588 * \retval SMESH::long_array* - list of elements' ID
590 //================================================================================
592 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
594 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
595 const SMESH_SequenceOfElemPtr& aSeq = myEditor.GetLastCreatedElems();
596 myLastCreatedElems->length( aSeq.Length() );
597 for ( int i = 1; i <= aSeq.Length(); i++ )
598 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
599 return myLastCreatedElems._retn();
602 //=======================================================================
604 * Returns description of an error/warning occured during the last operation
606 //=======================================================================
608 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
610 SMESH::ComputeError* errOut = new SMESH::ComputeError;
611 SMESH_ComputeErrorPtr& errIn = myEditor.GetError();
612 if ( errIn && !errIn->IsOK() )
614 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
615 errOut->comment = errIn->myComment.c_str();
616 errOut->subShapeID = -1;
617 errOut->hasBadMesh = !errIn->myBadElements.empty();
622 //=======================================================================
623 //function : MakeIDSource
624 //purpose : Wrap a sequence of ids in a SMESH_IDSource
625 //=======================================================================
627 struct _IDSource : public POA_SMESH::SMESH_IDSource
629 SMESH::long_array _ids;
630 SMESH::ElementType _type;
631 SMESH::SMESH_Mesh_ptr _mesh;
632 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
633 SMESH::long_array* GetMeshInfo() { return 0; }
634 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
635 bool IsMeshInfoCorrect() { return true; }
636 SMESH::array_of_ElementType* GetTypes()
638 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
639 if ( _ids.length() > 0 ) {
643 return types._retn();
647 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
648 SMESH::ElementType type)
650 _IDSource* anIDSource = new _IDSource;
651 anIDSource->_ids = ids;
652 anIDSource->_type = type;
653 anIDSource->_mesh = myMesh_i->_this();
654 SMESH::SMESH_IDSource_var anIDSourceVar = anIDSource->_this();
656 return anIDSourceVar._retn();
659 //=============================================================================
663 //=============================================================================
666 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
672 for (int i = 0; i < IDsOfElements.length(); i++)
673 IdList.push_back( IDsOfElements[i] );
675 // Update Python script
676 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
679 bool ret = myEditor.Remove( IdList, false );
680 myMesh->GetMeshDS()->Modified();
681 if ( IDsOfElements.length() )
682 myMesh->SetIsModified( true ); // issue 0020693
686 //=============================================================================
690 //=============================================================================
692 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
697 for (int i = 0; i < IDsOfNodes.length(); i++)
698 IdList.push_back( IDsOfNodes[i] );
700 // Update Python script
701 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
703 bool ret = myEditor.Remove( IdList, true );
704 myMesh->GetMeshDS()->Modified();
705 if ( IDsOfNodes.length() )
706 myMesh->SetIsModified( true ); // issue 0020693
710 //=============================================================================
714 //=============================================================================
716 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
721 // Update Python script
722 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
724 // Create filter to find all orphan nodes
725 SMESH::Controls::Filter::TIdSequence seq;
726 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
727 SMESH::Controls::Filter::GetElementsId( GetMeshDS(), predicate, seq );
729 // remove orphan nodes (if there are any)
731 for ( int i = 0; i < seq.size(); i++ )
732 IdList.push_back( seq[i] );
734 int nbNodesBefore = myMesh->NbNodes();
735 myEditor.Remove( IdList, true );
736 myMesh->GetMeshDS()->Modified();
738 myMesh->SetIsModified( true );
739 int nbNodesAfter = myMesh->NbNodes();
741 return nbNodesBefore - nbNodesAfter;
744 //=============================================================================
748 //=============================================================================
750 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
751 CORBA::Double y, CORBA::Double z)
755 const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
757 // Update Python script
758 TPythonDump() << "nodeID = " << this << ".AddNode( "
759 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
761 myMesh->GetMeshDS()->Modified();
762 myMesh->SetIsModified( true ); // issue 0020693
766 //=============================================================================
768 * Create 0D element on the given node.
770 //=============================================================================
772 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
776 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
777 SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode);
779 // Update Python script
780 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
782 myMesh->GetMeshDS()->Modified();
783 myMesh->SetIsModified( true ); // issue 0020693
786 return elem->GetID();
791 //=============================================================================
793 * Create a ball element on the given node.
795 //=============================================================================
797 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
798 throw (SALOME::SALOME_Exception)
802 if ( diameter < std::numeric_limits<double>::min() )
803 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
805 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
806 SMDS_MeshElement* elem = GetMeshDS()->AddBall(aNode, diameter);
808 // Update Python script
809 TPythonDump() << "ballElem = "
810 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
812 myMesh->GetMeshDS()->Modified();
813 myMesh->SetIsModified( true ); // issue 0020693
816 return elem->GetID();
821 //=============================================================================
823 * Create an edge, either linear and quadratic (this is determed
824 * by number of given nodes, two or three)
826 //=============================================================================
828 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
832 int NbNodes = IDsOfNodes.length();
833 SMDS_MeshElement* elem = 0;
836 CORBA::Long index1 = IDsOfNodes[0];
837 CORBA::Long index2 = IDsOfNodes[1];
838 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
840 // Update Python script
841 TPythonDump() << "edge = " << this << ".AddEdge([ "
842 << index1 << ", " << index2 <<" ])";
845 CORBA::Long n1 = IDsOfNodes[0];
846 CORBA::Long n2 = IDsOfNodes[1];
847 CORBA::Long n12 = IDsOfNodes[2];
848 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
849 GetMeshDS()->FindNode(n2),
850 GetMeshDS()->FindNode(n12));
851 // Update Python script
852 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
853 <<n1<<", "<<n2<<", "<<n12<<" ])";
856 myMesh->GetMeshDS()->Modified();
858 return myMesh->SetIsModified( true ), elem->GetID();
863 //=============================================================================
867 //=============================================================================
869 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
873 int NbNodes = IDsOfNodes.length();
879 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
880 for (int i = 0; i < NbNodes; i++)
881 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
883 SMDS_MeshElement* elem = 0;
885 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
887 else if (NbNodes == 4) {
888 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
890 else if (NbNodes == 6) {
891 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
894 else if (NbNodes == 8) {
895 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
896 nodes[4], nodes[5], nodes[6], nodes[7]);
898 else if (NbNodes == 9) {
899 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
900 nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
902 else if (NbNodes > 2) {
903 elem = GetMeshDS()->AddPolygonalFace(nodes);
906 // Update Python script
907 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
909 myMesh->GetMeshDS()->Modified();
911 return myMesh->SetIsModified( true ), elem->GetID();
916 //=============================================================================
920 //=============================================================================
921 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
925 int NbNodes = IDsOfNodes.length();
926 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
927 for (int i = 0; i < NbNodes; i++)
928 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
930 const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
932 // Update Python script
933 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
935 myMesh->GetMeshDS()->Modified();
936 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
939 //=============================================================================
941 * Create volume, either linear and quadratic (this is determed
942 * by number of given nodes)
944 //=============================================================================
946 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
950 int NbNodes = IDsOfNodes.length();
951 vector< const SMDS_MeshNode*> n(NbNodes);
952 for(int i=0;i<NbNodes;i++)
953 n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
955 SMDS_MeshElement* elem = 0;
958 case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
959 case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
960 case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
961 case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
962 case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
963 n[6],n[7],n[8],n[9]);
965 case 12:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
966 n[6],n[7],n[8],n[9],n[10],n[11]);
968 case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
969 n[7],n[8],n[9],n[10],n[11],n[12]);
971 case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
972 n[9],n[10],n[11],n[12],n[13],n[14]);
974 case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
975 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
976 n[15],n[16],n[17],n[18],n[19]);
978 case 27:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
979 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
980 n[15],n[16],n[17],n[18],n[19],
981 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
985 // Update Python script
986 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
988 myMesh->GetMeshDS()->Modified();
990 return myMesh->SetIsModified( true ), elem->GetID();
995 //=============================================================================
997 * AddPolyhedralVolume
999 //=============================================================================
1000 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1001 const SMESH::long_array & Quantities)
1005 int NbNodes = IDsOfNodes.length();
1006 std::vector<const SMDS_MeshNode*> n (NbNodes);
1007 for (int i = 0; i < NbNodes; i++)
1009 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
1010 if (!aNode) return 0;
1014 int NbFaces = Quantities.length();
1015 std::vector<int> q (NbFaces);
1016 for (int j = 0; j < NbFaces; j++)
1017 q[j] = Quantities[j];
1019 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
1021 // Update Python script
1022 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1023 << IDsOfNodes << ", " << Quantities << " )";
1024 myMesh->GetMeshDS()->Modified();
1026 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1029 //=============================================================================
1031 * AddPolyhedralVolumeByFaces
1033 //=============================================================================
1034 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1038 int NbFaces = IdsOfFaces.length();
1039 std::vector<const SMDS_MeshNode*> poly_nodes;
1040 std::vector<int> quantities (NbFaces);
1042 for (int i = 0; i < NbFaces; i++) {
1043 const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
1044 quantities[i] = aFace->NbNodes();
1046 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1047 while (It->more()) {
1048 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1052 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1054 // Update Python script
1055 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1056 << IdsOfFaces << " )";
1057 myMesh->GetMeshDS()->Modified();
1059 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1062 //=============================================================================
1064 * \brief Bind a node to a vertex
1065 * \param NodeID - node ID
1066 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1067 * \retval boolean - false if NodeID or VertexID is invalid
1069 //=============================================================================
1071 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1072 throw (SALOME::SALOME_Exception)
1074 Unexpect aCatch(SALOME_SalomeException);
1076 SMESHDS_Mesh * mesh = GetMeshDS();
1077 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1079 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1081 if ( mesh->MaxShapeIndex() < VertexID )
1082 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1084 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1085 if ( shape.ShapeType() != TopAbs_VERTEX )
1086 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1088 mesh->SetNodeOnVertex( node, VertexID );
1090 myMesh->SetIsModified( true );
1093 //=============================================================================
1095 * \brief Store node position on an edge
1096 * \param NodeID - node ID
1097 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1098 * \param paramOnEdge - parameter on edge where the node is located
1099 * \retval boolean - false if any parameter is invalid
1101 //=============================================================================
1103 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1104 CORBA::Double paramOnEdge)
1105 throw (SALOME::SALOME_Exception)
1107 Unexpect aCatch(SALOME_SalomeException);
1109 SMESHDS_Mesh * mesh = GetMeshDS();
1110 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1112 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1114 if ( mesh->MaxShapeIndex() < EdgeID )
1115 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1117 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1118 if ( shape.ShapeType() != TopAbs_EDGE )
1119 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1122 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1123 if ( paramOnEdge < f || paramOnEdge > l )
1124 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1126 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1128 myMesh->SetIsModified( true );
1131 //=============================================================================
1133 * \brief Store node position on a face
1134 * \param NodeID - node ID
1135 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1136 * \param u - U parameter on face where the node is located
1137 * \param v - V parameter on face where the node is located
1138 * \retval boolean - false if any parameter is invalid
1140 //=============================================================================
1142 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1143 CORBA::Double u, CORBA::Double v)
1144 throw (SALOME::SALOME_Exception)
1146 Unexpect aCatch(SALOME_SalomeException);
1148 SMESHDS_Mesh * mesh = GetMeshDS();
1149 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1151 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1153 if ( mesh->MaxShapeIndex() < FaceID )
1154 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1156 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1157 if ( shape.ShapeType() != TopAbs_FACE )
1158 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1160 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1161 bool isOut = ( u < surf.FirstUParameter() ||
1162 u > surf.LastUParameter() ||
1163 v < surf.FirstVParameter() ||
1164 v > surf.LastVParameter() );
1168 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1169 << " u( " << surf.FirstUParameter()
1170 << "," << surf.LastUParameter()
1171 << ") v( " << surf.FirstVParameter()
1172 << "," << surf.LastVParameter() << ")" );
1174 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1177 mesh->SetNodeOnFace( node, FaceID, u, v );
1178 myMesh->SetIsModified( true );
1181 //=============================================================================
1183 * \brief Bind a node to a solid
1184 * \param NodeID - node ID
1185 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1186 * \retval boolean - false if NodeID or SolidID is invalid
1188 //=============================================================================
1190 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1191 throw (SALOME::SALOME_Exception)
1193 Unexpect aCatch(SALOME_SalomeException);
1195 SMESHDS_Mesh * mesh = GetMeshDS();
1196 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1198 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1200 if ( mesh->MaxShapeIndex() < SolidID )
1201 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1203 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1204 if ( shape.ShapeType() != TopAbs_SOLID &&
1205 shape.ShapeType() != TopAbs_SHELL)
1206 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1208 mesh->SetNodeInVolume( node, SolidID );
1210 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
1213 //=============================================================================
1215 * \brief Bind an element to a shape
1216 * \param ElementID - element ID
1217 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1218 * \retval boolean - false if ElementID or ShapeID is invalid
1220 //=============================================================================
1222 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1223 CORBA::Long ShapeID)
1224 throw (SALOME::SALOME_Exception)
1226 Unexpect aCatch(SALOME_SalomeException);
1228 SMESHDS_Mesh * mesh = GetMeshDS();
1229 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1231 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1233 if ( mesh->MaxShapeIndex() < ShapeID )
1234 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1236 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1237 if ( shape.ShapeType() != TopAbs_EDGE &&
1238 shape.ShapeType() != TopAbs_FACE &&
1239 shape.ShapeType() != TopAbs_SOLID &&
1240 shape.ShapeType() != TopAbs_SHELL )
1241 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1243 mesh->SetMeshElementOnShape( elem, ShapeID );
1245 myMesh->SetIsModified( true );
1248 //=============================================================================
1252 //=============================================================================
1254 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1255 CORBA::Long NodeID2)
1259 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1260 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1264 // Update Python script
1265 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1266 << NodeID1 << ", " << NodeID2 << " )";
1269 int ret = myEditor.InverseDiag ( n1, n2 );
1270 myMesh->GetMeshDS()->Modified();
1271 myMesh->SetIsModified( true );
1275 //=============================================================================
1279 //=============================================================================
1281 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1282 CORBA::Long NodeID2)
1286 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1287 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1291 // Update Python script
1292 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1293 << NodeID1 << ", " << NodeID2 << " )";
1296 bool stat = myEditor.DeleteDiag ( n1, n2 );
1298 myMesh->GetMeshDS()->Modified();
1300 myMesh->SetIsModified( true ); // issue 0020693
1302 storeResult(myEditor);
1307 //=============================================================================
1311 //=============================================================================
1313 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1317 for (int i = 0; i < IDsOfElements.length(); i++)
1319 CORBA::Long index = IDsOfElements[i];
1320 const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
1322 myEditor.Reorient( elem );
1324 // Update Python script
1325 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1327 myMesh->GetMeshDS()->Modified();
1328 if ( IDsOfElements.length() )
1329 myMesh->SetIsModified( true ); // issue 0020693
1335 //=============================================================================
1339 //=============================================================================
1341 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1345 TPythonDump aTPythonDump; // suppress dump in Reorient()
1347 SMESH::long_array_var anElementsId = theObject->GetIDs();
1348 CORBA::Boolean isDone = Reorient(anElementsId);
1350 // Update Python script
1351 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1356 //=======================================================================
1357 //function : Reorient2D
1358 //purpose : Reorient faces contained in \a the2Dgroup.
1359 // the2Dgroup - the mesh or its part to reorient
1360 // theDirection - desired direction of normal of \a theFace
1361 // theFace - ID of face whose orientation is checked.
1362 // It can be < 1 then \a thePoint is used to find a face.
1363 // thePoint - is used to find a face if \a theFace < 1.
1364 // return number of reoriented elements.
1365 //=======================================================================
1367 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1368 const SMESH::DirStruct& theDirection,
1369 CORBA::Long theFace,
1370 const SMESH::PointStruct& thePoint)
1371 throw (SALOME::SALOME_Exception)
1373 Unexpect aCatch(SALOME_SalomeException);
1375 initData(/*deleteSearchers=*/false);
1377 TIDSortedElemSet elements;
1378 if ( !idSourceToSet( the2Dgroup, GetMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1379 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1382 const SMDS_MeshElement* face = 0;
1385 face = GetMeshDS()->FindElement( theFace );
1387 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1388 if ( face->GetType() != SMDSAbs_Face )
1389 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1393 // create theElementSearcher if needed
1394 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1395 if ( !theElementSearcher )
1397 if ( elements.empty() ) // search in the whole mesh
1399 if ( myMesh->NbFaces() == 0 )
1400 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1402 theElementSearcher = myEditor.GetElementSearcher();
1406 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1407 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1409 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
1413 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1414 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1417 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1418 if ( !elements.empty() && !elements.count( face ))
1419 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1422 const SMESH::PointStruct * P = &theDirection.PS;
1423 gp_Vec dirVec( P->x, P->y, P->z );
1424 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1425 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1427 int nbReori = myEditor.Reorient2D( elements, dirVec, face );
1428 storeResult(myEditor);
1431 myMesh->SetIsModified( true );
1432 myMesh->GetMeshDS()->Modified();
1434 TPythonDump() << this << ".Reorient2D( "
1435 << the2Dgroup << ", "
1436 << theDirection << ", "
1438 << thePoint << " )";
1443 //=============================================================================
1447 //=============================================================================
1448 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1449 SMESH::NumericalFunctor_ptr Criterion,
1450 CORBA::Double MaxAngle)
1454 SMESHDS_Mesh* aMesh = GetMeshDS();
1455 TIDSortedElemSet faces;
1456 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1458 SMESH::NumericalFunctor_i* aNumericalFunctor =
1459 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1460 SMESH::Controls::NumericalFunctorPtr aCrit;
1461 if ( !aNumericalFunctor )
1462 aCrit.reset( new SMESH::Controls::AspectRatio() );
1464 aCrit = aNumericalFunctor->GetNumericalFunctor();
1466 // Update Python script
1467 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1468 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1471 bool stat = myEditor.TriToQuad( faces, aCrit, MaxAngle );
1472 myMesh->GetMeshDS()->Modified();
1474 myMesh->SetIsModified( true ); // issue 0020693
1476 storeResult(myEditor);
1482 //=============================================================================
1486 //=============================================================================
1487 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1488 SMESH::NumericalFunctor_ptr Criterion,
1489 CORBA::Double MaxAngle)
1493 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1494 SMESH::long_array_var anElementsId = theObject->GetIDs();
1495 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1497 SMESH::NumericalFunctor_i* aNumericalFunctor =
1498 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1500 // Update Python script
1501 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1502 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1508 //=============================================================================
1512 //=============================================================================
1513 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1514 SMESH::NumericalFunctor_ptr Criterion)
1518 SMESHDS_Mesh* aMesh = GetMeshDS();
1519 TIDSortedElemSet faces;
1520 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1522 SMESH::NumericalFunctor_i* aNumericalFunctor =
1523 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1524 SMESH::Controls::NumericalFunctorPtr aCrit;
1525 if ( !aNumericalFunctor )
1526 aCrit.reset( new SMESH::Controls::AspectRatio() );
1528 aCrit = aNumericalFunctor->GetNumericalFunctor();
1531 // Update Python script
1532 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1534 CORBA::Boolean stat = myEditor.QuadToTri( faces, aCrit );
1535 myMesh->GetMeshDS()->Modified();
1537 myMesh->SetIsModified( true ); // issue 0020693
1539 storeResult(myEditor);
1545 //=============================================================================
1549 //=============================================================================
1550 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1551 SMESH::NumericalFunctor_ptr Criterion)
1555 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1557 SMESH::long_array_var anElementsId = theObject->GetIDs();
1558 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1560 SMESH::NumericalFunctor_i* aNumericalFunctor =
1561 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1563 // Update Python script
1564 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1570 //=============================================================================
1574 //=============================================================================
1575 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1576 CORBA::Boolean Diag13)
1580 SMESHDS_Mesh* aMesh = GetMeshDS();
1581 TIDSortedElemSet faces;
1582 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1584 // Update Python script
1585 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1586 << IDsOfElements << ", " << Diag13 << " )";
1588 CORBA::Boolean stat = myEditor.QuadToTri( faces, Diag13 );
1589 myMesh->GetMeshDS()->Modified();
1591 myMesh->SetIsModified( true ); // issue 0020693
1594 storeResult(myEditor);
1600 //=============================================================================
1604 //=============================================================================
1605 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1606 CORBA::Boolean Diag13)
1610 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1612 SMESH::long_array_var anElementsId = theObject->GetIDs();
1613 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1615 // Update Python script
1616 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1617 << theObject << ", " << Diag13 << " )";
1623 //=============================================================================
1627 //=============================================================================
1628 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1629 SMESH::NumericalFunctor_ptr Criterion)
1633 const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1634 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1636 SMESH::NumericalFunctor_i* aNumericalFunctor =
1637 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1638 SMESH::Controls::NumericalFunctorPtr aCrit;
1639 if (aNumericalFunctor)
1640 aCrit = aNumericalFunctor->GetNumericalFunctor();
1642 aCrit.reset(new SMESH::Controls::AspectRatio());
1644 return myEditor.BestSplit(quad, aCrit);
1649 //================================================================================
1651 * \brief Split volumic elements into tetrahedrons
1653 //================================================================================
1655 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1656 CORBA::Short methodFlags)
1657 throw (SALOME::SALOME_Exception)
1659 Unexpect aCatch(SALOME_SalomeException);
1663 SMESH::long_array_var anElementsId = elems->GetIDs();
1664 TIDSortedElemSet elemSet;
1665 arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume );
1667 myEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1668 myMesh->GetMeshDS()->Modified();
1670 storeResult(myEditor);
1672 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1673 // myMesh->SetIsModified( true ); // issue 0020693
1675 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1676 << elems << ", " << methodFlags << " )";
1679 //=======================================================================
1682 //=======================================================================
1685 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1686 const SMESH::long_array & IDsOfFixedNodes,
1687 CORBA::Long MaxNbOfIterations,
1688 CORBA::Double MaxAspectRatio,
1689 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1691 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1692 MaxAspectRatio, Method, false );
1696 //=======================================================================
1697 //function : SmoothParametric
1699 //=======================================================================
1702 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1703 const SMESH::long_array & IDsOfFixedNodes,
1704 CORBA::Long MaxNbOfIterations,
1705 CORBA::Double MaxAspectRatio,
1706 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1708 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1709 MaxAspectRatio, Method, true );
1713 //=======================================================================
1714 //function : SmoothObject
1716 //=======================================================================
1719 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1720 const SMESH::long_array & IDsOfFixedNodes,
1721 CORBA::Long MaxNbOfIterations,
1722 CORBA::Double MaxAspectRatio,
1723 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1725 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1726 MaxAspectRatio, Method, false);
1730 //=======================================================================
1731 //function : SmoothParametricObject
1733 //=======================================================================
1736 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1737 const SMESH::long_array & IDsOfFixedNodes,
1738 CORBA::Long MaxNbOfIterations,
1739 CORBA::Double MaxAspectRatio,
1740 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1742 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1743 MaxAspectRatio, Method, true);
1747 //=============================================================================
1751 //=============================================================================
1754 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1755 const SMESH::long_array & IDsOfFixedNodes,
1756 CORBA::Long MaxNbOfIterations,
1757 CORBA::Double MaxAspectRatio,
1758 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1763 SMESHDS_Mesh* aMesh = GetMeshDS();
1765 TIDSortedElemSet elements;
1766 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1768 set<const SMDS_MeshNode*> fixedNodes;
1769 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1770 CORBA::Long index = IDsOfFixedNodes[i];
1771 const SMDS_MeshNode * node = aMesh->FindNode(index);
1773 fixedNodes.insert( node );
1775 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1776 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1777 method = ::SMESH_MeshEditor::CENTROIDAL;
1779 myEditor.Smooth(elements, fixedNodes, method,
1780 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1782 myMesh->GetMeshDS()->Modified();
1783 myMesh->SetIsModified( true ); // issue 0020693
1785 storeResult(myEditor);
1787 // Update Python script
1788 TPythonDump() << "isDone = " << this << "."
1789 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1790 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1791 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1792 << "SMESH.SMESH_MeshEditor."
1793 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1794 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1800 //=============================================================================
1804 //=============================================================================
1807 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1808 const SMESH::long_array & IDsOfFixedNodes,
1809 CORBA::Long MaxNbOfIterations,
1810 CORBA::Double MaxAspectRatio,
1811 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1816 TPythonDump aTPythonDump; // suppress dump in smooth()
1818 SMESH::long_array_var anElementsId = theObject->GetIDs();
1819 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1820 MaxAspectRatio, Method, IsParametric);
1822 // Update Python script
1823 aTPythonDump << "isDone = " << this << "."
1824 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1825 << theObject << ", " << IDsOfFixedNodes << ", "
1826 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1827 << "SMESH.SMESH_MeshEditor."
1828 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1829 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1835 //=============================================================================
1839 //=============================================================================
1841 void SMESH_MeshEditor_i::RenumberNodes()
1843 // Update Python script
1844 TPythonDump() << this << ".RenumberNodes()";
1846 GetMeshDS()->Renumber( true );
1850 //=============================================================================
1854 //=============================================================================
1856 void SMESH_MeshEditor_i::RenumberElements()
1858 // Update Python script
1859 TPythonDump() << this << ".RenumberElements()";
1861 GetMeshDS()->Renumber( false );
1864 //=======================================================================
1866 * \brief Return groups by their IDs
1868 //=======================================================================
1870 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1874 myMesh_i->CreateGroupServants();
1875 return myMesh_i->GetGroups( *groupIDs );
1878 //=======================================================================
1879 //function : rotationSweep
1881 //=======================================================================
1883 SMESH::ListOfGroups*
1884 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1885 const SMESH::AxisStruct & theAxis,
1886 CORBA::Double theAngleInRadians,
1887 CORBA::Long theNbOfSteps,
1888 CORBA::Double theTolerance,
1889 const bool theMakeGroups,
1890 const SMDSAbs_ElementType theElementType)
1894 TIDSortedElemSet inElements, copyElements;
1895 arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
1897 TIDSortedElemSet* workElements = & inElements;
1898 TPreviewMesh tmpMesh( SMDSAbs_Face );
1899 SMESH_Mesh* mesh = 0;
1900 bool makeWalls=true;
1901 if ( myPreviewMode )
1903 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1904 tmpMesh.Copy( inElements, copyElements, select, avoid );
1906 workElements = & copyElements;
1907 //makeWalls = false;
1914 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
1915 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1917 ::SMESH_MeshEditor::PGroupIDs groupIds =
1918 myEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1919 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
1920 storeResult(myEditor);
1921 myMesh->GetMeshDS()->Modified();
1923 // myMesh->SetIsModified( true ); -- it does not influence Compute()
1925 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1928 //=======================================================================
1929 //function : RotationSweep
1931 //=======================================================================
1933 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1934 const SMESH::AxisStruct & theAxis,
1935 CORBA::Double theAngleInRadians,
1936 CORBA::Long theNbOfSteps,
1937 CORBA::Double theTolerance)
1939 if ( !myPreviewMode ) {
1940 TPythonDump() << this << ".RotationSweep( "
1941 << theIDsOfElements << ", "
1943 << TVar( theAngleInRadians ) << ", "
1944 << TVar( theNbOfSteps ) << ", "
1945 << TVar( theTolerance ) << " )";
1947 rotationSweep(theIDsOfElements,
1955 //=======================================================================
1956 //function : RotationSweepMakeGroups
1958 //=======================================================================
1960 SMESH::ListOfGroups*
1961 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1962 const SMESH::AxisStruct& theAxis,
1963 CORBA::Double theAngleInRadians,
1964 CORBA::Long theNbOfSteps,
1965 CORBA::Double theTolerance)
1967 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1969 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
1975 if (!myPreviewMode) {
1976 DumpGroupsList(aPythonDump, aGroups);
1977 aPythonDump << this << ".RotationSweepMakeGroups( "
1978 << theIDsOfElements << ", "
1980 << TVar( theAngleInRadians ) << ", "
1981 << TVar( theNbOfSteps ) << ", "
1982 << TVar( theTolerance ) << " )";
1987 //=======================================================================
1988 //function : RotationSweepObject
1990 //=======================================================================
1992 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1993 const SMESH::AxisStruct & theAxis,
1994 CORBA::Double theAngleInRadians,
1995 CORBA::Long theNbOfSteps,
1996 CORBA::Double theTolerance)
1998 if ( !myPreviewMode ) {
1999 TPythonDump() << this << ".RotationSweepObject( "
2000 << theObject << ", "
2002 << theAngleInRadians << ", "
2003 << theNbOfSteps << ", "
2004 << theTolerance << " )";
2006 SMESH::long_array_var anElementsId = theObject->GetIDs();
2007 rotationSweep(anElementsId,
2015 //=======================================================================
2016 //function : RotationSweepObject1D
2018 //=======================================================================
2020 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2021 const SMESH::AxisStruct & theAxis,
2022 CORBA::Double theAngleInRadians,
2023 CORBA::Long theNbOfSteps,
2024 CORBA::Double theTolerance)
2026 if ( !myPreviewMode ) {
2027 TPythonDump() << this << ".RotationSweepObject1D( "
2028 << theObject << ", "
2030 << TVar( theAngleInRadians ) << ", "
2031 << TVar( theNbOfSteps ) << ", "
2032 << TVar( theTolerance ) << " )";
2034 SMESH::long_array_var anElementsId = theObject->GetIDs();
2035 rotationSweep(anElementsId,
2044 //=======================================================================
2045 //function : RotationSweepObject2D
2047 //=======================================================================
2049 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2050 const SMESH::AxisStruct & theAxis,
2051 CORBA::Double theAngleInRadians,
2052 CORBA::Long theNbOfSteps,
2053 CORBA::Double theTolerance)
2055 if ( !myPreviewMode ) {
2056 TPythonDump() << this << ".RotationSweepObject2D( "
2057 << theObject << ", "
2059 << TVar( theAngleInRadians ) << ", "
2060 << TVar( theNbOfSteps ) << ", "
2061 << TVar( theTolerance ) << " )";
2063 SMESH::long_array_var anElementsId = theObject->GetIDs();
2064 rotationSweep(anElementsId,
2073 //=======================================================================
2074 //function : RotationSweepObjectMakeGroups
2076 //=======================================================================
2078 SMESH::ListOfGroups*
2079 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2080 const SMESH::AxisStruct& theAxis,
2081 CORBA::Double theAngleInRadians,
2082 CORBA::Long theNbOfSteps,
2083 CORBA::Double theTolerance)
2085 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2087 SMESH::long_array_var anElementsId = theObject->GetIDs();
2088 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2094 if (!myPreviewMode) {
2095 DumpGroupsList(aPythonDump, aGroups);
2096 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2097 << theObject << ", "
2099 << theAngleInRadians << ", "
2100 << theNbOfSteps << ", "
2101 << theTolerance << " )";
2106 //=======================================================================
2107 //function : RotationSweepObject1DMakeGroups
2109 //=======================================================================
2111 SMESH::ListOfGroups*
2112 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2113 const SMESH::AxisStruct& theAxis,
2114 CORBA::Double theAngleInRadians,
2115 CORBA::Long theNbOfSteps,
2116 CORBA::Double theTolerance)
2118 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2120 SMESH::long_array_var anElementsId = theObject->GetIDs();
2121 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2128 if (!myPreviewMode) {
2129 DumpGroupsList(aPythonDump, aGroups);
2130 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2131 << theObject << ", "
2133 << TVar( theAngleInRadians ) << ", "
2134 << TVar( theNbOfSteps ) << ", "
2135 << TVar( theTolerance ) << " )";
2140 //=======================================================================
2141 //function : RotationSweepObject2DMakeGroups
2143 //=======================================================================
2145 SMESH::ListOfGroups*
2146 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2147 const SMESH::AxisStruct& theAxis,
2148 CORBA::Double theAngleInRadians,
2149 CORBA::Long theNbOfSteps,
2150 CORBA::Double theTolerance)
2152 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2154 SMESH::long_array_var anElementsId = theObject->GetIDs();
2155 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2162 if (!myPreviewMode) {
2163 DumpGroupsList(aPythonDump, aGroups);
2164 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2165 << theObject << ", "
2167 << TVar( theAngleInRadians ) << ", "
2168 << TVar( theNbOfSteps ) << ", "
2169 << TVar( theTolerance ) << " )";
2175 //=======================================================================
2176 //function : extrusionSweep
2178 //=======================================================================
2180 SMESH::ListOfGroups*
2181 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2182 const SMESH::DirStruct & theStepVector,
2183 CORBA::Long theNbOfSteps,
2185 const SMDSAbs_ElementType theElementType)
2193 TIDSortedElemSet elements, copyElements;
2194 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2196 const SMESH::PointStruct * P = &theStepVector.PS;
2197 gp_Vec stepVec( P->x, P->y, P->z );
2199 TIDSortedElemSet* workElements = & elements;
2201 SMDSAbs_ElementType aType = SMDSAbs_Face;
2202 //::SMESH_MeshEditor::ExtrusionFlags aFlag = ::SMESH_MeshEditor::ExtrusionFlags::EXTRUSION_FLAG_BOUNDARY;
2203 if (theElementType == SMDSAbs_Node)
2205 aType = SMDSAbs_Edge;
2206 //aFlag = ::SMESH_MeshEditor::ExtrusionFlags::EXTRUSION_FLAG_SEW;
2208 TPreviewMesh tmpMesh( aType );
2209 SMESH_Mesh* mesh = myMesh;
2211 if ( myPreviewMode ) {
2212 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2213 tmpMesh.Copy( elements, copyElements, select, avoid );
2215 workElements = & copyElements;
2216 theMakeGroups = false;
2219 TElemOfElemListMap aHystory;
2220 ::SMESH_MeshEditor::PGroupIDs groupIds =
2221 myEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2223 myMesh->GetMeshDS()->Modified();
2224 storeResult(myEditor);
2226 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2228 } catch(Standard_Failure) {
2229 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2230 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
2235 //=======================================================================
2236 //function : ExtrusionSweep
2238 //=======================================================================
2240 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2241 const SMESH::DirStruct & theStepVector,
2242 CORBA::Long theNbOfSteps)
2244 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2245 if (!myPreviewMode) {
2246 TPythonDump() << this << ".ExtrusionSweep( "
2247 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2251 //=======================================================================
2252 //function : ExtrusionSweep0D
2254 //=======================================================================
2256 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2257 const SMESH::DirStruct & theStepVector,
2258 CORBA::Long theNbOfSteps)
2260 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2261 if (!myPreviewMode) {
2262 TPythonDump() << this << ".ExtrusionSweep0D( "
2263 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2267 //=======================================================================
2268 //function : ExtrusionSweepObject
2270 //=======================================================================
2272 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2273 const SMESH::DirStruct & theStepVector,
2274 CORBA::Long theNbOfSteps)
2276 SMESH::long_array_var anElementsId = theObject->GetIDs();
2277 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2278 if (!myPreviewMode) {
2279 TPythonDump() << this << ".ExtrusionSweepObject( "
2280 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2284 //=======================================================================
2285 //function : ExtrusionSweepObject0D
2287 //=======================================================================
2289 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2290 const SMESH::DirStruct & theStepVector,
2291 CORBA::Long theNbOfSteps)
2293 SMESH::long_array_var anElementsId = theObject->GetIDs();
2294 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2295 if ( !myPreviewMode ) {
2296 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2297 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2301 //=======================================================================
2302 //function : ExtrusionSweepObject1D
2304 //=======================================================================
2306 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2307 const SMESH::DirStruct & theStepVector,
2308 CORBA::Long theNbOfSteps)
2310 SMESH::long_array_var anElementsId = theObject->GetIDs();
2311 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2312 if ( !myPreviewMode ) {
2313 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2314 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2318 //=======================================================================
2319 //function : ExtrusionSweepObject2D
2321 //=======================================================================
2323 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2324 const SMESH::DirStruct & theStepVector,
2325 CORBA::Long theNbOfSteps)
2327 SMESH::long_array_var anElementsId = theObject->GetIDs();
2328 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2329 if ( !myPreviewMode ) {
2330 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2331 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2335 //=======================================================================
2336 //function : ExtrusionSweepMakeGroups
2338 //=======================================================================
2340 SMESH::ListOfGroups*
2341 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2342 const SMESH::DirStruct& theStepVector,
2343 CORBA::Long theNbOfSteps)
2345 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2347 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2349 if (!myPreviewMode) {
2350 DumpGroupsList(aPythonDump, aGroups);
2351 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2352 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2357 //=======================================================================
2358 //function : ExtrusionSweepMakeGroups0D
2360 //=======================================================================
2362 SMESH::ListOfGroups*
2363 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2364 const SMESH::DirStruct& theStepVector,
2365 CORBA::Long theNbOfSteps)
2367 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2369 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2371 if (!myPreviewMode) {
2372 DumpGroupsList(aPythonDump, aGroups);
2373 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2374 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2379 //=======================================================================
2380 //function : ExtrusionSweepObjectMakeGroups
2382 //=======================================================================
2384 SMESH::ListOfGroups*
2385 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2386 const SMESH::DirStruct& theStepVector,
2387 CORBA::Long theNbOfSteps)
2389 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2391 SMESH::long_array_var anElementsId = theObject->GetIDs();
2392 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2394 if (!myPreviewMode) {
2395 DumpGroupsList(aPythonDump, aGroups);
2396 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2397 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2402 //=======================================================================
2403 //function : ExtrusionSweepObject0DMakeGroups
2405 //=======================================================================
2407 SMESH::ListOfGroups*
2408 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2409 const SMESH::DirStruct& theStepVector,
2410 CORBA::Long theNbOfSteps)
2412 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2414 SMESH::long_array_var anElementsId = theObject->GetIDs();
2415 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2416 theNbOfSteps, true, SMDSAbs_Node);
2417 if (!myPreviewMode) {
2418 DumpGroupsList(aPythonDump, aGroups);
2419 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2420 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2425 //=======================================================================
2426 //function : ExtrusionSweepObject1DMakeGroups
2428 //=======================================================================
2430 SMESH::ListOfGroups*
2431 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2432 const SMESH::DirStruct& theStepVector,
2433 CORBA::Long theNbOfSteps)
2435 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2437 SMESH::long_array_var anElementsId = theObject->GetIDs();
2438 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2439 theNbOfSteps, true, SMDSAbs_Edge);
2440 if (!myPreviewMode) {
2441 DumpGroupsList(aPythonDump, aGroups);
2442 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2443 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2448 //=======================================================================
2449 //function : ExtrusionSweepObject2DMakeGroups
2451 //=======================================================================
2453 SMESH::ListOfGroups*
2454 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2455 const SMESH::DirStruct& theStepVector,
2456 CORBA::Long theNbOfSteps)
2458 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2460 SMESH::long_array_var anElementsId = theObject->GetIDs();
2461 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2462 theNbOfSteps, true, SMDSAbs_Face);
2463 if (!myPreviewMode) {
2464 DumpGroupsList(aPythonDump, aGroups);
2465 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2466 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2472 //=======================================================================
2473 //function : advancedExtrusion
2475 //=======================================================================
2477 SMESH::ListOfGroups*
2478 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2479 const SMESH::DirStruct & theStepVector,
2480 CORBA::Long theNbOfSteps,
2481 CORBA::Long theExtrFlags,
2482 CORBA::Double theSewTolerance,
2483 const bool theMakeGroups)
2487 TIDSortedElemSet elements;
2488 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2490 const SMESH::PointStruct * P = &theStepVector.PS;
2491 gp_Vec stepVec( P->x, P->y, P->z );
2493 TElemOfElemListMap aHystory;
2494 ::SMESH_MeshEditor::PGroupIDs groupIds =
2495 myEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2496 theMakeGroups, theExtrFlags, theSewTolerance);
2497 storeResult(myEditor);
2499 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2502 //=======================================================================
2503 //function : AdvancedExtrusion
2505 //=======================================================================
2507 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2508 const SMESH::DirStruct & theStepVector,
2509 CORBA::Long theNbOfSteps,
2510 CORBA::Long theExtrFlags,
2511 CORBA::Double theSewTolerance)
2513 if ( !myPreviewMode ) {
2514 TPythonDump() << "stepVector = " << theStepVector;
2515 TPythonDump() << this << ".AdvancedExtrusion("
2518 << theNbOfSteps << ","
2519 << theExtrFlags << ", "
2520 << theSewTolerance << " )";
2522 advancedExtrusion( theIDsOfElements,
2530 //=======================================================================
2531 //function : AdvancedExtrusionMakeGroups
2533 //=======================================================================
2534 SMESH::ListOfGroups*
2535 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2536 const SMESH::DirStruct& theStepVector,
2537 CORBA::Long theNbOfSteps,
2538 CORBA::Long theExtrFlags,
2539 CORBA::Double theSewTolerance)
2541 if (!myPreviewMode) {
2542 TPythonDump() << "stepVector = " << theStepVector;
2544 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2546 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2553 if (!myPreviewMode) {
2554 DumpGroupsList(aPythonDump, aGroups);
2555 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2558 << theNbOfSteps << ","
2559 << theExtrFlags << ", "
2560 << theSewTolerance << " )";
2566 //================================================================================
2568 * \brief Convert extrusion error to IDL enum
2570 //================================================================================
2572 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2574 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2578 RETCASE( EXTR_NO_ELEMENTS );
2579 RETCASE( EXTR_PATH_NOT_EDGE );
2580 RETCASE( EXTR_BAD_PATH_SHAPE );
2581 RETCASE( EXTR_BAD_STARTING_NODE );
2582 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2583 RETCASE( EXTR_CANT_GET_TANGENT );
2585 return SMESH::SMESH_MeshEditor::EXTR_OK;
2589 //=======================================================================
2590 //function : extrusionAlongPath
2592 //=======================================================================
2593 SMESH::ListOfGroups*
2594 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2595 SMESH::SMESH_Mesh_ptr thePathMesh,
2596 GEOM::GEOM_Object_ptr thePathShape,
2597 CORBA::Long theNodeStart,
2598 CORBA::Boolean theHasAngles,
2599 const SMESH::double_array & theAngles,
2600 CORBA::Boolean theHasRefPoint,
2601 const SMESH::PointStruct & theRefPoint,
2602 const bool theMakeGroups,
2603 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2604 const SMDSAbs_ElementType theElementType)
2606 MESSAGE("extrusionAlongPath");
2609 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2610 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2613 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2615 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2616 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2618 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2619 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2623 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2625 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2629 TIDSortedElemSet elements;
2630 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2632 list<double> angles;
2633 for (int i = 0; i < theAngles.length(); i++) {
2634 angles.push_back( theAngles[i] );
2637 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2639 int nbOldGroups = myMesh->NbGroup();
2641 ::SMESH_MeshEditor::Extrusion_Error error =
2642 myEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2643 theHasAngles, angles, false,
2644 theHasRefPoint, refPnt, theMakeGroups );
2645 myMesh->GetMeshDS()->Modified();
2646 storeResult(myEditor);
2647 theError = convExtrError( error );
2649 if ( theMakeGroups ) {
2650 list<int> groupIDs = myMesh->GetGroupIds();
2651 list<int>::iterator newBegin = groupIDs.begin();
2652 std::advance( newBegin, nbOldGroups ); // skip old groups
2653 groupIDs.erase( groupIDs.begin(), newBegin );
2654 return getGroups( & groupIDs );
2660 //=======================================================================
2661 //function : extrusionAlongPathX
2663 //=======================================================================
2664 SMESH::ListOfGroups*
2665 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2666 SMESH::SMESH_IDSource_ptr Path,
2667 CORBA::Long NodeStart,
2668 CORBA::Boolean HasAngles,
2669 const SMESH::double_array& Angles,
2670 CORBA::Boolean LinearVariation,
2671 CORBA::Boolean HasRefPoint,
2672 const SMESH::PointStruct& RefPoint,
2674 const SMDSAbs_ElementType ElementType,
2675 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2677 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2681 list<double> angles;
2682 for (int i = 0; i < Angles.length(); i++) {
2683 angles.push_back( Angles[i] );
2685 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2686 int nbOldGroups = myMesh->NbGroup();
2688 if ( Path->_is_nil() ) {
2689 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2693 TIDSortedElemSet elements, copyElements;
2694 arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
2696 TIDSortedElemSet* workElements = &elements;
2697 TPreviewMesh tmpMesh( SMDSAbs_Face );
2698 SMESH_Mesh* mesh = myMesh;
2700 if ( myPreviewMode )
2702 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2703 tmpMesh.Copy( elements, copyElements, select, avoid );
2705 workElements = & copyElements;
2709 ::SMESH_MeshEditor::Extrusion_Error error;
2711 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2714 SMDS_MeshNode* aNodeStart =
2715 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2716 if ( !aNodeStart ) {
2717 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2720 error = myEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2721 HasAngles, angles, LinearVariation,
2722 HasRefPoint, refPnt, MakeGroups );
2723 myMesh->GetMeshDS()->Modified();
2725 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2728 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2729 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2730 SMDS_MeshNode* aNodeStart =
2731 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2732 if ( !aNodeStart ) {
2733 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2736 SMESH_subMesh* aSubMesh =
2737 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2738 error = myEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2739 HasAngles, angles, LinearVariation,
2740 HasRefPoint, refPnt, MakeGroups );
2741 myMesh->GetMeshDS()->Modified();
2743 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2745 // path as group of 1D elements
2751 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2755 storeResult(myEditor);
2756 Error = convExtrError( error );
2759 list<int> groupIDs = myMesh->GetGroupIds();
2760 list<int>::iterator newBegin = groupIDs.begin();
2761 std::advance( newBegin, nbOldGroups ); // skip old groups
2762 groupIDs.erase( groupIDs.begin(), newBegin );
2763 return getGroups( & groupIDs );
2769 //=======================================================================
2770 //function : ExtrusionAlongPath
2772 //=======================================================================
2773 SMESH::SMESH_MeshEditor::Extrusion_Error
2774 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2775 SMESH::SMESH_Mesh_ptr thePathMesh,
2776 GEOM::GEOM_Object_ptr thePathShape,
2777 CORBA::Long theNodeStart,
2778 CORBA::Boolean theHasAngles,
2779 const SMESH::double_array & theAngles,
2780 CORBA::Boolean theHasRefPoint,
2781 const SMESH::PointStruct & theRefPoint)
2783 MESSAGE("ExtrusionAlongPath");
2784 if ( !myPreviewMode ) {
2785 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
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 ) << " ) )";
2798 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2799 extrusionAlongPath( theIDsOfElements,
2812 //=======================================================================
2813 //function : ExtrusionAlongPathObject
2815 //=======================================================================
2816 SMESH::SMESH_MeshEditor::Extrusion_Error
2817 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2818 SMESH::SMESH_Mesh_ptr thePathMesh,
2819 GEOM::GEOM_Object_ptr thePathShape,
2820 CORBA::Long theNodeStart,
2821 CORBA::Boolean theHasAngles,
2822 const SMESH::double_array & theAngles,
2823 CORBA::Boolean theHasRefPoint,
2824 const SMESH::PointStruct & theRefPoint)
2826 if ( !myPreviewMode ) {
2827 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2828 << theObject << ", "
2829 << thePathMesh << ", "
2830 << thePathShape << ", "
2831 << theNodeStart << ", "
2832 << theHasAngles << ", "
2833 << theAngles << ", "
2834 << theHasRefPoint << ", "
2835 << "SMESH.PointStruct( "
2836 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2837 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2838 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2840 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2841 SMESH::long_array_var anElementsId = theObject->GetIDs();
2842 extrusionAlongPath( anElementsId,
2855 //=======================================================================
2856 //function : ExtrusionAlongPathObject1D
2858 //=======================================================================
2859 SMESH::SMESH_MeshEditor::Extrusion_Error
2860 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2861 SMESH::SMESH_Mesh_ptr thePathMesh,
2862 GEOM::GEOM_Object_ptr thePathShape,
2863 CORBA::Long theNodeStart,
2864 CORBA::Boolean theHasAngles,
2865 const SMESH::double_array & theAngles,
2866 CORBA::Boolean theHasRefPoint,
2867 const SMESH::PointStruct & theRefPoint)
2869 if ( !myPreviewMode ) {
2870 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2871 << theObject << ", "
2872 << thePathMesh << ", "
2873 << thePathShape << ", "
2874 << theNodeStart << ", "
2875 << theHasAngles << ", "
2876 << theAngles << ", "
2877 << theHasRefPoint << ", "
2878 << "SMESH.PointStruct( "
2879 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2880 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2881 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2883 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2884 SMESH::long_array_var anElementsId = theObject->GetIDs();
2885 extrusionAlongPath( anElementsId,
2899 //=======================================================================
2900 //function : ExtrusionAlongPathObject2D
2902 //=======================================================================
2903 SMESH::SMESH_MeshEditor::Extrusion_Error
2904 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
2905 SMESH::SMESH_Mesh_ptr thePathMesh,
2906 GEOM::GEOM_Object_ptr thePathShape,
2907 CORBA::Long theNodeStart,
2908 CORBA::Boolean theHasAngles,
2909 const SMESH::double_array & theAngles,
2910 CORBA::Boolean theHasRefPoint,
2911 const SMESH::PointStruct & theRefPoint)
2913 if ( !myPreviewMode ) {
2914 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
2915 << theObject << ", "
2916 << thePathMesh << ", "
2917 << thePathShape << ", "
2918 << theNodeStart << ", "
2919 << theHasAngles << ", "
2920 << theAngles << ", "
2921 << theHasRefPoint << ", "
2922 << "SMESH.PointStruct( "
2923 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2924 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2925 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2927 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2928 SMESH::long_array_var anElementsId = theObject->GetIDs();
2929 extrusionAlongPath( anElementsId,
2944 //=======================================================================
2945 //function : ExtrusionAlongPathMakeGroups
2947 //=======================================================================
2948 SMESH::ListOfGroups*
2949 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
2950 SMESH::SMESH_Mesh_ptr thePathMesh,
2951 GEOM::GEOM_Object_ptr thePathShape,
2952 CORBA::Long theNodeStart,
2953 CORBA::Boolean theHasAngles,
2954 const SMESH::double_array& theAngles,
2955 CORBA::Boolean theHasRefPoint,
2956 const SMESH::PointStruct& theRefPoint,
2957 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2959 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2961 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
2971 if (!myPreviewMode) {
2972 bool isDumpGroups = aGroups && aGroups->length() > 0;
2974 aPythonDump << "(" << aGroups << ", error)";
2976 aPythonDump <<"error";
2978 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
2979 << theIDsOfElements << ", "
2980 << thePathMesh << ", "
2981 << thePathShape << ", "
2982 << theNodeStart << ", "
2983 << theHasAngles << ", "
2984 << theAngles << ", "
2985 << theHasRefPoint << ", "
2986 << "SMESH.PointStruct( "
2987 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2988 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2989 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2994 //=======================================================================
2995 //function : ExtrusionAlongPathObjectMakeGroups
2997 //=======================================================================
2998 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2999 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3000 SMESH::SMESH_Mesh_ptr thePathMesh,
3001 GEOM::GEOM_Object_ptr thePathShape,
3002 CORBA::Long theNodeStart,
3003 CORBA::Boolean theHasAngles,
3004 const SMESH::double_array& theAngles,
3005 CORBA::Boolean theHasRefPoint,
3006 const SMESH::PointStruct& theRefPoint,
3007 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3009 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3011 SMESH::long_array_var anElementsId = theObject->GetIDs();
3012 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3023 if (!myPreviewMode) {
3024 bool isDumpGroups = aGroups && aGroups->length() > 0;
3026 aPythonDump << "(" << aGroups << ", error)";
3028 aPythonDump <<"error";
3030 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3031 << theObject << ", "
3032 << thePathMesh << ", "
3033 << thePathShape << ", "
3034 << theNodeStart << ", "
3035 << theHasAngles << ", "
3036 << theAngles << ", "
3037 << theHasRefPoint << ", "
3038 << "SMESH.PointStruct( "
3039 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3040 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3041 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3046 //=======================================================================
3047 //function : ExtrusionAlongPathObject1DMakeGroups
3049 //=======================================================================
3050 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3051 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3052 SMESH::SMESH_Mesh_ptr thePathMesh,
3053 GEOM::GEOM_Object_ptr thePathShape,
3054 CORBA::Long theNodeStart,
3055 CORBA::Boolean theHasAngles,
3056 const SMESH::double_array& theAngles,
3057 CORBA::Boolean theHasRefPoint,
3058 const SMESH::PointStruct& theRefPoint,
3059 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3061 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3063 SMESH::long_array_var anElementsId = theObject->GetIDs();
3064 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3076 if (!myPreviewMode) {
3077 bool isDumpGroups = aGroups && aGroups->length() > 0;
3079 aPythonDump << "(" << aGroups << ", error)";
3081 aPythonDump << "error";
3083 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3084 << theObject << ", "
3085 << thePathMesh << ", "
3086 << thePathShape << ", "
3087 << theNodeStart << ", "
3088 << theHasAngles << ", "
3089 << theAngles << ", "
3090 << theHasRefPoint << ", "
3091 << "SMESH.PointStruct( "
3092 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3093 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3094 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3099 //=======================================================================
3100 //function : ExtrusionAlongPathObject2DMakeGroups
3102 //=======================================================================
3103 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3104 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3105 SMESH::SMESH_Mesh_ptr thePathMesh,
3106 GEOM::GEOM_Object_ptr thePathShape,
3107 CORBA::Long theNodeStart,
3108 CORBA::Boolean theHasAngles,
3109 const SMESH::double_array& theAngles,
3110 CORBA::Boolean theHasRefPoint,
3111 const SMESH::PointStruct& theRefPoint,
3112 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3114 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3116 SMESH::long_array_var anElementsId = theObject->GetIDs();
3117 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3129 if (!myPreviewMode) {
3130 bool isDumpGroups = aGroups && aGroups->length() > 0;
3132 aPythonDump << "(" << aGroups << ", error)";
3134 aPythonDump << "error";
3136 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3137 << theObject << ", "
3138 << thePathMesh << ", "
3139 << thePathShape << ", "
3140 << theNodeStart << ", "
3141 << theHasAngles << ", "
3142 << theAngles << ", "
3143 << theHasRefPoint << ", "
3144 << "SMESH.PointStruct( "
3145 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3146 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3147 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3153 //=======================================================================
3154 //function : ExtrusionAlongPathObjX
3156 //=======================================================================
3157 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3158 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3159 SMESH::SMESH_IDSource_ptr Path,
3160 CORBA::Long NodeStart,
3161 CORBA::Boolean HasAngles,
3162 const SMESH::double_array& Angles,
3163 CORBA::Boolean LinearVariation,
3164 CORBA::Boolean HasRefPoint,
3165 const SMESH::PointStruct& RefPoint,
3166 CORBA::Boolean MakeGroups,
3167 SMESH::ElementType ElemType,
3168 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3170 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3172 SMESH::long_array_var anElementsId = Object->GetIDs();
3173 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3182 (SMDSAbs_ElementType)ElemType,
3185 if (!myPreviewMode) {
3186 bool isDumpGroups = aGroups && aGroups->length() > 0;
3188 aPythonDump << "(" << *aGroups << ", error)";
3190 aPythonDump << "error";
3192 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3195 << NodeStart << ", "
3196 << HasAngles << ", "
3197 << TVar( Angles ) << ", "
3198 << LinearVariation << ", "
3199 << HasRefPoint << ", "
3200 << "SMESH.PointStruct( "
3201 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3202 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3203 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3204 << MakeGroups << ", "
3205 << ElemType << " )";
3211 //=======================================================================
3212 //function : ExtrusionAlongPathX
3214 //=======================================================================
3215 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3216 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3217 SMESH::SMESH_IDSource_ptr Path,
3218 CORBA::Long NodeStart,
3219 CORBA::Boolean HasAngles,
3220 const SMESH::double_array& Angles,
3221 CORBA::Boolean LinearVariation,
3222 CORBA::Boolean HasRefPoint,
3223 const SMESH::PointStruct& RefPoint,
3224 CORBA::Boolean MakeGroups,
3225 SMESH::ElementType ElemType,
3226 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3228 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3230 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3239 (SMDSAbs_ElementType)ElemType,
3242 if (!myPreviewMode) {
3243 bool isDumpGroups = aGroups && aGroups->length() > 0;
3245 aPythonDump << "(" << *aGroups << ", error)";
3247 aPythonDump <<"error";
3249 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3250 << IDsOfElements << ", "
3252 << NodeStart << ", "
3253 << HasAngles << ", "
3254 << TVar( Angles ) << ", "
3255 << LinearVariation << ", "
3256 << HasRefPoint << ", "
3257 << "SMESH.PointStruct( "
3258 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3259 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3260 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3261 << MakeGroups << ", "
3262 << ElemType << " )";
3268 //================================================================================
3270 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3271 * of given angles along path steps
3272 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3273 * which proceeds the extrusion
3274 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3275 * is used to define the sub-mesh for the path
3277 //================================================================================
3279 SMESH::double_array*
3280 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3281 GEOM::GEOM_Object_ptr thePathShape,
3282 const SMESH::double_array & theAngles)
3284 SMESH::double_array_var aResult = new SMESH::double_array();
3285 int nbAngles = theAngles.length();
3286 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3288 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3289 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3290 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3291 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3292 return aResult._retn();
3293 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3294 if ( nbSteps == nbAngles )
3296 aResult.inout() = theAngles;
3300 aResult->length( nbSteps );
3301 double rAn2St = double( nbAngles ) / double( nbSteps );
3302 double angPrev = 0, angle;
3303 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3305 double angCur = rAn2St * ( iSt+1 );
3306 double angCurFloor = floor( angCur );
3307 double angPrevFloor = floor( angPrev );
3308 if ( angPrevFloor == angCurFloor )
3309 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3312 int iP = int( angPrevFloor );
3313 double angPrevCeil = ceil(angPrev);
3314 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3316 int iC = int( angCurFloor );
3317 if ( iC < nbAngles )
3318 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3320 iP = int( angPrevCeil );
3322 angle += theAngles[ iC ];
3324 aResult[ iSt ] = angle;
3329 // Update Python script
3330 TPythonDump() << "rotAngles = " << theAngles;
3331 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3332 << thePathMesh << ", "
3333 << thePathShape << ", "
3336 return aResult._retn();
3340 //=======================================================================
3343 //=======================================================================
3345 SMESH::ListOfGroups*
3346 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3347 const SMESH::AxisStruct & theAxis,
3348 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3349 CORBA::Boolean theCopy,
3351 ::SMESH_Mesh* theTargetMesh)
3355 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3356 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3358 if ( theTargetMesh )
3362 switch ( theMirrorType ) {
3363 case SMESH::SMESH_MeshEditor::POINT:
3364 aTrsf.SetMirror( P );
3366 case SMESH::SMESH_MeshEditor::AXIS:
3367 aTrsf.SetMirror( gp_Ax1( P, V ));
3370 aTrsf.SetMirror( gp_Ax2( P, V ));
3373 TIDSortedElemSet copyElements;
3374 TPreviewMesh tmpMesh;
3375 TIDSortedElemSet* workElements = & theElements;
3376 SMESH_Mesh* mesh = myMesh;
3378 if ( myPreviewMode )
3380 tmpMesh.Copy( theElements, copyElements);
3381 if ( !theCopy && !theTargetMesh )
3383 TIDSortedElemSet elemsAround, elemsAroundCopy;
3384 getElementsAround( theElements, GetMeshDS(), elemsAround );
3385 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3388 workElements = & copyElements;
3389 theMakeGroups = false;
3392 ::SMESH_MeshEditor::PGroupIDs groupIds =
3393 myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3395 if(theCopy || myPreviewMode)
3396 storeResult(myEditor); // store preview data or new elements
3398 if ( !myPreviewMode )
3400 if ( theTargetMesh )
3402 theTargetMesh->GetMeshDS()->Modified();
3406 myMesh->GetMeshDS()->Modified();
3407 myMesh->SetIsModified( true );
3410 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3413 //=======================================================================
3416 //=======================================================================
3418 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3419 const SMESH::AxisStruct & theAxis,
3420 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3421 CORBA::Boolean theCopy)
3423 if ( !myPreviewMode ) {
3424 TPythonDump() << this << ".Mirror( "
3425 << theIDsOfElements << ", "
3427 << mirrorTypeName(theMirrorType) << ", "
3430 if ( theIDsOfElements.length() > 0 )
3432 TIDSortedElemSet elements;
3433 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3434 mirror(elements, theAxis, theMirrorType, theCopy, false);
3439 //=======================================================================
3440 //function : MirrorObject
3442 //=======================================================================
3444 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3445 const SMESH::AxisStruct & theAxis,
3446 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3447 CORBA::Boolean theCopy)
3449 if ( !myPreviewMode ) {
3450 TPythonDump() << this << ".MirrorObject( "
3451 << theObject << ", "
3453 << mirrorTypeName(theMirrorType) << ", "
3456 TIDSortedElemSet elements;
3458 bool emptyIfIsMesh = myPreviewMode ? false : true;
3460 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3461 mirror(elements, theAxis, theMirrorType, theCopy, false);
3464 //=======================================================================
3465 //function : MirrorMakeGroups
3467 //=======================================================================
3469 SMESH::ListOfGroups*
3470 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3471 const SMESH::AxisStruct& theMirror,
3472 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3474 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3476 SMESH::ListOfGroups * aGroups = 0;
3477 if ( theIDsOfElements.length() > 0 )
3479 TIDSortedElemSet elements;
3480 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3481 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3483 if (!myPreviewMode) {
3484 DumpGroupsList(aPythonDump, aGroups);
3485 aPythonDump << this << ".MirrorMakeGroups( "
3486 << theIDsOfElements << ", "
3487 << theMirror << ", "
3488 << mirrorTypeName(theMirrorType) << " )";
3493 //=======================================================================
3494 //function : MirrorObjectMakeGroups
3496 //=======================================================================
3498 SMESH::ListOfGroups*
3499 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3500 const SMESH::AxisStruct& theMirror,
3501 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3503 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3505 SMESH::ListOfGroups * aGroups = 0;
3506 TIDSortedElemSet elements;
3507 if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3508 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3512 DumpGroupsList(aPythonDump,aGroups);
3513 aPythonDump << this << ".MirrorObjectMakeGroups( "
3514 << theObject << ", "
3515 << theMirror << ", "
3516 << mirrorTypeName(theMirrorType) << " )";
3521 //=======================================================================
3522 //function : MirrorMakeMesh
3524 //=======================================================================
3526 SMESH::SMESH_Mesh_ptr
3527 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3528 const SMESH::AxisStruct& theMirror,
3529 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3530 CORBA::Boolean theCopyGroups,
3531 const char* theMeshName)
3533 SMESH_Mesh_i* mesh_i;
3534 SMESH::SMESH_Mesh_var mesh;
3535 { // open new scope to dump "MakeMesh" command
3536 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3538 TPythonDump pydump; // to prevent dump at mesh creation
3540 mesh = makeMesh( theMeshName );
3541 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3542 if (mesh_i && theIDsOfElements.length() > 0 )
3544 TIDSortedElemSet elements;
3545 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3546 mirror(elements, theMirror, theMirrorType,
3547 false, theCopyGroups, & mesh_i->GetImpl());
3548 mesh_i->CreateGroupServants();
3551 if (!myPreviewMode) {
3552 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3553 << theIDsOfElements << ", "
3554 << theMirror << ", "
3555 << mirrorTypeName(theMirrorType) << ", "
3556 << theCopyGroups << ", '"
3557 << theMeshName << "' )";
3562 if (!myPreviewMode && mesh_i)
3563 mesh_i->GetGroups();
3565 return mesh._retn();
3568 //=======================================================================
3569 //function : MirrorObjectMakeMesh
3571 //=======================================================================
3573 SMESH::SMESH_Mesh_ptr
3574 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3575 const SMESH::AxisStruct& theMirror,
3576 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3577 CORBA::Boolean theCopyGroups,
3578 const char* theMeshName)
3580 SMESH_Mesh_i* mesh_i;
3581 SMESH::SMESH_Mesh_var mesh;
3582 { // open new scope to dump "MakeMesh" command
3583 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3585 TPythonDump pydump; // to prevent dump at mesh creation
3587 mesh = makeMesh( theMeshName );
3588 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3589 TIDSortedElemSet elements;
3591 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3593 mirror(elements, theMirror, theMirrorType,
3594 false, theCopyGroups, & mesh_i->GetImpl());
3595 mesh_i->CreateGroupServants();
3597 if (!myPreviewMode) {
3598 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3599 << theObject << ", "
3600 << theMirror << ", "
3601 << mirrorTypeName(theMirrorType) << ", "
3602 << theCopyGroups << ", '"
3603 << theMeshName << "' )";
3608 if (!myPreviewMode && mesh_i)
3609 mesh_i->GetGroups();
3611 return mesh._retn();
3614 //=======================================================================
3615 //function : translate
3617 //=======================================================================
3619 SMESH::ListOfGroups*
3620 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3621 const SMESH::DirStruct & theVector,
3622 CORBA::Boolean theCopy,
3624 ::SMESH_Mesh* theTargetMesh)
3628 if ( theTargetMesh )
3632 const SMESH::PointStruct * P = &theVector.PS;
3633 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3635 TIDSortedElemSet copyElements;
3636 TIDSortedElemSet* workElements = &theElements;
3637 TPreviewMesh tmpMesh;
3638 SMESH_Mesh* mesh = myMesh;
3640 if ( myPreviewMode )
3642 tmpMesh.Copy( theElements, copyElements);
3643 if ( !theCopy && !theTargetMesh )
3645 TIDSortedElemSet elemsAround, elemsAroundCopy;
3646 getElementsAround( theElements, GetMeshDS(), elemsAround );
3647 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3650 workElements = & copyElements;
3651 theMakeGroups = false;
3654 ::SMESH_MeshEditor::PGroupIDs groupIds =
3655 myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3657 if(theCopy || myPreviewMode)
3658 storeResult(myEditor);
3660 if ( !myPreviewMode )
3662 if ( theTargetMesh )
3664 theTargetMesh->GetMeshDS()->Modified();
3668 myMesh->GetMeshDS()->Modified();
3669 myMesh->SetIsModified( true );
3673 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3676 //=======================================================================
3677 //function : Translate
3679 //=======================================================================
3681 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3682 const SMESH::DirStruct & theVector,
3683 CORBA::Boolean theCopy)
3685 if (!myPreviewMode) {
3686 TPythonDump() << this << ".Translate( "
3687 << theIDsOfElements << ", "
3688 << theVector << ", "
3691 if (theIDsOfElements.length()) {
3692 TIDSortedElemSet elements;
3693 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3694 translate(elements, theVector, theCopy, false);
3698 //=======================================================================
3699 //function : TranslateObject
3701 //=======================================================================
3703 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3704 const SMESH::DirStruct & theVector,
3705 CORBA::Boolean theCopy)
3707 if (!myPreviewMode) {
3708 TPythonDump() << this << ".TranslateObject( "
3709 << theObject << ", "
3710 << theVector << ", "
3713 TIDSortedElemSet elements;
3715 bool emptyIfIsMesh = myPreviewMode ? false : true;
3717 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3718 translate(elements, theVector, theCopy, false);
3721 //=======================================================================
3722 //function : TranslateMakeGroups
3724 //=======================================================================
3726 SMESH::ListOfGroups*
3727 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3728 const SMESH::DirStruct& theVector)
3730 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3732 SMESH::ListOfGroups * aGroups = 0;
3733 if (theIDsOfElements.length()) {
3734 TIDSortedElemSet elements;
3735 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3736 aGroups = translate(elements,theVector,true,true);
3738 if (!myPreviewMode) {
3739 DumpGroupsList(aPythonDump, aGroups);
3740 aPythonDump << this << ".TranslateMakeGroups( "
3741 << theIDsOfElements << ", "
3742 << theVector << " )";
3747 //=======================================================================
3748 //function : TranslateObjectMakeGroups
3750 //=======================================================================
3752 SMESH::ListOfGroups*
3753 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3754 const SMESH::DirStruct& theVector)
3756 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3758 SMESH::ListOfGroups * aGroups = 0;
3759 TIDSortedElemSet elements;
3760 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3761 aGroups = translate(elements, theVector, true, true);
3763 if (!myPreviewMode) {
3764 DumpGroupsList(aPythonDump, aGroups);
3765 aPythonDump << this << ".TranslateObjectMakeGroups( "
3766 << theObject << ", "
3767 << theVector << " )";
3772 //=======================================================================
3773 //function : TranslateMakeMesh
3775 //=======================================================================
3777 SMESH::SMESH_Mesh_ptr
3778 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3779 const SMESH::DirStruct& theVector,
3780 CORBA::Boolean theCopyGroups,
3781 const char* theMeshName)
3783 SMESH_Mesh_i* mesh_i;
3784 SMESH::SMESH_Mesh_var mesh;
3786 { // open new scope to dump "MakeMesh" command
3787 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3789 TPythonDump pydump; // to prevent dump at mesh creation
3791 mesh = makeMesh( theMeshName );
3792 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3794 if ( mesh_i && theIDsOfElements.length() )
3796 TIDSortedElemSet elements;
3797 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3798 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3799 mesh_i->CreateGroupServants();
3802 if ( !myPreviewMode ) {
3803 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3804 << theIDsOfElements << ", "
3805 << theVector << ", "
3806 << theCopyGroups << ", '"
3807 << theMeshName << "' )";
3812 if (!myPreviewMode && mesh_i)
3813 mesh_i->GetGroups();
3815 return mesh._retn();
3818 //=======================================================================
3819 //function : TranslateObjectMakeMesh
3821 //=======================================================================
3823 SMESH::SMESH_Mesh_ptr
3824 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3825 const SMESH::DirStruct& theVector,
3826 CORBA::Boolean theCopyGroups,
3827 const char* theMeshName)
3829 SMESH_Mesh_i* mesh_i;
3830 SMESH::SMESH_Mesh_var mesh;
3831 { // open new scope to dump "MakeMesh" command
3832 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3834 TPythonDump pydump; // to prevent dump at mesh creation
3835 mesh = makeMesh( theMeshName );
3836 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3838 TIDSortedElemSet elements;
3840 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3842 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3843 mesh_i->CreateGroupServants();
3845 if ( !myPreviewMode ) {
3846 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3847 << theObject << ", "
3848 << theVector << ", "
3849 << theCopyGroups << ", '"
3850 << theMeshName << "' )";
3855 if (!myPreviewMode && mesh_i)
3856 mesh_i->GetGroups();
3858 return mesh._retn();
3861 //=======================================================================
3864 //=======================================================================
3866 SMESH::ListOfGroups*
3867 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3868 const SMESH::AxisStruct & theAxis,
3869 CORBA::Double theAngle,
3870 CORBA::Boolean theCopy,
3872 ::SMESH_Mesh* theTargetMesh)
3876 if ( theTargetMesh )
3879 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3880 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3883 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3885 TIDSortedElemSet copyElements;
3886 TIDSortedElemSet* workElements = &theElements;
3887 TPreviewMesh tmpMesh;
3888 SMESH_Mesh* mesh = myMesh;
3890 if ( myPreviewMode ) {
3891 tmpMesh.Copy( theElements, copyElements );
3892 if ( !theCopy && !theTargetMesh )
3894 TIDSortedElemSet elemsAround, elemsAroundCopy;
3895 getElementsAround( theElements, GetMeshDS(), elemsAround );
3896 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3899 workElements = ©Elements;
3900 theMakeGroups = false;
3903 ::SMESH_MeshEditor::PGroupIDs groupIds =
3904 myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3906 if(theCopy || myPreviewMode)
3907 storeResult(myEditor);
3909 if ( !myPreviewMode )
3911 if ( theTargetMesh )
3913 theTargetMesh->GetMeshDS()->Modified();
3917 myMesh->GetMeshDS()->Modified();
3918 myMesh->SetIsModified( true );
3922 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3925 //=======================================================================
3928 //=======================================================================
3930 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3931 const SMESH::AxisStruct & theAxis,
3932 CORBA::Double theAngle,
3933 CORBA::Boolean theCopy)
3935 if (!myPreviewMode) {
3936 TPythonDump() << this << ".Rotate( "
3937 << theIDsOfElements << ", "
3939 << TVar( theAngle ) << ", "
3942 if (theIDsOfElements.length() > 0)
3944 TIDSortedElemSet elements;
3945 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3946 rotate(elements,theAxis,theAngle,theCopy,false);
3950 //=======================================================================
3951 //function : RotateObject
3953 //=======================================================================
3955 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3956 const SMESH::AxisStruct & theAxis,
3957 CORBA::Double theAngle,
3958 CORBA::Boolean theCopy)
3960 if ( !myPreviewMode ) {
3961 TPythonDump() << this << ".RotateObject( "
3962 << theObject << ", "
3964 << TVar( theAngle ) << ", "
3967 TIDSortedElemSet elements;
3968 bool emptyIfIsMesh = myPreviewMode ? false : true;
3969 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3970 rotate(elements,theAxis,theAngle,theCopy,false);
3973 //=======================================================================
3974 //function : RotateMakeGroups
3976 //=======================================================================
3978 SMESH::ListOfGroups*
3979 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3980 const SMESH::AxisStruct& theAxis,
3981 CORBA::Double theAngle)
3983 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3985 SMESH::ListOfGroups * aGroups = 0;
3986 if (theIDsOfElements.length() > 0)
3988 TIDSortedElemSet elements;
3989 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3990 aGroups = rotate(elements,theAxis,theAngle,true,true);
3992 if (!myPreviewMode) {
3993 DumpGroupsList(aPythonDump, aGroups);
3994 aPythonDump << this << ".RotateMakeGroups( "
3995 << theIDsOfElements << ", "
3997 << TVar( theAngle ) << " )";
4002 //=======================================================================
4003 //function : RotateObjectMakeGroups
4005 //=======================================================================
4007 SMESH::ListOfGroups*
4008 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4009 const SMESH::AxisStruct& theAxis,
4010 CORBA::Double theAngle)
4012 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4014 SMESH::ListOfGroups * aGroups = 0;
4015 TIDSortedElemSet elements;
4016 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4017 aGroups = rotate(elements, theAxis, theAngle, true, true);
4019 if (!myPreviewMode) {
4020 DumpGroupsList(aPythonDump, aGroups);
4021 aPythonDump << this << ".RotateObjectMakeGroups( "
4022 << theObject << ", "
4024 << TVar( theAngle ) << " )";
4029 //=======================================================================
4030 //function : RotateMakeMesh
4032 //=======================================================================
4034 SMESH::SMESH_Mesh_ptr
4035 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4036 const SMESH::AxisStruct& theAxis,
4037 CORBA::Double theAngleInRadians,
4038 CORBA::Boolean theCopyGroups,
4039 const char* theMeshName)
4041 SMESH::SMESH_Mesh_var mesh;
4042 SMESH_Mesh_i* mesh_i;
4044 { // open new scope to dump "MakeMesh" command
4045 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4047 TPythonDump pydump; // to prevent dump at mesh creation
4049 mesh = makeMesh( theMeshName );
4050 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4052 if ( mesh_i && theIDsOfElements.length() > 0 )
4054 TIDSortedElemSet elements;
4055 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
4056 rotate(elements, theAxis, theAngleInRadians,
4057 false, theCopyGroups, & mesh_i->GetImpl());
4058 mesh_i->CreateGroupServants();
4060 if ( !myPreviewMode ) {
4061 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4062 << theIDsOfElements << ", "
4064 << TVar( theAngleInRadians ) << ", "
4065 << theCopyGroups << ", '"
4066 << theMeshName << "' )";
4071 if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4072 mesh_i->GetGroups();
4074 return mesh._retn();
4077 //=======================================================================
4078 //function : RotateObjectMakeMesh
4080 //=======================================================================
4082 SMESH::SMESH_Mesh_ptr
4083 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4084 const SMESH::AxisStruct& theAxis,
4085 CORBA::Double theAngleInRadians,
4086 CORBA::Boolean theCopyGroups,
4087 const char* theMeshName)
4089 SMESH::SMESH_Mesh_var mesh;
4090 SMESH_Mesh_i* mesh_i;
4092 {// open new scope to dump "MakeMesh" command
4093 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4095 TPythonDump pydump; // to prevent dump at mesh creation
4096 mesh = makeMesh( theMeshName );
4097 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4099 TIDSortedElemSet elements;
4101 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4103 rotate(elements, theAxis, theAngleInRadians,
4104 false, theCopyGroups, & mesh_i->GetImpl());
4105 mesh_i->CreateGroupServants();
4107 if ( !myPreviewMode ) {
4108 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4109 << theObject << ", "
4111 << TVar( theAngleInRadians ) << ", "
4112 << theCopyGroups << ", '"
4113 << theMeshName << "' )";
4118 if (!myPreviewMode && mesh_i)
4119 mesh_i->GetGroups();
4121 return mesh._retn();
4124 //=======================================================================
4127 //=======================================================================
4129 SMESH::ListOfGroups*
4130 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4131 const SMESH::PointStruct& thePoint,
4132 const SMESH::double_array& theScaleFact,
4133 CORBA::Boolean theCopy,
4135 ::SMESH_Mesh* theTargetMesh)
4138 if ( theScaleFact.length() < 1 )
4139 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4140 if ( theScaleFact.length() == 2 )
4141 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4143 if ( theTargetMesh )
4146 TIDSortedElemSet elements;
4147 bool emptyIfIsMesh = myPreviewMode ? false : true;
4148 if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4153 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4154 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4156 double tol = std::numeric_limits<double>::max();
4158 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4159 0, S[1], 0, thePoint.y * (1-S[1]),
4160 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4162 TIDSortedElemSet copyElements;
4163 TPreviewMesh tmpMesh;
4164 TIDSortedElemSet* workElements = &elements;
4165 SMESH_Mesh* mesh = myMesh;
4167 if ( myPreviewMode )
4169 tmpMesh.Copy( elements, copyElements);
4170 if ( !theCopy && !theTargetMesh )
4172 TIDSortedElemSet elemsAround, elemsAroundCopy;
4173 getElementsAround( elements, GetMeshDS(), elemsAround );
4174 tmpMesh.Copy( elemsAround, elemsAroundCopy);
4177 workElements = & copyElements;
4178 theMakeGroups = false;
4181 ::SMESH_MeshEditor::PGroupIDs groupIds =
4182 myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4184 if(theCopy || myPreviewMode )
4185 storeResult(myEditor);
4187 if ( !myPreviewMode )
4189 if ( theTargetMesh )
4191 theTargetMesh->GetMeshDS()->Modified();
4195 myMesh->GetMeshDS()->Modified();
4196 myMesh->SetIsModified( true );
4200 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4203 //=======================================================================
4206 //=======================================================================
4208 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4209 const SMESH::PointStruct& thePoint,
4210 const SMESH::double_array& theScaleFact,
4211 CORBA::Boolean theCopy)
4213 if ( !myPreviewMode ) {
4214 TPythonDump() << this << ".Scale( "
4215 << theObject << ", "
4217 << TVar( theScaleFact ) << ", "
4220 scale(theObject, thePoint, theScaleFact, theCopy, false);
4224 //=======================================================================
4225 //function : ScaleMakeGroups
4227 //=======================================================================
4229 SMESH::ListOfGroups*
4230 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4231 const SMESH::PointStruct& thePoint,
4232 const SMESH::double_array& theScaleFact)
4234 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4236 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4237 if (!myPreviewMode) {
4238 DumpGroupsList(aPythonDump, aGroups);
4239 aPythonDump << this << ".Scale("
4242 << TVar( theScaleFact ) << ",True,True)";
4248 //=======================================================================
4249 //function : ScaleMakeMesh
4251 //=======================================================================
4253 SMESH::SMESH_Mesh_ptr
4254 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4255 const SMESH::PointStruct& thePoint,
4256 const SMESH::double_array& theScaleFact,
4257 CORBA::Boolean theCopyGroups,
4258 const char* theMeshName)
4260 SMESH_Mesh_i* mesh_i;
4261 SMESH::SMESH_Mesh_var mesh;
4262 { // open new scope to dump "MakeMesh" command
4263 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4265 TPythonDump pydump; // to prevent dump at mesh creation
4266 mesh = makeMesh( theMeshName );
4267 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4271 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4272 mesh_i->CreateGroupServants();
4274 if ( !myPreviewMode )
4275 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4276 << theObject << ", "
4278 << TVar( theScaleFact ) << ", "
4279 << theCopyGroups << ", '"
4280 << theMeshName << "' )";
4284 if (!myPreviewMode && mesh_i)
4285 mesh_i->GetGroups();
4287 return mesh._retn();
4291 //=======================================================================
4292 //function : FindCoincidentNodes
4294 //=======================================================================
4296 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4297 SMESH::array_of_long_array_out GroupsOfNodes)
4301 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4302 TIDSortedNodeSet nodes; // no input nodes
4303 myEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4305 GroupsOfNodes = new SMESH::array_of_long_array;
4306 GroupsOfNodes->length( aListOfListOfNodes.size() );
4307 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4308 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4309 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4310 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4311 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4312 aGroup.length( aListOfNodes.size() );
4313 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4314 aGroup[ j ] = (*lIt)->GetID();
4316 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4317 << Tolerance << " )";
4320 //=======================================================================
4321 //function : FindCoincidentNodesOnPart
4323 //=======================================================================
4324 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4325 CORBA::Double Tolerance,
4326 SMESH::array_of_long_array_out GroupsOfNodes)
4330 TIDSortedNodeSet nodes;
4331 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
4333 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4335 myEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4337 GroupsOfNodes = new SMESH::array_of_long_array;
4338 GroupsOfNodes->length( aListOfListOfNodes.size() );
4339 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4340 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4342 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4343 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4344 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4345 aGroup.length( aListOfNodes.size() );
4346 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4347 aGroup[ j ] = (*lIt)->GetID();
4349 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4351 << Tolerance << " )";
4354 //================================================================================
4356 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4357 * ExceptSubMeshOrGroups
4359 //================================================================================
4361 void SMESH_MeshEditor_i::
4362 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4363 CORBA::Double theTolerance,
4364 SMESH::array_of_long_array_out theGroupsOfNodes,
4365 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4369 TIDSortedNodeSet nodes;
4370 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
4372 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4374 TIDSortedNodeSet exceptNodes;
4375 idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
4376 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4377 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4378 nodes.erase( *avoidNode );
4380 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4382 myEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4384 theGroupsOfNodes = new SMESH::array_of_long_array;
4385 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4386 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4387 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4389 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4390 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4391 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4392 aGroup.length( aListOfNodes.size() );
4393 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4394 aGroup[ j ] = (*lIt)->GetID();
4396 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4398 << theTolerance << ", "
4399 << theExceptSubMeshOrGroups << " )";
4402 //=======================================================================
4403 //function : MergeNodes
4405 //=======================================================================
4407 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4411 SMESHDS_Mesh* aMesh = GetMeshDS();
4413 TPythonDump aTPythonDump;
4414 aTPythonDump << this << ".MergeNodes([";
4415 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4416 for (int i = 0; i < GroupsOfNodes.length(); i++)
4418 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4419 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4420 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4421 for ( int j = 0; j < aNodeGroup.length(); j++ )
4423 CORBA::Long index = aNodeGroup[ j ];
4424 const SMDS_MeshNode * node = aMesh->FindNode(index);
4426 aListOfNodes.push_back( node );
4428 if ( aListOfNodes.size() < 2 )
4429 aListOfListOfNodes.pop_back();
4431 if ( i > 0 ) aTPythonDump << ", ";
4432 aTPythonDump << aNodeGroup;
4434 myEditor.MergeNodes( aListOfListOfNodes );
4436 aTPythonDump << "])";
4437 myMesh->GetMeshDS()->Modified();
4438 myMesh->SetIsModified( true );
4441 //=======================================================================
4442 //function : FindEqualElements
4444 //=======================================================================
4445 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4446 SMESH::array_of_long_array_out GroupsOfElementsID)
4450 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4451 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4453 TIDSortedElemSet elems;
4454 idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4456 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4457 myEditor.FindEqualElements( elems, aListOfListOfElementsID );
4459 GroupsOfElementsID = new SMESH::array_of_long_array;
4460 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4462 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4463 aListOfListOfElementsID.begin();
4464 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4466 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4467 list<int>& listOfIDs = *arraysIt;
4468 aGroup.length( listOfIDs.size() );
4469 list<int>::iterator idIt = listOfIDs.begin();
4470 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4471 aGroup[ k ] = *idIt;
4474 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4479 //=======================================================================
4480 //function : MergeElements
4482 //=======================================================================
4484 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4488 TPythonDump aTPythonDump;
4489 aTPythonDump << this << ".MergeElements( [";
4491 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4493 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4494 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4495 aListOfListOfElementsID.push_back( list< int >() );
4496 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4497 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4498 CORBA::Long id = anElemsIDGroup[ j ];
4499 aListOfElemsID.push_back( id );
4501 if ( aListOfElemsID.size() < 2 )
4502 aListOfListOfElementsID.pop_back();
4503 if ( i > 0 ) aTPythonDump << ", ";
4504 aTPythonDump << anElemsIDGroup;
4507 myEditor.MergeElements(aListOfListOfElementsID);
4508 myMesh->GetMeshDS()->Modified();
4509 myMesh->SetIsModified( true );
4511 aTPythonDump << "] )";
4514 //=======================================================================
4515 //function : MergeEqualElements
4517 //=======================================================================
4519 void SMESH_MeshEditor_i::MergeEqualElements()
4523 myEditor.MergeEqualElements();
4525 myMesh->GetMeshDS()->Modified();
4527 TPythonDump() << this << ".MergeEqualElements()";
4530 //=============================================================================
4532 * Move the node to a given point
4534 //=============================================================================
4536 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4541 initData(/*deleteSearchers=*/false);
4543 const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
4547 if ( theNodeSearcher )
4548 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4550 if ( myPreviewMode ) // make preview data
4552 // in a preview mesh, make edges linked to a node
4553 TPreviewMesh tmpMesh;
4554 TIDSortedElemSet linkedNodes;
4555 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4556 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4557 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4558 for ( ; nIt != linkedNodes.end(); ++nIt )
4560 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4561 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4565 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4566 // fill preview data
4567 storeResult( myEditor );
4569 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4570 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4572 GetMeshDS()->MoveNode(node, x, y, z);
4574 if ( !myPreviewMode )
4576 // Update Python script
4577 TPythonDump() << "isDone = " << this << ".MoveNode( "
4578 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4579 myMesh->GetMeshDS()->Modified();
4580 myMesh->SetIsModified( true );
4586 //================================================================================
4588 * \brief Return ID of node closest to a given point
4590 //================================================================================
4592 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4596 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4598 if ( !theNodeSearcher ) {
4599 theNodeSearcher = myEditor.GetNodeSearcher();
4602 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4603 return node->GetID();
4608 //================================================================================
4610 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4611 * move the node closest to the point to point's location and return ID of the node
4613 //================================================================================
4615 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4618 CORBA::Long theNodeID)
4620 // We keep theNodeSearcher until any mesh modification:
4621 // 1) initData() deletes theNodeSearcher at any edition,
4622 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4624 initData(/*deleteSearchers=*/false);
4626 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4628 int nodeID = theNodeID;
4629 const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
4630 if ( !node ) // preview moving node
4632 if ( !theNodeSearcher ) {
4633 theNodeSearcher = myEditor.GetNodeSearcher();
4636 node = theNodeSearcher->FindClosestTo( p );
4639 nodeID = node->GetID();
4640 if ( myPreviewMode ) // make preview data
4642 // in a preview mesh, make edges linked to a node
4643 TPreviewMesh tmpMesh;
4644 TIDSortedElemSet linkedNodes;
4645 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4646 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4647 for ( ; nIt != linkedNodes.end(); ++nIt )
4649 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4650 tmpMesh.Copy( &edge );
4653 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4655 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4656 // fill preview data
4657 storeResult( myEditor );
4659 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4661 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4665 GetMeshDS()->MoveNode(node, x, y, z);
4669 if ( !myPreviewMode )
4671 TPythonDump() << "nodeID = " << this
4672 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4673 << ", " << nodeID << " )";
4675 myMesh->GetMeshDS()->Modified();
4676 myMesh->SetIsModified( true );
4682 //=======================================================================
4684 * Return elements of given type where the given point is IN or ON.
4686 * 'ALL' type means elements of any type excluding nodes
4688 //=======================================================================
4690 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4693 SMESH::ElementType type)
4695 SMESH::long_array_var res = new SMESH::long_array;
4696 vector< const SMDS_MeshElement* > foundElems;
4698 theSearchersDeleter.Set( myMesh );
4699 if ( !theElementSearcher ) {
4700 theElementSearcher = myEditor.GetElementSearcher();
4702 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4703 SMDSAbs_ElementType( type ),
4705 res->length( foundElems.size() );
4706 for ( int i = 0; i < foundElems.size(); ++i )
4707 res[i] = foundElems[i]->GetID();
4709 if ( !myPreviewMode ) // call from tui
4710 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4719 //=======================================================================
4720 //function : FindAmongElementsByPoint
4721 //purpose : Searching among the given elements, return elements of given type
4722 // where the given point is IN or ON.
4723 // 'ALL' type means elements of any type excluding nodes
4724 //=======================================================================
4727 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4731 SMESH::ElementType type)
4733 SMESH::long_array_var res = new SMESH::long_array;
4735 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4736 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4737 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4738 type != types[0] ) // but search of elements of dim > 0
4741 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4742 return FindElementsByPoint( x,y,z, type );
4744 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4746 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4747 if ( !theElementSearcher )
4749 // create a searcher from elementIDs
4750 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4751 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4753 if ( !idSourceToSet( elementIDs, meshDS, elements,
4754 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4757 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4758 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4760 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
4763 vector< const SMDS_MeshElement* > foundElems;
4765 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4766 SMDSAbs_ElementType( type ),
4768 res->length( foundElems.size() );
4769 for ( int i = 0; i < foundElems.size(); ++i )
4770 res[i] = foundElems[i]->GetID();
4772 if ( !myPreviewMode ) // call from tui
4773 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4774 << elementIDs << ", "
4783 //=======================================================================
4784 //function : GetPointState
4785 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4786 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4787 //=======================================================================
4789 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4793 theSearchersDeleter.Set( myMesh );
4794 if ( !theElementSearcher ) {
4795 theElementSearcher = myEditor.GetElementSearcher();
4797 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4800 //=======================================================================
4801 //function : convError
4803 //=======================================================================
4805 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4807 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4811 RETCASE( SEW_BORDER1_NOT_FOUND );
4812 RETCASE( SEW_BORDER2_NOT_FOUND );
4813 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4814 RETCASE( SEW_BAD_SIDE_NODES );
4815 RETCASE( SEW_VOLUMES_TO_SPLIT );
4816 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4817 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4818 RETCASE( SEW_BAD_SIDE1_NODES );
4819 RETCASE( SEW_BAD_SIDE2_NODES );
4821 return SMESH::SMESH_MeshEditor::SEW_OK;
4824 //=======================================================================
4825 //function : SewFreeBorders
4827 //=======================================================================
4829 SMESH::SMESH_MeshEditor::Sew_Error
4830 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4831 CORBA::Long SecondNodeID1,
4832 CORBA::Long LastNodeID1,
4833 CORBA::Long FirstNodeID2,
4834 CORBA::Long SecondNodeID2,
4835 CORBA::Long LastNodeID2,
4836 CORBA::Boolean CreatePolygons,
4837 CORBA::Boolean CreatePolyedrs)
4841 SMESHDS_Mesh* aMesh = GetMeshDS();
4843 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4844 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4845 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4846 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4847 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4848 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4850 if (!aBorderFirstNode ||
4851 !aBorderSecondNode||
4853 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4854 if (!aSide2FirstNode ||
4855 !aSide2SecondNode ||
4857 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4859 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4860 << FirstNodeID1 << ", "
4861 << SecondNodeID1 << ", "
4862 << LastNodeID1 << ", "
4863 << FirstNodeID2 << ", "
4864 << SecondNodeID2 << ", "
4865 << LastNodeID2 << ", "
4866 << CreatePolygons<< ", "
4867 << CreatePolyedrs<< " )";
4869 SMESH::SMESH_MeshEditor::Sew_Error error =
4870 convError( myEditor.SewFreeBorder (aBorderFirstNode,
4880 storeResult(myEditor);
4882 myMesh->GetMeshDS()->Modified();
4883 myMesh->SetIsModified( true );
4889 //=======================================================================
4890 //function : SewConformFreeBorders
4892 //=======================================================================
4894 SMESH::SMESH_MeshEditor::Sew_Error
4895 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4896 CORBA::Long SecondNodeID1,
4897 CORBA::Long LastNodeID1,
4898 CORBA::Long FirstNodeID2,
4899 CORBA::Long SecondNodeID2)
4903 SMESHDS_Mesh* aMesh = GetMeshDS();
4905 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4906 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4907 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4908 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4909 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4910 const SMDS_MeshNode* aSide2ThirdNode = 0;
4912 if (!aBorderFirstNode ||
4913 !aBorderSecondNode||
4915 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4916 if (!aSide2FirstNode ||
4918 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4920 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4921 << FirstNodeID1 << ", "
4922 << SecondNodeID1 << ", "
4923 << LastNodeID1 << ", "
4924 << FirstNodeID2 << ", "
4925 << SecondNodeID2 << " )";
4927 SMESH::SMESH_MeshEditor::Sew_Error error =
4928 convError( myEditor.SewFreeBorder (aBorderFirstNode,
4937 storeResult(myEditor);
4939 myMesh->GetMeshDS()->Modified();
4940 myMesh->SetIsModified( true );
4946 //=======================================================================
4947 //function : SewBorderToSide
4949 //=======================================================================
4951 SMESH::SMESH_MeshEditor::Sew_Error
4952 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4953 CORBA::Long SecondNodeIDOnFreeBorder,
4954 CORBA::Long LastNodeIDOnFreeBorder,
4955 CORBA::Long FirstNodeIDOnSide,
4956 CORBA::Long LastNodeIDOnSide,
4957 CORBA::Boolean CreatePolygons,
4958 CORBA::Boolean CreatePolyedrs)
4962 SMESHDS_Mesh* aMesh = GetMeshDS();
4964 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4965 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4966 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4967 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4968 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4969 const SMDS_MeshNode* aSide2ThirdNode = 0;
4971 if (!aBorderFirstNode ||
4972 !aBorderSecondNode||
4974 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4975 if (!aSide2FirstNode ||
4977 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4979 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4980 << FirstNodeIDOnFreeBorder << ", "
4981 << SecondNodeIDOnFreeBorder << ", "
4982 << LastNodeIDOnFreeBorder << ", "
4983 << FirstNodeIDOnSide << ", "
4984 << LastNodeIDOnSide << ", "
4985 << CreatePolygons << ", "
4986 << CreatePolyedrs << ") ";
4988 SMESH::SMESH_MeshEditor::Sew_Error error =
4989 convError( myEditor.SewFreeBorder (aBorderFirstNode,
4999 storeResult(myEditor);
5001 myMesh->GetMeshDS()->Modified();
5002 myMesh->SetIsModified( true );
5008 //=======================================================================
5009 //function : SewSideElements
5011 //=======================================================================
5013 SMESH::SMESH_MeshEditor::Sew_Error
5014 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5015 const SMESH::long_array& IDsOfSide2Elements,
5016 CORBA::Long NodeID1OfSide1ToMerge,
5017 CORBA::Long NodeID1OfSide2ToMerge,
5018 CORBA::Long NodeID2OfSide1ToMerge,
5019 CORBA::Long NodeID2OfSide2ToMerge)
5023 SMESHDS_Mesh* aMesh = GetMeshDS();
5025 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5026 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5027 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5028 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5030 if (!aFirstNode1ToMerge ||
5031 !aFirstNode2ToMerge )
5032 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5033 if (!aSecondNode1ToMerge||
5034 !aSecondNode2ToMerge)
5035 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5037 TIDSortedElemSet aSide1Elems, aSide2Elems;
5038 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5039 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5041 TPythonDump() << "error = " << this << ".SewSideElements( "
5042 << IDsOfSide1Elements << ", "
5043 << IDsOfSide2Elements << ", "
5044 << NodeID1OfSide1ToMerge << ", "
5045 << NodeID1OfSide2ToMerge << ", "
5046 << NodeID2OfSide1ToMerge << ", "
5047 << NodeID2OfSide2ToMerge << ")";
5049 SMESH::SMESH_MeshEditor::Sew_Error error =
5050 convError( myEditor.SewSideElements (aSide1Elems, aSide2Elems,
5053 aSecondNode1ToMerge,
5054 aSecondNode2ToMerge));
5056 storeResult(myEditor);
5058 myMesh->GetMeshDS()->Modified();
5059 myMesh->SetIsModified( true );
5064 //================================================================================
5066 * \brief Set new nodes for given element
5067 * \param ide - element id
5068 * \param newIDs - new node ids
5069 * \retval CORBA::Boolean - true if result is OK
5071 //================================================================================
5073 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5074 const SMESH::long_array& newIDs)
5078 const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
5079 if(!elem) return false;
5081 int nbn = newIDs.length();
5083 vector<const SMDS_MeshNode*> aNodes(nbn);
5086 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
5089 aNodes[nbn1] = aNode;
5092 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5093 << ide << ", " << newIDs << " )";
5095 MESSAGE("ChangeElementNodes");
5096 bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5098 myMesh->GetMeshDS()->Modified();
5100 myMesh->SetIsModified( true );
5105 //=======================================================================
5106 //function : ConvertToQuadratic
5108 //=======================================================================
5110 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5112 myEditor.ConvertToQuadratic(theForce3d);
5113 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
5114 myMesh->GetMeshDS()->Modified();
5115 myMesh->SetIsModified( true );
5118 //=======================================================================
5119 //function : ConvertFromQuadratic
5121 //=======================================================================
5123 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5125 CORBA::Boolean isDone = myEditor.ConvertFromQuadratic();
5126 TPythonDump() << this << ".ConvertFromQuadratic()";
5127 myMesh->GetMeshDS()->Modified();
5129 myMesh->SetIsModified( true );
5132 //================================================================================
5134 * \brief Makes a part of the mesh quadratic
5136 //================================================================================
5138 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5139 SMESH::SMESH_IDSource_ptr theObject)
5140 throw (SALOME::SALOME_Exception)
5142 Unexpect aCatch(SALOME_SalomeException);
5144 TIDSortedElemSet elems;
5145 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5147 if ( elems.empty() )
5149 ConvertToQuadratic( theForce3d );
5151 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5153 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5157 myEditor.ConvertToQuadratic(theForce3d, elems);
5160 myMesh->GetMeshDS()->Modified();
5161 myMesh->SetIsModified( true );
5163 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
5166 //================================================================================
5168 * \brief Makes a part of the mesh linear
5170 //================================================================================
5172 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5173 throw (SALOME::SALOME_Exception)
5175 Unexpect aCatch(SALOME_SalomeException);
5177 TIDSortedElemSet elems;
5178 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5180 if ( elems.empty() )
5182 ConvertFromQuadratic();
5184 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5186 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5190 myEditor.ConvertFromQuadratic(elems);
5193 myMesh->GetMeshDS()->Modified();
5194 myMesh->SetIsModified( true );
5196 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5199 //=======================================================================
5200 //function : makeMesh
5201 //purpose : create a named imported mesh
5202 //=======================================================================
5204 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5206 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5207 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5208 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5209 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
5210 gen->SetName( meshSO, theMeshName, "Mesh" );
5211 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5213 return mesh._retn();
5216 //=======================================================================
5217 //function : DumpGroupsList
5219 //=======================================================================
5220 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
5221 const SMESH::ListOfGroups * theGroupList)
5223 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
5224 if(isDumpGroupList) {
5225 theDumpPython << theGroupList << " = ";
5229 //================================================================================
5231 \brief Generates the unique group name.
5232 \param thePrefix name prefix
5235 //================================================================================
5236 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5238 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5239 set<string> groupNames;
5241 // Get existing group names
5242 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5243 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5244 if (CORBA::is_nil(aGroup))
5247 groupNames.insert(aGroup->GetName());
5251 string name = thePrefix;
5254 while (!groupNames.insert(name).second) {
5259 TCollection_AsciiString nbStr(index+1);
5260 name.resize( name.rfind('_')+1 );
5261 name += nbStr.ToCString();
5269 //================================================================================
5271 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5272 \param theNodes - identifiers of nodes to be doubled
5273 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5274 nodes. If list of element identifiers is empty then nodes are doubled but
5275 they not assigned to elements
5276 \return TRUE if operation has been completed successfully, FALSE otherwise
5277 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5279 //================================================================================
5281 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5282 const SMESH::long_array& theModifiedElems )
5286 list< int > aListOfNodes;
5288 for ( i = 0, n = theNodes.length(); i < n; i++ )
5289 aListOfNodes.push_back( theNodes[ i ] );
5291 list< int > aListOfElems;
5292 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5293 aListOfElems.push_back( theModifiedElems[ i ] );
5295 bool aResult = myEditor.DoubleNodes( aListOfNodes, aListOfElems );
5297 myMesh->GetMeshDS()->Modified();
5298 storeResult( myEditor) ;
5300 myMesh->SetIsModified( true );
5302 // Update Python script
5303 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5308 //================================================================================
5310 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5311 This method provided for convenience works as DoubleNodes() described above.
5312 \param theNodeId - identifier of node to be doubled.
5313 \param theModifiedElems - identifiers of elements to be updated.
5314 \return TRUE if operation has been completed successfully, FALSE otherwise
5315 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5317 //================================================================================
5319 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5320 const SMESH::long_array& theModifiedElems )
5322 SMESH::long_array_var aNodes = new SMESH::long_array;
5323 aNodes->length( 1 );
5324 aNodes[ 0 ] = theNodeId;
5326 TPythonDump pyDump; // suppress dump by the next line
5328 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5330 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5335 //================================================================================
5337 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5338 This method provided for convenience works as DoubleNodes() described above.
5339 \param theNodes - group of nodes to be doubled.
5340 \param theModifiedElems - group of elements to be updated.
5341 \return TRUE if operation has been completed successfully, FALSE otherwise
5342 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5344 //================================================================================
5346 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5347 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5349 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5352 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5353 SMESH::long_array_var aModifiedElems;
5354 if ( !CORBA::is_nil( theModifiedElems ) )
5355 aModifiedElems = theModifiedElems->GetListOfID();
5358 aModifiedElems = new SMESH::long_array;
5359 aModifiedElems->length( 0 );
5362 TPythonDump pyDump; // suppress dump by the next line
5364 bool done = DoubleNodes( aNodes, aModifiedElems );
5366 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5372 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5373 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5374 * \param theNodes - group of nodes to be doubled.
5375 * \param theModifiedElems - group of elements to be updated.
5376 * \return a new group with newly created nodes
5377 * \sa DoubleNodeGroup()
5379 SMESH::SMESH_Group_ptr
5380 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5381 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5383 SMESH::SMESH_Group_var aNewGroup;
5385 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5386 return aNewGroup._retn();
5389 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5390 SMESH::long_array_var aModifiedElems;
5391 if ( !CORBA::is_nil( theModifiedElems ) )
5392 aModifiedElems = theModifiedElems->GetListOfID();
5394 aModifiedElems = new SMESH::long_array;
5395 aModifiedElems->length( 0 );
5398 TPythonDump pyDump; // suppress dump by the next line
5400 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5403 // Create group with newly created nodes
5404 SMESH::long_array_var anIds = GetLastCreatedNodes();
5405 if (anIds->length() > 0) {
5406 string anUnindexedName (theNodes->GetName());
5407 string aNewName = generateGroupName(anUnindexedName + "_double");
5408 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5409 aNewGroup->Add(anIds);
5410 pyDump << aNewGroup << " = ";
5414 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5415 << theModifiedElems << " )";
5417 return aNewGroup._retn();
5420 //================================================================================
5422 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5423 This method provided for convenience works as DoubleNodes() described above.
5424 \param theNodes - list of groups of nodes to be doubled
5425 \param theModifiedElems - list of groups of elements to be updated.
5426 \return TRUE if operation has been completed successfully, FALSE otherwise
5427 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5429 //================================================================================
5431 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5432 const SMESH::ListOfGroups& theModifiedElems )
5437 std::list< int > aNodes;
5439 for ( i = 0, n = theNodes.length(); i < n; i++ )
5441 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5442 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5444 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5445 for ( j = 0, m = aCurr->length(); j < m; j++ )
5446 aNodes.push_back( aCurr[ j ] );
5450 std::list< int > anElems;
5451 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5453 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5454 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5456 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5457 for ( j = 0, m = aCurr->length(); j < m; j++ )
5458 anElems.push_back( aCurr[ j ] );
5462 bool aResult = myEditor.DoubleNodes( aNodes, anElems );
5464 storeResult( myEditor) ;
5466 myMesh->GetMeshDS()->Modified();
5468 myMesh->SetIsModified( true );
5471 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5476 //================================================================================
5478 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5479 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5480 * \param theNodes - group of nodes to be doubled.
5481 * \param theModifiedElems - group of elements to be updated.
5482 * \return a new group with newly created nodes
5483 * \sa DoubleNodeGroups()
5485 //================================================================================
5487 SMESH::SMESH_Group_ptr
5488 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5489 const SMESH::ListOfGroups& theModifiedElems )
5491 SMESH::SMESH_Group_var aNewGroup;
5493 TPythonDump pyDump; // suppress dump by the next line
5495 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5499 // Create group with newly created nodes
5500 SMESH::long_array_var anIds = GetLastCreatedNodes();
5501 if (anIds->length() > 0) {
5502 string anUnindexedName (theNodes[0]->GetName());
5503 string aNewName = generateGroupName(anUnindexedName + "_double");
5504 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5505 aNewGroup->Add(anIds);
5506 pyDump << aNewGroup << " = ";
5510 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5511 << theModifiedElems << " )";
5513 return aNewGroup._retn();
5517 //================================================================================
5519 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5520 \param theElems - the list of elements (edges or faces) to be replicated
5521 The nodes for duplication could be found from these elements
5522 \param theNodesNot - list of nodes to NOT replicate
5523 \param theAffectedElems - the list of elements (cells and edges) to which the
5524 replicated nodes should be associated to.
5525 \return TRUE if operation has been completed successfully, FALSE otherwise
5526 \sa DoubleNodeGroup(), DoubleNodeGroups()
5528 //================================================================================
5530 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5531 const SMESH::long_array& theNodesNot,
5532 const SMESH::long_array& theAffectedElems )
5538 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5539 TIDSortedElemSet anElems, aNodes, anAffected;
5540 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5541 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5542 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5544 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5546 storeResult( myEditor) ;
5548 myMesh->GetMeshDS()->Modified();
5550 myMesh->SetIsModified( true );
5552 // Update Python script
5553 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5554 << theNodesNot << ", " << theAffectedElems << " )";
5558 //================================================================================
5560 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5561 \param theElems - the list of elements (edges or faces) to be replicated
5562 The nodes for duplication could be found from these elements
5563 \param theNodesNot - list of nodes to NOT replicate
5564 \param theShape - shape to detect affected elements (element which geometric center
5565 located on or inside shape).
5566 The replicated nodes should be associated to affected elements.
5567 \return TRUE if operation has been completed successfully, FALSE otherwise
5568 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5570 //================================================================================
5572 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5573 const SMESH::long_array& theNodesNot,
5574 GEOM::GEOM_Object_ptr theShape )
5580 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5581 TIDSortedElemSet anElems, aNodes;
5582 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5583 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5585 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5586 bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5588 storeResult( myEditor) ;
5590 myMesh->GetMeshDS()->Modified();
5592 myMesh->SetIsModified( true );
5594 // Update Python script
5595 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5596 << theNodesNot << ", " << theShape << " )";
5600 //================================================================================
5602 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5603 \param theElems - group of of elements (edges or faces) to be replicated
5604 \param theNodesNot - group of nodes not to replicated
5605 \param theAffectedElems - group of elements to which the replicated nodes
5606 should be associated to.
5607 \return TRUE if operation has been completed successfully, FALSE otherwise
5608 \sa DoubleNodes(), DoubleNodeGroups()
5610 //================================================================================
5612 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5613 SMESH::SMESH_GroupBase_ptr theNodesNot,
5614 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5616 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5622 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5623 TIDSortedElemSet anElems, aNodes, anAffected;
5624 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5625 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5626 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5628 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5630 storeResult( myEditor) ;
5632 myMesh->GetMeshDS()->Modified();
5634 myMesh->SetIsModified( true );
5636 // Update Python script
5637 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5638 << theNodesNot << ", " << theAffectedElems << " )";
5643 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5644 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5645 * \param theElems - group of of elements (edges or faces) to be replicated
5646 * \param theNodesNot - group of nodes not to replicated
5647 * \param theAffectedElems - group of elements to which the replicated nodes
5648 * should be associated to.
5649 * \return a new group with newly created elements
5650 * \sa DoubleNodeElemGroup()
5652 SMESH::SMESH_Group_ptr
5653 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5654 SMESH::SMESH_GroupBase_ptr theNodesNot,
5655 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5658 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5662 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5663 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5665 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5667 << theNodesNot << ", "
5668 << theAffectedElems << " )";
5670 return elemGroup._retn();
5673 SMESH::ListOfGroups*
5674 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5675 SMESH::SMESH_GroupBase_ptr theNodesNot,
5676 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5677 CORBA::Boolean theElemGroupNeeded,
5678 CORBA::Boolean theNodeGroupNeeded)
5680 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5681 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5682 aTwoGroups->length( 2 );
5684 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5685 return aTwoGroups._retn();
5690 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5691 TIDSortedElemSet anElems, aNodes, anAffected;
5692 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5693 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5694 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5697 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5699 storeResult( myEditor) ;
5700 myMesh->GetMeshDS()->Modified();
5706 myMesh->SetIsModified( true );
5708 // Create group with newly created elements
5709 CORBA::String_var elemGroupName = theElems->GetName();
5710 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5711 if ( !myEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5713 SMESH::long_array_var anIds = GetLastCreatedElems();
5714 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5715 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5716 aNewElemGroup->Add(anIds);
5718 if ( !myEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5720 SMESH::long_array_var anIds = GetLastCreatedNodes();
5721 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5722 aNewNodeGroup->Add(anIds);
5726 // Update Python script
5729 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5730 else pyDump << aNewElemGroup << ", ";
5731 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5732 else pyDump << aNewNodeGroup << " ] = ";
5734 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5735 << theNodesNot << ", "
5736 << theAffectedElems << ", "
5737 << theElemGroupNeeded << ", "
5738 << theNodeGroupNeeded <<" )";
5740 aTwoGroups[0] = aNewElemGroup._retn();
5741 aTwoGroups[1] = aNewNodeGroup._retn();
5742 return aTwoGroups._retn();
5745 //================================================================================
5747 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5748 \param theElems - group of of elements (edges or faces) to be replicated
5749 \param theNodesNot - group of nodes not to replicated
5750 \param theShape - shape to detect affected elements (element which geometric center
5751 located on or inside shape).
5752 The replicated nodes should be associated to affected elements.
5753 \return TRUE if operation has been completed successfully, FALSE otherwise
5754 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5756 //================================================================================
5758 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5759 SMESH::SMESH_GroupBase_ptr theNodesNot,
5760 GEOM::GEOM_Object_ptr theShape )
5763 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5769 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5770 TIDSortedElemSet anElems, aNodes, anAffected;
5771 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5772 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5774 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5775 bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5777 storeResult( myEditor) ;
5779 myMesh->GetMeshDS()->Modified();
5781 myMesh->SetIsModified( true );
5783 // Update Python script
5784 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5785 << theNodesNot << ", " << theShape << " )";
5789 //================================================================================
5791 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5792 This method provided for convenience works as DoubleNodes() described above.
5793 \param theElems - list of groups of elements (edges or faces) to be replicated
5794 \param theNodesNot - list of groups of nodes not to replicated
5795 \param theAffectedElems - group of elements to which the replicated nodes
5796 should be associated to.
5797 \return TRUE if operation has been completed successfully, FALSE otherwise
5798 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5800 //================================================================================
5802 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5803 SMESHDS_Mesh* theMeshDS,
5804 TIDSortedElemSet& theElemSet,
5805 const bool theIsNodeGrp)
5807 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5809 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5810 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5811 : aGrp->GetType() != SMESH::NODE ) )
5813 SMESH::long_array_var anIDs = aGrp->GetIDs();
5814 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5819 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5820 const SMESH::ListOfGroups& theNodesNot,
5821 const SMESH::ListOfGroups& theAffectedElems)
5826 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5827 TIDSortedElemSet anElems, aNodes, anAffected;
5828 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5829 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5830 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5832 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5834 storeResult( myEditor) ;
5836 myMesh->GetMeshDS()->Modified();
5838 myMesh->SetIsModified( true );
5840 // Update Python script
5841 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5842 << &theNodesNot << ", " << &theAffectedElems << " )";
5846 //================================================================================
5848 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5849 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5850 \param theElems - list of groups of elements (edges or faces) to be replicated
5851 \param theNodesNot - list of groups of nodes not to replicated
5852 \param theAffectedElems - group of elements to which the replicated nodes
5853 should be associated to.
5854 * \return a new group with newly created elements
5855 * \sa DoubleNodeElemGroups()
5857 //================================================================================
5859 SMESH::SMESH_Group_ptr
5860 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5861 const SMESH::ListOfGroups& theNodesNot,
5862 const SMESH::ListOfGroups& theAffectedElems)
5865 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
5869 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5870 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5872 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
5874 << theNodesNot << ", "
5875 << theAffectedElems << " )";
5877 return elemGroup._retn();
5880 SMESH::ListOfGroups*
5881 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
5882 const SMESH::ListOfGroups& theNodesNot,
5883 const SMESH::ListOfGroups& theAffectedElems,
5884 CORBA::Boolean theElemGroupNeeded,
5885 CORBA::Boolean theNodeGroupNeeded)
5887 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5888 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5889 aTwoGroups->length( 2 );
5894 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5895 TIDSortedElemSet anElems, aNodes, anAffected;
5896 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5897 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5898 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5900 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5902 storeResult( myEditor) ;
5904 myMesh->GetMeshDS()->Modified();
5908 myMesh->SetIsModified( true );
5910 // Create group with newly created elements
5911 CORBA::String_var elemGroupName = theElems[0]->GetName();
5912 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5913 if ( !myEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5915 SMESH::long_array_var anIds = GetLastCreatedElems();
5916 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5917 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5918 aNewElemGroup->Add(anIds);
5920 if ( !myEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5922 SMESH::long_array_var anIds = GetLastCreatedNodes();
5923 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5924 aNewNodeGroup->Add(anIds);
5928 // Update Python script
5931 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5932 else pyDump << aNewElemGroup << ", ";
5933 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5934 else pyDump << aNewNodeGroup << " ] = ";
5936 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
5937 << &theNodesNot << ", "
5938 << &theAffectedElems << ", "
5939 << theElemGroupNeeded << ", "
5940 << theNodeGroupNeeded << " )";
5942 aTwoGroups[0] = aNewElemGroup._retn();
5943 aTwoGroups[1] = aNewNodeGroup._retn();
5944 return aTwoGroups._retn();
5947 //================================================================================
5949 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5950 This method provided for convenience works as DoubleNodes() described above.
5951 \param theElems - list of groups of elements (edges or faces) to be replicated
5952 \param theNodesNot - list of groups of nodes not to replicated
5953 \param theShape - shape to detect affected elements (element which geometric center
5954 located on or inside shape).
5955 The replicated nodes should be associated to affected elements.
5956 \return TRUE if operation has been completed successfully, FALSE otherwise
5957 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
5959 //================================================================================
5962 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
5963 const SMESH::ListOfGroups& theNodesNot,
5964 GEOM::GEOM_Object_ptr theShape )
5969 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5970 TIDSortedElemSet anElems, aNodes;
5971 listOfGroupToSet(theElems, aMeshDS, anElems,false );
5972 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5974 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5975 bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5977 storeResult( myEditor) ;
5979 myMesh->GetMeshDS()->Modified();
5981 myMesh->SetIsModified( true );
5983 // Update Python script
5984 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
5985 << &theNodesNot << ", " << theShape << " )";
5989 //================================================================================
5991 \brief Identify the elements that will be affected by node duplication (actual duplication is not performed.
5992 This method is the first step of DoubleNodeElemGroupsInRegion.
5993 \param theElems - list of groups of elements (edges or faces) to be replicated
5994 \param theNodesNot - list of groups of nodes not to replicated
5995 \param theShape - shape to detect affected elements (element which geometric center
5996 located on or inside shape).
5997 The replicated nodes should be associated to affected elements.
5998 \return groups of affected elements
5999 \sa DoubleNodeElemGroupsInRegion()
6001 //================================================================================
6002 SMESH::ListOfGroups*
6003 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6004 const SMESH::ListOfGroups& theNodesNot,
6005 GEOM::GEOM_Object_ptr theShape )
6007 MESSAGE("AffectedElemGroupsInRegion");
6008 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6009 bool isEdgeGroup = false;
6010 bool isFaceGroup = false;
6011 bool isVolumeGroup = false;
6012 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6013 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6014 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6018 ::SMESH_MeshEditor aMeshEditor(myMesh);
6020 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6021 TIDSortedElemSet anElems, aNodes;
6022 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6023 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6025 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6026 TIDSortedElemSet anAffected;
6027 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6029 storeResult(aMeshEditor);
6031 myMesh->GetMeshDS()->Modified();
6035 myMesh->SetIsModified(true);
6037 int lg = anAffected.size();
6038 MESSAGE("lg="<< lg);
6039 SMESH::long_array_var volumeIds = new SMESH::long_array;
6040 volumeIds->length(lg);
6041 SMESH::long_array_var faceIds = new SMESH::long_array;
6042 faceIds->length(lg);
6043 SMESH::long_array_var edgeIds = new SMESH::long_array;
6044 edgeIds->length(lg);
6049 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6050 for (; eIt != anAffected.end(); ++eIt)
6052 const SMDS_MeshElement* anElem = *eIt;
6055 int elemId = anElem->GetID();
6056 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6057 volumeIds[ivol++] = elemId;
6058 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6059 faceIds[iface++] = elemId;
6060 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6061 edgeIds[iedge++] = elemId;
6063 volumeIds->length(ivol);
6064 faceIds->length(iface);
6065 edgeIds->length(iedge);
6067 aNewVolumeGroup->Add(volumeIds);
6068 aNewFaceGroup->Add(faceIds);
6069 aNewEdgeGroup->Add(edgeIds);
6070 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6071 isFaceGroup = (aNewFaceGroup->Size() > 0);
6072 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6082 aListOfGroups->length(nbGroups);
6086 aListOfGroups[i++] = aNewEdgeGroup._retn();
6088 aListOfGroups[i++] = aNewFaceGroup._retn();
6090 aListOfGroups[i++] = aNewVolumeGroup._retn();
6092 // Update Python script
6096 pyDump << aNewEdgeGroup << ", ";
6098 pyDump << aNewFaceGroup << ", ";
6100 pyDump << aNewVolumeGroup << ", ";
6102 pyDump << this << ".AffectedElemGroupsInRegion( " << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6104 return aListOfGroups._retn();
6107 //================================================================================
6109 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6110 The created 2D mesh elements based on nodes of free faces of boundary volumes
6111 \return TRUE if operation has been completed successfully, FALSE otherwise
6113 //================================================================================
6115 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6119 bool aResult = myEditor.Make2DMeshFrom3D();
6120 storeResult( myEditor) ;
6121 myMesh->GetMeshDS()->Modified();
6122 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6126 //================================================================================
6128 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6129 * The list of groups must describe a partition of the mesh volumes.
6130 * The nodes of the internal faces at the boundaries of the groups are doubled.
6131 * In option, the internal faces are replaced by flat elements.
6132 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6133 * The flat elements are stored in groups of volumes.
6134 * @param theDomains - list of groups of volumes
6135 * @param createJointElems - if TRUE, create the elements
6136 * @return TRUE if operation has been completed successfully, FALSE otherwise
6138 //================================================================================
6140 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6141 CORBA::Boolean createJointElems )
6142 throw (SALOME::SALOME_Exception)
6147 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6149 vector<TIDSortedElemSet> domains;
6152 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6154 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6155 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6157 // if ( aGrp->GetType() != SMESH::VOLUME )
6158 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6159 TIDSortedElemSet domain;
6161 domains.push_back(domain);
6162 SMESH::long_array_var anIDs = aGrp->GetIDs();
6163 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6167 bool aResult = myEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
6168 // TODO publish the groups of flat elements in study
6170 storeResult( myEditor) ;
6171 myMesh->GetMeshDS()->Modified();
6173 // Update Python script
6174 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6175 << ", " << createJointElems << " )";
6179 //================================================================================
6181 * \brief Double nodes on some external faces and create flat elements.
6182 * Flat elements are mainly used by some types of mechanic calculations.
6184 * Each group of the list must be constituted of faces.
6185 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6186 * @param theGroupsOfFaces - list of groups of faces
6187 * @return TRUE if operation has been completed successfully, FALSE otherwise
6189 //================================================================================
6191 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6196 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6198 vector<TIDSortedElemSet> faceGroups;
6201 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6203 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6204 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6206 TIDSortedElemSet faceGroup;
6208 faceGroups.push_back(faceGroup);
6209 SMESH::long_array_var anIDs = aGrp->GetIDs();
6210 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6214 bool aResult = myEditor.CreateFlatElementsOnFacesGroups( faceGroups );
6215 // TODO publish the groups of flat elements in study
6217 storeResult( myEditor) ;
6218 myMesh->GetMeshDS()->Modified();
6220 // Update Python script
6221 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6226 * \brief identify all the elements around a geom shape, get the faces delimiting the hole
6227 * Build groups of volume to remove, groups of faces to replace on the skin of the object,
6228 * groups of faces to remove inside the object, (idem edges).
6229 * Build ordered list of nodes at the border of each group of faces to replace (to be used to build a geom subshape)
6231 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6232 GEOM::GEOM_Object_ptr theShape,
6233 const char* groupName,
6234 const SMESH::double_array& theNodesCoords,
6235 SMESH::array_of_long_array_out GroupsOfNodes)
6236 throw (SALOME::SALOME_Exception)
6239 std::vector<std::vector<int> > aListOfListOfNodes;
6240 ::SMESH_MeshEditor aMeshEditor( myMesh );
6242 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6243 if ( !theNodeSearcher )
6244 theNodeSearcher = aMeshEditor.GetNodeSearcher();
6246 vector<double> nodesCoords;
6247 for (int i = 0; i < theNodesCoords.length(); i++)
6249 nodesCoords.push_back( theNodesCoords[i] );
6252 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6253 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName, nodesCoords, aListOfListOfNodes);
6255 GroupsOfNodes = new SMESH::array_of_long_array;
6256 GroupsOfNodes->length( aListOfListOfNodes.size() );
6257 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6258 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6260 vector<int>& aListOfNodes = *llIt;
6261 vector<int>::iterator lIt = aListOfNodes.begin();;
6262 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6263 aGroup.length( aListOfNodes.size() );
6264 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6265 aGroup[ j ] = (*lIt);
6267 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6268 << radius << ", " << theShape << ", " << ", " << groupName << ", " << theNodesCoords << " )";
6272 // issue 20749 ===================================================================
6274 * \brief Creates missing boundary elements
6275 * \param elements - elements whose boundary is to be checked
6276 * \param dimension - defines type of boundary elements to create
6277 * \param groupName - a name of group to store created boundary elements in,
6278 * "" means not to create the group
6279 * \param meshName - a name of new mesh to store created boundary elements in,
6280 * "" means not to create the new mesh
6281 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6282 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6283 * boundary elements will be copied into the new mesh
6284 * \param group - returns the create group, if any
6285 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6287 // ================================================================================
6289 SMESH::SMESH_Mesh_ptr
6290 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6291 SMESH::Bnd_Dimension dim,
6292 const char* groupName,
6293 const char* meshName,
6294 CORBA::Boolean toCopyElements,
6295 CORBA::Boolean toCopyExistingBondary,
6296 SMESH::SMESH_Group_out group)
6300 if ( dim > SMESH::BND_1DFROM2D )
6301 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6303 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6305 SMESH::SMESH_Mesh_var mesh_var;
6306 SMESH::SMESH_Group_var group_var;
6310 TIDSortedElemSet elements;
6311 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6312 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6316 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6317 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6319 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6321 // group of new boundary elements
6322 SMESH_Group* smesh_group = 0;
6323 if ( strlen(groupName) )
6325 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6326 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6327 smesh_group = group_i->GetSmeshGroup();
6331 myEditor.MakeBoundaryMesh( elements,
6332 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6336 toCopyExistingBondary);
6337 storeResult( myEditor );
6340 smesh_mesh->GetMeshDS()->Modified();
6343 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6345 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6346 if ( mesh_var->_is_nil() )
6347 pyDump << myMesh_i->_this() << ", ";
6349 pyDump << mesh_var << ", ";
6350 if ( group_var->_is_nil() )
6351 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6353 pyDump << group_var << " = ";
6354 pyDump << this << ".MakeBoundaryMesh( "
6356 << "SMESH." << dimName[int(dim)] << ", "
6357 << "'" << groupName << "', "
6358 << "'" << meshName<< "', "
6359 << toCopyElements << ", "
6360 << toCopyExistingBondary << ")";
6362 group = group_var._retn();
6363 return mesh_var._retn();
6366 //================================================================================
6368 * \brief Creates missing boundary elements
6369 * \param dimension - defines type of boundary elements to create
6370 * \param groupName - a name of group to store all boundary elements in,
6371 * "" means not to create the group
6372 * \param meshName - a name of a new mesh, which is a copy of the initial
6373 * mesh + created boundary elements; "" means not to create the new mesh
6374 * \param toCopyAll - if true, the whole initial mesh will be copied into
6375 * the new mesh else only boundary elements will be copied into the new mesh
6376 * \param groups - optional groups of elements to make boundary around
6377 * \param mesh - returns the mesh where elements were added to
6378 * \param group - returns the created group, if any
6379 * \retval long - number of added boundary elements
6381 //================================================================================
6383 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6384 const char* groupName,
6385 const char* meshName,
6386 CORBA::Boolean toCopyAll,
6387 const SMESH::ListOfIDSources& groups,
6388 SMESH::SMESH_Mesh_out mesh,
6389 SMESH::SMESH_Group_out group)
6390 throw (SALOME::SALOME_Exception)
6392 Unexpect aCatch(SALOME_SalomeException);
6396 if ( dim > SMESH::BND_1DFROM2D )
6397 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6399 // separate groups belonging to this and other mesh
6400 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6401 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6402 groupsOfThisMesh->length( groups.length() );
6403 groupsOfOtherMesh->length( groups.length() );
6404 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6405 for ( int i = 0; i < groups.length(); ++i )
6407 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6408 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6409 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6411 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6412 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6413 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6415 groupsOfThisMesh->length( nbGroups );
6416 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6421 if ( nbGroupsOfOtherMesh > 0 )
6423 // process groups belonging to another mesh
6424 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6425 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6426 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6427 groupsOfOtherMesh, mesh, group );
6430 SMESH::SMESH_Mesh_var mesh_var;
6431 SMESH::SMESH_Group_var group_var;
6434 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6435 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6439 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6441 /*toCopyGroups=*/false,
6442 /*toKeepIDs=*/true);
6444 mesh_var = makeMesh(meshName);
6446 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6447 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6450 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6451 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6453 // group of boundary elements
6454 SMESH_Group* smesh_group = 0;
6455 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6456 if ( strlen(groupName) )
6458 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6459 group_var = mesh_i->CreateGroup( groupType, groupName );
6460 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6461 smesh_group = group_i->GetSmeshGroup();
6464 TIDSortedElemSet elements;
6466 if ( groups.length() > 0 )
6468 for ( int i = 0; i < nbGroups; ++i )
6471 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6473 SMESH::Bnd_Dimension bdim =
6474 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6475 nbAdded += myEditor.MakeBoundaryMesh( elements,
6476 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6479 /*toCopyElements=*/false,
6480 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6481 /*toAddExistingBondary=*/true,
6482 /*aroundElements=*/true);
6483 storeResult( myEditor );
6489 nbAdded += myEditor.MakeBoundaryMesh( elements,
6490 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6493 /*toCopyElements=*/false,
6494 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6495 /*toAddExistingBondary=*/true);
6496 storeResult( myEditor );
6498 tgtMesh->GetMeshDS()->Modified();
6500 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6502 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6503 pyDump << "nbAdded, ";
6504 if ( mesh_var->_is_nil() )
6505 pyDump << myMesh_i->_this() << ", ";
6507 pyDump << mesh_var << ", ";
6508 if ( group_var->_is_nil() )
6509 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6511 pyDump << group_var << " = ";
6512 pyDump << this << ".MakeBoundaryElements( "
6513 << "SMESH." << dimName[int(dim)] << ", "
6514 << "'" << groupName << "', "
6515 << "'" << meshName<< "', "
6516 << toCopyAll << ", "
6519 mesh = mesh_var._retn();
6520 group = group_var._retn();