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 typedef list<int> TListOfIDs;
4454 set<const SMDS_MeshElement*> elems;
4455 SMESH::long_array_var aElementsId = theObject->GetIDs();
4456 SMESHDS_Mesh* aMesh = GetMeshDS();
4458 for(int i = 0; i < aElementsId->length(); i++) {
4459 CORBA::Long anID = aElementsId[i];
4460 const SMDS_MeshElement * elem = aMesh->FindElement(anID);
4466 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4467 myEditor.FindEqualElements( elems, aListOfListOfElementsID );
4469 GroupsOfElementsID = new SMESH::array_of_long_array;
4470 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4472 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
4473 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
4474 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4475 TListOfIDs& listOfIDs = *arraysIt;
4476 aGroup.length( listOfIDs.size() );
4477 TListOfIDs::iterator idIt = listOfIDs.begin();
4478 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
4479 aGroup[ k ] = *idIt;
4483 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4488 //=======================================================================
4489 //function : MergeElements
4491 //=======================================================================
4493 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4497 TPythonDump aTPythonDump;
4498 aTPythonDump << this << ".MergeElements( [";
4500 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4502 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4503 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4504 aListOfListOfElementsID.push_back( list< int >() );
4505 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4506 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4507 CORBA::Long id = anElemsIDGroup[ j ];
4508 aListOfElemsID.push_back( id );
4510 if ( aListOfElemsID.size() < 2 )
4511 aListOfListOfElementsID.pop_back();
4512 if ( i > 0 ) aTPythonDump << ", ";
4513 aTPythonDump << anElemsIDGroup;
4516 myEditor.MergeElements(aListOfListOfElementsID);
4517 myMesh->GetMeshDS()->Modified();
4518 myMesh->SetIsModified( true );
4520 aTPythonDump << "] )";
4523 //=======================================================================
4524 //function : MergeEqualElements
4526 //=======================================================================
4528 void SMESH_MeshEditor_i::MergeEqualElements()
4532 myEditor.MergeEqualElements();
4534 myMesh->GetMeshDS()->Modified();
4536 TPythonDump() << this << ".MergeEqualElements()";
4539 //=============================================================================
4541 * Move the node to a given point
4543 //=============================================================================
4545 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4550 initData(/*deleteSearchers=*/false);
4552 const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
4556 if ( theNodeSearcher )
4557 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4559 if ( myPreviewMode ) // make preview data
4561 // in a preview mesh, make edges linked to a node
4562 TPreviewMesh tmpMesh;
4563 TIDSortedElemSet linkedNodes;
4564 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4565 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4566 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4567 for ( ; nIt != linkedNodes.end(); ++nIt )
4569 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4570 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4574 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4575 // fill preview data
4576 storeResult( myEditor );
4578 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4579 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4581 GetMeshDS()->MoveNode(node, x, y, z);
4583 if ( !myPreviewMode )
4585 // Update Python script
4586 TPythonDump() << "isDone = " << this << ".MoveNode( "
4587 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4588 myMesh->GetMeshDS()->Modified();
4589 myMesh->SetIsModified( true );
4595 //================================================================================
4597 * \brief Return ID of node closest to a given point
4599 //================================================================================
4601 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4605 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4607 if ( !theNodeSearcher ) {
4608 theNodeSearcher = myEditor.GetNodeSearcher();
4611 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4612 return node->GetID();
4617 //================================================================================
4619 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4620 * move the node closest to the point to point's location and return ID of the node
4622 //================================================================================
4624 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4627 CORBA::Long theNodeID)
4629 // We keep theNodeSearcher until any mesh modification:
4630 // 1) initData() deletes theNodeSearcher at any edition,
4631 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4633 initData(/*deleteSearchers=*/false);
4635 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4637 int nodeID = theNodeID;
4638 const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
4639 if ( !node ) // preview moving node
4641 if ( !theNodeSearcher ) {
4642 theNodeSearcher = myEditor.GetNodeSearcher();
4645 node = theNodeSearcher->FindClosestTo( p );
4648 nodeID = node->GetID();
4649 if ( myPreviewMode ) // make preview data
4651 // in a preview mesh, make edges linked to a node
4652 TPreviewMesh tmpMesh;
4653 TIDSortedElemSet linkedNodes;
4654 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4655 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4656 for ( ; nIt != linkedNodes.end(); ++nIt )
4658 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4659 tmpMesh.Copy( &edge );
4662 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4664 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4665 // fill preview data
4666 storeResult( myEditor );
4668 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4670 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4674 GetMeshDS()->MoveNode(node, x, y, z);
4678 if ( !myPreviewMode )
4680 TPythonDump() << "nodeID = " << this
4681 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4682 << ", " << nodeID << " )";
4684 myMesh->GetMeshDS()->Modified();
4685 myMesh->SetIsModified( true );
4691 //=======================================================================
4693 * Return elements of given type where the given point is IN or ON.
4695 * 'ALL' type means elements of any type excluding nodes
4697 //=======================================================================
4699 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4702 SMESH::ElementType type)
4704 SMESH::long_array_var res = new SMESH::long_array;
4705 vector< const SMDS_MeshElement* > foundElems;
4707 theSearchersDeleter.Set( myMesh );
4708 if ( !theElementSearcher ) {
4709 theElementSearcher = myEditor.GetElementSearcher();
4711 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4712 SMDSAbs_ElementType( type ),
4714 res->length( foundElems.size() );
4715 for ( int i = 0; i < foundElems.size(); ++i )
4716 res[i] = foundElems[i]->GetID();
4718 if ( !myPreviewMode ) // call from tui
4719 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4728 //=======================================================================
4729 //function : FindAmongElementsByPoint
4730 //purpose : Searching among the given elements, return elements of given type
4731 // where the given point is IN or ON.
4732 // 'ALL' type means elements of any type excluding nodes
4733 //=======================================================================
4736 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4740 SMESH::ElementType type)
4742 SMESH::long_array_var res = new SMESH::long_array;
4744 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4745 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4746 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4747 type != types[0] ) // but search of elements of dim > 0
4750 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4751 return FindElementsByPoint( x,y,z, type );
4753 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4755 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4756 if ( !theElementSearcher )
4758 // create a searcher from elementIDs
4759 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4760 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4762 if ( !idSourceToSet( elementIDs, meshDS, elements,
4763 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4766 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4767 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4769 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
4772 vector< const SMDS_MeshElement* > foundElems;
4774 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4775 SMDSAbs_ElementType( type ),
4777 res->length( foundElems.size() );
4778 for ( int i = 0; i < foundElems.size(); ++i )
4779 res[i] = foundElems[i]->GetID();
4781 if ( !myPreviewMode ) // call from tui
4782 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4783 << elementIDs << ", "
4792 //=======================================================================
4793 //function : GetPointState
4794 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4795 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4796 //=======================================================================
4798 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4802 theSearchersDeleter.Set( myMesh );
4803 if ( !theElementSearcher ) {
4804 theElementSearcher = myEditor.GetElementSearcher();
4806 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4809 //=======================================================================
4810 //function : convError
4812 //=======================================================================
4814 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4816 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4820 RETCASE( SEW_BORDER1_NOT_FOUND );
4821 RETCASE( SEW_BORDER2_NOT_FOUND );
4822 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4823 RETCASE( SEW_BAD_SIDE_NODES );
4824 RETCASE( SEW_VOLUMES_TO_SPLIT );
4825 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4826 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4827 RETCASE( SEW_BAD_SIDE1_NODES );
4828 RETCASE( SEW_BAD_SIDE2_NODES );
4830 return SMESH::SMESH_MeshEditor::SEW_OK;
4833 //=======================================================================
4834 //function : SewFreeBorders
4836 //=======================================================================
4838 SMESH::SMESH_MeshEditor::Sew_Error
4839 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4840 CORBA::Long SecondNodeID1,
4841 CORBA::Long LastNodeID1,
4842 CORBA::Long FirstNodeID2,
4843 CORBA::Long SecondNodeID2,
4844 CORBA::Long LastNodeID2,
4845 CORBA::Boolean CreatePolygons,
4846 CORBA::Boolean CreatePolyedrs)
4850 SMESHDS_Mesh* aMesh = GetMeshDS();
4852 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4853 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4854 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4855 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4856 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4857 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4859 if (!aBorderFirstNode ||
4860 !aBorderSecondNode||
4862 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4863 if (!aSide2FirstNode ||
4864 !aSide2SecondNode ||
4866 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4868 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4869 << FirstNodeID1 << ", "
4870 << SecondNodeID1 << ", "
4871 << LastNodeID1 << ", "
4872 << FirstNodeID2 << ", "
4873 << SecondNodeID2 << ", "
4874 << LastNodeID2 << ", "
4875 << CreatePolygons<< ", "
4876 << CreatePolyedrs<< " )";
4878 SMESH::SMESH_MeshEditor::Sew_Error error =
4879 convError( myEditor.SewFreeBorder (aBorderFirstNode,
4889 storeResult(myEditor);
4891 myMesh->GetMeshDS()->Modified();
4892 myMesh->SetIsModified( true );
4898 //=======================================================================
4899 //function : SewConformFreeBorders
4901 //=======================================================================
4903 SMESH::SMESH_MeshEditor::Sew_Error
4904 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4905 CORBA::Long SecondNodeID1,
4906 CORBA::Long LastNodeID1,
4907 CORBA::Long FirstNodeID2,
4908 CORBA::Long SecondNodeID2)
4912 SMESHDS_Mesh* aMesh = GetMeshDS();
4914 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4915 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4916 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4917 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4918 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4919 const SMDS_MeshNode* aSide2ThirdNode = 0;
4921 if (!aBorderFirstNode ||
4922 !aBorderSecondNode||
4924 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4925 if (!aSide2FirstNode ||
4927 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4929 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4930 << FirstNodeID1 << ", "
4931 << SecondNodeID1 << ", "
4932 << LastNodeID1 << ", "
4933 << FirstNodeID2 << ", "
4934 << SecondNodeID2 << " )";
4936 SMESH::SMESH_MeshEditor::Sew_Error error =
4937 convError( myEditor.SewFreeBorder (aBorderFirstNode,
4946 storeResult(myEditor);
4948 myMesh->GetMeshDS()->Modified();
4949 myMesh->SetIsModified( true );
4955 //=======================================================================
4956 //function : SewBorderToSide
4958 //=======================================================================
4960 SMESH::SMESH_MeshEditor::Sew_Error
4961 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4962 CORBA::Long SecondNodeIDOnFreeBorder,
4963 CORBA::Long LastNodeIDOnFreeBorder,
4964 CORBA::Long FirstNodeIDOnSide,
4965 CORBA::Long LastNodeIDOnSide,
4966 CORBA::Boolean CreatePolygons,
4967 CORBA::Boolean CreatePolyedrs)
4971 SMESHDS_Mesh* aMesh = GetMeshDS();
4973 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4974 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4975 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4976 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4977 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4978 const SMDS_MeshNode* aSide2ThirdNode = 0;
4980 if (!aBorderFirstNode ||
4981 !aBorderSecondNode||
4983 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4984 if (!aSide2FirstNode ||
4986 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4988 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4989 << FirstNodeIDOnFreeBorder << ", "
4990 << SecondNodeIDOnFreeBorder << ", "
4991 << LastNodeIDOnFreeBorder << ", "
4992 << FirstNodeIDOnSide << ", "
4993 << LastNodeIDOnSide << ", "
4994 << CreatePolygons << ", "
4995 << CreatePolyedrs << ") ";
4997 SMESH::SMESH_MeshEditor::Sew_Error error =
4998 convError( myEditor.SewFreeBorder (aBorderFirstNode,
5008 storeResult(myEditor);
5010 myMesh->GetMeshDS()->Modified();
5011 myMesh->SetIsModified( true );
5017 //=======================================================================
5018 //function : SewSideElements
5020 //=======================================================================
5022 SMESH::SMESH_MeshEditor::Sew_Error
5023 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5024 const SMESH::long_array& IDsOfSide2Elements,
5025 CORBA::Long NodeID1OfSide1ToMerge,
5026 CORBA::Long NodeID1OfSide2ToMerge,
5027 CORBA::Long NodeID2OfSide1ToMerge,
5028 CORBA::Long NodeID2OfSide2ToMerge)
5032 SMESHDS_Mesh* aMesh = GetMeshDS();
5034 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5035 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5036 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5037 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5039 if (!aFirstNode1ToMerge ||
5040 !aFirstNode2ToMerge )
5041 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5042 if (!aSecondNode1ToMerge||
5043 !aSecondNode2ToMerge)
5044 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5046 TIDSortedElemSet aSide1Elems, aSide2Elems;
5047 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5048 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5050 TPythonDump() << "error = " << this << ".SewSideElements( "
5051 << IDsOfSide1Elements << ", "
5052 << IDsOfSide2Elements << ", "
5053 << NodeID1OfSide1ToMerge << ", "
5054 << NodeID1OfSide2ToMerge << ", "
5055 << NodeID2OfSide1ToMerge << ", "
5056 << NodeID2OfSide2ToMerge << ")";
5058 SMESH::SMESH_MeshEditor::Sew_Error error =
5059 convError( myEditor.SewSideElements (aSide1Elems, aSide2Elems,
5062 aSecondNode1ToMerge,
5063 aSecondNode2ToMerge));
5065 storeResult(myEditor);
5067 myMesh->GetMeshDS()->Modified();
5068 myMesh->SetIsModified( true );
5073 //================================================================================
5075 * \brief Set new nodes for given element
5076 * \param ide - element id
5077 * \param newIDs - new node ids
5078 * \retval CORBA::Boolean - true if result is OK
5080 //================================================================================
5082 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5083 const SMESH::long_array& newIDs)
5087 const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
5088 if(!elem) return false;
5090 int nbn = newIDs.length();
5092 vector<const SMDS_MeshNode*> aNodes(nbn);
5095 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
5098 aNodes[nbn1] = aNode;
5101 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5102 << ide << ", " << newIDs << " )";
5104 MESSAGE("ChangeElementNodes");
5105 bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5107 myMesh->GetMeshDS()->Modified();
5109 myMesh->SetIsModified( true );
5114 //=======================================================================
5115 //function : ConvertToQuadratic
5117 //=======================================================================
5119 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5121 myEditor.ConvertToQuadratic(theForce3d);
5122 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
5123 myMesh->GetMeshDS()->Modified();
5124 myMesh->SetIsModified( true );
5127 //=======================================================================
5128 //function : ConvertFromQuadratic
5130 //=======================================================================
5132 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5134 CORBA::Boolean isDone = myEditor.ConvertFromQuadratic();
5135 TPythonDump() << this << ".ConvertFromQuadratic()";
5136 myMesh->GetMeshDS()->Modified();
5138 myMesh->SetIsModified( true );
5141 //================================================================================
5143 * \brief Makes a part of the mesh quadratic
5145 //================================================================================
5147 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5148 SMESH::SMESH_IDSource_ptr theObject)
5149 throw (SALOME::SALOME_Exception)
5151 Unexpect aCatch(SALOME_SalomeException);
5153 TIDSortedElemSet elems;
5154 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5156 if ( elems.empty() )
5158 ConvertToQuadratic( theForce3d );
5160 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5162 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5166 myEditor.ConvertToQuadratic(theForce3d, elems);
5169 myMesh->GetMeshDS()->Modified();
5170 myMesh->SetIsModified( true );
5172 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
5175 //================================================================================
5177 * \brief Makes a part of the mesh linear
5179 //================================================================================
5181 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5182 throw (SALOME::SALOME_Exception)
5184 Unexpect aCatch(SALOME_SalomeException);
5186 TIDSortedElemSet elems;
5187 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5189 if ( elems.empty() )
5191 ConvertFromQuadratic();
5193 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5195 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5199 myEditor.ConvertFromQuadratic(elems);
5202 myMesh->GetMeshDS()->Modified();
5203 myMesh->SetIsModified( true );
5205 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5208 //=======================================================================
5209 //function : makeMesh
5210 //purpose : create a named imported mesh
5211 //=======================================================================
5213 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5215 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5216 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5217 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5218 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
5219 gen->SetName( meshSO, theMeshName, "Mesh" );
5220 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5222 return mesh._retn();
5225 //=======================================================================
5226 //function : DumpGroupsList
5228 //=======================================================================
5229 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
5230 const SMESH::ListOfGroups * theGroupList)
5232 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
5233 if(isDumpGroupList) {
5234 theDumpPython << theGroupList << " = ";
5238 //================================================================================
5240 \brief Generates the unique group name.
5241 \param thePrefix name prefix
5244 //================================================================================
5245 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5247 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5248 set<string> groupNames;
5250 // Get existing group names
5251 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5252 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5253 if (CORBA::is_nil(aGroup))
5256 groupNames.insert(aGroup->GetName());
5260 string name = thePrefix;
5263 while (!groupNames.insert(name).second) {
5268 TCollection_AsciiString nbStr(index+1);
5269 name.resize( name.rfind('_')+1 );
5270 name += nbStr.ToCString();
5278 //================================================================================
5280 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5281 \param theNodes - identifiers of nodes to be doubled
5282 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5283 nodes. If list of element identifiers is empty then nodes are doubled but
5284 they not assigned to elements
5285 \return TRUE if operation has been completed successfully, FALSE otherwise
5286 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5288 //================================================================================
5290 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5291 const SMESH::long_array& theModifiedElems )
5295 list< int > aListOfNodes;
5297 for ( i = 0, n = theNodes.length(); i < n; i++ )
5298 aListOfNodes.push_back( theNodes[ i ] );
5300 list< int > aListOfElems;
5301 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5302 aListOfElems.push_back( theModifiedElems[ i ] );
5304 bool aResult = myEditor.DoubleNodes( aListOfNodes, aListOfElems );
5306 myMesh->GetMeshDS()->Modified();
5307 storeResult( myEditor) ;
5309 myMesh->SetIsModified( true );
5311 // Update Python script
5312 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5317 //================================================================================
5319 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5320 This method provided for convenience works as DoubleNodes() described above.
5321 \param theNodeId - identifier of node to be doubled.
5322 \param theModifiedElems - identifiers of elements to be updated.
5323 \return TRUE if operation has been completed successfully, FALSE otherwise
5324 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5326 //================================================================================
5328 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5329 const SMESH::long_array& theModifiedElems )
5331 SMESH::long_array_var aNodes = new SMESH::long_array;
5332 aNodes->length( 1 );
5333 aNodes[ 0 ] = theNodeId;
5335 TPythonDump pyDump; // suppress dump by the next line
5337 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5339 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5344 //================================================================================
5346 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5347 This method provided for convenience works as DoubleNodes() described above.
5348 \param theNodes - group of nodes to be doubled.
5349 \param theModifiedElems - group of elements to be updated.
5350 \return TRUE if operation has been completed successfully, FALSE otherwise
5351 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5353 //================================================================================
5355 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5356 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5358 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5361 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5362 SMESH::long_array_var aModifiedElems;
5363 if ( !CORBA::is_nil( theModifiedElems ) )
5364 aModifiedElems = theModifiedElems->GetListOfID();
5367 aModifiedElems = new SMESH::long_array;
5368 aModifiedElems->length( 0 );
5371 TPythonDump pyDump; // suppress dump by the next line
5373 bool done = DoubleNodes( aNodes, aModifiedElems );
5375 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5381 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5382 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5383 * \param theNodes - group of nodes to be doubled.
5384 * \param theModifiedElems - group of elements to be updated.
5385 * \return a new group with newly created nodes
5386 * \sa DoubleNodeGroup()
5388 SMESH::SMESH_Group_ptr
5389 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5390 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5392 SMESH::SMESH_Group_var aNewGroup;
5394 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5395 return aNewGroup._retn();
5398 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5399 SMESH::long_array_var aModifiedElems;
5400 if ( !CORBA::is_nil( theModifiedElems ) )
5401 aModifiedElems = theModifiedElems->GetListOfID();
5403 aModifiedElems = new SMESH::long_array;
5404 aModifiedElems->length( 0 );
5407 TPythonDump pyDump; // suppress dump by the next line
5409 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5412 // Create group with newly created nodes
5413 SMESH::long_array_var anIds = GetLastCreatedNodes();
5414 if (anIds->length() > 0) {
5415 string anUnindexedName (theNodes->GetName());
5416 string aNewName = generateGroupName(anUnindexedName + "_double");
5417 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5418 aNewGroup->Add(anIds);
5419 pyDump << aNewGroup << " = ";
5423 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5424 << theModifiedElems << " )";
5426 return aNewGroup._retn();
5429 //================================================================================
5431 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5432 This method provided for convenience works as DoubleNodes() described above.
5433 \param theNodes - list of groups of nodes to be doubled
5434 \param theModifiedElems - list of groups of elements to be updated.
5435 \return TRUE if operation has been completed successfully, FALSE otherwise
5436 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5438 //================================================================================
5440 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5441 const SMESH::ListOfGroups& theModifiedElems )
5446 std::list< int > aNodes;
5448 for ( i = 0, n = theNodes.length(); i < n; i++ )
5450 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5451 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5453 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5454 for ( j = 0, m = aCurr->length(); j < m; j++ )
5455 aNodes.push_back( aCurr[ j ] );
5459 std::list< int > anElems;
5460 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5462 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5463 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5465 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5466 for ( j = 0, m = aCurr->length(); j < m; j++ )
5467 anElems.push_back( aCurr[ j ] );
5471 bool aResult = myEditor.DoubleNodes( aNodes, anElems );
5473 storeResult( myEditor) ;
5475 myMesh->GetMeshDS()->Modified();
5477 myMesh->SetIsModified( true );
5480 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5485 //================================================================================
5487 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5488 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5489 * \param theNodes - group of nodes to be doubled.
5490 * \param theModifiedElems - group of elements to be updated.
5491 * \return a new group with newly created nodes
5492 * \sa DoubleNodeGroups()
5494 //================================================================================
5496 SMESH::SMESH_Group_ptr
5497 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5498 const SMESH::ListOfGroups& theModifiedElems )
5500 SMESH::SMESH_Group_var aNewGroup;
5502 TPythonDump pyDump; // suppress dump by the next line
5504 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5508 // Create group with newly created nodes
5509 SMESH::long_array_var anIds = GetLastCreatedNodes();
5510 if (anIds->length() > 0) {
5511 string anUnindexedName (theNodes[0]->GetName());
5512 string aNewName = generateGroupName(anUnindexedName + "_double");
5513 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5514 aNewGroup->Add(anIds);
5515 pyDump << aNewGroup << " = ";
5519 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5520 << theModifiedElems << " )";
5522 return aNewGroup._retn();
5526 //================================================================================
5528 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5529 \param theElems - the list of elements (edges or faces) to be replicated
5530 The nodes for duplication could be found from these elements
5531 \param theNodesNot - list of nodes to NOT replicate
5532 \param theAffectedElems - the list of elements (cells and edges) to which the
5533 replicated nodes should be associated to.
5534 \return TRUE if operation has been completed successfully, FALSE otherwise
5535 \sa DoubleNodeGroup(), DoubleNodeGroups()
5537 //================================================================================
5539 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5540 const SMESH::long_array& theNodesNot,
5541 const SMESH::long_array& theAffectedElems )
5547 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5548 TIDSortedElemSet anElems, aNodes, anAffected;
5549 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5550 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5551 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5553 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5555 storeResult( myEditor) ;
5557 myMesh->GetMeshDS()->Modified();
5559 myMesh->SetIsModified( true );
5561 // Update Python script
5562 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5563 << theNodesNot << ", " << theAffectedElems << " )";
5567 //================================================================================
5569 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5570 \param theElems - the list of elements (edges or faces) to be replicated
5571 The nodes for duplication could be found from these elements
5572 \param theNodesNot - list of nodes to NOT replicate
5573 \param theShape - shape to detect affected elements (element which geometric center
5574 located on or inside shape).
5575 The replicated nodes should be associated to affected elements.
5576 \return TRUE if operation has been completed successfully, FALSE otherwise
5577 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5579 //================================================================================
5581 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5582 const SMESH::long_array& theNodesNot,
5583 GEOM::GEOM_Object_ptr theShape )
5589 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5590 TIDSortedElemSet anElems, aNodes;
5591 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5592 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5594 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5595 bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5597 storeResult( myEditor) ;
5599 myMesh->GetMeshDS()->Modified();
5601 myMesh->SetIsModified( true );
5603 // Update Python script
5604 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5605 << theNodesNot << ", " << theShape << " )";
5609 //================================================================================
5611 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5612 \param theElems - group of of elements (edges or faces) to be replicated
5613 \param theNodesNot - group of nodes not to replicated
5614 \param theAffectedElems - group of elements to which the replicated nodes
5615 should be associated to.
5616 \return TRUE if operation has been completed successfully, FALSE otherwise
5617 \sa DoubleNodes(), DoubleNodeGroups()
5619 //================================================================================
5621 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5622 SMESH::SMESH_GroupBase_ptr theNodesNot,
5623 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5625 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5631 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5632 TIDSortedElemSet anElems, aNodes, anAffected;
5633 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5634 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5635 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5637 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5639 storeResult( myEditor) ;
5641 myMesh->GetMeshDS()->Modified();
5643 myMesh->SetIsModified( true );
5645 // Update Python script
5646 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5647 << theNodesNot << ", " << theAffectedElems << " )";
5652 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5653 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5654 * \param theElems - group of of elements (edges or faces) to be replicated
5655 * \param theNodesNot - group of nodes not to replicated
5656 * \param theAffectedElems - group of elements to which the replicated nodes
5657 * should be associated to.
5658 * \return a new group with newly created elements
5659 * \sa DoubleNodeElemGroup()
5661 SMESH::SMESH_Group_ptr
5662 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5663 SMESH::SMESH_GroupBase_ptr theNodesNot,
5664 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5667 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5671 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5672 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5674 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5676 << theNodesNot << ", "
5677 << theAffectedElems << " )";
5679 return elemGroup._retn();
5682 SMESH::ListOfGroups*
5683 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5684 SMESH::SMESH_GroupBase_ptr theNodesNot,
5685 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5686 CORBA::Boolean theElemGroupNeeded,
5687 CORBA::Boolean theNodeGroupNeeded)
5689 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5690 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5691 aTwoGroups->length( 2 );
5693 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5694 return aTwoGroups._retn();
5699 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5700 TIDSortedElemSet anElems, aNodes, anAffected;
5701 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5702 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5703 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5706 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5708 storeResult( myEditor) ;
5709 myMesh->GetMeshDS()->Modified();
5715 myMesh->SetIsModified( true );
5717 // Create group with newly created elements
5718 CORBA::String_var elemGroupName = theElems->GetName();
5719 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5720 if ( !myEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5722 SMESH::long_array_var anIds = GetLastCreatedElems();
5723 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5724 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5725 aNewElemGroup->Add(anIds);
5727 if ( !myEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5729 SMESH::long_array_var anIds = GetLastCreatedNodes();
5730 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5731 aNewNodeGroup->Add(anIds);
5735 // Update Python script
5738 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5739 else pyDump << aNewElemGroup << ", ";
5740 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5741 else pyDump << aNewNodeGroup << " ] = ";
5743 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5744 << theNodesNot << ", "
5745 << theAffectedElems << ", "
5746 << theElemGroupNeeded << ", "
5747 << theNodeGroupNeeded <<" )";
5749 aTwoGroups[0] = aNewElemGroup._retn();
5750 aTwoGroups[1] = aNewNodeGroup._retn();
5751 return aTwoGroups._retn();
5754 //================================================================================
5756 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5757 \param theElems - group of of elements (edges or faces) to be replicated
5758 \param theNodesNot - group of nodes not to replicated
5759 \param theShape - shape to detect affected elements (element which geometric center
5760 located on or inside shape).
5761 The replicated nodes should be associated to affected elements.
5762 \return TRUE if operation has been completed successfully, FALSE otherwise
5763 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5765 //================================================================================
5767 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5768 SMESH::SMESH_GroupBase_ptr theNodesNot,
5769 GEOM::GEOM_Object_ptr theShape )
5772 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5778 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5779 TIDSortedElemSet anElems, aNodes, anAffected;
5780 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5781 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5783 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5784 bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5786 storeResult( myEditor) ;
5788 myMesh->GetMeshDS()->Modified();
5790 myMesh->SetIsModified( true );
5792 // Update Python script
5793 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5794 << theNodesNot << ", " << theShape << " )";
5798 //================================================================================
5800 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5801 This method provided for convenience works as DoubleNodes() described above.
5802 \param theElems - list of groups of elements (edges or faces) to be replicated
5803 \param theNodesNot - list of groups of nodes not to replicated
5804 \param theAffectedElems - group of elements to which the replicated nodes
5805 should be associated to.
5806 \return TRUE if operation has been completed successfully, FALSE otherwise
5807 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5809 //================================================================================
5811 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5812 SMESHDS_Mesh* theMeshDS,
5813 TIDSortedElemSet& theElemSet,
5814 const bool theIsNodeGrp)
5816 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5818 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5819 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5820 : aGrp->GetType() != SMESH::NODE ) )
5822 SMESH::long_array_var anIDs = aGrp->GetIDs();
5823 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5828 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5829 const SMESH::ListOfGroups& theNodesNot,
5830 const SMESH::ListOfGroups& theAffectedElems)
5835 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5836 TIDSortedElemSet anElems, aNodes, anAffected;
5837 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5838 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5839 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5841 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5843 storeResult( myEditor) ;
5845 myMesh->GetMeshDS()->Modified();
5847 myMesh->SetIsModified( true );
5849 // Update Python script
5850 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5851 << &theNodesNot << ", " << &theAffectedElems << " )";
5855 //================================================================================
5857 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5858 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5859 \param theElems - list of groups of elements (edges or faces) to be replicated
5860 \param theNodesNot - list of groups of nodes not to replicated
5861 \param theAffectedElems - group of elements to which the replicated nodes
5862 should be associated to.
5863 * \return a new group with newly created elements
5864 * \sa DoubleNodeElemGroups()
5866 //================================================================================
5868 SMESH::SMESH_Group_ptr
5869 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5870 const SMESH::ListOfGroups& theNodesNot,
5871 const SMESH::ListOfGroups& theAffectedElems)
5874 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
5878 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5879 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5881 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
5883 << theNodesNot << ", "
5884 << theAffectedElems << " )";
5886 return elemGroup._retn();
5889 SMESH::ListOfGroups*
5890 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
5891 const SMESH::ListOfGroups& theNodesNot,
5892 const SMESH::ListOfGroups& theAffectedElems,
5893 CORBA::Boolean theElemGroupNeeded,
5894 CORBA::Boolean theNodeGroupNeeded)
5896 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5897 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5898 aTwoGroups->length( 2 );
5903 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5904 TIDSortedElemSet anElems, aNodes, anAffected;
5905 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5906 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5907 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5909 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5911 storeResult( myEditor) ;
5913 myMesh->GetMeshDS()->Modified();
5917 myMesh->SetIsModified( true );
5919 // Create group with newly created elements
5920 CORBA::String_var elemGroupName = theElems[0]->GetName();
5921 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5922 if ( !myEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5924 SMESH::long_array_var anIds = GetLastCreatedElems();
5925 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5926 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5927 aNewElemGroup->Add(anIds);
5929 if ( !myEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5931 SMESH::long_array_var anIds = GetLastCreatedNodes();
5932 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5933 aNewNodeGroup->Add(anIds);
5937 // Update Python script
5940 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5941 else pyDump << aNewElemGroup << ", ";
5942 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5943 else pyDump << aNewNodeGroup << " ] = ";
5945 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
5946 << &theNodesNot << ", "
5947 << &theAffectedElems << ", "
5948 << theElemGroupNeeded << ", "
5949 << theNodeGroupNeeded << " )";
5951 aTwoGroups[0] = aNewElemGroup._retn();
5952 aTwoGroups[1] = aNewNodeGroup._retn();
5953 return aTwoGroups._retn();
5956 //================================================================================
5958 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5959 This method provided for convenience works as DoubleNodes() described above.
5960 \param theElems - list of groups of elements (edges or faces) to be replicated
5961 \param theNodesNot - list of groups of nodes not to replicated
5962 \param theShape - shape to detect affected elements (element which geometric center
5963 located on or inside shape).
5964 The replicated nodes should be associated to affected elements.
5965 \return TRUE if operation has been completed successfully, FALSE otherwise
5966 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
5968 //================================================================================
5971 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
5972 const SMESH::ListOfGroups& theNodesNot,
5973 GEOM::GEOM_Object_ptr theShape )
5978 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5979 TIDSortedElemSet anElems, aNodes;
5980 listOfGroupToSet(theElems, aMeshDS, anElems,false );
5981 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5983 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5984 bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5986 storeResult( myEditor) ;
5988 myMesh->GetMeshDS()->Modified();
5990 myMesh->SetIsModified( true );
5992 // Update Python script
5993 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
5994 << &theNodesNot << ", " << theShape << " )";
5998 //================================================================================
6000 \brief Identify the elements that will be affected by node duplication (actual duplication is not performed.
6001 This method is the first step of DoubleNodeElemGroupsInRegion.
6002 \param theElems - list of groups of elements (edges or faces) to be replicated
6003 \param theNodesNot - list of groups of nodes not to replicated
6004 \param theShape - shape to detect affected elements (element which geometric center
6005 located on or inside shape).
6006 The replicated nodes should be associated to affected elements.
6007 \return groups of affected elements
6008 \sa DoubleNodeElemGroupsInRegion()
6010 //================================================================================
6011 SMESH::ListOfGroups*
6012 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6013 const SMESH::ListOfGroups& theNodesNot,
6014 GEOM::GEOM_Object_ptr theShape )
6016 MESSAGE("AffectedElemGroupsInRegion");
6017 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6018 bool isEdgeGroup = false;
6019 bool isFaceGroup = false;
6020 bool isVolumeGroup = false;
6021 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6022 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6023 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6027 ::SMESH_MeshEditor aMeshEditor(myMesh);
6029 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6030 TIDSortedElemSet anElems, aNodes;
6031 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6032 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6034 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6035 TIDSortedElemSet anAffected;
6036 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6038 storeResult(aMeshEditor);
6040 myMesh->GetMeshDS()->Modified();
6044 myMesh->SetIsModified(true);
6046 int lg = anAffected.size();
6047 MESSAGE("lg="<< lg);
6048 SMESH::long_array_var volumeIds = new SMESH::long_array;
6049 volumeIds->length(lg);
6050 SMESH::long_array_var faceIds = new SMESH::long_array;
6051 faceIds->length(lg);
6052 SMESH::long_array_var edgeIds = new SMESH::long_array;
6053 edgeIds->length(lg);
6058 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6059 for (; eIt != anAffected.end(); ++eIt)
6061 const SMDS_MeshElement* anElem = *eIt;
6064 int elemId = anElem->GetID();
6065 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6066 volumeIds[ivol++] = elemId;
6067 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6068 faceIds[iface++] = elemId;
6069 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6070 edgeIds[iedge++] = elemId;
6072 volumeIds->length(ivol);
6073 faceIds->length(iface);
6074 edgeIds->length(iedge);
6076 aNewVolumeGroup->Add(volumeIds);
6077 aNewFaceGroup->Add(faceIds);
6078 aNewEdgeGroup->Add(edgeIds);
6079 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6080 isFaceGroup = (aNewFaceGroup->Size() > 0);
6081 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6091 aListOfGroups->length(nbGroups);
6095 aListOfGroups[i++] = aNewEdgeGroup._retn();
6097 aListOfGroups[i++] = aNewFaceGroup._retn();
6099 aListOfGroups[i++] = aNewVolumeGroup._retn();
6101 // Update Python script
6105 pyDump << aNewEdgeGroup << ", ";
6107 pyDump << aNewFaceGroup << ", ";
6109 pyDump << aNewVolumeGroup << ", ";
6111 pyDump << this << ".AffectedElemGroupsInRegion( " << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6113 return aListOfGroups._retn();
6116 //================================================================================
6118 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6119 The created 2D mesh elements based on nodes of free faces of boundary volumes
6120 \return TRUE if operation has been completed successfully, FALSE otherwise
6122 //================================================================================
6124 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6128 bool aResult = myEditor.Make2DMeshFrom3D();
6129 storeResult( myEditor) ;
6130 myMesh->GetMeshDS()->Modified();
6131 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6135 //================================================================================
6137 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6138 * The list of groups must describe a partition of the mesh volumes.
6139 * The nodes of the internal faces at the boundaries of the groups are doubled.
6140 * In option, the internal faces are replaced by flat elements.
6141 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6142 * The flat elements are stored in groups of volumes.
6143 * @param theDomains - list of groups of volumes
6144 * @param createJointElems - if TRUE, create the elements
6145 * @return TRUE if operation has been completed successfully, FALSE otherwise
6147 //================================================================================
6149 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6150 CORBA::Boolean createJointElems )
6151 throw (SALOME::SALOME_Exception)
6156 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6158 vector<TIDSortedElemSet> domains;
6161 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6163 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6164 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6166 // if ( aGrp->GetType() != SMESH::VOLUME )
6167 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6168 TIDSortedElemSet domain;
6170 domains.push_back(domain);
6171 SMESH::long_array_var anIDs = aGrp->GetIDs();
6172 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6176 bool aResult = myEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
6177 // TODO publish the groups of flat elements in study
6179 storeResult( myEditor) ;
6180 myMesh->GetMeshDS()->Modified();
6182 // Update Python script
6183 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6184 << ", " << createJointElems << " )";
6188 //================================================================================
6190 * \brief Double nodes on some external faces and create flat elements.
6191 * Flat elements are mainly used by some types of mechanic calculations.
6193 * Each group of the list must be constituted of faces.
6194 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6195 * @param theGroupsOfFaces - list of groups of faces
6196 * @return TRUE if operation has been completed successfully, FALSE otherwise
6198 //================================================================================
6200 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6205 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6207 vector<TIDSortedElemSet> faceGroups;
6210 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6212 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6213 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6215 TIDSortedElemSet faceGroup;
6217 faceGroups.push_back(faceGroup);
6218 SMESH::long_array_var anIDs = aGrp->GetIDs();
6219 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6223 bool aResult = myEditor.CreateFlatElementsOnFacesGroups( faceGroups );
6224 // TODO publish the groups of flat elements in study
6226 storeResult( myEditor) ;
6227 myMesh->GetMeshDS()->Modified();
6229 // Update Python script
6230 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6235 * \brief identify all the elements around a geom shape, get the faces delimiting the hole
6236 * Build groups of volume to remove, groups of faces to replace on the skin of the object,
6237 * groups of faces to remove inside the object, (idem edges).
6238 * Build ordered list of nodes at the border of each group of faces to replace (to be used to build a geom subshape)
6240 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6241 GEOM::GEOM_Object_ptr theShape,
6242 const char* groupName,
6243 const SMESH::double_array& theNodesCoords,
6244 SMESH::array_of_long_array_out GroupsOfNodes)
6245 throw (SALOME::SALOME_Exception)
6248 std::vector<std::vector<int> > aListOfListOfNodes;
6249 ::SMESH_MeshEditor aMeshEditor( myMesh );
6251 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6252 if ( !theNodeSearcher )
6253 theNodeSearcher = aMeshEditor.GetNodeSearcher();
6255 vector<double> nodesCoords;
6256 for (int i = 0; i < theNodesCoords.length(); i++)
6258 nodesCoords.push_back( theNodesCoords[i] );
6261 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6262 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName, nodesCoords, aListOfListOfNodes);
6264 GroupsOfNodes = new SMESH::array_of_long_array;
6265 GroupsOfNodes->length( aListOfListOfNodes.size() );
6266 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6267 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6269 vector<int>& aListOfNodes = *llIt;
6270 vector<int>::iterator lIt = aListOfNodes.begin();;
6271 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6272 aGroup.length( aListOfNodes.size() );
6273 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6274 aGroup[ j ] = (*lIt);
6276 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6277 << radius << ", " << theShape << ", " << ", " << groupName << ", " << theNodesCoords << " )";
6281 // issue 20749 ===================================================================
6283 * \brief Creates missing boundary elements
6284 * \param elements - elements whose boundary is to be checked
6285 * \param dimension - defines type of boundary elements to create
6286 * \param groupName - a name of group to store created boundary elements in,
6287 * "" means not to create the group
6288 * \param meshName - a name of new mesh to store created boundary elements in,
6289 * "" means not to create the new mesh
6290 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6291 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6292 * boundary elements will be copied into the new mesh
6293 * \param group - returns the create group, if any
6294 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6296 // ================================================================================
6298 SMESH::SMESH_Mesh_ptr
6299 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6300 SMESH::Bnd_Dimension dim,
6301 const char* groupName,
6302 const char* meshName,
6303 CORBA::Boolean toCopyElements,
6304 CORBA::Boolean toCopyExistingBondary,
6305 SMESH::SMESH_Group_out group)
6309 if ( dim > SMESH::BND_1DFROM2D )
6310 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6312 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6314 SMESH::SMESH_Mesh_var mesh_var;
6315 SMESH::SMESH_Group_var group_var;
6319 TIDSortedElemSet elements;
6320 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6321 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6325 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6326 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6328 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6330 // group of new boundary elements
6331 SMESH_Group* smesh_group = 0;
6332 if ( strlen(groupName) )
6334 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6335 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6336 smesh_group = group_i->GetSmeshGroup();
6340 myEditor.MakeBoundaryMesh( elements,
6341 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6345 toCopyExistingBondary);
6346 storeResult( myEditor );
6349 smesh_mesh->GetMeshDS()->Modified();
6352 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6354 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6355 if ( mesh_var->_is_nil() )
6356 pyDump << myMesh_i->_this() << ", ";
6358 pyDump << mesh_var << ", ";
6359 if ( group_var->_is_nil() )
6360 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6362 pyDump << group_var << " = ";
6363 pyDump << this << ".MakeBoundaryMesh( "
6365 << "SMESH." << dimName[int(dim)] << ", "
6366 << "'" << groupName << "', "
6367 << "'" << meshName<< "', "
6368 << toCopyElements << ", "
6369 << toCopyExistingBondary << ")";
6371 group = group_var._retn();
6372 return mesh_var._retn();
6375 //================================================================================
6377 * \brief Creates missing boundary elements
6378 * \param dimension - defines type of boundary elements to create
6379 * \param groupName - a name of group to store all boundary elements in,
6380 * "" means not to create the group
6381 * \param meshName - a name of a new mesh, which is a copy of the initial
6382 * mesh + created boundary elements; "" means not to create the new mesh
6383 * \param toCopyAll - if true, the whole initial mesh will be copied into
6384 * the new mesh else only boundary elements will be copied into the new mesh
6385 * \param groups - optional groups of elements to make boundary around
6386 * \param mesh - returns the mesh where elements were added to
6387 * \param group - returns the created group, if any
6388 * \retval long - number of added boundary elements
6390 //================================================================================
6392 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6393 const char* groupName,
6394 const char* meshName,
6395 CORBA::Boolean toCopyAll,
6396 const SMESH::ListOfIDSources& groups,
6397 SMESH::SMESH_Mesh_out mesh,
6398 SMESH::SMESH_Group_out group)
6399 throw (SALOME::SALOME_Exception)
6401 Unexpect aCatch(SALOME_SalomeException);
6405 if ( dim > SMESH::BND_1DFROM2D )
6406 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6408 // separate groups belonging to this and other mesh
6409 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6410 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6411 groupsOfThisMesh->length( groups.length() );
6412 groupsOfOtherMesh->length( groups.length() );
6413 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6414 for ( int i = 0; i < groups.length(); ++i )
6416 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6417 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6418 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6420 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6421 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6422 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6424 groupsOfThisMesh->length( nbGroups );
6425 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6430 if ( nbGroupsOfOtherMesh > 0 )
6432 // process groups belonging to another mesh
6433 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6434 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6435 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6436 groupsOfOtherMesh, mesh, group );
6439 SMESH::SMESH_Mesh_var mesh_var;
6440 SMESH::SMESH_Group_var group_var;
6443 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6444 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6448 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6450 /*toCopyGroups=*/false,
6451 /*toKeepIDs=*/true);
6453 mesh_var = makeMesh(meshName);
6455 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6456 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6459 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6460 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6462 // group of boundary elements
6463 SMESH_Group* smesh_group = 0;
6464 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6465 if ( strlen(groupName) )
6467 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6468 group_var = mesh_i->CreateGroup( groupType, groupName );
6469 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6470 smesh_group = group_i->GetSmeshGroup();
6473 TIDSortedElemSet elements;
6475 if ( groups.length() > 0 )
6477 for ( int i = 0; i < nbGroups; ++i )
6480 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6482 SMESH::Bnd_Dimension bdim =
6483 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6484 nbAdded += myEditor.MakeBoundaryMesh( elements,
6485 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6488 /*toCopyElements=*/false,
6489 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6490 /*toAddExistingBondary=*/true,
6491 /*aroundElements=*/true);
6492 storeResult( myEditor );
6498 nbAdded += myEditor.MakeBoundaryMesh( elements,
6499 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6502 /*toCopyElements=*/false,
6503 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6504 /*toAddExistingBondary=*/true);
6505 storeResult( myEditor );
6507 tgtMesh->GetMeshDS()->Modified();
6509 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6511 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6512 pyDump << "nbAdded, ";
6513 if ( mesh_var->_is_nil() )
6514 pyDump << myMesh_i->_this() << ", ";
6516 pyDump << mesh_var << ", ";
6517 if ( group_var->_is_nil() )
6518 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6520 pyDump << group_var << " = ";
6521 pyDump << this << ".MakeBoundaryElements( "
6522 << "SMESH." << dimName[int(dim)] << ", "
6523 << "'" << groupName << "', "
6524 << "'" << meshName<< "', "
6525 << toCopyAll << ", "
6528 mesh = mesh_var._retn();
6529 group = group_var._retn();