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 ))
286 aMap.insert( aMap.end(), elem );
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()
446 deleteAuxIDSources();
449 //================================================================================
451 * \brief Clear members
453 //================================================================================
455 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
457 if ( myPreviewMode ) {
458 //myPreviewData = new SMESH::MeshPreviewStruct();
461 if ( deleteSearchers )
462 TSearchersDeleter::Delete();
464 myEditor.GetError().reset();
465 myEditor.CrearLastCreated();
468 //================================================================================
470 * \brief Now does nothing
472 //================================================================================
474 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& )
478 //================================================================================
480 * Return data of mesh edition preview
482 //================================================================================
484 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
486 const bool hasBadElems = ( myEditor.GetError() && myEditor.GetError()->HasBadElems() );
488 if ( myPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
490 list<int> aNodesConnectivity;
491 typedef map<int, int> TNodesMap;
494 SMESHDS_Mesh* aMeshDS;
495 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
497 aMeshPartDS.reset( new SMESH_MeshPartDS( myEditor.GetError()->myBadElements ));
498 aMeshDS = aMeshPartDS.get();
501 aMeshDS = myEditor.GetMeshDS();
503 int nbEdges = aMeshDS->NbEdges();
504 int nbFaces = aMeshDS->NbFaces();
505 int nbVolum = aMeshDS->NbVolumes();
506 myPreviewData = new SMESH::MeshPreviewStruct();
507 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
510 SMDSAbs_ElementType previewType = SMDSAbs_All;
512 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( myEditor.GetMesh() )) {
513 previewType = aPreviewMesh->myPreviewType;
514 switch ( previewType ) {
515 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
516 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
517 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
522 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
524 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
526 while ( itMeshElems->more() ) {
527 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
528 if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
531 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
532 while ( itElemNodes->more() ) {
533 const SMDS_MeshNode* aMeshNode =
534 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
535 int aNodeID = aMeshNode->GetID();
536 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
537 if ( anIter == nodesMap.end() ) {
538 // filling the nodes coordinates
539 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
540 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
541 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
542 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
545 aNodesConnectivity.push_back(anIter->second);
548 // filling the elements types
549 SMDSAbs_ElementType aType = aMeshElem->GetType();
550 bool isPoly = aMeshElem->IsPoly();
552 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
553 myPreviewData->elementTypes[i].isPoly = isPoly;
554 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
558 myPreviewData->nodesXYZ.length( j );
560 // filling the elements connectivities
561 list<int>::iterator aConnIter = aNodesConnectivity.begin();
562 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
563 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
564 myPreviewData->elementConnectivities[i] = *aConnIter;
567 return myPreviewData._retn();
570 //================================================================================
572 * \brief Returns list of it's IDs of created nodes
573 * \retval SMESH::long_array* - list of node ID
575 //================================================================================
577 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
579 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
580 const SMESH_SequenceOfElemPtr& aSeq = myEditor.GetLastCreatedNodes();
581 myLastCreatedNodes->length( aSeq.Length() );
582 for (int i = 1; i <= aSeq.Length(); i++)
583 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
584 return myLastCreatedNodes._retn();
587 //================================================================================
589 * \brief Returns list of it's IDs of created elements
590 * \retval SMESH::long_array* - list of elements' ID
592 //================================================================================
594 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
596 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
597 const SMESH_SequenceOfElemPtr& aSeq = myEditor.GetLastCreatedElems();
598 myLastCreatedElems->length( aSeq.Length() );
599 for ( int i = 1; i <= aSeq.Length(); i++ )
600 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
601 return myLastCreatedElems._retn();
604 //=======================================================================
606 * Returns description of an error/warning occured during the last operation
608 //=======================================================================
610 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
612 SMESH::ComputeError* errOut = new SMESH::ComputeError;
613 SMESH_ComputeErrorPtr& errIn = myEditor.GetError();
614 if ( errIn && !errIn->IsOK() )
616 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
617 errOut->comment = errIn->myComment.c_str();
618 errOut->subShapeID = -1;
619 errOut->hasBadMesh = !errIn->myBadElements.empty();
624 //=======================================================================
625 //function : MakeIDSource
626 //purpose : Wrap a sequence of ids in a SMESH_IDSource
627 //=======================================================================
629 struct SMESH_MeshEditor_i::_IDSource : public POA_SMESH::SMESH_IDSource
631 SMESH::long_array _ids;
632 SMESH::ElementType _type;
633 SMESH::SMESH_Mesh_ptr _mesh;
634 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
635 SMESH::long_array* GetMeshInfo() { return 0; }
636 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
637 bool IsMeshInfoCorrect() { return true; }
638 SMESH::array_of_ElementType* GetTypes()
640 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
641 if ( _ids.length() > 0 ) {
645 return types._retn();
649 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
650 SMESH::ElementType type)
652 if ( myAuxIDSources.size() > 10 )
653 deleteAuxIDSources();
655 _IDSource* idSrc = new _IDSource;
656 idSrc->_mesh = myMesh_i->_this();
659 myAuxIDSources.push_back( idSrc );
661 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
663 return anIDSourceVar._retn();
666 void SMESH_MeshEditor_i::deleteAuxIDSources()
668 std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
669 for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
671 myAuxIDSources.clear();
674 //=============================================================================
678 //=============================================================================
681 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
687 for (int i = 0; i < IDsOfElements.length(); i++)
688 IdList.push_back( IDsOfElements[i] );
690 // Update Python script
691 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
694 bool ret = myEditor.Remove( IdList, false );
695 myMesh->GetMeshDS()->Modified();
696 if ( IDsOfElements.length() )
697 myMesh->SetIsModified( true ); // issue 0020693
701 //=============================================================================
705 //=============================================================================
707 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
712 for (int i = 0; i < IDsOfNodes.length(); i++)
713 IdList.push_back( IDsOfNodes[i] );
715 // Update Python script
716 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
718 bool ret = myEditor.Remove( IdList, true );
719 myMesh->GetMeshDS()->Modified();
720 if ( IDsOfNodes.length() )
721 myMesh->SetIsModified( true ); // issue 0020693
725 //=============================================================================
729 //=============================================================================
731 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
736 // Update Python script
737 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
739 // Create filter to find all orphan nodes
740 SMESH::Controls::Filter::TIdSequence seq;
741 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
742 SMESH::Controls::Filter::GetElementsId( GetMeshDS(), predicate, seq );
744 // remove orphan nodes (if there are any)
746 for ( int i = 0; i < seq.size(); i++ )
747 IdList.push_back( seq[i] );
749 int nbNodesBefore = myMesh->NbNodes();
750 myEditor.Remove( IdList, true );
751 myMesh->GetMeshDS()->Modified();
753 myMesh->SetIsModified( true );
754 int nbNodesAfter = myMesh->NbNodes();
756 return nbNodesBefore - nbNodesAfter;
759 //=============================================================================
763 //=============================================================================
765 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
766 CORBA::Double y, CORBA::Double z)
770 const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
772 // Update Python script
773 TPythonDump() << "nodeID = " << this << ".AddNode( "
774 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
776 myMesh->GetMeshDS()->Modified();
777 myMesh->SetIsModified( true ); // issue 0020693
781 //=============================================================================
783 * Create 0D element on the given node.
785 //=============================================================================
787 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
791 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
792 SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode);
794 // Update Python script
795 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
797 myMesh->GetMeshDS()->Modified();
798 myMesh->SetIsModified( true ); // issue 0020693
801 return elem->GetID();
806 //=============================================================================
808 * Create a ball element on the given node.
810 //=============================================================================
812 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
813 throw (SALOME::SALOME_Exception)
817 if ( diameter < std::numeric_limits<double>::min() )
818 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
820 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
821 SMDS_MeshElement* elem = GetMeshDS()->AddBall(aNode, diameter);
823 // Update Python script
824 TPythonDump() << "ballElem = "
825 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
827 myMesh->GetMeshDS()->Modified();
828 myMesh->SetIsModified( true ); // issue 0020693
831 return elem->GetID();
836 //=============================================================================
838 * Create an edge, either linear and quadratic (this is determed
839 * by number of given nodes, two or three)
841 //=============================================================================
843 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
847 int NbNodes = IDsOfNodes.length();
848 SMDS_MeshElement* elem = 0;
851 CORBA::Long index1 = IDsOfNodes[0];
852 CORBA::Long index2 = IDsOfNodes[1];
853 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
855 // Update Python script
856 TPythonDump() << "edge = " << this << ".AddEdge([ "
857 << index1 << ", " << index2 <<" ])";
860 CORBA::Long n1 = IDsOfNodes[0];
861 CORBA::Long n2 = IDsOfNodes[1];
862 CORBA::Long n12 = IDsOfNodes[2];
863 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
864 GetMeshDS()->FindNode(n2),
865 GetMeshDS()->FindNode(n12));
866 // Update Python script
867 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
868 <<n1<<", "<<n2<<", "<<n12<<" ])";
871 myMesh->GetMeshDS()->Modified();
873 return myMesh->SetIsModified( true ), elem->GetID();
878 //=============================================================================
882 //=============================================================================
884 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
888 int NbNodes = IDsOfNodes.length();
894 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
895 for (int i = 0; i < NbNodes; i++)
896 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
898 SMDS_MeshElement* elem = 0;
900 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
902 else if (NbNodes == 4) {
903 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
905 else if (NbNodes == 6) {
906 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
909 else if (NbNodes == 8) {
910 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
911 nodes[4], nodes[5], nodes[6], nodes[7]);
913 else if (NbNodes == 9) {
914 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
915 nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
917 else if (NbNodes > 2) {
918 elem = GetMeshDS()->AddPolygonalFace(nodes);
921 // Update Python script
922 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
924 myMesh->GetMeshDS()->Modified();
926 return myMesh->SetIsModified( true ), elem->GetID();
931 //=============================================================================
935 //=============================================================================
936 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
940 int NbNodes = IDsOfNodes.length();
941 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
942 for (int i = 0; i < NbNodes; i++)
943 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
945 const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
947 // Update Python script
948 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
950 myMesh->GetMeshDS()->Modified();
951 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
954 //=============================================================================
956 * Create volume, either linear and quadratic (this is determed
957 * by number of given nodes)
959 //=============================================================================
961 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
965 int NbNodes = IDsOfNodes.length();
966 vector< const SMDS_MeshNode*> n(NbNodes);
967 for(int i=0;i<NbNodes;i++)
968 n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
970 SMDS_MeshElement* elem = 0;
973 case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
974 case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
975 case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
976 case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
977 case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
978 n[6],n[7],n[8],n[9]);
980 case 12:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
981 n[6],n[7],n[8],n[9],n[10],n[11]);
983 case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
984 n[7],n[8],n[9],n[10],n[11],n[12]);
986 case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
987 n[9],n[10],n[11],n[12],n[13],n[14]);
989 case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
990 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
991 n[15],n[16],n[17],n[18],n[19]);
993 case 27:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
994 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
995 n[15],n[16],n[17],n[18],n[19],
996 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1000 // Update Python script
1001 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1003 myMesh->GetMeshDS()->Modified();
1005 return myMesh->SetIsModified( true ), elem->GetID();
1010 //=============================================================================
1012 * AddPolyhedralVolume
1014 //=============================================================================
1015 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1016 const SMESH::long_array & Quantities)
1020 int NbNodes = IDsOfNodes.length();
1021 std::vector<const SMDS_MeshNode*> n (NbNodes);
1022 for (int i = 0; i < NbNodes; i++)
1024 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
1025 if (!aNode) return 0;
1029 int NbFaces = Quantities.length();
1030 std::vector<int> q (NbFaces);
1031 for (int j = 0; j < NbFaces; j++)
1032 q[j] = Quantities[j];
1034 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
1036 // Update Python script
1037 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1038 << IDsOfNodes << ", " << Quantities << " )";
1039 myMesh->GetMeshDS()->Modified();
1041 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1044 //=============================================================================
1046 * AddPolyhedralVolumeByFaces
1048 //=============================================================================
1050 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1054 int NbFaces = IdsOfFaces.length();
1055 std::vector<const SMDS_MeshNode*> poly_nodes;
1056 std::vector<int> quantities (NbFaces);
1058 for (int i = 0; i < NbFaces; i++) {
1059 const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
1060 quantities[i] = aFace->NbNodes();
1062 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1063 while (It->more()) {
1064 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1068 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1070 // Update Python script
1071 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1072 << IdsOfFaces << " )";
1073 myMesh->GetMeshDS()->Modified();
1075 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1078 //=============================================================================
1080 // \brief Create 0D elements on all nodes of the given object except those
1081 // nodes on which a 0D element already exists.
1082 // \param theObject object on whose nodes 0D elements will be created.
1083 // \param theGroupName optional name of a group to add 0D elements created
1084 // and/or found on nodes of \a theObject.
1085 // \return an object (a new group or a temporary SMESH_IDSource) holding
1086 // ids of new and/or found 0D elements.
1088 //=============================================================================
1090 SMESH::SMESH_IDSource_ptr
1091 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1092 const char* theGroupName)
1093 throw (SALOME::SALOME_Exception)
1097 SMESH::SMESH_IDSource_var result;
1100 TIDSortedElemSet elements, elems0D;
1101 if ( idSourceToSet( theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1102 myEditor.Create0DElementsOnAllNodes( elements, elems0D );
1104 SMESH::long_array_var newElems = new SMESH::long_array;
1105 newElems->length( elems0D.size() );
1106 TIDSortedElemSet::iterator eIt = elems0D.begin();
1107 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1108 newElems[ i ] = (*eIt)->GetID();
1110 SMESH::SMESH_GroupBase_var groupToFill;
1111 if ( theGroupName && strlen( theGroupName ))
1113 // Get existing group named theGroupName
1114 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1115 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1116 SMESH::SMESH_GroupBase_var group = groups[i];
1117 if ( !group->_is_nil() ) {
1118 CORBA::String_var name = group->GetName();
1119 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1120 groupToFill = group;
1125 if ( groupToFill->_is_nil() )
1126 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1127 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1128 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1131 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1133 group_i->Add( newElems );
1134 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1135 pyDump << groupToFill;
1139 result = MakeIDSource( newElems, SMESH::ELEM0D );
1140 pyDump << "elem0DIDs";
1143 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1144 << theObject << ", '" << theGroupName << "' )";
1146 return result._retn();
1149 //=============================================================================
1151 * \brief Bind a node to a vertex
1152 * \param NodeID - node ID
1153 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1154 * \retval boolean - false if NodeID or VertexID is invalid
1156 //=============================================================================
1158 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1159 throw (SALOME::SALOME_Exception)
1161 Unexpect aCatch(SALOME_SalomeException);
1163 SMESHDS_Mesh * mesh = GetMeshDS();
1164 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1166 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1168 if ( mesh->MaxShapeIndex() < VertexID )
1169 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1171 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1172 if ( shape.ShapeType() != TopAbs_VERTEX )
1173 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1175 mesh->SetNodeOnVertex( node, VertexID );
1177 myMesh->SetIsModified( true );
1180 //=============================================================================
1182 * \brief Store node position on an edge
1183 * \param NodeID - node ID
1184 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1185 * \param paramOnEdge - parameter on edge where the node is located
1186 * \retval boolean - false if any parameter is invalid
1188 //=============================================================================
1190 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1191 CORBA::Double paramOnEdge)
1192 throw (SALOME::SALOME_Exception)
1194 Unexpect aCatch(SALOME_SalomeException);
1196 SMESHDS_Mesh * mesh = GetMeshDS();
1197 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1199 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1201 if ( mesh->MaxShapeIndex() < EdgeID )
1202 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1204 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1205 if ( shape.ShapeType() != TopAbs_EDGE )
1206 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1209 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1210 if ( paramOnEdge < f || paramOnEdge > l )
1211 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1213 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1215 myMesh->SetIsModified( true );
1218 //=============================================================================
1220 * \brief Store node position on a face
1221 * \param NodeID - node ID
1222 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1223 * \param u - U parameter on face where the node is located
1224 * \param v - V parameter on face where the node is located
1225 * \retval boolean - false if any parameter is invalid
1227 //=============================================================================
1229 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1230 CORBA::Double u, CORBA::Double v)
1231 throw (SALOME::SALOME_Exception)
1233 Unexpect aCatch(SALOME_SalomeException);
1235 SMESHDS_Mesh * mesh = GetMeshDS();
1236 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1238 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1240 if ( mesh->MaxShapeIndex() < FaceID )
1241 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1243 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1244 if ( shape.ShapeType() != TopAbs_FACE )
1245 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1247 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1248 bool isOut = ( u < surf.FirstUParameter() ||
1249 u > surf.LastUParameter() ||
1250 v < surf.FirstVParameter() ||
1251 v > surf.LastVParameter() );
1255 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1256 << " u( " << surf.FirstUParameter()
1257 << "," << surf.LastUParameter()
1258 << ") v( " << surf.FirstVParameter()
1259 << "," << surf.LastVParameter() << ")" );
1261 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1264 mesh->SetNodeOnFace( node, FaceID, u, v );
1265 myMesh->SetIsModified( true );
1268 //=============================================================================
1270 * \brief Bind a node to a solid
1271 * \param NodeID - node ID
1272 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1273 * \retval boolean - false if NodeID or SolidID is invalid
1275 //=============================================================================
1277 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1278 throw (SALOME::SALOME_Exception)
1280 Unexpect aCatch(SALOME_SalomeException);
1282 SMESHDS_Mesh * mesh = GetMeshDS();
1283 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1285 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1287 if ( mesh->MaxShapeIndex() < SolidID )
1288 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1290 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1291 if ( shape.ShapeType() != TopAbs_SOLID &&
1292 shape.ShapeType() != TopAbs_SHELL)
1293 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1295 mesh->SetNodeInVolume( node, SolidID );
1297 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
1300 //=============================================================================
1302 * \brief Bind an element to a shape
1303 * \param ElementID - element ID
1304 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1305 * \retval boolean - false if ElementID or ShapeID is invalid
1307 //=============================================================================
1309 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1310 CORBA::Long ShapeID)
1311 throw (SALOME::SALOME_Exception)
1313 Unexpect aCatch(SALOME_SalomeException);
1315 SMESHDS_Mesh * mesh = GetMeshDS();
1316 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1318 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1320 if ( mesh->MaxShapeIndex() < ShapeID )
1321 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1323 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1324 if ( shape.ShapeType() != TopAbs_EDGE &&
1325 shape.ShapeType() != TopAbs_FACE &&
1326 shape.ShapeType() != TopAbs_SOLID &&
1327 shape.ShapeType() != TopAbs_SHELL )
1328 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1330 mesh->SetMeshElementOnShape( elem, ShapeID );
1332 myMesh->SetIsModified( true );
1335 //=============================================================================
1339 //=============================================================================
1341 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1342 CORBA::Long NodeID2)
1346 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1347 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1351 // Update Python script
1352 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1353 << NodeID1 << ", " << NodeID2 << " )";
1356 int ret = myEditor.InverseDiag ( n1, n2 );
1357 myMesh->GetMeshDS()->Modified();
1358 myMesh->SetIsModified( true );
1362 //=============================================================================
1366 //=============================================================================
1368 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1369 CORBA::Long NodeID2)
1373 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1374 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1378 // Update Python script
1379 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1380 << NodeID1 << ", " << NodeID2 << " )";
1383 bool stat = myEditor.DeleteDiag ( n1, n2 );
1385 myMesh->GetMeshDS()->Modified();
1387 myMesh->SetIsModified( true ); // issue 0020693
1389 storeResult(myEditor);
1394 //=============================================================================
1398 //=============================================================================
1400 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1404 for (int i = 0; i < IDsOfElements.length(); i++)
1406 CORBA::Long index = IDsOfElements[i];
1407 const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
1409 myEditor.Reorient( elem );
1411 // Update Python script
1412 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1414 myMesh->GetMeshDS()->Modified();
1415 if ( IDsOfElements.length() )
1416 myMesh->SetIsModified( true ); // issue 0020693
1422 //=============================================================================
1426 //=============================================================================
1428 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1432 TPythonDump aTPythonDump; // suppress dump in Reorient()
1434 SMESH::long_array_var anElementsId = theObject->GetIDs();
1435 CORBA::Boolean isDone = Reorient(anElementsId);
1437 // Update Python script
1438 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1443 //=======================================================================
1444 //function : Reorient2D
1445 //purpose : Reorient faces contained in \a the2Dgroup.
1446 // the2Dgroup - the mesh or its part to reorient
1447 // theDirection - desired direction of normal of \a theFace
1448 // theFace - ID of face whose orientation is checked.
1449 // It can be < 1 then \a thePoint is used to find a face.
1450 // thePoint - is used to find a face if \a theFace < 1.
1451 // return number of reoriented elements.
1452 //=======================================================================
1454 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1455 const SMESH::DirStruct& theDirection,
1456 CORBA::Long theFace,
1457 const SMESH::PointStruct& thePoint)
1458 throw (SALOME::SALOME_Exception)
1460 Unexpect aCatch(SALOME_SalomeException);
1462 initData(/*deleteSearchers=*/false);
1464 TIDSortedElemSet elements;
1465 if ( !idSourceToSet( the2Dgroup, GetMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1466 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1469 const SMDS_MeshElement* face = 0;
1472 face = GetMeshDS()->FindElement( theFace );
1474 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1475 if ( face->GetType() != SMDSAbs_Face )
1476 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1480 // create theElementSearcher if needed
1481 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1482 if ( !theElementSearcher )
1484 if ( elements.empty() ) // search in the whole mesh
1486 if ( myMesh->NbFaces() == 0 )
1487 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1489 theElementSearcher = myEditor.GetElementSearcher();
1493 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1494 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1496 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
1500 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1501 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1504 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1505 if ( !elements.empty() && !elements.count( face ))
1506 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1509 const SMESH::PointStruct * P = &theDirection.PS;
1510 gp_Vec dirVec( P->x, P->y, P->z );
1511 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1512 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1514 int nbReori = myEditor.Reorient2D( elements, dirVec, face );
1515 storeResult(myEditor);
1518 myMesh->SetIsModified( true );
1519 myMesh->GetMeshDS()->Modified();
1521 TPythonDump() << this << ".Reorient2D( "
1522 << the2Dgroup << ", "
1523 << theDirection << ", "
1525 << thePoint << " )";
1530 //=============================================================================
1534 //=============================================================================
1535 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1536 SMESH::NumericalFunctor_ptr Criterion,
1537 CORBA::Double MaxAngle)
1541 SMESHDS_Mesh* aMesh = GetMeshDS();
1542 TIDSortedElemSet faces;
1543 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1545 SMESH::NumericalFunctor_i* aNumericalFunctor =
1546 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1547 SMESH::Controls::NumericalFunctorPtr aCrit;
1548 if ( !aNumericalFunctor )
1549 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1551 aCrit = aNumericalFunctor->GetNumericalFunctor();
1553 // Update Python script
1554 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1555 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1558 bool stat = myEditor.TriToQuad( faces, aCrit, MaxAngle );
1559 myMesh->GetMeshDS()->Modified();
1561 myMesh->SetIsModified( true ); // issue 0020693
1563 storeResult(myEditor);
1569 //=============================================================================
1573 //=============================================================================
1574 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1575 SMESH::NumericalFunctor_ptr Criterion,
1576 CORBA::Double MaxAngle)
1580 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1581 SMESH::long_array_var anElementsId = theObject->GetIDs();
1582 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1584 SMESH::NumericalFunctor_i* aNumericalFunctor =
1585 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1587 // Update Python script
1588 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1589 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1595 //=============================================================================
1599 //=============================================================================
1600 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1601 SMESH::NumericalFunctor_ptr Criterion)
1605 SMESHDS_Mesh* aMesh = GetMeshDS();
1606 TIDSortedElemSet faces;
1607 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1609 SMESH::NumericalFunctor_i* aNumericalFunctor =
1610 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1611 SMESH::Controls::NumericalFunctorPtr aCrit;
1612 if ( !aNumericalFunctor )
1613 aCrit.reset( new SMESH::Controls::AspectRatio() );
1615 aCrit = aNumericalFunctor->GetNumericalFunctor();
1618 // Update Python script
1619 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1621 CORBA::Boolean stat = myEditor.QuadToTri( faces, aCrit );
1622 myMesh->GetMeshDS()->Modified();
1624 myMesh->SetIsModified( true ); // issue 0020693
1626 storeResult(myEditor);
1632 //=============================================================================
1636 //=============================================================================
1637 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1638 SMESH::NumericalFunctor_ptr Criterion)
1642 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1644 SMESH::long_array_var anElementsId = theObject->GetIDs();
1645 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1647 SMESH::NumericalFunctor_i* aNumericalFunctor =
1648 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1650 // Update Python script
1651 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1657 //=============================================================================
1661 //=============================================================================
1662 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1663 CORBA::Boolean Diag13)
1667 SMESHDS_Mesh* aMesh = GetMeshDS();
1668 TIDSortedElemSet faces;
1669 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1671 // Update Python script
1672 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1673 << IDsOfElements << ", " << Diag13 << " )";
1675 CORBA::Boolean stat = myEditor.QuadToTri( faces, Diag13 );
1676 myMesh->GetMeshDS()->Modified();
1678 myMesh->SetIsModified( true ); // issue 0020693
1681 storeResult(myEditor);
1687 //=============================================================================
1691 //=============================================================================
1692 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1693 CORBA::Boolean Diag13)
1697 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1699 SMESH::long_array_var anElementsId = theObject->GetIDs();
1700 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1702 // Update Python script
1703 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1704 << theObject << ", " << Diag13 << " )";
1710 //=============================================================================
1714 //=============================================================================
1715 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1716 SMESH::NumericalFunctor_ptr Criterion)
1720 const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1721 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1723 SMESH::NumericalFunctor_i* aNumericalFunctor =
1724 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1725 SMESH::Controls::NumericalFunctorPtr aCrit;
1726 if (aNumericalFunctor)
1727 aCrit = aNumericalFunctor->GetNumericalFunctor();
1729 aCrit.reset(new SMESH::Controls::AspectRatio());
1731 return myEditor.BestSplit(quad, aCrit);
1736 //================================================================================
1738 * \brief Split volumic elements into tetrahedrons
1740 //================================================================================
1742 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1743 CORBA::Short methodFlags)
1744 throw (SALOME::SALOME_Exception)
1746 Unexpect aCatch(SALOME_SalomeException);
1750 SMESH::long_array_var anElementsId = elems->GetIDs();
1751 TIDSortedElemSet elemSet;
1752 arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume );
1754 myEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1755 myMesh->GetMeshDS()->Modified();
1757 storeResult(myEditor);
1759 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1760 // myMesh->SetIsModified( true ); // issue 0020693
1762 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1763 << elems << ", " << methodFlags << " )";
1766 //=======================================================================
1769 //=======================================================================
1772 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1773 const SMESH::long_array & IDsOfFixedNodes,
1774 CORBA::Long MaxNbOfIterations,
1775 CORBA::Double MaxAspectRatio,
1776 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1778 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1779 MaxAspectRatio, Method, false );
1783 //=======================================================================
1784 //function : SmoothParametric
1786 //=======================================================================
1789 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1790 const SMESH::long_array & IDsOfFixedNodes,
1791 CORBA::Long MaxNbOfIterations,
1792 CORBA::Double MaxAspectRatio,
1793 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1795 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1796 MaxAspectRatio, Method, true );
1800 //=======================================================================
1801 //function : SmoothObject
1803 //=======================================================================
1806 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1807 const SMESH::long_array & IDsOfFixedNodes,
1808 CORBA::Long MaxNbOfIterations,
1809 CORBA::Double MaxAspectRatio,
1810 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1812 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1813 MaxAspectRatio, Method, false);
1817 //=======================================================================
1818 //function : SmoothParametricObject
1820 //=======================================================================
1823 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1824 const SMESH::long_array & IDsOfFixedNodes,
1825 CORBA::Long MaxNbOfIterations,
1826 CORBA::Double MaxAspectRatio,
1827 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1829 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1830 MaxAspectRatio, Method, true);
1834 //=============================================================================
1838 //=============================================================================
1841 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1842 const SMESH::long_array & IDsOfFixedNodes,
1843 CORBA::Long MaxNbOfIterations,
1844 CORBA::Double MaxAspectRatio,
1845 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1850 SMESHDS_Mesh* aMesh = GetMeshDS();
1852 TIDSortedElemSet elements;
1853 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1855 set<const SMDS_MeshNode*> fixedNodes;
1856 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1857 CORBA::Long index = IDsOfFixedNodes[i];
1858 const SMDS_MeshNode * node = aMesh->FindNode(index);
1860 fixedNodes.insert( node );
1862 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1863 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1864 method = ::SMESH_MeshEditor::CENTROIDAL;
1866 myEditor.Smooth(elements, fixedNodes, method,
1867 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1869 myMesh->GetMeshDS()->Modified();
1870 myMesh->SetIsModified( true ); // issue 0020693
1872 storeResult(myEditor);
1874 // Update Python script
1875 TPythonDump() << "isDone = " << this << "."
1876 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1877 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1878 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1879 << "SMESH.SMESH_MeshEditor."
1880 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1881 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1887 //=============================================================================
1891 //=============================================================================
1894 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1895 const SMESH::long_array & IDsOfFixedNodes,
1896 CORBA::Long MaxNbOfIterations,
1897 CORBA::Double MaxAspectRatio,
1898 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1903 TPythonDump aTPythonDump; // suppress dump in smooth()
1905 SMESH::long_array_var anElementsId = theObject->GetIDs();
1906 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1907 MaxAspectRatio, Method, IsParametric);
1909 // Update Python script
1910 aTPythonDump << "isDone = " << this << "."
1911 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1912 << theObject << ", " << IDsOfFixedNodes << ", "
1913 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1914 << "SMESH.SMESH_MeshEditor."
1915 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1916 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1922 //=============================================================================
1926 //=============================================================================
1928 void SMESH_MeshEditor_i::RenumberNodes()
1930 // Update Python script
1931 TPythonDump() << this << ".RenumberNodes()";
1933 GetMeshDS()->Renumber( true );
1937 //=============================================================================
1941 //=============================================================================
1943 void SMESH_MeshEditor_i::RenumberElements()
1945 // Update Python script
1946 TPythonDump() << this << ".RenumberElements()";
1948 GetMeshDS()->Renumber( false );
1951 //=======================================================================
1953 * \brief Return groups by their IDs
1955 //=======================================================================
1957 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1961 myMesh_i->CreateGroupServants();
1962 return myMesh_i->GetGroups( *groupIDs );
1965 //=======================================================================
1966 //function : rotationSweep
1968 //=======================================================================
1970 SMESH::ListOfGroups*
1971 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1972 const SMESH::AxisStruct & theAxis,
1973 CORBA::Double theAngleInRadians,
1974 CORBA::Long theNbOfSteps,
1975 CORBA::Double theTolerance,
1976 const bool theMakeGroups,
1977 const SMDSAbs_ElementType theElementType)
1981 TIDSortedElemSet inElements, copyElements;
1982 arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
1984 TIDSortedElemSet* workElements = & inElements;
1985 TPreviewMesh tmpMesh( SMDSAbs_Face );
1986 SMESH_Mesh* mesh = 0;
1987 bool makeWalls=true;
1988 if ( myPreviewMode )
1990 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1991 tmpMesh.Copy( inElements, copyElements, select, avoid );
1993 workElements = & copyElements;
1994 //makeWalls = false;
2001 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2002 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2004 ::SMESH_MeshEditor::PGroupIDs groupIds =
2005 myEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
2006 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2007 storeResult(myEditor);
2008 myMesh->GetMeshDS()->Modified();
2010 // myMesh->SetIsModified( true ); -- it does not influence Compute()
2012 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2015 //=======================================================================
2016 //function : RotationSweep
2018 //=======================================================================
2020 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2021 const SMESH::AxisStruct & theAxis,
2022 CORBA::Double theAngleInRadians,
2023 CORBA::Long theNbOfSteps,
2024 CORBA::Double theTolerance)
2026 if ( !myPreviewMode ) {
2027 TPythonDump() << this << ".RotationSweep( "
2028 << theIDsOfElements << ", "
2030 << TVar( theAngleInRadians ) << ", "
2031 << TVar( theNbOfSteps ) << ", "
2032 << TVar( theTolerance ) << " )";
2034 rotationSweep(theIDsOfElements,
2042 //=======================================================================
2043 //function : RotationSweepMakeGroups
2045 //=======================================================================
2047 SMESH::ListOfGroups*
2048 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2049 const SMESH::AxisStruct& theAxis,
2050 CORBA::Double theAngleInRadians,
2051 CORBA::Long theNbOfSteps,
2052 CORBA::Double theTolerance)
2054 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2056 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2062 if (!myPreviewMode) {
2063 DumpGroupsList(aPythonDump, aGroups);
2064 aPythonDump << this << ".RotationSweepMakeGroups( "
2065 << theIDsOfElements << ", "
2067 << TVar( theAngleInRadians ) << ", "
2068 << TVar( theNbOfSteps ) << ", "
2069 << TVar( theTolerance ) << " )";
2074 //=======================================================================
2075 //function : RotationSweepObject
2077 //=======================================================================
2079 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2080 const SMESH::AxisStruct & theAxis,
2081 CORBA::Double theAngleInRadians,
2082 CORBA::Long theNbOfSteps,
2083 CORBA::Double theTolerance)
2085 if ( !myPreviewMode ) {
2086 TPythonDump() << this << ".RotationSweepObject( "
2087 << theObject << ", "
2089 << theAngleInRadians << ", "
2090 << theNbOfSteps << ", "
2091 << theTolerance << " )";
2093 SMESH::long_array_var anElementsId = theObject->GetIDs();
2094 rotationSweep(anElementsId,
2102 //=======================================================================
2103 //function : RotationSweepObject1D
2105 //=======================================================================
2107 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2108 const SMESH::AxisStruct & theAxis,
2109 CORBA::Double theAngleInRadians,
2110 CORBA::Long theNbOfSteps,
2111 CORBA::Double theTolerance)
2113 if ( !myPreviewMode ) {
2114 TPythonDump() << this << ".RotationSweepObject1D( "
2115 << theObject << ", "
2117 << TVar( theAngleInRadians ) << ", "
2118 << TVar( theNbOfSteps ) << ", "
2119 << TVar( theTolerance ) << " )";
2121 SMESH::long_array_var anElementsId = theObject->GetIDs();
2122 rotationSweep(anElementsId,
2131 //=======================================================================
2132 //function : RotationSweepObject2D
2134 //=======================================================================
2136 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2137 const SMESH::AxisStruct & theAxis,
2138 CORBA::Double theAngleInRadians,
2139 CORBA::Long theNbOfSteps,
2140 CORBA::Double theTolerance)
2142 if ( !myPreviewMode ) {
2143 TPythonDump() << this << ".RotationSweepObject2D( "
2144 << theObject << ", "
2146 << TVar( theAngleInRadians ) << ", "
2147 << TVar( theNbOfSteps ) << ", "
2148 << TVar( theTolerance ) << " )";
2150 SMESH::long_array_var anElementsId = theObject->GetIDs();
2151 rotationSweep(anElementsId,
2160 //=======================================================================
2161 //function : RotationSweepObjectMakeGroups
2163 //=======================================================================
2165 SMESH::ListOfGroups*
2166 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2167 const SMESH::AxisStruct& theAxis,
2168 CORBA::Double theAngleInRadians,
2169 CORBA::Long theNbOfSteps,
2170 CORBA::Double theTolerance)
2172 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2174 SMESH::long_array_var anElementsId = theObject->GetIDs();
2175 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2181 if (!myPreviewMode) {
2182 DumpGroupsList(aPythonDump, aGroups);
2183 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2184 << theObject << ", "
2186 << theAngleInRadians << ", "
2187 << theNbOfSteps << ", "
2188 << theTolerance << " )";
2193 //=======================================================================
2194 //function : RotationSweepObject1DMakeGroups
2196 //=======================================================================
2198 SMESH::ListOfGroups*
2199 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2200 const SMESH::AxisStruct& theAxis,
2201 CORBA::Double theAngleInRadians,
2202 CORBA::Long theNbOfSteps,
2203 CORBA::Double theTolerance)
2205 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2207 SMESH::long_array_var anElementsId = theObject->GetIDs();
2208 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2215 if (!myPreviewMode) {
2216 DumpGroupsList(aPythonDump, aGroups);
2217 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2218 << theObject << ", "
2220 << TVar( theAngleInRadians ) << ", "
2221 << TVar( theNbOfSteps ) << ", "
2222 << TVar( theTolerance ) << " )";
2227 //=======================================================================
2228 //function : RotationSweepObject2DMakeGroups
2230 //=======================================================================
2232 SMESH::ListOfGroups*
2233 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2234 const SMESH::AxisStruct& theAxis,
2235 CORBA::Double theAngleInRadians,
2236 CORBA::Long theNbOfSteps,
2237 CORBA::Double theTolerance)
2239 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2241 SMESH::long_array_var anElementsId = theObject->GetIDs();
2242 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2249 if (!myPreviewMode) {
2250 DumpGroupsList(aPythonDump, aGroups);
2251 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2252 << theObject << ", "
2254 << TVar( theAngleInRadians ) << ", "
2255 << TVar( theNbOfSteps ) << ", "
2256 << TVar( theTolerance ) << " )";
2262 //=======================================================================
2263 //function : extrusionSweep
2265 //=======================================================================
2267 SMESH::ListOfGroups*
2268 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2269 const SMESH::DirStruct & theStepVector,
2270 CORBA::Long theNbOfSteps,
2272 const SMDSAbs_ElementType theElementType)
2280 TIDSortedElemSet elements, copyElements;
2281 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2283 const SMESH::PointStruct * P = &theStepVector.PS;
2284 gp_Vec stepVec( P->x, P->y, P->z );
2286 TIDSortedElemSet* workElements = & elements;
2288 SMDSAbs_ElementType aType = SMDSAbs_Face;
2289 //::SMESH_MeshEditor::ExtrusionFlags aFlag = ::SMESH_MeshEditor::ExtrusionFlags::EXTRUSION_FLAG_BOUNDARY;
2290 if (theElementType == SMDSAbs_Node)
2292 aType = SMDSAbs_Edge;
2293 //aFlag = ::SMESH_MeshEditor::ExtrusionFlags::EXTRUSION_FLAG_SEW;
2295 TPreviewMesh tmpMesh( aType );
2296 SMESH_Mesh* mesh = myMesh;
2298 if ( myPreviewMode ) {
2299 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2300 tmpMesh.Copy( elements, copyElements, select, avoid );
2302 workElements = & copyElements;
2303 theMakeGroups = false;
2306 TElemOfElemListMap aHystory;
2307 ::SMESH_MeshEditor::PGroupIDs groupIds =
2308 myEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2310 myMesh->GetMeshDS()->Modified();
2311 storeResult(myEditor);
2313 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2315 } catch(Standard_Failure) {
2316 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2317 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
2322 //=======================================================================
2323 //function : ExtrusionSweep
2325 //=======================================================================
2327 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2328 const SMESH::DirStruct & theStepVector,
2329 CORBA::Long theNbOfSteps)
2331 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2332 if (!myPreviewMode) {
2333 TPythonDump() << this << ".ExtrusionSweep( "
2334 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2338 //=======================================================================
2339 //function : ExtrusionSweep0D
2341 //=======================================================================
2343 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2344 const SMESH::DirStruct & theStepVector,
2345 CORBA::Long theNbOfSteps)
2347 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2348 if (!myPreviewMode) {
2349 TPythonDump() << this << ".ExtrusionSweep0D( "
2350 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2354 //=======================================================================
2355 //function : ExtrusionSweepObject
2357 //=======================================================================
2359 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2360 const SMESH::DirStruct & theStepVector,
2361 CORBA::Long theNbOfSteps)
2363 SMESH::long_array_var anElementsId = theObject->GetIDs();
2364 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2365 if (!myPreviewMode) {
2366 TPythonDump() << this << ".ExtrusionSweepObject( "
2367 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2371 //=======================================================================
2372 //function : ExtrusionSweepObject0D
2374 //=======================================================================
2376 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2377 const SMESH::DirStruct & theStepVector,
2378 CORBA::Long theNbOfSteps)
2380 SMESH::long_array_var anElementsId = theObject->GetIDs();
2381 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2382 if ( !myPreviewMode ) {
2383 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2384 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2388 //=======================================================================
2389 //function : ExtrusionSweepObject1D
2391 //=======================================================================
2393 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2394 const SMESH::DirStruct & theStepVector,
2395 CORBA::Long theNbOfSteps)
2397 SMESH::long_array_var anElementsId = theObject->GetIDs();
2398 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2399 if ( !myPreviewMode ) {
2400 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2401 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2405 //=======================================================================
2406 //function : ExtrusionSweepObject2D
2408 //=======================================================================
2410 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2411 const SMESH::DirStruct & theStepVector,
2412 CORBA::Long theNbOfSteps)
2414 SMESH::long_array_var anElementsId = theObject->GetIDs();
2415 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2416 if ( !myPreviewMode ) {
2417 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2418 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2422 //=======================================================================
2423 //function : ExtrusionSweepMakeGroups
2425 //=======================================================================
2427 SMESH::ListOfGroups*
2428 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2429 const SMESH::DirStruct& theStepVector,
2430 CORBA::Long theNbOfSteps)
2432 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2434 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2436 if (!myPreviewMode) {
2437 DumpGroupsList(aPythonDump, aGroups);
2438 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2439 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2444 //=======================================================================
2445 //function : ExtrusionSweepMakeGroups0D
2447 //=======================================================================
2449 SMESH::ListOfGroups*
2450 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2451 const SMESH::DirStruct& theStepVector,
2452 CORBA::Long theNbOfSteps)
2454 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2456 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2458 if (!myPreviewMode) {
2459 DumpGroupsList(aPythonDump, aGroups);
2460 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2461 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2466 //=======================================================================
2467 //function : ExtrusionSweepObjectMakeGroups
2469 //=======================================================================
2471 SMESH::ListOfGroups*
2472 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2473 const SMESH::DirStruct& theStepVector,
2474 CORBA::Long theNbOfSteps)
2476 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2478 SMESH::long_array_var anElementsId = theObject->GetIDs();
2479 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2481 if (!myPreviewMode) {
2482 DumpGroupsList(aPythonDump, aGroups);
2483 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2484 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2489 //=======================================================================
2490 //function : ExtrusionSweepObject0DMakeGroups
2492 //=======================================================================
2494 SMESH::ListOfGroups*
2495 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2496 const SMESH::DirStruct& theStepVector,
2497 CORBA::Long theNbOfSteps)
2499 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2501 SMESH::long_array_var anElementsId = theObject->GetIDs();
2502 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2503 theNbOfSteps, true, SMDSAbs_Node);
2504 if (!myPreviewMode) {
2505 DumpGroupsList(aPythonDump, aGroups);
2506 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2507 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2512 //=======================================================================
2513 //function : ExtrusionSweepObject1DMakeGroups
2515 //=======================================================================
2517 SMESH::ListOfGroups*
2518 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2519 const SMESH::DirStruct& theStepVector,
2520 CORBA::Long theNbOfSteps)
2522 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2524 SMESH::long_array_var anElementsId = theObject->GetIDs();
2525 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2526 theNbOfSteps, true, SMDSAbs_Edge);
2527 if (!myPreviewMode) {
2528 DumpGroupsList(aPythonDump, aGroups);
2529 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2530 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2535 //=======================================================================
2536 //function : ExtrusionSweepObject2DMakeGroups
2538 //=======================================================================
2540 SMESH::ListOfGroups*
2541 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2542 const SMESH::DirStruct& theStepVector,
2543 CORBA::Long theNbOfSteps)
2545 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2547 SMESH::long_array_var anElementsId = theObject->GetIDs();
2548 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2549 theNbOfSteps, true, SMDSAbs_Face);
2550 if (!myPreviewMode) {
2551 DumpGroupsList(aPythonDump, aGroups);
2552 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2553 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2559 //=======================================================================
2560 //function : advancedExtrusion
2562 //=======================================================================
2564 SMESH::ListOfGroups*
2565 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2566 const SMESH::DirStruct & theStepVector,
2567 CORBA::Long theNbOfSteps,
2568 CORBA::Long theExtrFlags,
2569 CORBA::Double theSewTolerance,
2570 const bool theMakeGroups)
2574 TIDSortedElemSet elements;
2575 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2577 const SMESH::PointStruct * P = &theStepVector.PS;
2578 gp_Vec stepVec( P->x, P->y, P->z );
2580 TElemOfElemListMap aHystory;
2581 ::SMESH_MeshEditor::PGroupIDs groupIds =
2582 myEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2583 theMakeGroups, theExtrFlags, theSewTolerance);
2584 storeResult(myEditor);
2586 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2589 //=======================================================================
2590 //function : AdvancedExtrusion
2592 //=======================================================================
2594 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2595 const SMESH::DirStruct & theStepVector,
2596 CORBA::Long theNbOfSteps,
2597 CORBA::Long theExtrFlags,
2598 CORBA::Double theSewTolerance)
2600 if ( !myPreviewMode ) {
2601 TPythonDump() << "stepVector = " << theStepVector;
2602 TPythonDump() << this << ".AdvancedExtrusion("
2605 << theNbOfSteps << ","
2606 << theExtrFlags << ", "
2607 << theSewTolerance << " )";
2609 advancedExtrusion( theIDsOfElements,
2617 //=======================================================================
2618 //function : AdvancedExtrusionMakeGroups
2620 //=======================================================================
2621 SMESH::ListOfGroups*
2622 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2623 const SMESH::DirStruct& theStepVector,
2624 CORBA::Long theNbOfSteps,
2625 CORBA::Long theExtrFlags,
2626 CORBA::Double theSewTolerance)
2628 if (!myPreviewMode) {
2629 TPythonDump() << "stepVector = " << theStepVector;
2631 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2633 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2640 if (!myPreviewMode) {
2641 DumpGroupsList(aPythonDump, aGroups);
2642 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2645 << theNbOfSteps << ","
2646 << theExtrFlags << ", "
2647 << theSewTolerance << " )";
2653 //================================================================================
2655 * \brief Convert extrusion error to IDL enum
2657 //================================================================================
2659 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2661 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2665 RETCASE( EXTR_NO_ELEMENTS );
2666 RETCASE( EXTR_PATH_NOT_EDGE );
2667 RETCASE( EXTR_BAD_PATH_SHAPE );
2668 RETCASE( EXTR_BAD_STARTING_NODE );
2669 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2670 RETCASE( EXTR_CANT_GET_TANGENT );
2672 return SMESH::SMESH_MeshEditor::EXTR_OK;
2676 //=======================================================================
2677 //function : extrusionAlongPath
2679 //=======================================================================
2680 SMESH::ListOfGroups*
2681 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2682 SMESH::SMESH_Mesh_ptr thePathMesh,
2683 GEOM::GEOM_Object_ptr thePathShape,
2684 CORBA::Long theNodeStart,
2685 CORBA::Boolean theHasAngles,
2686 const SMESH::double_array & theAngles,
2687 CORBA::Boolean theHasRefPoint,
2688 const SMESH::PointStruct & theRefPoint,
2689 const bool theMakeGroups,
2690 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2691 const SMDSAbs_ElementType theElementType)
2693 MESSAGE("extrusionAlongPath");
2696 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2697 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2700 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2702 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2703 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2705 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2706 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2710 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2712 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2716 TIDSortedElemSet elements;
2717 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2719 list<double> angles;
2720 for (int i = 0; i < theAngles.length(); i++) {
2721 angles.push_back( theAngles[i] );
2724 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2726 int nbOldGroups = myMesh->NbGroup();
2728 ::SMESH_MeshEditor::Extrusion_Error error =
2729 myEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2730 theHasAngles, angles, false,
2731 theHasRefPoint, refPnt, theMakeGroups );
2732 myMesh->GetMeshDS()->Modified();
2733 storeResult(myEditor);
2734 theError = convExtrError( error );
2736 if ( theMakeGroups ) {
2737 list<int> groupIDs = myMesh->GetGroupIds();
2738 list<int>::iterator newBegin = groupIDs.begin();
2739 std::advance( newBegin, nbOldGroups ); // skip old groups
2740 groupIDs.erase( groupIDs.begin(), newBegin );
2741 return getGroups( & groupIDs );
2747 //=======================================================================
2748 //function : extrusionAlongPathX
2750 //=======================================================================
2751 SMESH::ListOfGroups*
2752 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2753 SMESH::SMESH_IDSource_ptr Path,
2754 CORBA::Long NodeStart,
2755 CORBA::Boolean HasAngles,
2756 const SMESH::double_array& Angles,
2757 CORBA::Boolean LinearVariation,
2758 CORBA::Boolean HasRefPoint,
2759 const SMESH::PointStruct& RefPoint,
2761 const SMDSAbs_ElementType ElementType,
2762 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2764 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2768 list<double> angles;
2769 for (int i = 0; i < Angles.length(); i++) {
2770 angles.push_back( Angles[i] );
2772 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2773 int nbOldGroups = myMesh->NbGroup();
2775 if ( Path->_is_nil() ) {
2776 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2780 TIDSortedElemSet elements, copyElements;
2781 arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
2783 TIDSortedElemSet* workElements = &elements;
2784 TPreviewMesh tmpMesh( SMDSAbs_Face );
2785 SMESH_Mesh* mesh = myMesh;
2787 if ( myPreviewMode )
2789 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2790 tmpMesh.Copy( elements, copyElements, select, avoid );
2792 workElements = & copyElements;
2796 ::SMESH_MeshEditor::Extrusion_Error error;
2798 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2801 SMDS_MeshNode* aNodeStart =
2802 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2803 if ( !aNodeStart ) {
2804 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2807 error = myEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2808 HasAngles, angles, LinearVariation,
2809 HasRefPoint, refPnt, MakeGroups );
2810 myMesh->GetMeshDS()->Modified();
2812 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2815 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2816 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2817 SMDS_MeshNode* aNodeStart =
2818 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2819 if ( !aNodeStart ) {
2820 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2823 SMESH_subMesh* aSubMesh =
2824 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2825 error = myEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2826 HasAngles, angles, LinearVariation,
2827 HasRefPoint, refPnt, MakeGroups );
2828 myMesh->GetMeshDS()->Modified();
2830 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2832 // path as group of 1D elements
2838 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2842 storeResult(myEditor);
2843 Error = convExtrError( error );
2846 list<int> groupIDs = myMesh->GetGroupIds();
2847 list<int>::iterator newBegin = groupIDs.begin();
2848 std::advance( newBegin, nbOldGroups ); // skip old groups
2849 groupIDs.erase( groupIDs.begin(), newBegin );
2850 return getGroups( & groupIDs );
2856 //=======================================================================
2857 //function : ExtrusionAlongPath
2859 //=======================================================================
2860 SMESH::SMESH_MeshEditor::Extrusion_Error
2861 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2862 SMESH::SMESH_Mesh_ptr thePathMesh,
2863 GEOM::GEOM_Object_ptr thePathShape,
2864 CORBA::Long theNodeStart,
2865 CORBA::Boolean theHasAngles,
2866 const SMESH::double_array & theAngles,
2867 CORBA::Boolean theHasRefPoint,
2868 const SMESH::PointStruct & theRefPoint)
2870 MESSAGE("ExtrusionAlongPath");
2871 if ( !myPreviewMode ) {
2872 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2873 << theIDsOfElements << ", "
2874 << thePathMesh << ", "
2875 << thePathShape << ", "
2876 << theNodeStart << ", "
2877 << theHasAngles << ", "
2878 << theAngles << ", "
2879 << theHasRefPoint << ", "
2880 << "SMESH.PointStruct( "
2881 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2882 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2883 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2885 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2886 extrusionAlongPath( theIDsOfElements,
2899 //=======================================================================
2900 //function : ExtrusionAlongPathObject
2902 //=======================================================================
2903 SMESH::SMESH_MeshEditor::Extrusion_Error
2904 SMESH_MeshEditor_i::ExtrusionAlongPathObject(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 << ".ExtrusionAlongPathObject( "
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,
2942 //=======================================================================
2943 //function : ExtrusionAlongPathObject1D
2945 //=======================================================================
2946 SMESH::SMESH_MeshEditor::Extrusion_Error
2947 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2948 SMESH::SMESH_Mesh_ptr thePathMesh,
2949 GEOM::GEOM_Object_ptr thePathShape,
2950 CORBA::Long theNodeStart,
2951 CORBA::Boolean theHasAngles,
2952 const SMESH::double_array & theAngles,
2953 CORBA::Boolean theHasRefPoint,
2954 const SMESH::PointStruct & theRefPoint)
2956 if ( !myPreviewMode ) {
2957 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2958 << theObject << ", "
2959 << thePathMesh << ", "
2960 << thePathShape << ", "
2961 << theNodeStart << ", "
2962 << theHasAngles << ", "
2963 << theAngles << ", "
2964 << theHasRefPoint << ", "
2965 << "SMESH.PointStruct( "
2966 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2967 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2968 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2970 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2971 SMESH::long_array_var anElementsId = theObject->GetIDs();
2972 extrusionAlongPath( anElementsId,
2986 //=======================================================================
2987 //function : ExtrusionAlongPathObject2D
2989 //=======================================================================
2990 SMESH::SMESH_MeshEditor::Extrusion_Error
2991 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
2992 SMESH::SMESH_Mesh_ptr thePathMesh,
2993 GEOM::GEOM_Object_ptr thePathShape,
2994 CORBA::Long theNodeStart,
2995 CORBA::Boolean theHasAngles,
2996 const SMESH::double_array & theAngles,
2997 CORBA::Boolean theHasRefPoint,
2998 const SMESH::PointStruct & theRefPoint)
3000 if ( !myPreviewMode ) {
3001 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3002 << theObject << ", "
3003 << thePathMesh << ", "
3004 << thePathShape << ", "
3005 << theNodeStart << ", "
3006 << theHasAngles << ", "
3007 << theAngles << ", "
3008 << theHasRefPoint << ", "
3009 << "SMESH.PointStruct( "
3010 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3011 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3012 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3014 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3015 SMESH::long_array_var anElementsId = theObject->GetIDs();
3016 extrusionAlongPath( anElementsId,
3031 //=======================================================================
3032 //function : ExtrusionAlongPathMakeGroups
3034 //=======================================================================
3035 SMESH::ListOfGroups*
3036 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3037 SMESH::SMESH_Mesh_ptr thePathMesh,
3038 GEOM::GEOM_Object_ptr thePathShape,
3039 CORBA::Long theNodeStart,
3040 CORBA::Boolean theHasAngles,
3041 const SMESH::double_array& theAngles,
3042 CORBA::Boolean theHasRefPoint,
3043 const SMESH::PointStruct& theRefPoint,
3044 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3046 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3048 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3058 if (!myPreviewMode) {
3059 bool isDumpGroups = aGroups && aGroups->length() > 0;
3061 aPythonDump << "(" << aGroups << ", error)";
3063 aPythonDump <<"error";
3065 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3066 << theIDsOfElements << ", "
3067 << thePathMesh << ", "
3068 << thePathShape << ", "
3069 << theNodeStart << ", "
3070 << theHasAngles << ", "
3071 << theAngles << ", "
3072 << theHasRefPoint << ", "
3073 << "SMESH.PointStruct( "
3074 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3075 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3076 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3081 //=======================================================================
3082 //function : ExtrusionAlongPathObjectMakeGroups
3084 //=======================================================================
3085 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3086 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3087 SMESH::SMESH_Mesh_ptr thePathMesh,
3088 GEOM::GEOM_Object_ptr thePathShape,
3089 CORBA::Long theNodeStart,
3090 CORBA::Boolean theHasAngles,
3091 const SMESH::double_array& theAngles,
3092 CORBA::Boolean theHasRefPoint,
3093 const SMESH::PointStruct& theRefPoint,
3094 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3096 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3098 SMESH::long_array_var anElementsId = theObject->GetIDs();
3099 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3110 if (!myPreviewMode) {
3111 bool isDumpGroups = aGroups && aGroups->length() > 0;
3113 aPythonDump << "(" << aGroups << ", error)";
3115 aPythonDump <<"error";
3117 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3118 << theObject << ", "
3119 << thePathMesh << ", "
3120 << thePathShape << ", "
3121 << theNodeStart << ", "
3122 << theHasAngles << ", "
3123 << theAngles << ", "
3124 << theHasRefPoint << ", "
3125 << "SMESH.PointStruct( "
3126 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3127 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3128 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3133 //=======================================================================
3134 //function : ExtrusionAlongPathObject1DMakeGroups
3136 //=======================================================================
3137 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3138 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3139 SMESH::SMESH_Mesh_ptr thePathMesh,
3140 GEOM::GEOM_Object_ptr thePathShape,
3141 CORBA::Long theNodeStart,
3142 CORBA::Boolean theHasAngles,
3143 const SMESH::double_array& theAngles,
3144 CORBA::Boolean theHasRefPoint,
3145 const SMESH::PointStruct& theRefPoint,
3146 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3148 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3150 SMESH::long_array_var anElementsId = theObject->GetIDs();
3151 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3163 if (!myPreviewMode) {
3164 bool isDumpGroups = aGroups && aGroups->length() > 0;
3166 aPythonDump << "(" << aGroups << ", error)";
3168 aPythonDump << "error";
3170 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3171 << theObject << ", "
3172 << thePathMesh << ", "
3173 << thePathShape << ", "
3174 << theNodeStart << ", "
3175 << theHasAngles << ", "
3176 << theAngles << ", "
3177 << theHasRefPoint << ", "
3178 << "SMESH.PointStruct( "
3179 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3180 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3181 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3186 //=======================================================================
3187 //function : ExtrusionAlongPathObject2DMakeGroups
3189 //=======================================================================
3190 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3191 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3192 SMESH::SMESH_Mesh_ptr thePathMesh,
3193 GEOM::GEOM_Object_ptr thePathShape,
3194 CORBA::Long theNodeStart,
3195 CORBA::Boolean theHasAngles,
3196 const SMESH::double_array& theAngles,
3197 CORBA::Boolean theHasRefPoint,
3198 const SMESH::PointStruct& theRefPoint,
3199 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3201 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3203 SMESH::long_array_var anElementsId = theObject->GetIDs();
3204 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3216 if (!myPreviewMode) {
3217 bool isDumpGroups = aGroups && aGroups->length() > 0;
3219 aPythonDump << "(" << aGroups << ", error)";
3221 aPythonDump << "error";
3223 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3224 << theObject << ", "
3225 << thePathMesh << ", "
3226 << thePathShape << ", "
3227 << theNodeStart << ", "
3228 << theHasAngles << ", "
3229 << theAngles << ", "
3230 << theHasRefPoint << ", "
3231 << "SMESH.PointStruct( "
3232 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3233 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3234 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3240 //=======================================================================
3241 //function : ExtrusionAlongPathObjX
3243 //=======================================================================
3244 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3245 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3246 SMESH::SMESH_IDSource_ptr Path,
3247 CORBA::Long NodeStart,
3248 CORBA::Boolean HasAngles,
3249 const SMESH::double_array& Angles,
3250 CORBA::Boolean LinearVariation,
3251 CORBA::Boolean HasRefPoint,
3252 const SMESH::PointStruct& RefPoint,
3253 CORBA::Boolean MakeGroups,
3254 SMESH::ElementType ElemType,
3255 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3257 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3259 SMESH::long_array_var anElementsId = Object->GetIDs();
3260 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3269 (SMDSAbs_ElementType)ElemType,
3272 if (!myPreviewMode) {
3273 bool isDumpGroups = aGroups && aGroups->length() > 0;
3275 aPythonDump << "(" << *aGroups << ", error)";
3277 aPythonDump << "error";
3279 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3282 << NodeStart << ", "
3283 << HasAngles << ", "
3284 << TVar( Angles ) << ", "
3285 << LinearVariation << ", "
3286 << HasRefPoint << ", "
3287 << "SMESH.PointStruct( "
3288 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3289 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3290 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3291 << MakeGroups << ", "
3292 << ElemType << " )";
3298 //=======================================================================
3299 //function : ExtrusionAlongPathX
3301 //=======================================================================
3302 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3303 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3304 SMESH::SMESH_IDSource_ptr Path,
3305 CORBA::Long NodeStart,
3306 CORBA::Boolean HasAngles,
3307 const SMESH::double_array& Angles,
3308 CORBA::Boolean LinearVariation,
3309 CORBA::Boolean HasRefPoint,
3310 const SMESH::PointStruct& RefPoint,
3311 CORBA::Boolean MakeGroups,
3312 SMESH::ElementType ElemType,
3313 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3315 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3317 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3326 (SMDSAbs_ElementType)ElemType,
3329 if (!myPreviewMode) {
3330 bool isDumpGroups = aGroups && aGroups->length() > 0;
3332 aPythonDump << "(" << *aGroups << ", error)";
3334 aPythonDump <<"error";
3336 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3337 << IDsOfElements << ", "
3339 << NodeStart << ", "
3340 << HasAngles << ", "
3341 << TVar( Angles ) << ", "
3342 << LinearVariation << ", "
3343 << HasRefPoint << ", "
3344 << "SMESH.PointStruct( "
3345 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3346 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3347 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3348 << MakeGroups << ", "
3349 << ElemType << " )";
3355 //================================================================================
3357 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3358 * of given angles along path steps
3359 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3360 * which proceeds the extrusion
3361 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3362 * is used to define the sub-mesh for the path
3364 //================================================================================
3366 SMESH::double_array*
3367 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3368 GEOM::GEOM_Object_ptr thePathShape,
3369 const SMESH::double_array & theAngles)
3371 SMESH::double_array_var aResult = new SMESH::double_array();
3372 int nbAngles = theAngles.length();
3373 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3375 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3376 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3377 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3378 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3379 return aResult._retn();
3380 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3381 if ( nbSteps == nbAngles )
3383 aResult.inout() = theAngles;
3387 aResult->length( nbSteps );
3388 double rAn2St = double( nbAngles ) / double( nbSteps );
3389 double angPrev = 0, angle;
3390 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3392 double angCur = rAn2St * ( iSt+1 );
3393 double angCurFloor = floor( angCur );
3394 double angPrevFloor = floor( angPrev );
3395 if ( angPrevFloor == angCurFloor )
3396 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3399 int iP = int( angPrevFloor );
3400 double angPrevCeil = ceil(angPrev);
3401 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3403 int iC = int( angCurFloor );
3404 if ( iC < nbAngles )
3405 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3407 iP = int( angPrevCeil );
3409 angle += theAngles[ iC ];
3411 aResult[ iSt ] = angle;
3416 // Update Python script
3417 TPythonDump() << "rotAngles = " << theAngles;
3418 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3419 << thePathMesh << ", "
3420 << thePathShape << ", "
3423 return aResult._retn();
3427 //=======================================================================
3430 //=======================================================================
3432 SMESH::ListOfGroups*
3433 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3434 const SMESH::AxisStruct & theAxis,
3435 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3436 CORBA::Boolean theCopy,
3438 ::SMESH_Mesh* theTargetMesh)
3442 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3443 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3445 if ( theTargetMesh )
3449 switch ( theMirrorType ) {
3450 case SMESH::SMESH_MeshEditor::POINT:
3451 aTrsf.SetMirror( P );
3453 case SMESH::SMESH_MeshEditor::AXIS:
3454 aTrsf.SetMirror( gp_Ax1( P, V ));
3457 aTrsf.SetMirror( gp_Ax2( P, V ));
3460 TIDSortedElemSet copyElements;
3461 TPreviewMesh tmpMesh;
3462 TIDSortedElemSet* workElements = & theElements;
3463 SMESH_Mesh* mesh = myMesh;
3465 if ( myPreviewMode )
3467 tmpMesh.Copy( theElements, copyElements);
3468 if ( !theCopy && !theTargetMesh )
3470 TIDSortedElemSet elemsAround, elemsAroundCopy;
3471 getElementsAround( theElements, GetMeshDS(), elemsAround );
3472 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3475 workElements = & copyElements;
3476 theMakeGroups = false;
3479 ::SMESH_MeshEditor::PGroupIDs groupIds =
3480 myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3482 if(theCopy || myPreviewMode)
3483 storeResult(myEditor); // store preview data or new elements
3485 if ( !myPreviewMode )
3487 if ( theTargetMesh )
3489 theTargetMesh->GetMeshDS()->Modified();
3493 myMesh->GetMeshDS()->Modified();
3494 myMesh->SetIsModified( true );
3497 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3500 //=======================================================================
3503 //=======================================================================
3505 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3506 const SMESH::AxisStruct & theAxis,
3507 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3508 CORBA::Boolean theCopy)
3510 if ( !myPreviewMode ) {
3511 TPythonDump() << this << ".Mirror( "
3512 << theIDsOfElements << ", "
3514 << mirrorTypeName(theMirrorType) << ", "
3517 if ( theIDsOfElements.length() > 0 )
3519 TIDSortedElemSet elements;
3520 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3521 mirror(elements, theAxis, theMirrorType, theCopy, false);
3526 //=======================================================================
3527 //function : MirrorObject
3529 //=======================================================================
3531 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3532 const SMESH::AxisStruct & theAxis,
3533 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3534 CORBA::Boolean theCopy)
3536 if ( !myPreviewMode ) {
3537 TPythonDump() << this << ".MirrorObject( "
3538 << theObject << ", "
3540 << mirrorTypeName(theMirrorType) << ", "
3543 TIDSortedElemSet elements;
3545 bool emptyIfIsMesh = myPreviewMode ? false : true;
3547 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3548 mirror(elements, theAxis, theMirrorType, theCopy, false);
3551 //=======================================================================
3552 //function : MirrorMakeGroups
3554 //=======================================================================
3556 SMESH::ListOfGroups*
3557 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3558 const SMESH::AxisStruct& theMirror,
3559 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3561 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3563 SMESH::ListOfGroups * aGroups = 0;
3564 if ( theIDsOfElements.length() > 0 )
3566 TIDSortedElemSet elements;
3567 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3568 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3570 if (!myPreviewMode) {
3571 DumpGroupsList(aPythonDump, aGroups);
3572 aPythonDump << this << ".MirrorMakeGroups( "
3573 << theIDsOfElements << ", "
3574 << theMirror << ", "
3575 << mirrorTypeName(theMirrorType) << " )";
3580 //=======================================================================
3581 //function : MirrorObjectMakeGroups
3583 //=======================================================================
3585 SMESH::ListOfGroups*
3586 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3587 const SMESH::AxisStruct& theMirror,
3588 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3590 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3592 SMESH::ListOfGroups * aGroups = 0;
3593 TIDSortedElemSet elements;
3594 if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3595 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3599 DumpGroupsList(aPythonDump,aGroups);
3600 aPythonDump << this << ".MirrorObjectMakeGroups( "
3601 << theObject << ", "
3602 << theMirror << ", "
3603 << mirrorTypeName(theMirrorType) << " )";
3608 //=======================================================================
3609 //function : MirrorMakeMesh
3611 //=======================================================================
3613 SMESH::SMESH_Mesh_ptr
3614 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3615 const SMESH::AxisStruct& theMirror,
3616 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3617 CORBA::Boolean theCopyGroups,
3618 const char* theMeshName)
3620 SMESH_Mesh_i* mesh_i;
3621 SMESH::SMESH_Mesh_var mesh;
3622 { // open new scope to dump "MakeMesh" command
3623 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3625 TPythonDump pydump; // to prevent dump at mesh creation
3627 mesh = makeMesh( theMeshName );
3628 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3629 if (mesh_i && theIDsOfElements.length() > 0 )
3631 TIDSortedElemSet elements;
3632 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3633 mirror(elements, theMirror, theMirrorType,
3634 false, theCopyGroups, & mesh_i->GetImpl());
3635 mesh_i->CreateGroupServants();
3638 if (!myPreviewMode) {
3639 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3640 << theIDsOfElements << ", "
3641 << theMirror << ", "
3642 << mirrorTypeName(theMirrorType) << ", "
3643 << theCopyGroups << ", '"
3644 << theMeshName << "' )";
3649 if (!myPreviewMode && mesh_i)
3650 mesh_i->GetGroups();
3652 return mesh._retn();
3655 //=======================================================================
3656 //function : MirrorObjectMakeMesh
3658 //=======================================================================
3660 SMESH::SMESH_Mesh_ptr
3661 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3662 const SMESH::AxisStruct& theMirror,
3663 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3664 CORBA::Boolean theCopyGroups,
3665 const char* theMeshName)
3667 SMESH_Mesh_i* mesh_i;
3668 SMESH::SMESH_Mesh_var mesh;
3669 { // open new scope to dump "MakeMesh" command
3670 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3672 TPythonDump pydump; // to prevent dump at mesh creation
3674 mesh = makeMesh( theMeshName );
3675 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3676 TIDSortedElemSet elements;
3678 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3680 mirror(elements, theMirror, theMirrorType,
3681 false, theCopyGroups, & mesh_i->GetImpl());
3682 mesh_i->CreateGroupServants();
3684 if (!myPreviewMode) {
3685 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3686 << theObject << ", "
3687 << theMirror << ", "
3688 << mirrorTypeName(theMirrorType) << ", "
3689 << theCopyGroups << ", '"
3690 << theMeshName << "' )";
3695 if (!myPreviewMode && mesh_i)
3696 mesh_i->GetGroups();
3698 return mesh._retn();
3701 //=======================================================================
3702 //function : translate
3704 //=======================================================================
3706 SMESH::ListOfGroups*
3707 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3708 const SMESH::DirStruct & theVector,
3709 CORBA::Boolean theCopy,
3711 ::SMESH_Mesh* theTargetMesh)
3715 if ( theTargetMesh )
3719 const SMESH::PointStruct * P = &theVector.PS;
3720 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3722 TIDSortedElemSet copyElements;
3723 TIDSortedElemSet* workElements = &theElements;
3724 TPreviewMesh tmpMesh;
3725 SMESH_Mesh* mesh = myMesh;
3727 if ( myPreviewMode )
3729 tmpMesh.Copy( theElements, copyElements);
3730 if ( !theCopy && !theTargetMesh )
3732 TIDSortedElemSet elemsAround, elemsAroundCopy;
3733 getElementsAround( theElements, GetMeshDS(), elemsAround );
3734 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3737 workElements = & copyElements;
3738 theMakeGroups = false;
3741 ::SMESH_MeshEditor::PGroupIDs groupIds =
3742 myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3744 if(theCopy || myPreviewMode)
3745 storeResult(myEditor);
3747 if ( !myPreviewMode )
3749 if ( theTargetMesh )
3751 theTargetMesh->GetMeshDS()->Modified();
3755 myMesh->GetMeshDS()->Modified();
3756 myMesh->SetIsModified( true );
3760 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3763 //=======================================================================
3764 //function : Translate
3766 //=======================================================================
3768 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3769 const SMESH::DirStruct & theVector,
3770 CORBA::Boolean theCopy)
3772 if (!myPreviewMode) {
3773 TPythonDump() << this << ".Translate( "
3774 << theIDsOfElements << ", "
3775 << theVector << ", "
3778 if (theIDsOfElements.length()) {
3779 TIDSortedElemSet elements;
3780 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3781 translate(elements, theVector, theCopy, false);
3785 //=======================================================================
3786 //function : TranslateObject
3788 //=======================================================================
3790 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3791 const SMESH::DirStruct & theVector,
3792 CORBA::Boolean theCopy)
3794 if (!myPreviewMode) {
3795 TPythonDump() << this << ".TranslateObject( "
3796 << theObject << ", "
3797 << theVector << ", "
3800 TIDSortedElemSet elements;
3802 bool emptyIfIsMesh = myPreviewMode ? false : true;
3804 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3805 translate(elements, theVector, theCopy, false);
3808 //=======================================================================
3809 //function : TranslateMakeGroups
3811 //=======================================================================
3813 SMESH::ListOfGroups*
3814 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3815 const SMESH::DirStruct& theVector)
3817 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3819 SMESH::ListOfGroups * aGroups = 0;
3820 if (theIDsOfElements.length()) {
3821 TIDSortedElemSet elements;
3822 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3823 aGroups = translate(elements,theVector,true,true);
3825 if (!myPreviewMode) {
3826 DumpGroupsList(aPythonDump, aGroups);
3827 aPythonDump << this << ".TranslateMakeGroups( "
3828 << theIDsOfElements << ", "
3829 << theVector << " )";
3834 //=======================================================================
3835 //function : TranslateObjectMakeGroups
3837 //=======================================================================
3839 SMESH::ListOfGroups*
3840 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3841 const SMESH::DirStruct& theVector)
3843 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3845 SMESH::ListOfGroups * aGroups = 0;
3846 TIDSortedElemSet elements;
3847 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3848 aGroups = translate(elements, theVector, true, true);
3850 if (!myPreviewMode) {
3851 DumpGroupsList(aPythonDump, aGroups);
3852 aPythonDump << this << ".TranslateObjectMakeGroups( "
3853 << theObject << ", "
3854 << theVector << " )";
3859 //=======================================================================
3860 //function : TranslateMakeMesh
3862 //=======================================================================
3864 SMESH::SMESH_Mesh_ptr
3865 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3866 const SMESH::DirStruct& theVector,
3867 CORBA::Boolean theCopyGroups,
3868 const char* theMeshName)
3870 SMESH_Mesh_i* mesh_i;
3871 SMESH::SMESH_Mesh_var mesh;
3873 { // open new scope to dump "MakeMesh" command
3874 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3876 TPythonDump pydump; // to prevent dump at mesh creation
3878 mesh = makeMesh( theMeshName );
3879 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3881 if ( mesh_i && theIDsOfElements.length() )
3883 TIDSortedElemSet elements;
3884 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3885 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3886 mesh_i->CreateGroupServants();
3889 if ( !myPreviewMode ) {
3890 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3891 << theIDsOfElements << ", "
3892 << theVector << ", "
3893 << theCopyGroups << ", '"
3894 << theMeshName << "' )";
3899 if (!myPreviewMode && mesh_i)
3900 mesh_i->GetGroups();
3902 return mesh._retn();
3905 //=======================================================================
3906 //function : TranslateObjectMakeMesh
3908 //=======================================================================
3910 SMESH::SMESH_Mesh_ptr
3911 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3912 const SMESH::DirStruct& theVector,
3913 CORBA::Boolean theCopyGroups,
3914 const char* theMeshName)
3916 SMESH_Mesh_i* mesh_i;
3917 SMESH::SMESH_Mesh_var mesh;
3918 { // open new scope to dump "MakeMesh" command
3919 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3921 TPythonDump pydump; // to prevent dump at mesh creation
3922 mesh = makeMesh( theMeshName );
3923 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3925 TIDSortedElemSet elements;
3927 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3929 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3930 mesh_i->CreateGroupServants();
3932 if ( !myPreviewMode ) {
3933 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3934 << theObject << ", "
3935 << theVector << ", "
3936 << theCopyGroups << ", '"
3937 << theMeshName << "' )";
3942 if (!myPreviewMode && mesh_i)
3943 mesh_i->GetGroups();
3945 return mesh._retn();
3948 //=======================================================================
3951 //=======================================================================
3953 SMESH::ListOfGroups*
3954 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3955 const SMESH::AxisStruct & theAxis,
3956 CORBA::Double theAngle,
3957 CORBA::Boolean theCopy,
3959 ::SMESH_Mesh* theTargetMesh)
3963 if ( theTargetMesh )
3966 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3967 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3970 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3972 TIDSortedElemSet copyElements;
3973 TIDSortedElemSet* workElements = &theElements;
3974 TPreviewMesh tmpMesh;
3975 SMESH_Mesh* mesh = myMesh;
3977 if ( myPreviewMode ) {
3978 tmpMesh.Copy( theElements, copyElements );
3979 if ( !theCopy && !theTargetMesh )
3981 TIDSortedElemSet elemsAround, elemsAroundCopy;
3982 getElementsAround( theElements, GetMeshDS(), elemsAround );
3983 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3986 workElements = ©Elements;
3987 theMakeGroups = false;
3990 ::SMESH_MeshEditor::PGroupIDs groupIds =
3991 myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3993 if(theCopy || myPreviewMode)
3994 storeResult(myEditor);
3996 if ( !myPreviewMode )
3998 if ( theTargetMesh )
4000 theTargetMesh->GetMeshDS()->Modified();
4004 myMesh->GetMeshDS()->Modified();
4005 myMesh->SetIsModified( true );
4009 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4012 //=======================================================================
4015 //=======================================================================
4017 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4018 const SMESH::AxisStruct & theAxis,
4019 CORBA::Double theAngle,
4020 CORBA::Boolean theCopy)
4022 if (!myPreviewMode) {
4023 TPythonDump() << this << ".Rotate( "
4024 << theIDsOfElements << ", "
4026 << TVar( theAngle ) << ", "
4029 if (theIDsOfElements.length() > 0)
4031 TIDSortedElemSet elements;
4032 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
4033 rotate(elements,theAxis,theAngle,theCopy,false);
4037 //=======================================================================
4038 //function : RotateObject
4040 //=======================================================================
4042 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4043 const SMESH::AxisStruct & theAxis,
4044 CORBA::Double theAngle,
4045 CORBA::Boolean theCopy)
4047 if ( !myPreviewMode ) {
4048 TPythonDump() << this << ".RotateObject( "
4049 << theObject << ", "
4051 << TVar( theAngle ) << ", "
4054 TIDSortedElemSet elements;
4055 bool emptyIfIsMesh = myPreviewMode ? false : true;
4056 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4057 rotate(elements,theAxis,theAngle,theCopy,false);
4060 //=======================================================================
4061 //function : RotateMakeGroups
4063 //=======================================================================
4065 SMESH::ListOfGroups*
4066 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4067 const SMESH::AxisStruct& theAxis,
4068 CORBA::Double theAngle)
4070 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4072 SMESH::ListOfGroups * aGroups = 0;
4073 if (theIDsOfElements.length() > 0)
4075 TIDSortedElemSet elements;
4076 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
4077 aGroups = rotate(elements,theAxis,theAngle,true,true);
4079 if (!myPreviewMode) {
4080 DumpGroupsList(aPythonDump, aGroups);
4081 aPythonDump << this << ".RotateMakeGroups( "
4082 << theIDsOfElements << ", "
4084 << TVar( theAngle ) << " )";
4089 //=======================================================================
4090 //function : RotateObjectMakeGroups
4092 //=======================================================================
4094 SMESH::ListOfGroups*
4095 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4096 const SMESH::AxisStruct& theAxis,
4097 CORBA::Double theAngle)
4099 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4101 SMESH::ListOfGroups * aGroups = 0;
4102 TIDSortedElemSet elements;
4103 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4104 aGroups = rotate(elements, theAxis, theAngle, true, true);
4106 if (!myPreviewMode) {
4107 DumpGroupsList(aPythonDump, aGroups);
4108 aPythonDump << this << ".RotateObjectMakeGroups( "
4109 << theObject << ", "
4111 << TVar( theAngle ) << " )";
4116 //=======================================================================
4117 //function : RotateMakeMesh
4119 //=======================================================================
4121 SMESH::SMESH_Mesh_ptr
4122 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4123 const SMESH::AxisStruct& theAxis,
4124 CORBA::Double theAngleInRadians,
4125 CORBA::Boolean theCopyGroups,
4126 const char* theMeshName)
4128 SMESH::SMESH_Mesh_var mesh;
4129 SMESH_Mesh_i* mesh_i;
4131 { // open new scope to dump "MakeMesh" command
4132 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4134 TPythonDump pydump; // to prevent dump at mesh creation
4136 mesh = makeMesh( theMeshName );
4137 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4139 if ( mesh_i && theIDsOfElements.length() > 0 )
4141 TIDSortedElemSet elements;
4142 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
4143 rotate(elements, theAxis, theAngleInRadians,
4144 false, theCopyGroups, & mesh_i->GetImpl());
4145 mesh_i->CreateGroupServants();
4147 if ( !myPreviewMode ) {
4148 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4149 << theIDsOfElements << ", "
4151 << TVar( theAngleInRadians ) << ", "
4152 << theCopyGroups << ", '"
4153 << theMeshName << "' )";
4158 if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4159 mesh_i->GetGroups();
4161 return mesh._retn();
4164 //=======================================================================
4165 //function : RotateObjectMakeMesh
4167 //=======================================================================
4169 SMESH::SMESH_Mesh_ptr
4170 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4171 const SMESH::AxisStruct& theAxis,
4172 CORBA::Double theAngleInRadians,
4173 CORBA::Boolean theCopyGroups,
4174 const char* theMeshName)
4176 SMESH::SMESH_Mesh_var mesh;
4177 SMESH_Mesh_i* mesh_i;
4179 {// open new scope to dump "MakeMesh" command
4180 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4182 TPythonDump pydump; // to prevent dump at mesh creation
4183 mesh = makeMesh( theMeshName );
4184 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4186 TIDSortedElemSet elements;
4188 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4190 rotate(elements, theAxis, theAngleInRadians,
4191 false, theCopyGroups, & mesh_i->GetImpl());
4192 mesh_i->CreateGroupServants();
4194 if ( !myPreviewMode ) {
4195 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4196 << theObject << ", "
4198 << TVar( theAngleInRadians ) << ", "
4199 << theCopyGroups << ", '"
4200 << theMeshName << "' )";
4205 if (!myPreviewMode && mesh_i)
4206 mesh_i->GetGroups();
4208 return mesh._retn();
4211 //=======================================================================
4214 //=======================================================================
4216 SMESH::ListOfGroups*
4217 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4218 const SMESH::PointStruct& thePoint,
4219 const SMESH::double_array& theScaleFact,
4220 CORBA::Boolean theCopy,
4222 ::SMESH_Mesh* theTargetMesh)
4225 if ( theScaleFact.length() < 1 )
4226 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4227 if ( theScaleFact.length() == 2 )
4228 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4230 if ( theTargetMesh )
4233 TIDSortedElemSet elements;
4234 bool emptyIfIsMesh = myPreviewMode ? false : true;
4235 if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4240 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4241 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4243 double tol = std::numeric_limits<double>::max();
4245 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4246 0, S[1], 0, thePoint.y * (1-S[1]),
4247 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4249 TIDSortedElemSet copyElements;
4250 TPreviewMesh tmpMesh;
4251 TIDSortedElemSet* workElements = &elements;
4252 SMESH_Mesh* mesh = myMesh;
4254 if ( myPreviewMode )
4256 tmpMesh.Copy( elements, copyElements);
4257 if ( !theCopy && !theTargetMesh )
4259 TIDSortedElemSet elemsAround, elemsAroundCopy;
4260 getElementsAround( elements, GetMeshDS(), elemsAround );
4261 tmpMesh.Copy( elemsAround, elemsAroundCopy);
4264 workElements = & copyElements;
4265 theMakeGroups = false;
4268 ::SMESH_MeshEditor::PGroupIDs groupIds =
4269 myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4271 if(theCopy || myPreviewMode )
4272 storeResult(myEditor);
4274 if ( !myPreviewMode )
4276 if ( theTargetMesh )
4278 theTargetMesh->GetMeshDS()->Modified();
4282 myMesh->GetMeshDS()->Modified();
4283 myMesh->SetIsModified( true );
4287 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4290 //=======================================================================
4293 //=======================================================================
4295 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4296 const SMESH::PointStruct& thePoint,
4297 const SMESH::double_array& theScaleFact,
4298 CORBA::Boolean theCopy)
4300 if ( !myPreviewMode ) {
4301 TPythonDump() << this << ".Scale( "
4302 << theObject << ", "
4304 << TVar( theScaleFact ) << ", "
4307 scale(theObject, thePoint, theScaleFact, theCopy, false);
4311 //=======================================================================
4312 //function : ScaleMakeGroups
4314 //=======================================================================
4316 SMESH::ListOfGroups*
4317 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4318 const SMESH::PointStruct& thePoint,
4319 const SMESH::double_array& theScaleFact)
4321 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4323 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4324 if (!myPreviewMode) {
4325 DumpGroupsList(aPythonDump, aGroups);
4326 aPythonDump << this << ".Scale("
4329 << TVar( theScaleFact ) << ",True,True)";
4335 //=======================================================================
4336 //function : ScaleMakeMesh
4338 //=======================================================================
4340 SMESH::SMESH_Mesh_ptr
4341 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4342 const SMESH::PointStruct& thePoint,
4343 const SMESH::double_array& theScaleFact,
4344 CORBA::Boolean theCopyGroups,
4345 const char* theMeshName)
4347 SMESH_Mesh_i* mesh_i;
4348 SMESH::SMESH_Mesh_var mesh;
4349 { // open new scope to dump "MakeMesh" command
4350 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4352 TPythonDump pydump; // to prevent dump at mesh creation
4353 mesh = makeMesh( theMeshName );
4354 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4358 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4359 mesh_i->CreateGroupServants();
4361 if ( !myPreviewMode )
4362 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4363 << theObject << ", "
4365 << TVar( theScaleFact ) << ", "
4366 << theCopyGroups << ", '"
4367 << theMeshName << "' )";
4371 if (!myPreviewMode && mesh_i)
4372 mesh_i->GetGroups();
4374 return mesh._retn();
4378 //=======================================================================
4379 //function : FindCoincidentNodes
4381 //=======================================================================
4383 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4384 SMESH::array_of_long_array_out GroupsOfNodes)
4388 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4389 TIDSortedNodeSet nodes; // no input nodes
4390 myEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4392 GroupsOfNodes = new SMESH::array_of_long_array;
4393 GroupsOfNodes->length( aListOfListOfNodes.size() );
4394 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4395 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4396 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4397 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4398 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4399 aGroup.length( aListOfNodes.size() );
4400 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4401 aGroup[ j ] = (*lIt)->GetID();
4403 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4404 << Tolerance << " )";
4407 //=======================================================================
4408 //function : FindCoincidentNodesOnPart
4410 //=======================================================================
4411 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4412 CORBA::Double Tolerance,
4413 SMESH::array_of_long_array_out GroupsOfNodes)
4417 TIDSortedNodeSet nodes;
4418 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
4420 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4422 myEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4424 GroupsOfNodes = new SMESH::array_of_long_array;
4425 GroupsOfNodes->length( aListOfListOfNodes.size() );
4426 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4427 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4429 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4430 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4431 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4432 aGroup.length( aListOfNodes.size() );
4433 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4434 aGroup[ j ] = (*lIt)->GetID();
4436 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4438 << Tolerance << " )";
4441 //================================================================================
4443 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4444 * ExceptSubMeshOrGroups
4446 //================================================================================
4448 void SMESH_MeshEditor_i::
4449 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4450 CORBA::Double theTolerance,
4451 SMESH::array_of_long_array_out theGroupsOfNodes,
4452 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4456 TIDSortedNodeSet nodes;
4457 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
4459 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4461 TIDSortedNodeSet exceptNodes;
4462 idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
4463 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4464 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4465 nodes.erase( *avoidNode );
4467 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4469 myEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4471 theGroupsOfNodes = new SMESH::array_of_long_array;
4472 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4473 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4474 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4476 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4477 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4478 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4479 aGroup.length( aListOfNodes.size() );
4480 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4481 aGroup[ j ] = (*lIt)->GetID();
4483 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4485 << theTolerance << ", "
4486 << theExceptSubMeshOrGroups << " )";
4489 //=======================================================================
4490 //function : MergeNodes
4492 //=======================================================================
4494 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4498 SMESHDS_Mesh* aMesh = GetMeshDS();
4500 TPythonDump aTPythonDump;
4501 aTPythonDump << this << ".MergeNodes([";
4502 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4503 for (int i = 0; i < GroupsOfNodes.length(); i++)
4505 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4506 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4507 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4508 for ( int j = 0; j < aNodeGroup.length(); j++ )
4510 CORBA::Long index = aNodeGroup[ j ];
4511 const SMDS_MeshNode * node = aMesh->FindNode(index);
4513 aListOfNodes.push_back( node );
4515 if ( aListOfNodes.size() < 2 )
4516 aListOfListOfNodes.pop_back();
4518 if ( i > 0 ) aTPythonDump << ", ";
4519 aTPythonDump << aNodeGroup;
4521 myEditor.MergeNodes( aListOfListOfNodes );
4523 aTPythonDump << "])";
4524 myMesh->GetMeshDS()->Modified();
4525 myMesh->SetIsModified( true );
4528 //=======================================================================
4529 //function : FindEqualElements
4531 //=======================================================================
4532 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4533 SMESH::array_of_long_array_out GroupsOfElementsID)
4537 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4538 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4540 TIDSortedElemSet elems;
4541 idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4543 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4544 myEditor.FindEqualElements( elems, aListOfListOfElementsID );
4546 GroupsOfElementsID = new SMESH::array_of_long_array;
4547 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4549 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4550 aListOfListOfElementsID.begin();
4551 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4553 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4554 list<int>& listOfIDs = *arraysIt;
4555 aGroup.length( listOfIDs.size() );
4556 list<int>::iterator idIt = listOfIDs.begin();
4557 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4558 aGroup[ k ] = *idIt;
4561 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4566 //=======================================================================
4567 //function : MergeElements
4569 //=======================================================================
4571 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4575 TPythonDump aTPythonDump;
4576 aTPythonDump << this << ".MergeElements( [";
4578 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4580 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4581 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4582 aListOfListOfElementsID.push_back( list< int >() );
4583 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4584 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4585 CORBA::Long id = anElemsIDGroup[ j ];
4586 aListOfElemsID.push_back( id );
4588 if ( aListOfElemsID.size() < 2 )
4589 aListOfListOfElementsID.pop_back();
4590 if ( i > 0 ) aTPythonDump << ", ";
4591 aTPythonDump << anElemsIDGroup;
4594 myEditor.MergeElements(aListOfListOfElementsID);
4595 myMesh->GetMeshDS()->Modified();
4596 myMesh->SetIsModified( true );
4598 aTPythonDump << "] )";
4601 //=======================================================================
4602 //function : MergeEqualElements
4604 //=======================================================================
4606 void SMESH_MeshEditor_i::MergeEqualElements()
4610 myEditor.MergeEqualElements();
4612 myMesh->GetMeshDS()->Modified();
4614 TPythonDump() << this << ".MergeEqualElements()";
4617 //=============================================================================
4619 * Move the node to a given point
4621 //=============================================================================
4623 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4628 initData(/*deleteSearchers=*/false);
4630 const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
4634 if ( theNodeSearcher )
4635 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4637 if ( myPreviewMode ) // make preview data
4639 // in a preview mesh, make edges linked to a node
4640 TPreviewMesh tmpMesh;
4641 TIDSortedElemSet linkedNodes;
4642 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4643 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4644 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4645 for ( ; nIt != linkedNodes.end(); ++nIt )
4647 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4648 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4652 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4653 // fill preview data
4654 storeResult( myEditor );
4656 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4657 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4659 GetMeshDS()->MoveNode(node, x, y, z);
4661 if ( !myPreviewMode )
4663 // Update Python script
4664 TPythonDump() << "isDone = " << this << ".MoveNode( "
4665 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4666 myMesh->GetMeshDS()->Modified();
4667 myMesh->SetIsModified( true );
4673 //================================================================================
4675 * \brief Return ID of node closest to a given point
4677 //================================================================================
4679 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4683 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4685 if ( !theNodeSearcher ) {
4686 theNodeSearcher = myEditor.GetNodeSearcher();
4689 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4690 return node->GetID();
4695 //================================================================================
4697 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4698 * move the node closest to the point to point's location and return ID of the node
4700 //================================================================================
4702 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4705 CORBA::Long theNodeID)
4707 // We keep theNodeSearcher until any mesh modification:
4708 // 1) initData() deletes theNodeSearcher at any edition,
4709 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4711 initData(/*deleteSearchers=*/false);
4713 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4715 int nodeID = theNodeID;
4716 const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
4717 if ( !node ) // preview moving node
4719 if ( !theNodeSearcher ) {
4720 theNodeSearcher = myEditor.GetNodeSearcher();
4723 node = theNodeSearcher->FindClosestTo( p );
4726 nodeID = node->GetID();
4727 if ( myPreviewMode ) // make preview data
4729 // in a preview mesh, make edges linked to a node
4730 TPreviewMesh tmpMesh;
4731 TIDSortedElemSet linkedNodes;
4732 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4733 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4734 for ( ; nIt != linkedNodes.end(); ++nIt )
4736 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4737 tmpMesh.Copy( &edge );
4740 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4742 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4743 // fill preview data
4744 storeResult( myEditor );
4746 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4748 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4752 GetMeshDS()->MoveNode(node, x, y, z);
4756 if ( !myPreviewMode )
4758 TPythonDump() << "nodeID = " << this
4759 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4760 << ", " << nodeID << " )";
4762 myMesh->GetMeshDS()->Modified();
4763 myMesh->SetIsModified( true );
4769 //=======================================================================
4771 * Return elements of given type where the given point is IN or ON.
4773 * 'ALL' type means elements of any type excluding nodes
4775 //=======================================================================
4777 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4780 SMESH::ElementType type)
4782 SMESH::long_array_var res = new SMESH::long_array;
4783 vector< const SMDS_MeshElement* > foundElems;
4785 theSearchersDeleter.Set( myMesh );
4786 if ( !theElementSearcher ) {
4787 theElementSearcher = myEditor.GetElementSearcher();
4789 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4790 SMDSAbs_ElementType( type ),
4792 res->length( foundElems.size() );
4793 for ( int i = 0; i < foundElems.size(); ++i )
4794 res[i] = foundElems[i]->GetID();
4796 if ( !myPreviewMode ) // call from tui
4797 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4806 //=======================================================================
4807 //function : FindAmongElementsByPoint
4808 //purpose : Searching among the given elements, return elements of given type
4809 // where the given point is IN or ON.
4810 // 'ALL' type means elements of any type excluding nodes
4811 //=======================================================================
4814 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4818 SMESH::ElementType type)
4820 SMESH::long_array_var res = new SMESH::long_array;
4822 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4823 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4824 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4825 type != types[0] ) // but search of elements of dim > 0
4828 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4829 return FindElementsByPoint( x,y,z, type );
4831 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4833 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4834 if ( !theElementSearcher )
4836 // create a searcher from elementIDs
4837 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4838 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4840 if ( !idSourceToSet( elementIDs, meshDS, elements,
4841 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4844 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4845 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4847 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
4850 vector< const SMDS_MeshElement* > foundElems;
4852 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4853 SMDSAbs_ElementType( type ),
4855 res->length( foundElems.size() );
4856 for ( int i = 0; i < foundElems.size(); ++i )
4857 res[i] = foundElems[i]->GetID();
4859 if ( !myPreviewMode ) // call from tui
4860 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4861 << elementIDs << ", "
4870 //=======================================================================
4871 //function : GetPointState
4872 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4873 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4874 //=======================================================================
4876 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4880 theSearchersDeleter.Set( myMesh );
4881 if ( !theElementSearcher ) {
4882 theElementSearcher = myEditor.GetElementSearcher();
4884 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4887 //=======================================================================
4888 //function : convError
4890 //=======================================================================
4892 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4894 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4898 RETCASE( SEW_BORDER1_NOT_FOUND );
4899 RETCASE( SEW_BORDER2_NOT_FOUND );
4900 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4901 RETCASE( SEW_BAD_SIDE_NODES );
4902 RETCASE( SEW_VOLUMES_TO_SPLIT );
4903 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4904 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4905 RETCASE( SEW_BAD_SIDE1_NODES );
4906 RETCASE( SEW_BAD_SIDE2_NODES );
4908 return SMESH::SMESH_MeshEditor::SEW_OK;
4911 //=======================================================================
4912 //function : SewFreeBorders
4914 //=======================================================================
4916 SMESH::SMESH_MeshEditor::Sew_Error
4917 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4918 CORBA::Long SecondNodeID1,
4919 CORBA::Long LastNodeID1,
4920 CORBA::Long FirstNodeID2,
4921 CORBA::Long SecondNodeID2,
4922 CORBA::Long LastNodeID2,
4923 CORBA::Boolean CreatePolygons,
4924 CORBA::Boolean CreatePolyedrs)
4928 SMESHDS_Mesh* aMesh = GetMeshDS();
4930 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4931 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4932 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4933 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4934 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4935 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4937 if (!aBorderFirstNode ||
4938 !aBorderSecondNode||
4940 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4941 if (!aSide2FirstNode ||
4942 !aSide2SecondNode ||
4944 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4946 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4947 << FirstNodeID1 << ", "
4948 << SecondNodeID1 << ", "
4949 << LastNodeID1 << ", "
4950 << FirstNodeID2 << ", "
4951 << SecondNodeID2 << ", "
4952 << LastNodeID2 << ", "
4953 << CreatePolygons<< ", "
4954 << CreatePolyedrs<< " )";
4956 SMESH::SMESH_MeshEditor::Sew_Error error =
4957 convError( myEditor.SewFreeBorder (aBorderFirstNode,
4967 storeResult(myEditor);
4969 myMesh->GetMeshDS()->Modified();
4970 myMesh->SetIsModified( true );
4976 //=======================================================================
4977 //function : SewConformFreeBorders
4979 //=======================================================================
4981 SMESH::SMESH_MeshEditor::Sew_Error
4982 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4983 CORBA::Long SecondNodeID1,
4984 CORBA::Long LastNodeID1,
4985 CORBA::Long FirstNodeID2,
4986 CORBA::Long SecondNodeID2)
4990 SMESHDS_Mesh* aMesh = GetMeshDS();
4992 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4993 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4994 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4995 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4996 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4997 const SMDS_MeshNode* aSide2ThirdNode = 0;
4999 if (!aBorderFirstNode ||
5000 !aBorderSecondNode||
5002 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5003 if (!aSide2FirstNode ||
5005 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5007 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5008 << FirstNodeID1 << ", "
5009 << SecondNodeID1 << ", "
5010 << LastNodeID1 << ", "
5011 << FirstNodeID2 << ", "
5012 << SecondNodeID2 << " )";
5014 SMESH::SMESH_MeshEditor::Sew_Error error =
5015 convError( myEditor.SewFreeBorder (aBorderFirstNode,
5024 storeResult(myEditor);
5026 myMesh->GetMeshDS()->Modified();
5027 myMesh->SetIsModified( true );
5033 //=======================================================================
5034 //function : SewBorderToSide
5036 //=======================================================================
5038 SMESH::SMESH_MeshEditor::Sew_Error
5039 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5040 CORBA::Long SecondNodeIDOnFreeBorder,
5041 CORBA::Long LastNodeIDOnFreeBorder,
5042 CORBA::Long FirstNodeIDOnSide,
5043 CORBA::Long LastNodeIDOnSide,
5044 CORBA::Boolean CreatePolygons,
5045 CORBA::Boolean CreatePolyedrs)
5049 SMESHDS_Mesh* aMesh = GetMeshDS();
5051 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5052 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5053 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5054 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5055 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5056 const SMDS_MeshNode* aSide2ThirdNode = 0;
5058 if (!aBorderFirstNode ||
5059 !aBorderSecondNode||
5061 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5062 if (!aSide2FirstNode ||
5064 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5066 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5067 << FirstNodeIDOnFreeBorder << ", "
5068 << SecondNodeIDOnFreeBorder << ", "
5069 << LastNodeIDOnFreeBorder << ", "
5070 << FirstNodeIDOnSide << ", "
5071 << LastNodeIDOnSide << ", "
5072 << CreatePolygons << ", "
5073 << CreatePolyedrs << ") ";
5075 SMESH::SMESH_MeshEditor::Sew_Error error =
5076 convError( myEditor.SewFreeBorder (aBorderFirstNode,
5086 storeResult(myEditor);
5088 myMesh->GetMeshDS()->Modified();
5089 myMesh->SetIsModified( true );
5095 //=======================================================================
5096 //function : SewSideElements
5098 //=======================================================================
5100 SMESH::SMESH_MeshEditor::Sew_Error
5101 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5102 const SMESH::long_array& IDsOfSide2Elements,
5103 CORBA::Long NodeID1OfSide1ToMerge,
5104 CORBA::Long NodeID1OfSide2ToMerge,
5105 CORBA::Long NodeID2OfSide1ToMerge,
5106 CORBA::Long NodeID2OfSide2ToMerge)
5110 SMESHDS_Mesh* aMesh = GetMeshDS();
5112 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5113 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5114 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5115 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5117 if (!aFirstNode1ToMerge ||
5118 !aFirstNode2ToMerge )
5119 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5120 if (!aSecondNode1ToMerge||
5121 !aSecondNode2ToMerge)
5122 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5124 TIDSortedElemSet aSide1Elems, aSide2Elems;
5125 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5126 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5128 TPythonDump() << "error = " << this << ".SewSideElements( "
5129 << IDsOfSide1Elements << ", "
5130 << IDsOfSide2Elements << ", "
5131 << NodeID1OfSide1ToMerge << ", "
5132 << NodeID1OfSide2ToMerge << ", "
5133 << NodeID2OfSide1ToMerge << ", "
5134 << NodeID2OfSide2ToMerge << ")";
5136 SMESH::SMESH_MeshEditor::Sew_Error error =
5137 convError( myEditor.SewSideElements (aSide1Elems, aSide2Elems,
5140 aSecondNode1ToMerge,
5141 aSecondNode2ToMerge));
5143 storeResult(myEditor);
5145 myMesh->GetMeshDS()->Modified();
5146 myMesh->SetIsModified( true );
5151 //================================================================================
5153 * \brief Set new nodes for given element
5154 * \param ide - element id
5155 * \param newIDs - new node ids
5156 * \retval CORBA::Boolean - true if result is OK
5158 //================================================================================
5160 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5161 const SMESH::long_array& newIDs)
5165 const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
5166 if(!elem) return false;
5168 int nbn = newIDs.length();
5170 vector<const SMDS_MeshNode*> aNodes(nbn);
5173 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
5176 aNodes[nbn1] = aNode;
5179 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5180 << ide << ", " << newIDs << " )";
5182 MESSAGE("ChangeElementNodes");
5183 bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5185 myMesh->GetMeshDS()->Modified();
5187 myMesh->SetIsModified( true );
5192 //=======================================================================
5193 //function : ConvertToQuadratic
5195 //=======================================================================
5197 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5199 myEditor.ConvertToQuadratic(theForce3d);
5200 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
5201 myMesh->GetMeshDS()->Modified();
5202 myMesh->SetIsModified( true );
5205 //=======================================================================
5206 //function : ConvertFromQuadratic
5208 //=======================================================================
5210 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5212 CORBA::Boolean isDone = myEditor.ConvertFromQuadratic();
5213 TPythonDump() << this << ".ConvertFromQuadratic()";
5214 myMesh->GetMeshDS()->Modified();
5216 myMesh->SetIsModified( true );
5219 //================================================================================
5221 * \brief Makes a part of the mesh quadratic
5223 //================================================================================
5225 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5226 SMESH::SMESH_IDSource_ptr theObject)
5227 throw (SALOME::SALOME_Exception)
5229 Unexpect aCatch(SALOME_SalomeException);
5231 TIDSortedElemSet elems;
5232 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5234 if ( elems.empty() )
5236 ConvertToQuadratic( theForce3d );
5238 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5240 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5244 myEditor.ConvertToQuadratic(theForce3d, elems);
5247 myMesh->GetMeshDS()->Modified();
5248 myMesh->SetIsModified( true );
5250 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
5253 //================================================================================
5255 * \brief Makes a part of the mesh linear
5257 //================================================================================
5259 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5260 throw (SALOME::SALOME_Exception)
5262 Unexpect aCatch(SALOME_SalomeException);
5264 TIDSortedElemSet elems;
5265 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5267 if ( elems.empty() )
5269 ConvertFromQuadratic();
5271 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5273 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5277 myEditor.ConvertFromQuadratic(elems);
5280 myMesh->GetMeshDS()->Modified();
5281 myMesh->SetIsModified( true );
5283 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5286 //=======================================================================
5287 //function : makeMesh
5288 //purpose : create a named imported mesh
5289 //=======================================================================
5291 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5293 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5294 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5295 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5296 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
5297 gen->SetName( meshSO, theMeshName, "Mesh" );
5298 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5300 return mesh._retn();
5303 //=======================================================================
5304 //function : DumpGroupsList
5306 //=======================================================================
5307 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
5308 const SMESH::ListOfGroups * theGroupList)
5310 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
5311 if(isDumpGroupList) {
5312 theDumpPython << theGroupList << " = ";
5316 //================================================================================
5318 \brief Generates the unique group name.
5319 \param thePrefix name prefix
5322 //================================================================================
5323 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5325 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5326 set<string> groupNames;
5328 // Get existing group names
5329 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5330 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5331 if (CORBA::is_nil(aGroup))
5334 CORBA::String_var name = aGroup->GetName();
5335 groupNames.insert( name.in() );
5339 string name = thePrefix;
5342 while (!groupNames.insert(name).second)
5343 name = SMESH_Comment( thePrefix ) << "_" << index;
5348 //================================================================================
5350 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5351 \param theNodes - identifiers of nodes to be doubled
5352 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5353 nodes. If list of element identifiers is empty then nodes are doubled but
5354 they not assigned to elements
5355 \return TRUE if operation has been completed successfully, FALSE otherwise
5356 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5358 //================================================================================
5360 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5361 const SMESH::long_array& theModifiedElems )
5365 list< int > aListOfNodes;
5367 for ( i = 0, n = theNodes.length(); i < n; i++ )
5368 aListOfNodes.push_back( theNodes[ i ] );
5370 list< int > aListOfElems;
5371 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5372 aListOfElems.push_back( theModifiedElems[ i ] );
5374 bool aResult = myEditor.DoubleNodes( aListOfNodes, aListOfElems );
5376 myMesh->GetMeshDS()->Modified();
5377 storeResult( myEditor) ;
5379 myMesh->SetIsModified( true );
5381 // Update Python script
5382 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5387 //================================================================================
5389 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5390 This method provided for convenience works as DoubleNodes() described above.
5391 \param theNodeId - identifier of node to be doubled.
5392 \param theModifiedElems - identifiers of elements to be updated.
5393 \return TRUE if operation has been completed successfully, FALSE otherwise
5394 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5396 //================================================================================
5398 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5399 const SMESH::long_array& theModifiedElems )
5401 SMESH::long_array_var aNodes = new SMESH::long_array;
5402 aNodes->length( 1 );
5403 aNodes[ 0 ] = theNodeId;
5405 TPythonDump pyDump; // suppress dump by the next line
5407 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5409 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5414 //================================================================================
5416 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5417 This method provided for convenience works as DoubleNodes() described above.
5418 \param theNodes - group of nodes to be doubled.
5419 \param theModifiedElems - group of elements to be updated.
5420 \return TRUE if operation has been completed successfully, FALSE otherwise
5421 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5423 //================================================================================
5425 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5426 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5428 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5431 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5432 SMESH::long_array_var aModifiedElems;
5433 if ( !CORBA::is_nil( theModifiedElems ) )
5434 aModifiedElems = theModifiedElems->GetListOfID();
5437 aModifiedElems = new SMESH::long_array;
5438 aModifiedElems->length( 0 );
5441 TPythonDump pyDump; // suppress dump by the next line
5443 bool done = DoubleNodes( aNodes, aModifiedElems );
5445 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5451 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5452 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5453 * \param theNodes - group of nodes to be doubled.
5454 * \param theModifiedElems - group of elements to be updated.
5455 * \return a new group with newly created nodes
5456 * \sa DoubleNodeGroup()
5458 SMESH::SMESH_Group_ptr
5459 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5460 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5462 SMESH::SMESH_Group_var aNewGroup;
5464 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5465 return aNewGroup._retn();
5468 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5469 SMESH::long_array_var aModifiedElems;
5470 if ( !CORBA::is_nil( theModifiedElems ) )
5471 aModifiedElems = theModifiedElems->GetListOfID();
5473 aModifiedElems = new SMESH::long_array;
5474 aModifiedElems->length( 0 );
5477 TPythonDump pyDump; // suppress dump by the next line
5479 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5482 // Create group with newly created nodes
5483 SMESH::long_array_var anIds = GetLastCreatedNodes();
5484 if (anIds->length() > 0) {
5485 string anUnindexedName (theNodes->GetName());
5486 string aNewName = generateGroupName(anUnindexedName + "_double");
5487 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5488 aNewGroup->Add(anIds);
5489 pyDump << aNewGroup << " = ";
5493 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5494 << theModifiedElems << " )";
5496 return aNewGroup._retn();
5499 //================================================================================
5501 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5502 This method provided for convenience works as DoubleNodes() described above.
5503 \param theNodes - list of groups of nodes to be doubled
5504 \param theModifiedElems - list of groups of elements to be updated.
5505 \return TRUE if operation has been completed successfully, FALSE otherwise
5506 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5508 //================================================================================
5510 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5511 const SMESH::ListOfGroups& theModifiedElems )
5516 std::list< int > aNodes;
5518 for ( i = 0, n = theNodes.length(); i < n; i++ )
5520 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5521 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5523 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5524 for ( j = 0, m = aCurr->length(); j < m; j++ )
5525 aNodes.push_back( aCurr[ j ] );
5529 std::list< int > anElems;
5530 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5532 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5533 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5535 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5536 for ( j = 0, m = aCurr->length(); j < m; j++ )
5537 anElems.push_back( aCurr[ j ] );
5541 bool aResult = myEditor.DoubleNodes( aNodes, anElems );
5543 storeResult( myEditor) ;
5545 myMesh->GetMeshDS()->Modified();
5547 myMesh->SetIsModified( true );
5550 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5555 //================================================================================
5557 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5558 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5559 * \param theNodes - group of nodes to be doubled.
5560 * \param theModifiedElems - group of elements to be updated.
5561 * \return a new group with newly created nodes
5562 * \sa DoubleNodeGroups()
5564 //================================================================================
5566 SMESH::SMESH_Group_ptr
5567 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5568 const SMESH::ListOfGroups& theModifiedElems )
5570 SMESH::SMESH_Group_var aNewGroup;
5572 TPythonDump pyDump; // suppress dump by the next line
5574 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5578 // Create group with newly created nodes
5579 SMESH::long_array_var anIds = GetLastCreatedNodes();
5580 if (anIds->length() > 0) {
5581 string anUnindexedName (theNodes[0]->GetName());
5582 string aNewName = generateGroupName(anUnindexedName + "_double");
5583 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5584 aNewGroup->Add(anIds);
5585 pyDump << aNewGroup << " = ";
5589 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5590 << theModifiedElems << " )";
5592 return aNewGroup._retn();
5596 //================================================================================
5598 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5599 \param theElems - the list of elements (edges or faces) to be replicated
5600 The nodes for duplication could be found from these elements
5601 \param theNodesNot - list of nodes to NOT replicate
5602 \param theAffectedElems - the list of elements (cells and edges) to which the
5603 replicated nodes should be associated to.
5604 \return TRUE if operation has been completed successfully, FALSE otherwise
5605 \sa DoubleNodeGroup(), DoubleNodeGroups()
5607 //================================================================================
5609 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5610 const SMESH::long_array& theNodesNot,
5611 const SMESH::long_array& theAffectedElems )
5617 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5618 TIDSortedElemSet anElems, aNodes, anAffected;
5619 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5620 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5621 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5623 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5625 storeResult( myEditor) ;
5627 myMesh->GetMeshDS()->Modified();
5629 myMesh->SetIsModified( true );
5631 // Update Python script
5632 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5633 << theNodesNot << ", " << theAffectedElems << " )";
5637 //================================================================================
5639 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5640 \param theElems - the list of elements (edges or faces) to be replicated
5641 The nodes for duplication could be found from these elements
5642 \param theNodesNot - list of nodes to NOT replicate
5643 \param theShape - shape to detect affected elements (element which geometric center
5644 located on or inside shape).
5645 The replicated nodes should be associated to affected elements.
5646 \return TRUE if operation has been completed successfully, FALSE otherwise
5647 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5649 //================================================================================
5651 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5652 const SMESH::long_array& theNodesNot,
5653 GEOM::GEOM_Object_ptr theShape )
5659 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5660 TIDSortedElemSet anElems, aNodes;
5661 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5662 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5664 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5665 bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5667 storeResult( myEditor) ;
5669 myMesh->GetMeshDS()->Modified();
5671 myMesh->SetIsModified( true );
5673 // Update Python script
5674 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5675 << theNodesNot << ", " << theShape << " )";
5679 //================================================================================
5681 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5682 \param theElems - group of of elements (edges or faces) to be replicated
5683 \param theNodesNot - group of nodes not to replicated
5684 \param theAffectedElems - group of elements to which the replicated nodes
5685 should be associated to.
5686 \return TRUE if operation has been completed successfully, FALSE otherwise
5687 \sa DoubleNodes(), DoubleNodeGroups()
5689 //================================================================================
5691 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5692 SMESH::SMESH_GroupBase_ptr theNodesNot,
5693 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5695 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5701 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5702 TIDSortedElemSet anElems, aNodes, anAffected;
5703 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5704 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5705 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5707 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5709 storeResult( myEditor) ;
5711 myMesh->GetMeshDS()->Modified();
5713 myMesh->SetIsModified( true );
5715 // Update Python script
5716 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5717 << theNodesNot << ", " << theAffectedElems << " )";
5722 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5723 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5724 * \param theElems - group of of elements (edges or faces) to be replicated
5725 * \param theNodesNot - group of nodes not to replicated
5726 * \param theAffectedElems - group of elements to which the replicated nodes
5727 * should be associated to.
5728 * \return a new group with newly created elements
5729 * \sa DoubleNodeElemGroup()
5731 SMESH::SMESH_Group_ptr
5732 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5733 SMESH::SMESH_GroupBase_ptr theNodesNot,
5734 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5737 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5741 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5742 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5744 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5746 << theNodesNot << ", "
5747 << theAffectedElems << " )";
5749 return elemGroup._retn();
5752 SMESH::ListOfGroups*
5753 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5754 SMESH::SMESH_GroupBase_ptr theNodesNot,
5755 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5756 CORBA::Boolean theElemGroupNeeded,
5757 CORBA::Boolean theNodeGroupNeeded)
5759 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5760 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5761 aTwoGroups->length( 2 );
5763 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5764 return aTwoGroups._retn();
5769 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5770 TIDSortedElemSet anElems, aNodes, anAffected;
5771 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5772 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5773 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5776 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5778 storeResult( myEditor) ;
5779 myMesh->GetMeshDS()->Modified();
5785 myMesh->SetIsModified( true );
5787 // Create group with newly created elements
5788 CORBA::String_var elemGroupName = theElems->GetName();
5789 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5790 if ( !myEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5792 SMESH::long_array_var anIds = GetLastCreatedElems();
5793 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5794 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5795 aNewElemGroup->Add(anIds);
5797 if ( !myEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5799 SMESH::long_array_var anIds = GetLastCreatedNodes();
5800 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5801 aNewNodeGroup->Add(anIds);
5805 // Update Python script
5808 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5809 else pyDump << aNewElemGroup << ", ";
5810 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5811 else pyDump << aNewNodeGroup << " ] = ";
5813 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5814 << theNodesNot << ", "
5815 << theAffectedElems << ", "
5816 << theElemGroupNeeded << ", "
5817 << theNodeGroupNeeded <<" )";
5819 aTwoGroups[0] = aNewElemGroup._retn();
5820 aTwoGroups[1] = aNewNodeGroup._retn();
5821 return aTwoGroups._retn();
5824 //================================================================================
5826 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5827 \param theElems - group of of elements (edges or faces) to be replicated
5828 \param theNodesNot - group of nodes not to replicated
5829 \param theShape - shape to detect affected elements (element which geometric center
5830 located on or inside shape).
5831 The replicated nodes should be associated to affected elements.
5832 \return TRUE if operation has been completed successfully, FALSE otherwise
5833 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5835 //================================================================================
5837 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5838 SMESH::SMESH_GroupBase_ptr theNodesNot,
5839 GEOM::GEOM_Object_ptr theShape )
5842 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5848 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5849 TIDSortedElemSet anElems, aNodes, anAffected;
5850 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5851 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5853 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5854 bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5856 storeResult( myEditor) ;
5858 myMesh->GetMeshDS()->Modified();
5860 myMesh->SetIsModified( true );
5862 // Update Python script
5863 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5864 << theNodesNot << ", " << theShape << " )";
5868 //================================================================================
5870 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5871 This method provided for convenience works as DoubleNodes() described above.
5872 \param theElems - list of groups of elements (edges or faces) to be replicated
5873 \param theNodesNot - list of groups of nodes not to replicated
5874 \param theAffectedElems - group of elements to which the replicated nodes
5875 should be associated to.
5876 \return TRUE if operation has been completed successfully, FALSE otherwise
5877 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5879 //================================================================================
5881 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5882 SMESHDS_Mesh* theMeshDS,
5883 TIDSortedElemSet& theElemSet,
5884 const bool theIsNodeGrp)
5886 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5888 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5889 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5890 : aGrp->GetType() != SMESH::NODE ) )
5892 SMESH::long_array_var anIDs = aGrp->GetIDs();
5893 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5898 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5899 const SMESH::ListOfGroups& theNodesNot,
5900 const SMESH::ListOfGroups& theAffectedElems)
5905 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5906 TIDSortedElemSet anElems, aNodes, anAffected;
5907 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5908 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5909 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5911 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5913 storeResult( myEditor) ;
5915 myMesh->GetMeshDS()->Modified();
5917 myMesh->SetIsModified( true );
5919 // Update Python script
5920 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5921 << &theNodesNot << ", " << &theAffectedElems << " )";
5925 //================================================================================
5927 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5928 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5929 \param theElems - list of groups of elements (edges or faces) to be replicated
5930 \param theNodesNot - list of groups of nodes not to replicated
5931 \param theAffectedElems - group of elements to which the replicated nodes
5932 should be associated to.
5933 * \return a new group with newly created elements
5934 * \sa DoubleNodeElemGroups()
5936 //================================================================================
5938 SMESH::SMESH_Group_ptr
5939 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5940 const SMESH::ListOfGroups& theNodesNot,
5941 const SMESH::ListOfGroups& theAffectedElems)
5944 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
5948 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5949 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5951 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
5953 << theNodesNot << ", "
5954 << theAffectedElems << " )";
5956 return elemGroup._retn();
5959 SMESH::ListOfGroups*
5960 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
5961 const SMESH::ListOfGroups& theNodesNot,
5962 const SMESH::ListOfGroups& theAffectedElems,
5963 CORBA::Boolean theElemGroupNeeded,
5964 CORBA::Boolean theNodeGroupNeeded)
5966 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5967 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5968 aTwoGroups->length( 2 );
5973 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5974 TIDSortedElemSet anElems, aNodes, anAffected;
5975 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5976 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5977 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5979 bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
5981 storeResult( myEditor) ;
5983 myMesh->GetMeshDS()->Modified();
5987 myMesh->SetIsModified( true );
5989 // Create group with newly created elements
5990 CORBA::String_var elemGroupName = theElems[0]->GetName();
5991 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5992 if ( !myEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5994 SMESH::long_array_var anIds = GetLastCreatedElems();
5995 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5996 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5997 aNewElemGroup->Add(anIds);
5999 if ( !myEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6001 SMESH::long_array_var anIds = GetLastCreatedNodes();
6002 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6003 aNewNodeGroup->Add(anIds);
6007 // Update Python script
6010 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6011 else pyDump << aNewElemGroup << ", ";
6012 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6013 else pyDump << aNewNodeGroup << " ] = ";
6015 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6016 << &theNodesNot << ", "
6017 << &theAffectedElems << ", "
6018 << theElemGroupNeeded << ", "
6019 << theNodeGroupNeeded << " )";
6021 aTwoGroups[0] = aNewElemGroup._retn();
6022 aTwoGroups[1] = aNewNodeGroup._retn();
6023 return aTwoGroups._retn();
6026 //================================================================================
6028 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6029 This method provided for convenience works as DoubleNodes() described above.
6030 \param theElems - list of groups of elements (edges or faces) to be replicated
6031 \param theNodesNot - list of groups of nodes not to replicated
6032 \param theShape - shape to detect affected elements (element which geometric center
6033 located on or inside shape).
6034 The replicated nodes should be associated to affected elements.
6035 \return TRUE if operation has been completed successfully, FALSE otherwise
6036 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6038 //================================================================================
6041 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6042 const SMESH::ListOfGroups& theNodesNot,
6043 GEOM::GEOM_Object_ptr theShape )
6048 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6049 TIDSortedElemSet anElems, aNodes;
6050 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6051 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6053 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6054 bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
6056 storeResult( myEditor) ;
6058 myMesh->GetMeshDS()->Modified();
6060 myMesh->SetIsModified( true );
6062 // Update Python script
6063 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6064 << &theNodesNot << ", " << theShape << " )";
6068 //================================================================================
6070 \brief Identify the elements that will be affected by node duplication (actual duplication is not performed.
6071 This method is the first step of DoubleNodeElemGroupsInRegion.
6072 \param theElems - list of groups of elements (edges or faces) to be replicated
6073 \param theNodesNot - list of groups of nodes not to replicated
6074 \param theShape - shape to detect affected elements (element which geometric center
6075 located on or inside shape).
6076 The replicated nodes should be associated to affected elements.
6077 \return groups of affected elements
6078 \sa DoubleNodeElemGroupsInRegion()
6080 //================================================================================
6081 SMESH::ListOfGroups*
6082 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6083 const SMESH::ListOfGroups& theNodesNot,
6084 GEOM::GEOM_Object_ptr theShape )
6086 MESSAGE("AffectedElemGroupsInRegion");
6087 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6088 bool isEdgeGroup = false;
6089 bool isFaceGroup = false;
6090 bool isVolumeGroup = false;
6091 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6092 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6093 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6097 ::SMESH_MeshEditor aMeshEditor(myMesh);
6099 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6100 TIDSortedElemSet anElems, aNodes;
6101 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6102 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6104 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6105 TIDSortedElemSet anAffected;
6106 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6108 storeResult(aMeshEditor);
6110 myMesh->GetMeshDS()->Modified();
6114 myMesh->SetIsModified(true);
6116 int lg = anAffected.size();
6117 MESSAGE("lg="<< lg);
6118 SMESH::long_array_var volumeIds = new SMESH::long_array;
6119 volumeIds->length(lg);
6120 SMESH::long_array_var faceIds = new SMESH::long_array;
6121 faceIds->length(lg);
6122 SMESH::long_array_var edgeIds = new SMESH::long_array;
6123 edgeIds->length(lg);
6128 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6129 for (; eIt != anAffected.end(); ++eIt)
6131 const SMDS_MeshElement* anElem = *eIt;
6134 int elemId = anElem->GetID();
6135 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6136 volumeIds[ivol++] = elemId;
6137 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6138 faceIds[iface++] = elemId;
6139 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6140 edgeIds[iedge++] = elemId;
6142 volumeIds->length(ivol);
6143 faceIds->length(iface);
6144 edgeIds->length(iedge);
6146 aNewVolumeGroup->Add(volumeIds);
6147 aNewFaceGroup->Add(faceIds);
6148 aNewEdgeGroup->Add(edgeIds);
6149 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6150 isFaceGroup = (aNewFaceGroup->Size() > 0);
6151 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6161 aListOfGroups->length(nbGroups);
6165 aListOfGroups[i++] = aNewEdgeGroup._retn();
6167 aListOfGroups[i++] = aNewFaceGroup._retn();
6169 aListOfGroups[i++] = aNewVolumeGroup._retn();
6171 // Update Python script
6175 pyDump << aNewEdgeGroup << ", ";
6177 pyDump << aNewFaceGroup << ", ";
6179 pyDump << aNewVolumeGroup << ", ";
6181 pyDump << this << ".AffectedElemGroupsInRegion( " << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6183 return aListOfGroups._retn();
6186 //================================================================================
6188 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6189 The created 2D mesh elements based on nodes of free faces of boundary volumes
6190 \return TRUE if operation has been completed successfully, FALSE otherwise
6192 //================================================================================
6194 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6198 bool aResult = myEditor.Make2DMeshFrom3D();
6199 storeResult( myEditor) ;
6200 myMesh->GetMeshDS()->Modified();
6201 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6205 //================================================================================
6207 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6208 * The list of groups must describe a partition of the mesh volumes.
6209 * The nodes of the internal faces at the boundaries of the groups are doubled.
6210 * In option, the internal faces are replaced by flat elements.
6211 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6212 * The flat elements are stored in groups of volumes.
6213 * @param theDomains - list of groups of volumes
6214 * @param createJointElems - if TRUE, create the elements
6215 * @return TRUE if operation has been completed successfully, FALSE otherwise
6217 //================================================================================
6219 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6220 CORBA::Boolean createJointElems )
6221 throw (SALOME::SALOME_Exception)
6226 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6228 vector<TIDSortedElemSet> domains;
6231 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6233 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6234 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6236 // if ( aGrp->GetType() != SMESH::VOLUME )
6237 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6238 TIDSortedElemSet domain;
6240 domains.push_back(domain);
6241 SMESH::long_array_var anIDs = aGrp->GetIDs();
6242 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6246 bool aResult = myEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
6247 // TODO publish the groups of flat elements in study
6249 storeResult( myEditor) ;
6250 myMesh->GetMeshDS()->Modified();
6252 // Update Python script
6253 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6254 << ", " << createJointElems << " )";
6258 //================================================================================
6260 * \brief Double nodes on some external faces and create flat elements.
6261 * Flat elements are mainly used by some types of mechanic calculations.
6263 * Each group of the list must be constituted of faces.
6264 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6265 * @param theGroupsOfFaces - list of groups of faces
6266 * @return TRUE if operation has been completed successfully, FALSE otherwise
6268 //================================================================================
6270 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6275 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6277 vector<TIDSortedElemSet> faceGroups;
6280 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6282 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6283 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6285 TIDSortedElemSet faceGroup;
6287 faceGroups.push_back(faceGroup);
6288 SMESH::long_array_var anIDs = aGrp->GetIDs();
6289 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6293 bool aResult = myEditor.CreateFlatElementsOnFacesGroups( faceGroups );
6294 // TODO publish the groups of flat elements in study
6296 storeResult( myEditor) ;
6297 myMesh->GetMeshDS()->Modified();
6299 // Update Python script
6300 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6305 * \brief identify all the elements around a geom shape, get the faces delimiting the hole
6306 * Build groups of volume to remove, groups of faces to replace on the skin of the object,
6307 * groups of faces to remove inside the object, (idem edges).
6308 * Build ordered list of nodes at the border of each group of faces to replace (to be used to build a geom subshape)
6310 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6311 GEOM::GEOM_Object_ptr theShape,
6312 const char* groupName,
6313 const SMESH::double_array& theNodesCoords,
6314 SMESH::array_of_long_array_out GroupsOfNodes)
6315 throw (SALOME::SALOME_Exception)
6318 std::vector<std::vector<int> > aListOfListOfNodes;
6319 ::SMESH_MeshEditor aMeshEditor( myMesh );
6321 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6322 if ( !theNodeSearcher )
6323 theNodeSearcher = aMeshEditor.GetNodeSearcher();
6325 vector<double> nodesCoords;
6326 for (int i = 0; i < theNodesCoords.length(); i++)
6328 nodesCoords.push_back( theNodesCoords[i] );
6331 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6332 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName, nodesCoords, aListOfListOfNodes);
6334 GroupsOfNodes = new SMESH::array_of_long_array;
6335 GroupsOfNodes->length( aListOfListOfNodes.size() );
6336 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6337 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6339 vector<int>& aListOfNodes = *llIt;
6340 vector<int>::iterator lIt = aListOfNodes.begin();;
6341 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6342 aGroup.length( aListOfNodes.size() );
6343 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6344 aGroup[ j ] = (*lIt);
6346 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6347 << radius << ", " << theShape << ", " << ", " << groupName << ", " << theNodesCoords << " )";
6351 // issue 20749 ===================================================================
6353 * \brief Creates missing boundary elements
6354 * \param elements - elements whose boundary is to be checked
6355 * \param dimension - defines type of boundary elements to create
6356 * \param groupName - a name of group to store created boundary elements in,
6357 * "" means not to create the group
6358 * \param meshName - a name of new mesh to store created boundary elements in,
6359 * "" means not to create the new mesh
6360 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6361 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6362 * boundary elements will be copied into the new mesh
6363 * \param group - returns the create group, if any
6364 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6366 // ================================================================================
6368 SMESH::SMESH_Mesh_ptr
6369 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6370 SMESH::Bnd_Dimension dim,
6371 const char* groupName,
6372 const char* meshName,
6373 CORBA::Boolean toCopyElements,
6374 CORBA::Boolean toCopyExistingBondary,
6375 SMESH::SMESH_Group_out group)
6379 if ( dim > SMESH::BND_1DFROM2D )
6380 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6382 SMESHDS_Mesh* aMeshDS = GetMeshDS();
6384 SMESH::SMESH_Mesh_var mesh_var;
6385 SMESH::SMESH_Group_var group_var;
6389 TIDSortedElemSet elements;
6390 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6391 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6395 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6396 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6398 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6400 // group of new boundary elements
6401 SMESH_Group* smesh_group = 0;
6402 if ( strlen(groupName) )
6404 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6405 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6406 smesh_group = group_i->GetSmeshGroup();
6410 myEditor.MakeBoundaryMesh( elements,
6411 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6415 toCopyExistingBondary);
6416 storeResult( myEditor );
6419 smesh_mesh->GetMeshDS()->Modified();
6422 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6424 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6425 if ( mesh_var->_is_nil() )
6426 pyDump << myMesh_i->_this() << ", ";
6428 pyDump << mesh_var << ", ";
6429 if ( group_var->_is_nil() )
6430 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6432 pyDump << group_var << " = ";
6433 pyDump << this << ".MakeBoundaryMesh( "
6435 << "SMESH." << dimName[int(dim)] << ", "
6436 << "'" << groupName << "', "
6437 << "'" << meshName<< "', "
6438 << toCopyElements << ", "
6439 << toCopyExistingBondary << ")";
6441 group = group_var._retn();
6442 return mesh_var._retn();
6445 //================================================================================
6447 * \brief Creates missing boundary elements
6448 * \param dimension - defines type of boundary elements to create
6449 * \param groupName - a name of group to store all boundary elements in,
6450 * "" means not to create the group
6451 * \param meshName - a name of a new mesh, which is a copy of the initial
6452 * mesh + created boundary elements; "" means not to create the new mesh
6453 * \param toCopyAll - if true, the whole initial mesh will be copied into
6454 * the new mesh else only boundary elements will be copied into the new mesh
6455 * \param groups - optional groups of elements to make boundary around
6456 * \param mesh - returns the mesh where elements were added to
6457 * \param group - returns the created group, if any
6458 * \retval long - number of added boundary elements
6460 //================================================================================
6462 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6463 const char* groupName,
6464 const char* meshName,
6465 CORBA::Boolean toCopyAll,
6466 const SMESH::ListOfIDSources& groups,
6467 SMESH::SMESH_Mesh_out mesh,
6468 SMESH::SMESH_Group_out group)
6469 throw (SALOME::SALOME_Exception)
6471 Unexpect aCatch(SALOME_SalomeException);
6475 if ( dim > SMESH::BND_1DFROM2D )
6476 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6478 // separate groups belonging to this and other mesh
6479 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6480 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6481 groupsOfThisMesh->length( groups.length() );
6482 groupsOfOtherMesh->length( groups.length() );
6483 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6484 for ( int i = 0; i < groups.length(); ++i )
6486 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6487 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6488 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6490 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6491 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6492 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6494 groupsOfThisMesh->length( nbGroups );
6495 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6500 if ( nbGroupsOfOtherMesh > 0 )
6502 // process groups belonging to another mesh
6503 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6504 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6505 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6506 groupsOfOtherMesh, mesh, group );
6509 SMESH::SMESH_Mesh_var mesh_var;
6510 SMESH::SMESH_Group_var group_var;
6513 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6514 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6518 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6520 /*toCopyGroups=*/false,
6521 /*toKeepIDs=*/true);
6523 mesh_var = makeMesh(meshName);
6525 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6526 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6529 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6530 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6532 // group of boundary elements
6533 SMESH_Group* smesh_group = 0;
6534 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6535 if ( strlen(groupName) )
6537 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6538 group_var = mesh_i->CreateGroup( groupType, groupName );
6539 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6540 smesh_group = group_i->GetSmeshGroup();
6543 TIDSortedElemSet elements;
6545 if ( groups.length() > 0 )
6547 for ( int i = 0; i < nbGroups; ++i )
6550 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6552 SMESH::Bnd_Dimension bdim =
6553 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6554 nbAdded += myEditor.MakeBoundaryMesh( elements,
6555 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6558 /*toCopyElements=*/false,
6559 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6560 /*toAddExistingBondary=*/true,
6561 /*aroundElements=*/true);
6562 storeResult( myEditor );
6568 nbAdded += myEditor.MakeBoundaryMesh( elements,
6569 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6572 /*toCopyElements=*/false,
6573 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6574 /*toAddExistingBondary=*/true);
6575 storeResult( myEditor );
6577 tgtMesh->GetMeshDS()->Modified();
6579 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6581 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6582 pyDump << "nbAdded, ";
6583 if ( mesh_var->_is_nil() )
6584 pyDump << myMesh_i->_this() << ", ";
6586 pyDump << mesh_var << ", ";
6587 if ( group_var->_is_nil() )
6588 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6590 pyDump << group_var << " = ";
6591 pyDump << this << ".MakeBoundaryElements( "
6592 << "SMESH." << dimName[int(dim)] << ", "
6593 << "'" << groupName << "', "
6594 << "'" << meshName<< "', "
6595 << toCopyAll << ", "
6598 mesh = mesh_var._retn();
6599 group = group_var._retn();