1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 #include "SMESH_MeshEditor_i.hxx"
32 #include "SMDS_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_LinearEdge.hxx"
37 #include "SMDS_Mesh0DElement.hxx"
38 #include "SMDS_MeshFace.hxx"
39 #include "SMDS_MeshVolume.hxx"
40 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
41 #include "SMDS_SetIterator.hxx"
42 #include "SMDS_VolumeTool.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_ControlsDef.hxx"
46 #include "SMESH_Filter_i.hxx"
47 #include "SMESH_Gen_i.hxx"
48 #include "SMESH_Group.hxx"
49 #include "SMESH_Group_i.hxx"
50 #include "SMESH_MeshPartDS.hxx"
51 #include "SMESH_MesherHelper.hxx"
52 #include "SMESH_PythonDump.hxx"
53 #include "SMESH_subMeshEventListener.hxx"
54 #include "SMESH_subMesh_i.hxx"
56 #include <utilities.h>
57 #include <Utils_ExceptHandlers.hxx>
58 #include <Utils_CorbaException.hxx>
59 #include <SALOMEDS_wrap.hxx>
61 #include <BRepAdaptor_Surface.hxx>
62 #include <BRep_Tool.hxx>
63 #include <TopExp_Explorer.hxx>
65 #include <TopoDS_Edge.hxx>
66 #include <TopoDS_Face.hxx>
71 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
75 #include <Standard_Failure.hxx>
78 #include <Standard_ErrorHandler.hxx>
84 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
86 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
89 using SMESH::TPythonDump;
92 namespace MeshEditor_I {
94 //=============================================================================
96 * \brief Mesh to apply modifications for preview purposes
98 //=============================================================================
100 struct TPreviewMesh: public SMESH_Mesh
102 SMDSAbs_ElementType myPreviewType; // type to show
104 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
105 _isShapeToMesh = (_id =_studyId = 0);
106 _myMeshDS = new SMESHDS_Mesh( _id, true );
107 myPreviewType = previewElements;
110 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
111 //!< Copy a set of elements
112 void Copy(const TIDSortedElemSet & theElements,
113 TIDSortedElemSet& theCopyElements,
114 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
115 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
117 // loop on theIDsOfElements
118 TIDSortedElemSet::const_iterator eIt = theElements.begin();
119 for ( ; eIt != theElements.end(); ++eIt )
121 const SMDS_MeshElement* anElem = *eIt;
122 if ( !anElem ) continue;
123 SMDSAbs_ElementType type = anElem->GetType();
124 if ( type == theAvoidType ||
125 ( theSelectType != SMDSAbs_All && type != theSelectType ))
127 const SMDS_MeshElement* anElemCopy;
128 if ( type == SMDSAbs_Node)
129 anElemCopy = Copy( cast2Node(anElem) );
131 anElemCopy = Copy( anElem );
133 theCopyElements.insert( theCopyElements.end(), anElemCopy );
137 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
139 // copy element nodes
140 int anElemNbNodes = anElem->NbNodes();
141 vector< int > anElemNodesID( anElemNbNodes ) ;
142 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
143 for ( int i = 0; itElemNodes->more(); i++)
145 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
147 anElemNodesID[i] = anElemNode->GetID();
150 // creates a corresponding element on copied nodes
151 SMDS_MeshElement* anElemCopy = 0;
152 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
154 const SMDS_VtkVolume* ph =
155 dynamic_cast<const SMDS_VtkVolume*> (anElem);
157 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
158 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
161 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
168 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
170 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
171 anElemNode->GetID());
173 };// struct TPreviewMesh
175 static SMESH_NodeSearcher * theNodeSearcher = 0;
176 static SMESH_ElementSearcher * theElementSearcher = 0;
178 //=============================================================================
180 * \brief Deleter of theNodeSearcher at any compute event occured
182 //=============================================================================
184 struct TSearchersDeleter : public SMESH_subMeshEventListener
187 string myMeshPartIOR;
189 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
190 "SMESH_MeshEditor_i::TSearchersDeleter"),
192 //!< Delete theNodeSearcher
195 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
196 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
198 typedef map < int, SMESH_subMesh * > TDependsOnMap;
199 //!< The meshod called by submesh: do my main job
200 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
201 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
203 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
205 Unset( sm->GetFather() );
208 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
209 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
211 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
218 myMeshPartIOR = meshPartIOR;
219 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
220 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
221 TDependsOnMap::const_iterator sm;
222 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
223 sm->second->SetEventListener( this, 0, sm->second );
227 //!< delete self from all submeshes
228 void Unset(SMESH_Mesh* mesh)
230 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
231 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
232 TDependsOnMap::const_iterator sm;
233 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
234 sm->second->DeleteEventListener( this );
239 } theSearchersDeleter;
241 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
243 TCollection_AsciiString typeStr;
244 switch ( theMirrorType ) {
245 case SMESH::SMESH_MeshEditor::POINT:
246 typeStr = "SMESH.SMESH_MeshEditor.POINT";
248 case SMESH::SMESH_MeshEditor::AXIS:
249 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
252 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
256 //================================================================================
258 * \brief function for conversion of long_array to TIDSortedElemSet
259 * \param IDs - array of IDs
260 * \param aMesh - mesh
261 * \param aMap - collection to fill
262 * \param aType - element type
264 //================================================================================
266 void arrayToSet(const SMESH::long_array & IDs,
267 const SMESHDS_Mesh* aMesh,
268 TIDSortedElemSet& aMap,
269 const SMDSAbs_ElementType aType = SMDSAbs_All )
271 for (int i=0; i<IDs.length(); i++) {
272 CORBA::Long ind = IDs[i];
273 const SMDS_MeshElement * elem =
274 (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
275 if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
276 aMap.insert( aMap.end(), elem );
279 //================================================================================
281 * \brief Retrieve elements of given type from SMESH_IDSource
283 //================================================================================
285 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
286 const SMESHDS_Mesh* theMeshDS,
287 TIDSortedElemSet& theElemSet,
288 const SMDSAbs_ElementType theType,
289 const bool emptyIfIsMesh=false)
292 if ( CORBA::is_nil( theIDSource ) )
294 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
297 SMESH::long_array_var anIDs = theIDSource->GetIDs();
298 if ( anIDs->length() == 0 )
300 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
301 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
303 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
304 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
310 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
311 return bool(anIDs->length()) == bool(theElemSet.size());
315 //================================================================================
317 * \brief Retrieve nodes from SMESH_IDSource
319 //================================================================================
321 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
322 const SMESHDS_Mesh* theMeshDS,
323 TIDSortedNodeSet& theNodeSet)
326 if ( CORBA::is_nil( theObject ) )
328 SMESH::array_of_ElementType_var types = theObject->GetTypes();
329 SMESH::long_array_var aElementsId = theObject->GetIDs();
330 if ( types->length() == 1 && types[0] == SMESH::NODE)
332 for(int i = 0; i < aElementsId->length(); i++)
333 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
334 theNodeSet.insert( theNodeSet.end(), n);
336 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
338 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
339 while ( nIt->more( ))
340 if( const SMDS_MeshElement * elem = nIt->next() )
341 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
345 for(int i = 0; i < aElementsId->length(); i++)
346 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
347 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
351 //================================================================================
353 * \brief Returns elements connected to the given elements
355 //================================================================================
357 void getElementsAround(const TIDSortedElemSet& theElements,
358 const SMESHDS_Mesh* theMeshDS,
359 TIDSortedElemSet& theElementsAround)
361 if ( theElements.empty() ) return;
363 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
364 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
366 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
367 return; // all the elements are in theElements
370 elemType = SMDSAbs_All;
372 TIDSortedElemSet visitedNodes;
373 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
374 for ( ; elemIt != theElements.end(); ++elemIt )
376 const SMDS_MeshElement* e = *elemIt;
377 int i = e->NbCornerNodes();
380 const SMDS_MeshNode* n = e->GetNode( i );
381 if ( visitedNodes.insert( n ).second )
383 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
384 while ( invIt->more() )
386 const SMDS_MeshElement* elemAround = invIt->next();
387 if ( !theElements.count( elemAround ))
388 theElementsAround.insert( elemAround );
395 //================================================================================
397 * \brief Return a string used to detect change of mesh part on which theElementSearcher
398 * is going to be used
400 //================================================================================
402 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
404 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
405 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
406 // take into account passible group modification
407 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
408 partIOR += SMESH_Comment( type );
412 } // namespace MeshEditor_I
414 using namespace MeshEditor_I;
416 //=============================================================================
420 //=============================================================================
422 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
424 myMesh( &theMesh->GetImpl() ),
426 myIsPreviewMode ( isPreview ),
432 //================================================================================
436 //================================================================================
438 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
440 deleteAuxIDSources();
441 delete myPreviewMesh; myPreviewMesh = 0;
442 delete myPreviewEditor; myPreviewEditor = 0;
445 //================================================================================
447 * \brief Clear members
449 //================================================================================
451 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
453 if ( myIsPreviewMode ) {
454 if ( myPreviewMesh ) myPreviewMesh->Clear();
457 if ( deleteSearchers )
458 TSearchersDeleter::Delete();
460 getEditor().GetError().reset();
461 getEditor().CrearLastCreated();
463 //================================================================================
465 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
466 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
468 //================================================================================
470 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
472 if ( myIsPreviewMode && !myPreviewEditor ) {
473 if ( !myPreviewMesh ) getPreviewMesh();
474 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
476 return myIsPreviewMode ? *myPreviewEditor : myEditor;
479 //================================================================================
481 * \brief Initialize and return myPreviewMesh
482 * \param previewElements - type of elements to show in preview
484 * WARNING: call it once par a method!
486 //================================================================================
488 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
490 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
492 delete myPreviewEditor;
494 delete myPreviewMesh;
495 myPreviewMesh = new TPreviewMesh( previewElements );
497 myPreviewMesh->Clear();
498 return myPreviewMesh;
501 //================================================================================
503 * \brief Now does nothing
505 //================================================================================
507 // void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& )
511 //================================================================================
513 * Return data of mesh edition preview
515 //================================================================================
517 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
519 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
521 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
523 list<int> aNodesConnectivity;
524 typedef map<int, int> TNodesMap;
527 SMESHDS_Mesh* aMeshDS;
528 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
530 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
531 aMeshDS = aMeshPartDS.get();
534 aMeshDS = getEditor().GetMeshDS();
536 myPreviewData = new SMESH::MeshPreviewStruct();
537 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
540 SMDSAbs_ElementType previewType = SMDSAbs_All;
542 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
543 previewType = aPreviewMesh->myPreviewType;
544 switch ( previewType ) {
545 case SMDSAbs_Edge : break;
546 case SMDSAbs_Face : break;
547 case SMDSAbs_Volume: break;
549 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
553 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
555 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
557 while ( itMeshElems->more() ) {
558 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
559 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
560 while ( itElemNodes->more() ) {
561 const SMDS_MeshNode* aMeshNode =
562 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
563 int aNodeID = aMeshNode->GetID();
564 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
565 if ( anIter == nodesMap.end() ) {
566 // filling the nodes coordinates
567 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
568 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
569 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
570 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
573 aNodesConnectivity.push_back(anIter->second);
576 // filling the elements types
577 SMDSAbs_ElementType aType = aMeshElem->GetType();
578 bool isPoly = aMeshElem->IsPoly();
580 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
581 myPreviewData->elementTypes[i].isPoly = isPoly;
582 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
586 myPreviewData->nodesXYZ.length( j );
588 // filling the elements connectivities
589 list<int>::iterator aConnIter = aNodesConnectivity.begin();
590 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
591 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
592 myPreviewData->elementConnectivities[i] = *aConnIter;
595 return myPreviewData._retn();
598 //================================================================================
600 * \brief Returns list of it's IDs of created nodes
601 * \retval SMESH::long_array* - list of node ID
603 //================================================================================
605 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
607 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
608 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
609 myLastCreatedNodes->length( aSeq.Length() );
610 for (int i = 1; i <= aSeq.Length(); i++)
611 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
612 return myLastCreatedNodes._retn();
615 //================================================================================
617 * \brief Returns list of it's IDs of created elements
618 * \retval SMESH::long_array* - list of elements' ID
620 //================================================================================
622 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
624 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
625 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
626 myLastCreatedElems->length( aSeq.Length() );
627 for ( int i = 1; i <= aSeq.Length(); i++ )
628 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
629 return myLastCreatedElems._retn();
632 //=======================================================================
634 * Returns description of an error/warning occured during the last operation
636 //=======================================================================
638 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
640 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
641 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
642 if ( errIn && !errIn->IsOK() )
644 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
645 errOut->comment = errIn->myComment.c_str();
646 errOut->subShapeID = -1;
647 errOut->hasBadMesh = !errIn->myBadElements.empty();
652 errOut->subShapeID = -1;
653 errOut->hasBadMesh = false;
655 return errOut._retn();
658 //=======================================================================
659 //function : MakeIDSource
660 //purpose : Wrap a sequence of ids in a SMESH_IDSource
661 //=======================================================================
663 struct SMESH_MeshEditor_i::_IDSource : public POA_SMESH::SMESH_IDSource
665 SMESH::long_array _ids;
666 SMESH::ElementType _type;
667 SMESH::SMESH_Mesh_ptr _mesh;
668 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
669 SMESH::long_array* GetMeshInfo() { return 0; }
670 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
671 bool IsMeshInfoCorrect() { return true; }
672 SMESH::array_of_ElementType* GetTypes()
674 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
675 if ( _ids.length() > 0 ) {
679 return types._retn();
683 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
684 SMESH::ElementType type)
686 if ( myAuxIDSources.size() > 10 )
687 deleteAuxIDSources();
689 _IDSource* idSrc = new _IDSource;
690 idSrc->_mesh = myMesh_i->_this();
693 myAuxIDSources.push_back( idSrc );
695 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
697 return anIDSourceVar._retn();
700 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
702 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
705 void SMESH_MeshEditor_i::deleteAuxIDSources()
707 std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
708 for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
710 myAuxIDSources.clear();
713 //=============================================================================
717 //=============================================================================
720 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
726 for (int i = 0; i < IDsOfElements.length(); i++)
727 IdList.push_back( IDsOfElements[i] );
729 // Update Python script
730 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
733 bool ret = getEditor().Remove( IdList, false );
734 myMesh->GetMeshDS()->Modified();
735 if ( IDsOfElements.length() )
736 myMesh->SetIsModified( true ); // issue 0020693
740 //=============================================================================
744 //=============================================================================
746 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
751 for (int i = 0; i < IDsOfNodes.length(); i++)
752 IdList.push_back( IDsOfNodes[i] );
754 // Update Python script
755 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
757 bool ret = getEditor().Remove( IdList, true );
758 myMesh->GetMeshDS()->Modified();
759 if ( IDsOfNodes.length() )
760 myMesh->SetIsModified( true ); // issue 0020693
764 //=============================================================================
768 //=============================================================================
770 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
775 // Update Python script
776 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
778 // Create filter to find all orphan nodes
779 SMESH::Controls::Filter::TIdSequence seq;
780 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
781 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
783 // remove orphan nodes (if there are any)
785 for ( int i = 0; i < seq.size(); i++ )
786 IdList.push_back( seq[i] );
788 int nbNodesBefore = myMesh->NbNodes();
789 getEditor().Remove( IdList, true );
790 myMesh->GetMeshDS()->Modified();
792 myMesh->SetIsModified( true );
793 int nbNodesAfter = myMesh->NbNodes();
795 return nbNodesBefore - nbNodesAfter;
798 //=============================================================================
802 //=============================================================================
804 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
805 CORBA::Double y, CORBA::Double z)
809 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
811 // Update Python script
812 TPythonDump() << "nodeID = " << this << ".AddNode( "
813 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
815 myMesh->GetMeshDS()->Modified();
816 myMesh->SetIsModified( true ); // issue 0020693
820 //=============================================================================
822 * Create 0D element on the given node.
824 //=============================================================================
826 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
830 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
831 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
833 // Update Python script
834 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
836 myMesh->GetMeshDS()->Modified();
837 myMesh->SetIsModified( true ); // issue 0020693
840 return elem->GetID();
845 //=============================================================================
847 * Create a ball element on the given node.
849 //=============================================================================
851 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
852 throw (SALOME::SALOME_Exception)
856 if ( diameter < std::numeric_limits<double>::min() )
857 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
861 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
862 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
864 // Update Python script
865 TPythonDump() << "ballElem = "
866 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
868 myMesh->GetMeshDS()->Modified();
869 myMesh->SetIsModified( true ); // issue 0020693
872 return elem->GetID();
874 SMESH_CATCH( SMESH::throwCorbaException );
879 //=============================================================================
881 * Create an edge, either linear and quadratic (this is determed
882 * by number of given nodes, two or three)
884 //=============================================================================
886 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
890 int NbNodes = IDsOfNodes.length();
891 SMDS_MeshElement* elem = 0;
894 CORBA::Long index1 = IDsOfNodes[0];
895 CORBA::Long index2 = IDsOfNodes[1];
896 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
897 getMeshDS()->FindNode(index2));
899 // Update Python script
900 TPythonDump() << "edge = " << this << ".AddEdge([ "
901 << index1 << ", " << index2 <<" ])";
904 CORBA::Long n1 = IDsOfNodes[0];
905 CORBA::Long n2 = IDsOfNodes[1];
906 CORBA::Long n12 = IDsOfNodes[2];
907 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
908 getMeshDS()->FindNode(n2),
909 getMeshDS()->FindNode(n12));
910 // Update Python script
911 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
912 <<n1<<", "<<n2<<", "<<n12<<" ])";
915 myMesh->GetMeshDS()->Modified();
917 return myMesh->SetIsModified( true ), elem->GetID();
922 //=============================================================================
926 //=============================================================================
928 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
932 int NbNodes = IDsOfNodes.length();
938 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
939 for (int i = 0; i < NbNodes; i++)
940 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
942 SMDS_MeshElement* elem = 0;
944 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
946 else if (NbNodes == 4) {
947 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
949 else if (NbNodes == 6) {
950 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
953 else if (NbNodes == 8) {
954 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
955 nodes[4], nodes[5], nodes[6], nodes[7]);
957 else if (NbNodes == 9) {
958 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
959 nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
961 else if (NbNodes > 2) {
962 elem = getMeshDS()->AddPolygonalFace(nodes);
965 // Update Python script
966 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
968 myMesh->GetMeshDS()->Modified();
970 return myMesh->SetIsModified( true ), elem->GetID();
975 //=============================================================================
979 //=============================================================================
980 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
984 int NbNodes = IDsOfNodes.length();
985 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
986 for (int i = 0; i < NbNodes; i++)
987 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
989 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
991 // Update Python script
992 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
994 myMesh->GetMeshDS()->Modified();
995 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
998 //=============================================================================
1000 * Create volume, either linear and quadratic (this is determed
1001 * by number of given nodes)
1003 //=============================================================================
1005 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1009 int NbNodes = IDsOfNodes.length();
1010 vector< const SMDS_MeshNode*> n(NbNodes);
1011 for(int i=0;i<NbNodes;i++)
1012 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1014 SMDS_MeshElement* elem = 0;
1017 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1018 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1019 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1020 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1021 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1022 n[6],n[7],n[8],n[9]);
1024 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1025 n[6],n[7],n[8],n[9],n[10],n[11]);
1027 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1028 n[7],n[8],n[9],n[10],n[11],n[12]);
1030 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1031 n[9],n[10],n[11],n[12],n[13],n[14]);
1033 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1034 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1035 n[15],n[16],n[17],n[18],n[19]);
1037 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1038 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1039 n[15],n[16],n[17],n[18],n[19],
1040 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1044 // Update Python script
1045 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1047 myMesh->GetMeshDS()->Modified();
1049 return myMesh->SetIsModified( true ), elem->GetID();
1054 //=============================================================================
1056 * AddPolyhedralVolume
1058 //=============================================================================
1059 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1060 const SMESH::long_array & Quantities)
1064 int NbNodes = IDsOfNodes.length();
1065 std::vector<const SMDS_MeshNode*> n (NbNodes);
1066 for (int i = 0; i < NbNodes; i++)
1068 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1069 if (!aNode) return 0;
1073 int NbFaces = Quantities.length();
1074 std::vector<int> q (NbFaces);
1075 for (int j = 0; j < NbFaces; j++)
1076 q[j] = Quantities[j];
1078 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1080 // Update Python script
1081 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1082 << IDsOfNodes << ", " << Quantities << " )";
1083 myMesh->GetMeshDS()->Modified();
1085 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1088 //=============================================================================
1090 * AddPolyhedralVolumeByFaces
1092 //=============================================================================
1094 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1098 int NbFaces = IdsOfFaces.length();
1099 std::vector<const SMDS_MeshNode*> poly_nodes;
1100 std::vector<int> quantities (NbFaces);
1102 for (int i = 0; i < NbFaces; i++) {
1103 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1104 quantities[i] = aFace->NbNodes();
1106 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1107 while (It->more()) {
1108 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1112 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1114 // Update Python script
1115 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1116 << IdsOfFaces << " )";
1117 myMesh->GetMeshDS()->Modified();
1119 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1122 //=============================================================================
1124 // \brief Create 0D elements on all nodes of the given object except those
1125 // nodes on which a 0D element already exists.
1126 // \param theObject object on whose nodes 0D elements will be created.
1127 // \param theGroupName optional name of a group to add 0D elements created
1128 // and/or found on nodes of \a theObject.
1129 // \return an object (a new group or a temporary SMESH_IDSource) holding
1130 // ids of new and/or found 0D elements.
1132 //=============================================================================
1134 SMESH::SMESH_IDSource_ptr
1135 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1136 const char* theGroupName)
1137 throw (SALOME::SALOME_Exception)
1141 SMESH::SMESH_IDSource_var result;
1146 TIDSortedElemSet elements, elems0D;
1147 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1148 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1150 SMESH::long_array_var newElems = new SMESH::long_array;
1151 newElems->length( elems0D.size() );
1152 TIDSortedElemSet::iterator eIt = elems0D.begin();
1153 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1154 newElems[ i ] = (*eIt)->GetID();
1156 SMESH::SMESH_GroupBase_var groupToFill;
1157 if ( theGroupName && strlen( theGroupName ))
1159 // Get existing group named theGroupName
1160 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1161 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1162 SMESH::SMESH_GroupBase_var group = groups[i];
1163 if ( !group->_is_nil() ) {
1164 CORBA::String_var name = group->GetName();
1165 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1166 groupToFill = group;
1171 if ( groupToFill->_is_nil() )
1172 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1173 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1174 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1177 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1179 group_i->Add( newElems );
1180 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1181 pyDump << groupToFill;
1185 result = MakeIDSource( newElems, SMESH::ELEM0D );
1186 pyDump << "elem0DIDs";
1189 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1190 << theObject << ", '" << theGroupName << "' )";
1192 SMESH_CATCH( SMESH::throwCorbaException );
1194 return result._retn();
1197 //=============================================================================
1199 * \brief Bind a node to a vertex
1200 * \param NodeID - node ID
1201 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1202 * \retval boolean - false if NodeID or VertexID is invalid
1204 //=============================================================================
1206 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1207 throw (SALOME::SALOME_Exception)
1209 Unexpect aCatch(SALOME_SalomeException);
1211 SMESHDS_Mesh * mesh = getMeshDS();
1212 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1214 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1216 if ( mesh->MaxShapeIndex() < VertexID )
1217 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1219 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1220 if ( shape.ShapeType() != TopAbs_VERTEX )
1221 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1223 mesh->SetNodeOnVertex( node, VertexID );
1225 myMesh->SetIsModified( true );
1228 //=============================================================================
1230 * \brief Store node position on an edge
1231 * \param NodeID - node ID
1232 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1233 * \param paramOnEdge - parameter on edge where the node is located
1234 * \retval boolean - false if any parameter is invalid
1236 //=============================================================================
1238 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1239 CORBA::Double paramOnEdge)
1240 throw (SALOME::SALOME_Exception)
1242 Unexpect aCatch(SALOME_SalomeException);
1244 SMESHDS_Mesh * mesh = getMeshDS();
1245 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1247 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1249 if ( mesh->MaxShapeIndex() < EdgeID )
1250 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1252 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1253 if ( shape.ShapeType() != TopAbs_EDGE )
1254 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1257 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1258 if ( paramOnEdge < f || paramOnEdge > l )
1259 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1261 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1263 myMesh->SetIsModified( true );
1266 //=============================================================================
1268 * \brief Store node position on a face
1269 * \param NodeID - node ID
1270 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1271 * \param u - U parameter on face where the node is located
1272 * \param v - V parameter on face where the node is located
1273 * \retval boolean - false if any parameter is invalid
1275 //=============================================================================
1277 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1278 CORBA::Double u, CORBA::Double v)
1279 throw (SALOME::SALOME_Exception)
1281 Unexpect aCatch(SALOME_SalomeException);
1283 SMESHDS_Mesh * mesh = getMeshDS();
1284 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1286 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1288 if ( mesh->MaxShapeIndex() < FaceID )
1289 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1291 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1292 if ( shape.ShapeType() != TopAbs_FACE )
1293 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1295 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1296 bool isOut = ( u < surf.FirstUParameter() ||
1297 u > surf.LastUParameter() ||
1298 v < surf.FirstVParameter() ||
1299 v > surf.LastVParameter() );
1303 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1304 << " u( " << surf.FirstUParameter()
1305 << "," << surf.LastUParameter()
1306 << ") v( " << surf.FirstVParameter()
1307 << "," << surf.LastVParameter() << ")" );
1309 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1312 mesh->SetNodeOnFace( node, FaceID, u, v );
1313 myMesh->SetIsModified( true );
1316 //=============================================================================
1318 * \brief Bind a node to a solid
1319 * \param NodeID - node ID
1320 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1321 * \retval boolean - false if NodeID or SolidID is invalid
1323 //=============================================================================
1325 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1326 throw (SALOME::SALOME_Exception)
1328 Unexpect aCatch(SALOME_SalomeException);
1330 SMESHDS_Mesh * mesh = getMeshDS();
1331 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1333 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1335 if ( mesh->MaxShapeIndex() < SolidID )
1336 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1338 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1339 if ( shape.ShapeType() != TopAbs_SOLID &&
1340 shape.ShapeType() != TopAbs_SHELL)
1341 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1343 mesh->SetNodeInVolume( node, SolidID );
1345 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
1348 //=============================================================================
1350 * \brief Bind an element to a shape
1351 * \param ElementID - element ID
1352 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1353 * \retval boolean - false if ElementID or ShapeID is invalid
1355 //=============================================================================
1357 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1358 CORBA::Long ShapeID)
1359 throw (SALOME::SALOME_Exception)
1361 Unexpect aCatch(SALOME_SalomeException);
1363 SMESHDS_Mesh * mesh = getMeshDS();
1364 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1366 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1368 if ( mesh->MaxShapeIndex() < ShapeID )
1369 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1371 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1372 if ( shape.ShapeType() != TopAbs_EDGE &&
1373 shape.ShapeType() != TopAbs_FACE &&
1374 shape.ShapeType() != TopAbs_SOLID &&
1375 shape.ShapeType() != TopAbs_SHELL )
1376 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1378 mesh->SetMeshElementOnShape( elem, ShapeID );
1380 myMesh->SetIsModified( true );
1383 //=============================================================================
1387 //=============================================================================
1389 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1390 CORBA::Long NodeID2)
1394 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1395 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1399 // Update Python script
1400 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1401 << NodeID1 << ", " << NodeID2 << " )";
1404 int ret = getEditor().InverseDiag ( n1, n2 );
1405 myMesh->GetMeshDS()->Modified();
1406 myMesh->SetIsModified( true );
1410 //=============================================================================
1414 //=============================================================================
1416 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1417 CORBA::Long NodeID2)
1421 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1422 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1426 // Update Python script
1427 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1428 << NodeID1 << ", " << NodeID2 << " )";
1431 bool stat = getEditor().DeleteDiag ( n1, n2 );
1433 myMesh->GetMeshDS()->Modified();
1435 myMesh->SetIsModified( true ); // issue 0020693
1441 //=============================================================================
1445 //=============================================================================
1447 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1451 for (int i = 0; i < IDsOfElements.length(); i++)
1453 CORBA::Long index = IDsOfElements[i];
1454 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1456 getEditor().Reorient( elem );
1458 // Update Python script
1459 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1461 myMesh->GetMeshDS()->Modified();
1462 if ( IDsOfElements.length() )
1463 myMesh->SetIsModified( true ); // issue 0020693
1469 //=============================================================================
1473 //=============================================================================
1475 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1479 TPythonDump aTPythonDump; // suppress dump in Reorient()
1481 SMESH::long_array_var anElementsId = theObject->GetIDs();
1482 CORBA::Boolean isDone = Reorient(anElementsId);
1484 // Update Python script
1485 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1490 //=======================================================================
1491 //function : Reorient2D
1492 //purpose : Reorient faces contained in \a the2Dgroup.
1493 // the2Dgroup - the mesh or its part to reorient
1494 // theDirection - desired direction of normal of \a theFace
1495 // theFace - ID of face whose orientation is checked.
1496 // It can be < 1 then \a thePoint is used to find a face.
1497 // thePoint - is used to find a face if \a theFace < 1.
1498 // return number of reoriented elements.
1499 //=======================================================================
1501 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1502 const SMESH::DirStruct& theDirection,
1503 CORBA::Long theFace,
1504 const SMESH::PointStruct& thePoint)
1505 throw (SALOME::SALOME_Exception)
1507 Unexpect aCatch(SALOME_SalomeException);
1509 initData(/*deleteSearchers=*/false);
1511 TIDSortedElemSet elements;
1512 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1513 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1516 const SMDS_MeshElement* face = 0;
1519 face = getMeshDS()->FindElement( theFace );
1521 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1522 if ( face->GetType() != SMDSAbs_Face )
1523 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1527 // create theElementSearcher if needed
1528 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1529 if ( !theElementSearcher )
1531 if ( elements.empty() ) // search in the whole mesh
1533 if ( myMesh->NbFaces() == 0 )
1534 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1536 theElementSearcher = myEditor.GetElementSearcher();
1540 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1541 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1543 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
1547 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1548 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1551 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1552 if ( !elements.empty() && !elements.count( face ))
1553 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1556 const SMESH::PointStruct * P = &theDirection.PS;
1557 gp_Vec dirVec( P->x, P->y, P->z );
1558 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1559 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1561 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1564 myMesh->SetIsModified( true );
1565 myMesh->GetMeshDS()->Modified();
1567 TPythonDump() << this << ".Reorient2D( "
1568 << the2Dgroup << ", "
1569 << theDirection << ", "
1571 << thePoint << " )";
1576 //=============================================================================
1580 //=============================================================================
1581 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1582 SMESH::NumericalFunctor_ptr Criterion,
1583 CORBA::Double MaxAngle)
1587 SMESHDS_Mesh* aMesh = getMeshDS();
1588 TIDSortedElemSet faces;
1589 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1591 SMESH::NumericalFunctor_i* aNumericalFunctor =
1592 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1593 SMESH::Controls::NumericalFunctorPtr aCrit;
1594 if ( !aNumericalFunctor )
1595 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1597 aCrit = aNumericalFunctor->GetNumericalFunctor();
1599 // Update Python script
1600 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1601 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1604 bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle );
1605 myMesh->GetMeshDS()->Modified();
1607 myMesh->SetIsModified( true ); // issue 0020693
1614 //=============================================================================
1618 //=============================================================================
1619 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1620 SMESH::NumericalFunctor_ptr Criterion,
1621 CORBA::Double MaxAngle)
1625 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1626 SMESH::long_array_var anElementsId = theObject->GetIDs();
1627 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1629 SMESH::NumericalFunctor_i* aNumericalFunctor =
1630 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1632 // Update Python script
1633 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1634 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1640 //=============================================================================
1644 //=============================================================================
1645 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1646 SMESH::NumericalFunctor_ptr Criterion)
1650 SMESHDS_Mesh* aMesh = getMeshDS();
1651 TIDSortedElemSet faces;
1652 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1654 SMESH::NumericalFunctor_i* aNumericalFunctor =
1655 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1656 SMESH::Controls::NumericalFunctorPtr aCrit;
1657 if ( !aNumericalFunctor )
1658 aCrit.reset( new SMESH::Controls::AspectRatio() );
1660 aCrit = aNumericalFunctor->GetNumericalFunctor();
1663 // Update Python script
1664 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1666 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1667 myMesh->GetMeshDS()->Modified();
1669 myMesh->SetIsModified( true ); // issue 0020693
1676 //=============================================================================
1680 //=============================================================================
1681 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1682 SMESH::NumericalFunctor_ptr Criterion)
1686 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1688 SMESH::long_array_var anElementsId = theObject->GetIDs();
1689 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1691 SMESH::NumericalFunctor_i* aNumericalFunctor =
1692 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1694 // Update Python script
1695 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1701 //=============================================================================
1705 //=============================================================================
1706 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1707 CORBA::Boolean Diag13)
1711 SMESHDS_Mesh* aMesh = getMeshDS();
1712 TIDSortedElemSet faces;
1713 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1715 // Update Python script
1716 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1717 << IDsOfElements << ", " << Diag13 << " )";
1719 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1720 myMesh->GetMeshDS()->Modified();
1722 myMesh->SetIsModified( true ); // issue 0020693
1730 //=============================================================================
1734 //=============================================================================
1735 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1736 CORBA::Boolean Diag13)
1740 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1742 SMESH::long_array_var anElementsId = theObject->GetIDs();
1743 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1745 // Update Python script
1746 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1747 << theObject << ", " << Diag13 << " )";
1753 //=============================================================================
1757 //=============================================================================
1758 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1759 SMESH::NumericalFunctor_ptr Criterion)
1763 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1764 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1766 SMESH::NumericalFunctor_i* aNumericalFunctor =
1767 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1768 SMESH::Controls::NumericalFunctorPtr aCrit;
1769 if (aNumericalFunctor)
1770 aCrit = aNumericalFunctor->GetNumericalFunctor();
1772 aCrit.reset(new SMESH::Controls::AspectRatio());
1774 return getEditor().BestSplit(quad, aCrit);
1779 //================================================================================
1781 * \brief Split volumic elements into tetrahedrons
1783 //================================================================================
1785 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1786 CORBA::Short methodFlags)
1787 throw (SALOME::SALOME_Exception)
1789 Unexpect aCatch(SALOME_SalomeException);
1793 SMESH::long_array_var anElementsId = elems->GetIDs();
1794 TIDSortedElemSet elemSet;
1795 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
1797 getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1798 myMesh->GetMeshDS()->Modified();
1801 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1802 // myMesh->SetIsModified( true ); // issue 0020693
1804 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1805 << elems << ", " << methodFlags << " )";
1808 //=======================================================================
1811 //=======================================================================
1814 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1815 const SMESH::long_array & IDsOfFixedNodes,
1816 CORBA::Long MaxNbOfIterations,
1817 CORBA::Double MaxAspectRatio,
1818 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1820 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1821 MaxAspectRatio, Method, false );
1825 //=======================================================================
1826 //function : SmoothParametric
1828 //=======================================================================
1831 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1832 const SMESH::long_array & IDsOfFixedNodes,
1833 CORBA::Long MaxNbOfIterations,
1834 CORBA::Double MaxAspectRatio,
1835 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1837 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1838 MaxAspectRatio, Method, true );
1842 //=======================================================================
1843 //function : SmoothObject
1845 //=======================================================================
1848 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1849 const SMESH::long_array & IDsOfFixedNodes,
1850 CORBA::Long MaxNbOfIterations,
1851 CORBA::Double MaxAspectRatio,
1852 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1854 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1855 MaxAspectRatio, Method, false);
1859 //=======================================================================
1860 //function : SmoothParametricObject
1862 //=======================================================================
1865 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1866 const SMESH::long_array & IDsOfFixedNodes,
1867 CORBA::Long MaxNbOfIterations,
1868 CORBA::Double MaxAspectRatio,
1869 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1871 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1872 MaxAspectRatio, Method, true);
1876 //=============================================================================
1880 //=============================================================================
1883 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1884 const SMESH::long_array & IDsOfFixedNodes,
1885 CORBA::Long MaxNbOfIterations,
1886 CORBA::Double MaxAspectRatio,
1887 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1892 SMESHDS_Mesh* aMesh = getMeshDS();
1894 TIDSortedElemSet elements;
1895 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1897 set<const SMDS_MeshNode*> fixedNodes;
1898 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1899 CORBA::Long index = IDsOfFixedNodes[i];
1900 const SMDS_MeshNode * node = aMesh->FindNode(index);
1902 fixedNodes.insert( node );
1904 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1905 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1906 method = ::SMESH_MeshEditor::CENTROIDAL;
1908 getEditor().Smooth(elements, fixedNodes, method,
1909 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1911 myMesh->GetMeshDS()->Modified();
1912 myMesh->SetIsModified( true ); // issue 0020693
1915 // Update Python script
1916 TPythonDump() << "isDone = " << this << "."
1917 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1918 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1919 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1920 << "SMESH.SMESH_MeshEditor."
1921 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1922 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1928 //=============================================================================
1932 //=============================================================================
1935 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1936 const SMESH::long_array & IDsOfFixedNodes,
1937 CORBA::Long MaxNbOfIterations,
1938 CORBA::Double MaxAspectRatio,
1939 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1944 TPythonDump aTPythonDump; // suppress dump in smooth()
1946 SMESH::long_array_var anElementsId = theObject->GetIDs();
1947 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1948 MaxAspectRatio, Method, IsParametric);
1950 // Update Python script
1951 aTPythonDump << "isDone = " << this << "."
1952 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1953 << theObject << ", " << IDsOfFixedNodes << ", "
1954 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1955 << "SMESH.SMESH_MeshEditor."
1956 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1957 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1963 //=============================================================================
1967 //=============================================================================
1969 void SMESH_MeshEditor_i::RenumberNodes()
1971 // Update Python script
1972 TPythonDump() << this << ".RenumberNodes()";
1974 getMeshDS()->Renumber( true );
1978 //=============================================================================
1982 //=============================================================================
1984 void SMESH_MeshEditor_i::RenumberElements()
1986 // Update Python script
1987 TPythonDump() << this << ".RenumberElements()";
1989 getMeshDS()->Renumber( false );
1992 //=======================================================================
1994 * \brief Return groups by their IDs
1996 //=======================================================================
1998 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2002 myMesh_i->CreateGroupServants();
2003 return myMesh_i->GetGroups( *groupIDs );
2006 //=======================================================================
2007 //function : rotationSweep
2009 //=======================================================================
2011 SMESH::ListOfGroups*
2012 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2013 const SMESH::AxisStruct & theAxis,
2014 CORBA::Double theAngleInRadians,
2015 CORBA::Long theNbOfSteps,
2016 CORBA::Double theTolerance,
2017 const bool theMakeGroups,
2018 const SMDSAbs_ElementType theElementType)
2022 TIDSortedElemSet inElements, copyElements;
2023 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2025 TIDSortedElemSet* workElements = & inElements;
2026 bool makeWalls=true;
2027 if ( myIsPreviewMode )
2029 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2030 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2031 workElements = & copyElements;
2032 //makeWalls = false;
2035 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2036 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2038 ::SMESH_MeshEditor::PGroupIDs groupIds =
2039 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2040 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2041 myMesh->GetMeshDS()->Modified();
2043 // myMesh->SetIsModified( true ); -- it does not influence Compute()
2045 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2048 //=======================================================================
2049 //function : RotationSweep
2051 //=======================================================================
2053 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2054 const SMESH::AxisStruct & theAxis,
2055 CORBA::Double theAngleInRadians,
2056 CORBA::Long theNbOfSteps,
2057 CORBA::Double theTolerance)
2059 if ( !myIsPreviewMode ) {
2060 TPythonDump() << this << ".RotationSweep( "
2061 << theIDsOfElements << ", "
2063 << TVar( theAngleInRadians ) << ", "
2064 << TVar( theNbOfSteps ) << ", "
2065 << TVar( theTolerance ) << " )";
2067 rotationSweep(theIDsOfElements,
2075 //=======================================================================
2076 //function : RotationSweepMakeGroups
2078 //=======================================================================
2080 SMESH::ListOfGroups*
2081 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2082 const SMESH::AxisStruct& theAxis,
2083 CORBA::Double theAngleInRadians,
2084 CORBA::Long theNbOfSteps,
2085 CORBA::Double theTolerance)
2087 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2089 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2095 if (!myIsPreviewMode) {
2096 DumpGroupsList(aPythonDump, aGroups);
2097 aPythonDump << this << ".RotationSweepMakeGroups( "
2098 << theIDsOfElements << ", "
2100 << TVar( theAngleInRadians ) << ", "
2101 << TVar( theNbOfSteps ) << ", "
2102 << TVar( theTolerance ) << " )";
2107 //=======================================================================
2108 //function : RotationSweepObject
2110 //=======================================================================
2112 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2113 const SMESH::AxisStruct & theAxis,
2114 CORBA::Double theAngleInRadians,
2115 CORBA::Long theNbOfSteps,
2116 CORBA::Double theTolerance)
2118 if ( !myIsPreviewMode ) {
2119 TPythonDump() << this << ".RotationSweepObject( "
2120 << theObject << ", "
2122 << theAngleInRadians << ", "
2123 << theNbOfSteps << ", "
2124 << theTolerance << " )";
2126 SMESH::long_array_var anElementsId = theObject->GetIDs();
2127 rotationSweep(anElementsId,
2135 //=======================================================================
2136 //function : RotationSweepObject1D
2138 //=======================================================================
2140 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2141 const SMESH::AxisStruct & theAxis,
2142 CORBA::Double theAngleInRadians,
2143 CORBA::Long theNbOfSteps,
2144 CORBA::Double theTolerance)
2146 if ( !myIsPreviewMode ) {
2147 TPythonDump() << this << ".RotationSweepObject1D( "
2148 << theObject << ", "
2150 << TVar( theAngleInRadians ) << ", "
2151 << TVar( theNbOfSteps ) << ", "
2152 << TVar( theTolerance ) << " )";
2154 SMESH::long_array_var anElementsId = theObject->GetIDs();
2155 rotationSweep(anElementsId,
2164 //=======================================================================
2165 //function : RotationSweepObject2D
2167 //=======================================================================
2169 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2170 const SMESH::AxisStruct & theAxis,
2171 CORBA::Double theAngleInRadians,
2172 CORBA::Long theNbOfSteps,
2173 CORBA::Double theTolerance)
2175 if ( !myIsPreviewMode ) {
2176 TPythonDump() << this << ".RotationSweepObject2D( "
2177 << theObject << ", "
2179 << TVar( theAngleInRadians ) << ", "
2180 << TVar( theNbOfSteps ) << ", "
2181 << TVar( theTolerance ) << " )";
2183 SMESH::long_array_var anElementsId = theObject->GetIDs();
2184 rotationSweep(anElementsId,
2193 //=======================================================================
2194 //function : RotationSweepObjectMakeGroups
2196 //=======================================================================
2198 SMESH::ListOfGroups*
2199 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(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,
2214 if (!myIsPreviewMode) {
2215 DumpGroupsList(aPythonDump, aGroups);
2216 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2217 << theObject << ", "
2219 << theAngleInRadians << ", "
2220 << theNbOfSteps << ", "
2221 << theTolerance << " )";
2226 //=======================================================================
2227 //function : RotationSweepObject1DMakeGroups
2229 //=======================================================================
2231 SMESH::ListOfGroups*
2232 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2233 const SMESH::AxisStruct& theAxis,
2234 CORBA::Double theAngleInRadians,
2235 CORBA::Long theNbOfSteps,
2236 CORBA::Double theTolerance)
2238 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2240 SMESH::long_array_var anElementsId = theObject->GetIDs();
2241 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2248 if (!myIsPreviewMode) {
2249 DumpGroupsList(aPythonDump, aGroups);
2250 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2251 << theObject << ", "
2253 << TVar( theAngleInRadians ) << ", "
2254 << TVar( theNbOfSteps ) << ", "
2255 << TVar( theTolerance ) << " )";
2260 //=======================================================================
2261 //function : RotationSweepObject2DMakeGroups
2263 //=======================================================================
2265 SMESH::ListOfGroups*
2266 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2267 const SMESH::AxisStruct& theAxis,
2268 CORBA::Double theAngleInRadians,
2269 CORBA::Long theNbOfSteps,
2270 CORBA::Double theTolerance)
2272 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2274 SMESH::long_array_var anElementsId = theObject->GetIDs();
2275 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2282 if (!myIsPreviewMode) {
2283 DumpGroupsList(aPythonDump, aGroups);
2284 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2285 << theObject << ", "
2287 << TVar( theAngleInRadians ) << ", "
2288 << TVar( theNbOfSteps ) << ", "
2289 << TVar( theTolerance ) << " )";
2295 //=======================================================================
2296 //function : extrusionSweep
2298 //=======================================================================
2300 SMESH::ListOfGroups*
2301 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2302 const SMESH::DirStruct & theStepVector,
2303 CORBA::Long theNbOfSteps,
2305 const SMDSAbs_ElementType theElementType)
2313 TIDSortedElemSet elements, copyElements;
2314 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2316 const SMESH::PointStruct * P = &theStepVector.PS;
2317 gp_Vec stepVec( P->x, P->y, P->z );
2319 TIDSortedElemSet* workElements = & elements;
2321 SMDSAbs_ElementType aType = SMDSAbs_Face;
2322 if (theElementType == SMDSAbs_Node)
2324 aType = SMDSAbs_Edge;
2326 if ( myIsPreviewMode ) {
2327 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2328 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2329 workElements = & copyElements;
2330 theMakeGroups = false;
2333 TElemOfElemListMap aHystory;
2334 ::SMESH_MeshEditor::PGroupIDs groupIds =
2335 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2337 myMesh->GetMeshDS()->Modified();
2339 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2341 } catch(Standard_Failure) {
2342 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2343 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
2348 //=======================================================================
2349 //function : ExtrusionSweep
2351 //=======================================================================
2353 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2354 const SMESH::DirStruct & theStepVector,
2355 CORBA::Long theNbOfSteps)
2357 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2358 if (!myIsPreviewMode) {
2359 TPythonDump() << this << ".ExtrusionSweep( "
2360 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2364 //=======================================================================
2365 //function : ExtrusionSweep0D
2367 //=======================================================================
2369 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2370 const SMESH::DirStruct & theStepVector,
2371 CORBA::Long theNbOfSteps)
2373 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2374 if (!myIsPreviewMode) {
2375 TPythonDump() << this << ".ExtrusionSweep0D( "
2376 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2380 //=======================================================================
2381 //function : ExtrusionSweepObject
2383 //=======================================================================
2385 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2386 const SMESH::DirStruct & theStepVector,
2387 CORBA::Long theNbOfSteps)
2389 SMESH::long_array_var anElementsId = theObject->GetIDs();
2390 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2391 if (!myIsPreviewMode) {
2392 TPythonDump() << this << ".ExtrusionSweepObject( "
2393 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2397 //=======================================================================
2398 //function : ExtrusionSweepObject0D
2400 //=======================================================================
2402 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2403 const SMESH::DirStruct & theStepVector,
2404 CORBA::Long theNbOfSteps)
2406 SMESH::long_array_var anElementsId = theObject->GetIDs();
2407 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2408 if ( !myIsPreviewMode ) {
2409 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2410 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2414 //=======================================================================
2415 //function : ExtrusionSweepObject1D
2417 //=======================================================================
2419 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2420 const SMESH::DirStruct & theStepVector,
2421 CORBA::Long theNbOfSteps)
2423 SMESH::long_array_var anElementsId = theObject->GetIDs();
2424 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2425 if ( !myIsPreviewMode ) {
2426 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2427 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2431 //=======================================================================
2432 //function : ExtrusionSweepObject2D
2434 //=======================================================================
2436 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2437 const SMESH::DirStruct & theStepVector,
2438 CORBA::Long theNbOfSteps)
2440 SMESH::long_array_var anElementsId = theObject->GetIDs();
2441 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2442 if ( !myIsPreviewMode ) {
2443 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2444 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2448 //=======================================================================
2449 //function : ExtrusionSweepMakeGroups
2451 //=======================================================================
2453 SMESH::ListOfGroups*
2454 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2455 const SMESH::DirStruct& theStepVector,
2456 CORBA::Long theNbOfSteps)
2458 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2460 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2462 if (!myIsPreviewMode) {
2463 DumpGroupsList(aPythonDump, aGroups);
2464 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2465 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2470 //=======================================================================
2471 //function : ExtrusionSweepMakeGroups0D
2473 //=======================================================================
2475 SMESH::ListOfGroups*
2476 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2477 const SMESH::DirStruct& theStepVector,
2478 CORBA::Long theNbOfSteps)
2480 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2482 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2484 if (!myIsPreviewMode) {
2485 DumpGroupsList(aPythonDump, aGroups);
2486 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2487 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2492 //=======================================================================
2493 //function : ExtrusionSweepObjectMakeGroups
2495 //=======================================================================
2497 SMESH::ListOfGroups*
2498 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2499 const SMESH::DirStruct& theStepVector,
2500 CORBA::Long theNbOfSteps)
2502 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2504 SMESH::long_array_var anElementsId = theObject->GetIDs();
2505 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2507 if (!myIsPreviewMode) {
2508 DumpGroupsList(aPythonDump, aGroups);
2509 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2510 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2515 //=======================================================================
2516 //function : ExtrusionSweepObject0DMakeGroups
2518 //=======================================================================
2520 SMESH::ListOfGroups*
2521 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2522 const SMESH::DirStruct& theStepVector,
2523 CORBA::Long theNbOfSteps)
2525 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2527 SMESH::long_array_var anElementsId = theObject->GetIDs();
2528 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2529 theNbOfSteps, true, SMDSAbs_Node);
2530 if (!myIsPreviewMode) {
2531 DumpGroupsList(aPythonDump, aGroups);
2532 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2533 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2538 //=======================================================================
2539 //function : ExtrusionSweepObject1DMakeGroups
2541 //=======================================================================
2543 SMESH::ListOfGroups*
2544 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2545 const SMESH::DirStruct& theStepVector,
2546 CORBA::Long theNbOfSteps)
2548 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2550 SMESH::long_array_var anElementsId = theObject->GetIDs();
2551 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2552 theNbOfSteps, true, SMDSAbs_Edge);
2553 if (!myIsPreviewMode) {
2554 DumpGroupsList(aPythonDump, aGroups);
2555 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2556 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2561 //=======================================================================
2562 //function : ExtrusionSweepObject2DMakeGroups
2564 //=======================================================================
2566 SMESH::ListOfGroups*
2567 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2568 const SMESH::DirStruct& theStepVector,
2569 CORBA::Long theNbOfSteps)
2571 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2573 SMESH::long_array_var anElementsId = theObject->GetIDs();
2574 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2575 theNbOfSteps, true, SMDSAbs_Face);
2576 if (!myIsPreviewMode) {
2577 DumpGroupsList(aPythonDump, aGroups);
2578 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2579 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2585 //=======================================================================
2586 //function : advancedExtrusion
2588 //=======================================================================
2590 SMESH::ListOfGroups*
2591 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2592 const SMESH::DirStruct & theStepVector,
2593 CORBA::Long theNbOfSteps,
2594 CORBA::Long theExtrFlags,
2595 CORBA::Double theSewTolerance,
2596 const bool theMakeGroups)
2600 TIDSortedElemSet elements;
2601 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2603 const SMESH::PointStruct * P = &theStepVector.PS;
2604 gp_Vec stepVec( P->x, P->y, P->z );
2606 TElemOfElemListMap aHystory;
2607 ::SMESH_MeshEditor::PGroupIDs groupIds =
2608 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2609 theMakeGroups, theExtrFlags, theSewTolerance);
2611 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2614 //=======================================================================
2615 //function : AdvancedExtrusion
2617 //=======================================================================
2619 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2620 const SMESH::DirStruct & theStepVector,
2621 CORBA::Long theNbOfSteps,
2622 CORBA::Long theExtrFlags,
2623 CORBA::Double theSewTolerance)
2625 if ( !myIsPreviewMode ) {
2626 TPythonDump() << "stepVector = " << theStepVector;
2627 TPythonDump() << this << ".AdvancedExtrusion("
2630 << theNbOfSteps << ","
2631 << theExtrFlags << ", "
2632 << theSewTolerance << " )";
2634 advancedExtrusion( theIDsOfElements,
2642 //=======================================================================
2643 //function : AdvancedExtrusionMakeGroups
2645 //=======================================================================
2646 SMESH::ListOfGroups*
2647 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2648 const SMESH::DirStruct& theStepVector,
2649 CORBA::Long theNbOfSteps,
2650 CORBA::Long theExtrFlags,
2651 CORBA::Double theSewTolerance)
2653 if (!myIsPreviewMode) {
2654 TPythonDump() << "stepVector = " << theStepVector;
2656 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2658 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2665 if (!myIsPreviewMode) {
2666 DumpGroupsList(aPythonDump, aGroups);
2667 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2670 << theNbOfSteps << ","
2671 << theExtrFlags << ", "
2672 << theSewTolerance << " )";
2678 //================================================================================
2680 * \brief Convert extrusion error to IDL enum
2682 //================================================================================
2684 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2686 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2690 RETCASE( EXTR_NO_ELEMENTS );
2691 RETCASE( EXTR_PATH_NOT_EDGE );
2692 RETCASE( EXTR_BAD_PATH_SHAPE );
2693 RETCASE( EXTR_BAD_STARTING_NODE );
2694 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2695 RETCASE( EXTR_CANT_GET_TANGENT );
2697 return SMESH::SMESH_MeshEditor::EXTR_OK;
2701 //=======================================================================
2702 //function : extrusionAlongPath
2704 //=======================================================================
2705 SMESH::ListOfGroups*
2706 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2707 SMESH::SMESH_Mesh_ptr thePathMesh,
2708 GEOM::GEOM_Object_ptr thePathShape,
2709 CORBA::Long theNodeStart,
2710 CORBA::Boolean theHasAngles,
2711 const SMESH::double_array & theAngles,
2712 CORBA::Boolean theHasRefPoint,
2713 const SMESH::PointStruct & theRefPoint,
2714 const bool theMakeGroups,
2715 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2716 const SMDSAbs_ElementType theElementType)
2718 MESSAGE("extrusionAlongPath");
2721 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2722 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2725 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2727 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2728 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2730 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2731 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2735 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2737 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2741 TIDSortedElemSet elements;
2742 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2744 list<double> angles;
2745 for (int i = 0; i < theAngles.length(); i++) {
2746 angles.push_back( theAngles[i] );
2749 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2751 int nbOldGroups = myMesh->NbGroup();
2753 ::SMESH_MeshEditor::Extrusion_Error error =
2754 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2755 theHasAngles, angles, false,
2756 theHasRefPoint, refPnt, theMakeGroups );
2757 myMesh->GetMeshDS()->Modified();
2758 theError = convExtrError( error );
2760 if ( theMakeGroups ) {
2761 list<int> groupIDs = myMesh->GetGroupIds();
2762 list<int>::iterator newBegin = groupIDs.begin();
2763 std::advance( newBegin, nbOldGroups ); // skip old groups
2764 groupIDs.erase( groupIDs.begin(), newBegin );
2765 return getGroups( & groupIDs );
2771 //=======================================================================
2772 //function : extrusionAlongPathX
2774 //=======================================================================
2775 SMESH::ListOfGroups*
2776 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2777 SMESH::SMESH_IDSource_ptr Path,
2778 CORBA::Long NodeStart,
2779 CORBA::Boolean HasAngles,
2780 const SMESH::double_array& Angles,
2781 CORBA::Boolean LinearVariation,
2782 CORBA::Boolean HasRefPoint,
2783 const SMESH::PointStruct& RefPoint,
2785 const SMDSAbs_ElementType ElementType,
2786 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2788 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2792 list<double> angles;
2793 for (int i = 0; i < Angles.length(); i++) {
2794 angles.push_back( Angles[i] );
2796 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2797 int nbOldGroups = myMesh->NbGroup();
2799 if ( Path->_is_nil() ) {
2800 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2804 TIDSortedElemSet elements, copyElements;
2805 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
2807 TIDSortedElemSet* workElements = &elements;
2809 if ( myIsPreviewMode )
2811 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2812 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
2813 workElements = & copyElements;
2817 ::SMESH_MeshEditor::Extrusion_Error error;
2819 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2822 SMDS_MeshNode* aNodeStart =
2823 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2824 if ( !aNodeStart ) {
2825 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2828 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2829 HasAngles, angles, LinearVariation,
2830 HasRefPoint, refPnt, MakeGroups );
2831 myMesh->GetMeshDS()->Modified();
2833 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2836 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2837 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2838 SMDS_MeshNode* aNodeStart =
2839 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2840 if ( !aNodeStart ) {
2841 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2844 SMESH_subMesh* aSubMesh =
2845 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2846 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2847 HasAngles, angles, LinearVariation,
2848 HasRefPoint, refPnt, MakeGroups );
2849 myMesh->GetMeshDS()->Modified();
2851 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2853 // path as group of 1D elements
2859 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2863 Error = convExtrError( error );
2866 list<int> groupIDs = myMesh->GetGroupIds();
2867 list<int>::iterator newBegin = groupIDs.begin();
2868 std::advance( newBegin, nbOldGroups ); // skip old groups
2869 groupIDs.erase( groupIDs.begin(), newBegin );
2870 return getGroups( & groupIDs );
2876 //=======================================================================
2877 //function : ExtrusionAlongPath
2879 //=======================================================================
2880 SMESH::SMESH_MeshEditor::Extrusion_Error
2881 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2882 SMESH::SMESH_Mesh_ptr thePathMesh,
2883 GEOM::GEOM_Object_ptr thePathShape,
2884 CORBA::Long theNodeStart,
2885 CORBA::Boolean theHasAngles,
2886 const SMESH::double_array & theAngles,
2887 CORBA::Boolean theHasRefPoint,
2888 const SMESH::PointStruct & theRefPoint)
2890 MESSAGE("ExtrusionAlongPath");
2891 if ( !myIsPreviewMode ) {
2892 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2893 << theIDsOfElements << ", "
2894 << thePathMesh << ", "
2895 << thePathShape << ", "
2896 << theNodeStart << ", "
2897 << theHasAngles << ", "
2898 << theAngles << ", "
2899 << theHasRefPoint << ", "
2900 << "SMESH.PointStruct( "
2901 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2902 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2903 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2905 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2906 extrusionAlongPath( theIDsOfElements,
2919 //=======================================================================
2920 //function : ExtrusionAlongPathObject
2922 //=======================================================================
2923 SMESH::SMESH_MeshEditor::Extrusion_Error
2924 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2925 SMESH::SMESH_Mesh_ptr thePathMesh,
2926 GEOM::GEOM_Object_ptr thePathShape,
2927 CORBA::Long theNodeStart,
2928 CORBA::Boolean theHasAngles,
2929 const SMESH::double_array & theAngles,
2930 CORBA::Boolean theHasRefPoint,
2931 const SMESH::PointStruct & theRefPoint)
2933 if ( !myIsPreviewMode ) {
2934 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2935 << theObject << ", "
2936 << thePathMesh << ", "
2937 << thePathShape << ", "
2938 << theNodeStart << ", "
2939 << theHasAngles << ", "
2940 << theAngles << ", "
2941 << theHasRefPoint << ", "
2942 << "SMESH.PointStruct( "
2943 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2944 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2945 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2947 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2948 SMESH::long_array_var anElementsId = theObject->GetIDs();
2949 extrusionAlongPath( anElementsId,
2962 //=======================================================================
2963 //function : ExtrusionAlongPathObject1D
2965 //=======================================================================
2966 SMESH::SMESH_MeshEditor::Extrusion_Error
2967 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2968 SMESH::SMESH_Mesh_ptr thePathMesh,
2969 GEOM::GEOM_Object_ptr thePathShape,
2970 CORBA::Long theNodeStart,
2971 CORBA::Boolean theHasAngles,
2972 const SMESH::double_array & theAngles,
2973 CORBA::Boolean theHasRefPoint,
2974 const SMESH::PointStruct & theRefPoint)
2976 if ( !myIsPreviewMode ) {
2977 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2978 << theObject << ", "
2979 << thePathMesh << ", "
2980 << thePathShape << ", "
2981 << theNodeStart << ", "
2982 << theHasAngles << ", "
2983 << theAngles << ", "
2984 << theHasRefPoint << ", "
2985 << "SMESH.PointStruct( "
2986 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2987 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2988 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2990 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2991 SMESH::long_array_var anElementsId = theObject->GetIDs();
2992 extrusionAlongPath( anElementsId,
3006 //=======================================================================
3007 //function : ExtrusionAlongPathObject2D
3009 //=======================================================================
3010 SMESH::SMESH_MeshEditor::Extrusion_Error
3011 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3012 SMESH::SMESH_Mesh_ptr thePathMesh,
3013 GEOM::GEOM_Object_ptr thePathShape,
3014 CORBA::Long theNodeStart,
3015 CORBA::Boolean theHasAngles,
3016 const SMESH::double_array & theAngles,
3017 CORBA::Boolean theHasRefPoint,
3018 const SMESH::PointStruct & theRefPoint)
3020 if ( !myIsPreviewMode ) {
3021 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3022 << theObject << ", "
3023 << thePathMesh << ", "
3024 << thePathShape << ", "
3025 << theNodeStart << ", "
3026 << theHasAngles << ", "
3027 << theAngles << ", "
3028 << theHasRefPoint << ", "
3029 << "SMESH.PointStruct( "
3030 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3031 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3032 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3034 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3035 SMESH::long_array_var anElementsId = theObject->GetIDs();
3036 extrusionAlongPath( anElementsId,
3051 //=======================================================================
3052 //function : ExtrusionAlongPathMakeGroups
3054 //=======================================================================
3055 SMESH::ListOfGroups*
3056 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3057 SMESH::SMESH_Mesh_ptr thePathMesh,
3058 GEOM::GEOM_Object_ptr thePathShape,
3059 CORBA::Long theNodeStart,
3060 CORBA::Boolean theHasAngles,
3061 const SMESH::double_array& theAngles,
3062 CORBA::Boolean theHasRefPoint,
3063 const SMESH::PointStruct& theRefPoint,
3064 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3066 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3068 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3078 if (!myIsPreviewMode) {
3079 bool isDumpGroups = aGroups && aGroups->length() > 0;
3081 aPythonDump << "(" << aGroups << ", error)";
3083 aPythonDump <<"error";
3085 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3086 << theIDsOfElements << ", "
3087 << thePathMesh << ", "
3088 << thePathShape << ", "
3089 << theNodeStart << ", "
3090 << theHasAngles << ", "
3091 << theAngles << ", "
3092 << theHasRefPoint << ", "
3093 << "SMESH.PointStruct( "
3094 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3095 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3096 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3101 //=======================================================================
3102 //function : ExtrusionAlongPathObjectMakeGroups
3104 //=======================================================================
3105 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3106 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3107 SMESH::SMESH_Mesh_ptr thePathMesh,
3108 GEOM::GEOM_Object_ptr thePathShape,
3109 CORBA::Long theNodeStart,
3110 CORBA::Boolean theHasAngles,
3111 const SMESH::double_array& theAngles,
3112 CORBA::Boolean theHasRefPoint,
3113 const SMESH::PointStruct& theRefPoint,
3114 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3116 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3118 SMESH::long_array_var anElementsId = theObject->GetIDs();
3119 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3130 if (!myIsPreviewMode) {
3131 bool isDumpGroups = aGroups && aGroups->length() > 0;
3133 aPythonDump << "(" << aGroups << ", error)";
3135 aPythonDump <<"error";
3137 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3138 << theObject << ", "
3139 << thePathMesh << ", "
3140 << thePathShape << ", "
3141 << theNodeStart << ", "
3142 << theHasAngles << ", "
3143 << theAngles << ", "
3144 << theHasRefPoint << ", "
3145 << "SMESH.PointStruct( "
3146 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3147 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3148 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3153 //=======================================================================
3154 //function : ExtrusionAlongPathObject1DMakeGroups
3156 //=======================================================================
3157 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3158 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3159 SMESH::SMESH_Mesh_ptr thePathMesh,
3160 GEOM::GEOM_Object_ptr thePathShape,
3161 CORBA::Long theNodeStart,
3162 CORBA::Boolean theHasAngles,
3163 const SMESH::double_array& theAngles,
3164 CORBA::Boolean theHasRefPoint,
3165 const SMESH::PointStruct& theRefPoint,
3166 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3168 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3170 SMESH::long_array_var anElementsId = theObject->GetIDs();
3171 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3183 if (!myIsPreviewMode) {
3184 bool isDumpGroups = aGroups && aGroups->length() > 0;
3186 aPythonDump << "(" << aGroups << ", error)";
3188 aPythonDump << "error";
3190 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3191 << theObject << ", "
3192 << thePathMesh << ", "
3193 << thePathShape << ", "
3194 << theNodeStart << ", "
3195 << theHasAngles << ", "
3196 << theAngles << ", "
3197 << theHasRefPoint << ", "
3198 << "SMESH.PointStruct( "
3199 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3200 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3201 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3206 //=======================================================================
3207 //function : ExtrusionAlongPathObject2DMakeGroups
3209 //=======================================================================
3210 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3211 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3212 SMESH::SMESH_Mesh_ptr thePathMesh,
3213 GEOM::GEOM_Object_ptr thePathShape,
3214 CORBA::Long theNodeStart,
3215 CORBA::Boolean theHasAngles,
3216 const SMESH::double_array& theAngles,
3217 CORBA::Boolean theHasRefPoint,
3218 const SMESH::PointStruct& theRefPoint,
3219 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3221 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3223 SMESH::long_array_var anElementsId = theObject->GetIDs();
3224 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3236 if (!myIsPreviewMode) {
3237 bool isDumpGroups = aGroups && aGroups->length() > 0;
3239 aPythonDump << "(" << aGroups << ", error)";
3241 aPythonDump << "error";
3243 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3244 << theObject << ", "
3245 << thePathMesh << ", "
3246 << thePathShape << ", "
3247 << theNodeStart << ", "
3248 << theHasAngles << ", "
3249 << theAngles << ", "
3250 << theHasRefPoint << ", "
3251 << "SMESH.PointStruct( "
3252 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3253 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3254 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3260 //=======================================================================
3261 //function : ExtrusionAlongPathObjX
3263 //=======================================================================
3264 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3265 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3266 SMESH::SMESH_IDSource_ptr Path,
3267 CORBA::Long NodeStart,
3268 CORBA::Boolean HasAngles,
3269 const SMESH::double_array& Angles,
3270 CORBA::Boolean LinearVariation,
3271 CORBA::Boolean HasRefPoint,
3272 const SMESH::PointStruct& RefPoint,
3273 CORBA::Boolean MakeGroups,
3274 SMESH::ElementType ElemType,
3275 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3277 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3279 SMESH::long_array_var anElementsId = Object->GetIDs();
3280 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3289 (SMDSAbs_ElementType)ElemType,
3292 if (!myIsPreviewMode) {
3293 bool isDumpGroups = aGroups && aGroups->length() > 0;
3295 aPythonDump << "(" << *aGroups << ", error)";
3297 aPythonDump << "error";
3299 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3302 << NodeStart << ", "
3303 << HasAngles << ", "
3304 << TVar( Angles ) << ", "
3305 << LinearVariation << ", "
3306 << HasRefPoint << ", "
3307 << "SMESH.PointStruct( "
3308 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3309 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3310 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3311 << MakeGroups << ", "
3312 << ElemType << " )";
3318 //=======================================================================
3319 //function : ExtrusionAlongPathX
3321 //=======================================================================
3322 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3323 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3324 SMESH::SMESH_IDSource_ptr Path,
3325 CORBA::Long NodeStart,
3326 CORBA::Boolean HasAngles,
3327 const SMESH::double_array& Angles,
3328 CORBA::Boolean LinearVariation,
3329 CORBA::Boolean HasRefPoint,
3330 const SMESH::PointStruct& RefPoint,
3331 CORBA::Boolean MakeGroups,
3332 SMESH::ElementType ElemType,
3333 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3335 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3337 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3346 (SMDSAbs_ElementType)ElemType,
3349 if (!myIsPreviewMode) {
3350 bool isDumpGroups = aGroups && aGroups->length() > 0;
3352 aPythonDump << "(" << *aGroups << ", error)";
3354 aPythonDump <<"error";
3356 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3357 << IDsOfElements << ", "
3359 << NodeStart << ", "
3360 << HasAngles << ", "
3361 << TVar( Angles ) << ", "
3362 << LinearVariation << ", "
3363 << HasRefPoint << ", "
3364 << "SMESH.PointStruct( "
3365 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3366 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3367 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3368 << MakeGroups << ", "
3369 << ElemType << " )";
3375 //================================================================================
3377 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3378 * of given angles along path steps
3379 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3380 * which proceeds the extrusion
3381 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3382 * is used to define the sub-mesh for the path
3384 //================================================================================
3386 SMESH::double_array*
3387 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3388 GEOM::GEOM_Object_ptr thePathShape,
3389 const SMESH::double_array & theAngles)
3391 SMESH::double_array_var aResult = new SMESH::double_array();
3392 int nbAngles = theAngles.length();
3393 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3395 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3396 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3397 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3398 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3399 return aResult._retn();
3400 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3401 if ( nbSteps == nbAngles )
3403 aResult.inout() = theAngles;
3407 aResult->length( nbSteps );
3408 double rAn2St = double( nbAngles ) / double( nbSteps );
3409 double angPrev = 0, angle;
3410 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3412 double angCur = rAn2St * ( iSt+1 );
3413 double angCurFloor = floor( angCur );
3414 double angPrevFloor = floor( angPrev );
3415 if ( angPrevFloor == angCurFloor )
3416 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3419 int iP = int( angPrevFloor );
3420 double angPrevCeil = ceil(angPrev);
3421 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3423 int iC = int( angCurFloor );
3424 if ( iC < nbAngles )
3425 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3427 iP = int( angPrevCeil );
3429 angle += theAngles[ iC ];
3431 aResult[ iSt ] = angle;
3436 // Update Python script
3437 TPythonDump() << "rotAngles = " << theAngles;
3438 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3439 << thePathMesh << ", "
3440 << thePathShape << ", "
3443 return aResult._retn();
3447 //=======================================================================
3450 //=======================================================================
3452 SMESH::ListOfGroups*
3453 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3454 const SMESH::AxisStruct & theAxis,
3455 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3456 CORBA::Boolean theCopy,
3458 ::SMESH_Mesh* theTargetMesh)
3462 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3463 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3465 if ( theTargetMesh )
3469 switch ( theMirrorType ) {
3470 case SMESH::SMESH_MeshEditor::POINT:
3471 aTrsf.SetMirror( P );
3473 case SMESH::SMESH_MeshEditor::AXIS:
3474 aTrsf.SetMirror( gp_Ax1( P, V ));
3477 aTrsf.SetMirror( gp_Ax2( P, V ));
3480 TIDSortedElemSet copyElements;
3481 TIDSortedElemSet* workElements = & theElements;
3483 if ( myIsPreviewMode )
3485 TPreviewMesh * tmpMesh = getPreviewMesh();
3486 tmpMesh->Copy( theElements, copyElements);
3487 if ( !theCopy && !theTargetMesh )
3489 TIDSortedElemSet elemsAround, elemsAroundCopy;
3490 getElementsAround( theElements, getMeshDS(), elemsAround );
3491 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3493 workElements = & copyElements;
3494 theMakeGroups = false;
3497 ::SMESH_MeshEditor::PGroupIDs groupIds =
3498 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3500 if ( theCopy && !myIsPreviewMode)
3502 if ( theTargetMesh )
3504 theTargetMesh->GetMeshDS()->Modified();
3508 myMesh->GetMeshDS()->Modified();
3509 myMesh->SetIsModified( true );
3512 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3515 //=======================================================================
3518 //=======================================================================
3520 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3521 const SMESH::AxisStruct & theAxis,
3522 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3523 CORBA::Boolean theCopy)
3525 if ( !myIsPreviewMode ) {
3526 TPythonDump() << this << ".Mirror( "
3527 << theIDsOfElements << ", "
3529 << mirrorTypeName(theMirrorType) << ", "
3532 if ( theIDsOfElements.length() > 0 )
3534 TIDSortedElemSet elements;
3535 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3536 mirror(elements, theAxis, theMirrorType, theCopy, false);
3541 //=======================================================================
3542 //function : MirrorObject
3544 //=======================================================================
3546 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3547 const SMESH::AxisStruct & theAxis,
3548 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3549 CORBA::Boolean theCopy)
3551 if ( !myIsPreviewMode ) {
3552 TPythonDump() << this << ".MirrorObject( "
3553 << theObject << ", "
3555 << mirrorTypeName(theMirrorType) << ", "
3558 TIDSortedElemSet elements;
3560 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3562 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3563 mirror(elements, theAxis, theMirrorType, theCopy, false);
3566 //=======================================================================
3567 //function : MirrorMakeGroups
3569 //=======================================================================
3571 SMESH::ListOfGroups*
3572 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3573 const SMESH::AxisStruct& theMirror,
3574 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3576 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3578 SMESH::ListOfGroups * aGroups = 0;
3579 if ( theIDsOfElements.length() > 0 )
3581 TIDSortedElemSet elements;
3582 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3583 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3585 if (!myIsPreviewMode) {
3586 DumpGroupsList(aPythonDump, aGroups);
3587 aPythonDump << this << ".MirrorMakeGroups( "
3588 << theIDsOfElements << ", "
3589 << theMirror << ", "
3590 << mirrorTypeName(theMirrorType) << " )";
3595 //=======================================================================
3596 //function : MirrorObjectMakeGroups
3598 //=======================================================================
3600 SMESH::ListOfGroups*
3601 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3602 const SMESH::AxisStruct& theMirror,
3603 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3605 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3607 SMESH::ListOfGroups * aGroups = 0;
3608 TIDSortedElemSet elements;
3609 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3610 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3612 if (!myIsPreviewMode)
3614 DumpGroupsList(aPythonDump,aGroups);
3615 aPythonDump << this << ".MirrorObjectMakeGroups( "
3616 << theObject << ", "
3617 << theMirror << ", "
3618 << mirrorTypeName(theMirrorType) << " )";
3623 //=======================================================================
3624 //function : MirrorMakeMesh
3626 //=======================================================================
3628 SMESH::SMESH_Mesh_ptr
3629 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3630 const SMESH::AxisStruct& theMirror,
3631 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3632 CORBA::Boolean theCopyGroups,
3633 const char* theMeshName)
3635 SMESH_Mesh_i* mesh_i;
3636 SMESH::SMESH_Mesh_var mesh;
3637 { // open new scope to dump "MakeMesh" command
3638 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3640 TPythonDump pydump; // to prevent dump at mesh creation
3642 mesh = makeMesh( theMeshName );
3643 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3644 if (mesh_i && theIDsOfElements.length() > 0 )
3646 TIDSortedElemSet elements;
3647 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3648 mirror(elements, theMirror, theMirrorType,
3649 false, theCopyGroups, & mesh_i->GetImpl());
3650 mesh_i->CreateGroupServants();
3653 if (!myIsPreviewMode) {
3654 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3655 << theIDsOfElements << ", "
3656 << theMirror << ", "
3657 << mirrorTypeName(theMirrorType) << ", "
3658 << theCopyGroups << ", '"
3659 << theMeshName << "' )";
3664 if (!myIsPreviewMode && mesh_i)
3665 mesh_i->GetGroups();
3667 return mesh._retn();
3670 //=======================================================================
3671 //function : MirrorObjectMakeMesh
3673 //=======================================================================
3675 SMESH::SMESH_Mesh_ptr
3676 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3677 const SMESH::AxisStruct& theMirror,
3678 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3679 CORBA::Boolean theCopyGroups,
3680 const char* theMeshName)
3682 SMESH_Mesh_i* mesh_i;
3683 SMESH::SMESH_Mesh_var mesh;
3684 { // open new scope to dump "MakeMesh" command
3685 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3687 TPythonDump pydump; // to prevent dump at mesh creation
3689 mesh = makeMesh( theMeshName );
3690 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3691 TIDSortedElemSet elements;
3693 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3695 mirror(elements, theMirror, theMirrorType,
3696 false, theCopyGroups, & mesh_i->GetImpl());
3697 mesh_i->CreateGroupServants();
3699 if (!myIsPreviewMode) {
3700 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3701 << theObject << ", "
3702 << theMirror << ", "
3703 << mirrorTypeName(theMirrorType) << ", "
3704 << theCopyGroups << ", '"
3705 << theMeshName << "' )";
3710 if (!myIsPreviewMode && mesh_i)
3711 mesh_i->GetGroups();
3713 return mesh._retn();
3716 //=======================================================================
3717 //function : translate
3719 //=======================================================================
3721 SMESH::ListOfGroups*
3722 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3723 const SMESH::DirStruct & theVector,
3724 CORBA::Boolean theCopy,
3726 ::SMESH_Mesh* theTargetMesh)
3730 if ( theTargetMesh )
3734 const SMESH::PointStruct * P = &theVector.PS;
3735 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3737 TIDSortedElemSet copyElements;
3738 TIDSortedElemSet* workElements = &theElements;
3740 if ( myIsPreviewMode )
3742 TPreviewMesh * tmpMesh = getPreviewMesh();
3743 tmpMesh->Copy( theElements, copyElements);
3744 if ( !theCopy && !theTargetMesh )
3746 TIDSortedElemSet elemsAround, elemsAroundCopy;
3747 getElementsAround( theElements, getMeshDS(), elemsAround );
3748 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3750 workElements = & copyElements;
3751 theMakeGroups = false;
3754 ::SMESH_MeshEditor::PGroupIDs groupIds =
3755 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3757 if ( theCopy && !myIsPreviewMode )
3759 if ( theTargetMesh )
3761 theTargetMesh->GetMeshDS()->Modified();
3765 myMesh->GetMeshDS()->Modified();
3766 myMesh->SetIsModified( true );
3770 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3773 //=======================================================================
3774 //function : Translate
3776 //=======================================================================
3778 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3779 const SMESH::DirStruct & theVector,
3780 CORBA::Boolean theCopy)
3782 if (!myIsPreviewMode) {
3783 TPythonDump() << this << ".Translate( "
3784 << theIDsOfElements << ", "
3785 << theVector << ", "
3788 if (theIDsOfElements.length()) {
3789 TIDSortedElemSet elements;
3790 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3791 translate(elements, theVector, theCopy, false);
3795 //=======================================================================
3796 //function : TranslateObject
3798 //=======================================================================
3800 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3801 const SMESH::DirStruct & theVector,
3802 CORBA::Boolean theCopy)
3804 if (!myIsPreviewMode) {
3805 TPythonDump() << this << ".TranslateObject( "
3806 << theObject << ", "
3807 << theVector << ", "
3810 TIDSortedElemSet elements;
3812 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3814 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3815 translate(elements, theVector, theCopy, false);
3818 //=======================================================================
3819 //function : TranslateMakeGroups
3821 //=======================================================================
3823 SMESH::ListOfGroups*
3824 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3825 const SMESH::DirStruct& theVector)
3827 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3829 SMESH::ListOfGroups * aGroups = 0;
3830 if (theIDsOfElements.length()) {
3831 TIDSortedElemSet elements;
3832 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3833 aGroups = translate(elements,theVector,true,true);
3835 if (!myIsPreviewMode) {
3836 DumpGroupsList(aPythonDump, aGroups);
3837 aPythonDump << this << ".TranslateMakeGroups( "
3838 << theIDsOfElements << ", "
3839 << theVector << " )";
3844 //=======================================================================
3845 //function : TranslateObjectMakeGroups
3847 //=======================================================================
3849 SMESH::ListOfGroups*
3850 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3851 const SMESH::DirStruct& theVector)
3853 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3855 SMESH::ListOfGroups * aGroups = 0;
3856 TIDSortedElemSet elements;
3857 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3858 aGroups = translate(elements, theVector, true, true);
3860 if (!myIsPreviewMode) {
3861 DumpGroupsList(aPythonDump, aGroups);
3862 aPythonDump << this << ".TranslateObjectMakeGroups( "
3863 << theObject << ", "
3864 << theVector << " )";
3869 //=======================================================================
3870 //function : TranslateMakeMesh
3872 //=======================================================================
3874 SMESH::SMESH_Mesh_ptr
3875 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3876 const SMESH::DirStruct& theVector,
3877 CORBA::Boolean theCopyGroups,
3878 const char* theMeshName)
3880 SMESH_Mesh_i* mesh_i;
3881 SMESH::SMESH_Mesh_var mesh;
3883 { // open new scope to dump "MakeMesh" command
3884 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3886 TPythonDump pydump; // to prevent dump at mesh creation
3888 mesh = makeMesh( theMeshName );
3889 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3891 if ( mesh_i && theIDsOfElements.length() )
3893 TIDSortedElemSet elements;
3894 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3895 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3896 mesh_i->CreateGroupServants();
3899 if ( !myIsPreviewMode ) {
3900 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3901 << theIDsOfElements << ", "
3902 << theVector << ", "
3903 << theCopyGroups << ", '"
3904 << theMeshName << "' )";
3909 if (!myIsPreviewMode && mesh_i)
3910 mesh_i->GetGroups();
3912 return mesh._retn();
3915 //=======================================================================
3916 //function : TranslateObjectMakeMesh
3918 //=======================================================================
3920 SMESH::SMESH_Mesh_ptr
3921 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3922 const SMESH::DirStruct& theVector,
3923 CORBA::Boolean theCopyGroups,
3924 const char* theMeshName)
3926 SMESH_Mesh_i* mesh_i;
3927 SMESH::SMESH_Mesh_var mesh;
3928 { // open new scope to dump "MakeMesh" command
3929 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3931 TPythonDump pydump; // to prevent dump at mesh creation
3932 mesh = makeMesh( theMeshName );
3933 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3935 TIDSortedElemSet elements;
3937 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3939 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3940 mesh_i->CreateGroupServants();
3942 if ( !myIsPreviewMode ) {
3943 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3944 << theObject << ", "
3945 << theVector << ", "
3946 << theCopyGroups << ", '"
3947 << theMeshName << "' )";
3952 if (!myIsPreviewMode && mesh_i)
3953 mesh_i->GetGroups();
3955 return mesh._retn();
3958 //=======================================================================
3961 //=======================================================================
3963 SMESH::ListOfGroups*
3964 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3965 const SMESH::AxisStruct & theAxis,
3966 CORBA::Double theAngle,
3967 CORBA::Boolean theCopy,
3969 ::SMESH_Mesh* theTargetMesh)
3973 if ( theTargetMesh )
3976 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3977 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3980 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3982 TIDSortedElemSet copyElements;
3983 TIDSortedElemSet* workElements = &theElements;
3984 if ( myIsPreviewMode ) {
3985 TPreviewMesh * tmpMesh = getPreviewMesh();
3986 tmpMesh->Copy( theElements, copyElements );
3987 if ( !theCopy && !theTargetMesh )
3989 TIDSortedElemSet elemsAround, elemsAroundCopy;
3990 getElementsAround( theElements, getMeshDS(), elemsAround );
3991 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3993 workElements = ©Elements;
3994 theMakeGroups = false;
3997 ::SMESH_MeshEditor::PGroupIDs groupIds =
3998 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4000 if ( theCopy && !myIsPreviewMode)
4002 if ( theTargetMesh )
4004 theTargetMesh->GetMeshDS()->Modified();
4008 myMesh->GetMeshDS()->Modified();
4009 myMesh->SetIsModified( true );
4013 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4016 //=======================================================================
4019 //=======================================================================
4021 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4022 const SMESH::AxisStruct & theAxis,
4023 CORBA::Double theAngle,
4024 CORBA::Boolean theCopy)
4026 if (!myIsPreviewMode) {
4027 TPythonDump() << this << ".Rotate( "
4028 << theIDsOfElements << ", "
4030 << TVar( theAngle ) << ", "
4033 if (theIDsOfElements.length() > 0)
4035 TIDSortedElemSet elements;
4036 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4037 rotate(elements,theAxis,theAngle,theCopy,false);
4041 //=======================================================================
4042 //function : RotateObject
4044 //=======================================================================
4046 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4047 const SMESH::AxisStruct & theAxis,
4048 CORBA::Double theAngle,
4049 CORBA::Boolean theCopy)
4051 if ( !myIsPreviewMode ) {
4052 TPythonDump() << this << ".RotateObject( "
4053 << theObject << ", "
4055 << TVar( theAngle ) << ", "
4058 TIDSortedElemSet elements;
4059 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4060 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4061 rotate(elements,theAxis,theAngle,theCopy,false);
4064 //=======================================================================
4065 //function : RotateMakeGroups
4067 //=======================================================================
4069 SMESH::ListOfGroups*
4070 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4071 const SMESH::AxisStruct& theAxis,
4072 CORBA::Double theAngle)
4074 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4076 SMESH::ListOfGroups * aGroups = 0;
4077 if (theIDsOfElements.length() > 0)
4079 TIDSortedElemSet elements;
4080 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4081 aGroups = rotate(elements,theAxis,theAngle,true,true);
4083 if (!myIsPreviewMode) {
4084 DumpGroupsList(aPythonDump, aGroups);
4085 aPythonDump << this << ".RotateMakeGroups( "
4086 << theIDsOfElements << ", "
4088 << TVar( theAngle ) << " )";
4093 //=======================================================================
4094 //function : RotateObjectMakeGroups
4096 //=======================================================================
4098 SMESH::ListOfGroups*
4099 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4100 const SMESH::AxisStruct& theAxis,
4101 CORBA::Double theAngle)
4103 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4105 SMESH::ListOfGroups * aGroups = 0;
4106 TIDSortedElemSet elements;
4107 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4108 aGroups = rotate(elements, theAxis, theAngle, true, true);
4110 if (!myIsPreviewMode) {
4111 DumpGroupsList(aPythonDump, aGroups);
4112 aPythonDump << this << ".RotateObjectMakeGroups( "
4113 << theObject << ", "
4115 << TVar( theAngle ) << " )";
4120 //=======================================================================
4121 //function : RotateMakeMesh
4123 //=======================================================================
4125 SMESH::SMESH_Mesh_ptr
4126 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4127 const SMESH::AxisStruct& theAxis,
4128 CORBA::Double theAngleInRadians,
4129 CORBA::Boolean theCopyGroups,
4130 const char* theMeshName)
4132 SMESH::SMESH_Mesh_var mesh;
4133 SMESH_Mesh_i* mesh_i;
4135 { // open new scope to dump "MakeMesh" command
4136 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4138 TPythonDump pydump; // to prevent dump at mesh creation
4140 mesh = makeMesh( theMeshName );
4141 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4143 if ( mesh_i && theIDsOfElements.length() > 0 )
4145 TIDSortedElemSet elements;
4146 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4147 rotate(elements, theAxis, theAngleInRadians,
4148 false, theCopyGroups, & mesh_i->GetImpl());
4149 mesh_i->CreateGroupServants();
4151 if ( !myIsPreviewMode ) {
4152 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4153 << theIDsOfElements << ", "
4155 << TVar( theAngleInRadians ) << ", "
4156 << theCopyGroups << ", '"
4157 << theMeshName << "' )";
4162 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4163 mesh_i->GetGroups();
4165 return mesh._retn();
4168 //=======================================================================
4169 //function : RotateObjectMakeMesh
4171 //=======================================================================
4173 SMESH::SMESH_Mesh_ptr
4174 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4175 const SMESH::AxisStruct& theAxis,
4176 CORBA::Double theAngleInRadians,
4177 CORBA::Boolean theCopyGroups,
4178 const char* theMeshName)
4180 SMESH::SMESH_Mesh_var mesh;
4181 SMESH_Mesh_i* mesh_i;
4183 {// open new scope to dump "MakeMesh" command
4184 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4186 TPythonDump pydump; // to prevent dump at mesh creation
4187 mesh = makeMesh( theMeshName );
4188 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4190 TIDSortedElemSet elements;
4192 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4194 rotate(elements, theAxis, theAngleInRadians,
4195 false, theCopyGroups, & mesh_i->GetImpl());
4196 mesh_i->CreateGroupServants();
4198 if ( !myIsPreviewMode ) {
4199 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4200 << theObject << ", "
4202 << TVar( theAngleInRadians ) << ", "
4203 << theCopyGroups << ", '"
4204 << theMeshName << "' )";
4209 if (!myIsPreviewMode && mesh_i)
4210 mesh_i->GetGroups();
4212 return mesh._retn();
4215 //=======================================================================
4218 //=======================================================================
4220 SMESH::ListOfGroups*
4221 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4222 const SMESH::PointStruct& thePoint,
4223 const SMESH::double_array& theScaleFact,
4224 CORBA::Boolean theCopy,
4226 ::SMESH_Mesh* theTargetMesh)
4229 if ( theScaleFact.length() < 1 )
4230 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4231 if ( theScaleFact.length() == 2 )
4232 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4234 if ( theTargetMesh )
4237 TIDSortedElemSet elements;
4238 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4239 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4244 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4245 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4247 double tol = std::numeric_limits<double>::max();
4249 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4250 0, S[1], 0, thePoint.y * (1-S[1]),
4251 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4253 TIDSortedElemSet copyElements;
4254 TIDSortedElemSet* workElements = &elements;
4255 if ( myIsPreviewMode )
4257 TPreviewMesh * tmpMesh = getPreviewMesh();
4258 tmpMesh->Copy( elements, copyElements);
4259 if ( !theCopy && !theTargetMesh )
4261 TIDSortedElemSet elemsAround, elemsAroundCopy;
4262 getElementsAround( elements, getMeshDS(), elemsAround );
4263 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4265 workElements = & copyElements;
4266 theMakeGroups = false;
4269 ::SMESH_MeshEditor::PGroupIDs groupIds =
4270 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4272 if ( theCopy && !myIsPreviewMode )
4274 if ( theTargetMesh )
4276 theTargetMesh->GetMeshDS()->Modified();
4280 myMesh->GetMeshDS()->Modified();
4281 myMesh->SetIsModified( true );
4285 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4288 //=======================================================================
4291 //=======================================================================
4293 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4294 const SMESH::PointStruct& thePoint,
4295 const SMESH::double_array& theScaleFact,
4296 CORBA::Boolean theCopy)
4298 if ( !myIsPreviewMode ) {
4299 TPythonDump() << this << ".Scale( "
4300 << theObject << ", "
4302 << TVar( theScaleFact ) << ", "
4305 scale(theObject, thePoint, theScaleFact, theCopy, false);
4309 //=======================================================================
4310 //function : ScaleMakeGroups
4312 //=======================================================================
4314 SMESH::ListOfGroups*
4315 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4316 const SMESH::PointStruct& thePoint,
4317 const SMESH::double_array& theScaleFact)
4319 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4321 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4322 if (!myIsPreviewMode) {
4323 DumpGroupsList(aPythonDump, aGroups);
4324 aPythonDump << this << ".Scale("
4327 << TVar( theScaleFact ) << ",True,True)";
4333 //=======================================================================
4334 //function : ScaleMakeMesh
4336 //=======================================================================
4338 SMESH::SMESH_Mesh_ptr
4339 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4340 const SMESH::PointStruct& thePoint,
4341 const SMESH::double_array& theScaleFact,
4342 CORBA::Boolean theCopyGroups,
4343 const char* theMeshName)
4345 SMESH_Mesh_i* mesh_i;
4346 SMESH::SMESH_Mesh_var mesh;
4347 { // open new scope to dump "MakeMesh" command
4348 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4350 TPythonDump pydump; // to prevent dump at mesh creation
4351 mesh = makeMesh( theMeshName );
4352 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4356 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4357 mesh_i->CreateGroupServants();
4359 if ( !myIsPreviewMode )
4360 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4361 << theObject << ", "
4363 << TVar( theScaleFact ) << ", "
4364 << theCopyGroups << ", '"
4365 << theMeshName << "' )";
4369 if (!myIsPreviewMode && mesh_i)
4370 mesh_i->GetGroups();
4372 return mesh._retn();
4376 //=======================================================================
4377 //function : FindCoincidentNodes
4379 //=======================================================================
4381 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4382 SMESH::array_of_long_array_out GroupsOfNodes)
4386 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4387 TIDSortedNodeSet nodes; // no input nodes
4388 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4390 GroupsOfNodes = new SMESH::array_of_long_array;
4391 GroupsOfNodes->length( aListOfListOfNodes.size() );
4392 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4393 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4394 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4395 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4396 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4397 aGroup.length( aListOfNodes.size() );
4398 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4399 aGroup[ j ] = (*lIt)->GetID();
4401 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4402 << Tolerance << " )";
4405 //=======================================================================
4406 //function : FindCoincidentNodesOnPart
4408 //=======================================================================
4409 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4410 CORBA::Double Tolerance,
4411 SMESH::array_of_long_array_out GroupsOfNodes)
4415 TIDSortedNodeSet nodes;
4416 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4418 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4420 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4422 GroupsOfNodes = new SMESH::array_of_long_array;
4423 GroupsOfNodes->length( aListOfListOfNodes.size() );
4424 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4425 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4427 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4428 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4429 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4430 aGroup.length( aListOfNodes.size() );
4431 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4432 aGroup[ j ] = (*lIt)->GetID();
4434 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4436 << Tolerance << " )";
4439 //================================================================================
4441 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4442 * ExceptSubMeshOrGroups
4444 //================================================================================
4446 void SMESH_MeshEditor_i::
4447 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4448 CORBA::Double theTolerance,
4449 SMESH::array_of_long_array_out theGroupsOfNodes,
4450 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4454 TIDSortedNodeSet nodes;
4455 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4457 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4459 TIDSortedNodeSet exceptNodes;
4460 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4461 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4462 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4463 nodes.erase( *avoidNode );
4465 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4467 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4469 theGroupsOfNodes = new SMESH::array_of_long_array;
4470 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4471 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4472 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4474 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4475 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4476 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4477 aGroup.length( aListOfNodes.size() );
4478 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4479 aGroup[ j ] = (*lIt)->GetID();
4481 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4483 << theTolerance << ", "
4484 << theExceptSubMeshOrGroups << " )";
4487 //=======================================================================
4488 //function : MergeNodes
4490 //=======================================================================
4492 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4496 SMESHDS_Mesh* aMesh = getMeshDS();
4498 TPythonDump aTPythonDump;
4499 aTPythonDump << this << ".MergeNodes([";
4500 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4501 for (int i = 0; i < GroupsOfNodes.length(); i++)
4503 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4504 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4505 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4506 for ( int j = 0; j < aNodeGroup.length(); j++ )
4508 CORBA::Long index = aNodeGroup[ j ];
4509 const SMDS_MeshNode * node = aMesh->FindNode(index);
4511 aListOfNodes.push_back( node );
4513 if ( aListOfNodes.size() < 2 )
4514 aListOfListOfNodes.pop_back();
4516 if ( i > 0 ) aTPythonDump << ", ";
4517 aTPythonDump << aNodeGroup;
4519 getEditor().MergeNodes( aListOfListOfNodes );
4521 aTPythonDump << "])";
4522 myMesh->GetMeshDS()->Modified();
4523 myMesh->SetIsModified( true );
4526 //=======================================================================
4527 //function : FindEqualElements
4529 //=======================================================================
4530 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4531 SMESH::array_of_long_array_out GroupsOfElementsID)
4535 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4536 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4538 TIDSortedElemSet elems;
4539 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4541 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4542 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4544 GroupsOfElementsID = new SMESH::array_of_long_array;
4545 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4547 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4548 aListOfListOfElementsID.begin();
4549 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4551 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4552 list<int>& listOfIDs = *arraysIt;
4553 aGroup.length( listOfIDs.size() );
4554 list<int>::iterator idIt = listOfIDs.begin();
4555 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4556 aGroup[ k ] = *idIt;
4559 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4564 //=======================================================================
4565 //function : MergeElements
4567 //=======================================================================
4569 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4573 TPythonDump aTPythonDump;
4574 aTPythonDump << this << ".MergeElements( [";
4576 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4578 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4579 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4580 aListOfListOfElementsID.push_back( list< int >() );
4581 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4582 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4583 CORBA::Long id = anElemsIDGroup[ j ];
4584 aListOfElemsID.push_back( id );
4586 if ( aListOfElemsID.size() < 2 )
4587 aListOfListOfElementsID.pop_back();
4588 if ( i > 0 ) aTPythonDump << ", ";
4589 aTPythonDump << anElemsIDGroup;
4592 getEditor().MergeElements(aListOfListOfElementsID);
4593 myMesh->GetMeshDS()->Modified();
4594 myMesh->SetIsModified( true );
4596 aTPythonDump << "] )";
4599 //=======================================================================
4600 //function : MergeEqualElements
4602 //=======================================================================
4604 void SMESH_MeshEditor_i::MergeEqualElements()
4608 getEditor().MergeEqualElements();
4610 myMesh->GetMeshDS()->Modified();
4612 TPythonDump() << this << ".MergeEqualElements()";
4615 //=============================================================================
4617 * Move the node to a given point
4619 //=============================================================================
4621 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4626 initData(/*deleteSearchers=*/false);
4628 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4632 if ( theNodeSearcher )
4633 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4635 if ( myIsPreviewMode ) // make preview data
4637 // in a preview mesh, make edges linked to a node
4638 TPreviewMesh& tmpMesh = *getPreviewMesh();
4639 TIDSortedElemSet linkedNodes;
4640 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4641 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4642 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4643 for ( ; nIt != linkedNodes.end(); ++nIt )
4645 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4646 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4650 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4651 // fill preview data
4653 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4654 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4656 getMeshDS()->MoveNode(node, x, y, z);
4658 if ( !myIsPreviewMode )
4660 // Update Python script
4661 TPythonDump() << "isDone = " << this << ".MoveNode( "
4662 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4663 myMesh->GetMeshDS()->Modified();
4664 myMesh->SetIsModified( true );
4670 //================================================================================
4672 * \brief Return ID of node closest to a given point
4674 //================================================================================
4676 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4680 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4682 if ( !theNodeSearcher ) {
4683 theNodeSearcher = myEditor.GetNodeSearcher();
4686 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4687 return node->GetID();
4692 //================================================================================
4694 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4695 * move the node closest to the point to point's location and return ID of the node
4697 //================================================================================
4699 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4702 CORBA::Long theNodeID)
4704 // We keep theNodeSearcher until any mesh modification:
4705 // 1) initData() deletes theNodeSearcher at any edition,
4706 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4708 initData(/*deleteSearchers=*/false);
4710 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4712 int nodeID = theNodeID;
4713 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
4714 if ( !node ) // preview moving node
4716 if ( !theNodeSearcher ) {
4717 theNodeSearcher = myEditor.GetNodeSearcher();
4720 node = theNodeSearcher->FindClosestTo( p );
4723 nodeID = node->GetID();
4724 if ( myIsPreviewMode ) // make preview data
4726 // in a preview mesh, make edges linked to a node
4727 TPreviewMesh tmpMesh = *getPreviewMesh();
4728 TIDSortedElemSet linkedNodes;
4729 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4730 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4731 for ( ; nIt != linkedNodes.end(); ++nIt )
4733 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4734 tmpMesh.Copy( &edge );
4737 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4739 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4740 // fill preview data
4742 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4744 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4748 getMeshDS()->MoveNode(node, x, y, z);
4752 if ( !myIsPreviewMode )
4754 TPythonDump() << "nodeID = " << this
4755 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4756 << ", " << nodeID << " )";
4758 myMesh->GetMeshDS()->Modified();
4759 myMesh->SetIsModified( true );
4765 //=======================================================================
4767 * Return elements of given type where the given point is IN or ON.
4769 * 'ALL' type means elements of any type excluding nodes
4771 //=======================================================================
4773 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4776 SMESH::ElementType type)
4778 SMESH::long_array_var res = new SMESH::long_array;
4779 vector< const SMDS_MeshElement* > foundElems;
4781 theSearchersDeleter.Set( myMesh );
4782 if ( !theElementSearcher ) {
4783 theElementSearcher = myEditor.GetElementSearcher();
4785 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4786 SMDSAbs_ElementType( type ),
4788 res->length( foundElems.size() );
4789 for ( int i = 0; i < foundElems.size(); ++i )
4790 res[i] = foundElems[i]->GetID();
4792 if ( !myIsPreviewMode ) // call from tui
4793 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4802 //=======================================================================
4803 //function : FindAmongElementsByPoint
4804 //purpose : Searching among the given elements, return elements of given type
4805 // where the given point is IN or ON.
4806 // 'ALL' type means elements of any type excluding nodes
4807 //=======================================================================
4810 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4814 SMESH::ElementType type)
4816 SMESH::long_array_var res = new SMESH::long_array;
4818 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4819 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4820 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4821 type != types[0] ) // but search of elements of dim > 0
4824 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4825 return FindElementsByPoint( x,y,z, type );
4827 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4829 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4830 if ( !theElementSearcher )
4832 // create a searcher from elementIDs
4833 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4834 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4836 if ( !idSourceToSet( elementIDs, meshDS, elements,
4837 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4840 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4841 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4843 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
4846 vector< const SMDS_MeshElement* > foundElems;
4848 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4849 SMDSAbs_ElementType( type ),
4851 res->length( foundElems.size() );
4852 for ( int i = 0; i < foundElems.size(); ++i )
4853 res[i] = foundElems[i]->GetID();
4855 if ( !myIsPreviewMode ) // call from tui
4856 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4857 << elementIDs << ", "
4866 //=======================================================================
4867 //function : GetPointState
4868 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4869 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4870 //=======================================================================
4872 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4876 theSearchersDeleter.Set( myMesh );
4877 if ( !theElementSearcher ) {
4878 theElementSearcher = myEditor.GetElementSearcher();
4880 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4883 //=======================================================================
4884 //function : convError
4886 //=======================================================================
4888 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4890 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4894 RETCASE( SEW_BORDER1_NOT_FOUND );
4895 RETCASE( SEW_BORDER2_NOT_FOUND );
4896 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4897 RETCASE( SEW_BAD_SIDE_NODES );
4898 RETCASE( SEW_VOLUMES_TO_SPLIT );
4899 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4900 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4901 RETCASE( SEW_BAD_SIDE1_NODES );
4902 RETCASE( SEW_BAD_SIDE2_NODES );
4904 return SMESH::SMESH_MeshEditor::SEW_OK;
4907 //=======================================================================
4908 //function : SewFreeBorders
4910 //=======================================================================
4912 SMESH::SMESH_MeshEditor::Sew_Error
4913 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4914 CORBA::Long SecondNodeID1,
4915 CORBA::Long LastNodeID1,
4916 CORBA::Long FirstNodeID2,
4917 CORBA::Long SecondNodeID2,
4918 CORBA::Long LastNodeID2,
4919 CORBA::Boolean CreatePolygons,
4920 CORBA::Boolean CreatePolyedrs)
4924 SMESHDS_Mesh* aMesh = getMeshDS();
4926 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4927 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4928 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4929 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4930 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4931 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4933 if (!aBorderFirstNode ||
4934 !aBorderSecondNode||
4936 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4937 if (!aSide2FirstNode ||
4938 !aSide2SecondNode ||
4940 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4942 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4943 << FirstNodeID1 << ", "
4944 << SecondNodeID1 << ", "
4945 << LastNodeID1 << ", "
4946 << FirstNodeID2 << ", "
4947 << SecondNodeID2 << ", "
4948 << LastNodeID2 << ", "
4949 << CreatePolygons<< ", "
4950 << CreatePolyedrs<< " )";
4952 SMESH::SMESH_MeshEditor::Sew_Error error =
4953 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4964 myMesh->GetMeshDS()->Modified();
4965 myMesh->SetIsModified( true );
4971 //=======================================================================
4972 //function : SewConformFreeBorders
4974 //=======================================================================
4976 SMESH::SMESH_MeshEditor::Sew_Error
4977 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4978 CORBA::Long SecondNodeID1,
4979 CORBA::Long LastNodeID1,
4980 CORBA::Long FirstNodeID2,
4981 CORBA::Long SecondNodeID2)
4985 SMESHDS_Mesh* aMesh = getMeshDS();
4987 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4988 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4989 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4990 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4991 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4992 const SMDS_MeshNode* aSide2ThirdNode = 0;
4994 if (!aBorderFirstNode ||
4995 !aBorderSecondNode||
4997 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4998 if (!aSide2FirstNode ||
5000 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5002 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5003 << FirstNodeID1 << ", "
5004 << SecondNodeID1 << ", "
5005 << LastNodeID1 << ", "
5006 << FirstNodeID2 << ", "
5007 << SecondNodeID2 << " )";
5009 SMESH::SMESH_MeshEditor::Sew_Error error =
5010 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5020 myMesh->GetMeshDS()->Modified();
5021 myMesh->SetIsModified( true );
5027 //=======================================================================
5028 //function : SewBorderToSide
5030 //=======================================================================
5032 SMESH::SMESH_MeshEditor::Sew_Error
5033 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5034 CORBA::Long SecondNodeIDOnFreeBorder,
5035 CORBA::Long LastNodeIDOnFreeBorder,
5036 CORBA::Long FirstNodeIDOnSide,
5037 CORBA::Long LastNodeIDOnSide,
5038 CORBA::Boolean CreatePolygons,
5039 CORBA::Boolean CreatePolyedrs)
5043 SMESHDS_Mesh* aMesh = getMeshDS();
5045 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5046 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5047 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5048 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5049 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5050 const SMDS_MeshNode* aSide2ThirdNode = 0;
5052 if (!aBorderFirstNode ||
5053 !aBorderSecondNode||
5055 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5056 if (!aSide2FirstNode ||
5058 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5060 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5061 << FirstNodeIDOnFreeBorder << ", "
5062 << SecondNodeIDOnFreeBorder << ", "
5063 << LastNodeIDOnFreeBorder << ", "
5064 << FirstNodeIDOnSide << ", "
5065 << LastNodeIDOnSide << ", "
5066 << CreatePolygons << ", "
5067 << CreatePolyedrs << ") ";
5069 SMESH::SMESH_MeshEditor::Sew_Error error =
5070 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5081 myMesh->GetMeshDS()->Modified();
5082 myMesh->SetIsModified( true );
5088 //=======================================================================
5089 //function : SewSideElements
5091 //=======================================================================
5093 SMESH::SMESH_MeshEditor::Sew_Error
5094 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5095 const SMESH::long_array& IDsOfSide2Elements,
5096 CORBA::Long NodeID1OfSide1ToMerge,
5097 CORBA::Long NodeID1OfSide2ToMerge,
5098 CORBA::Long NodeID2OfSide1ToMerge,
5099 CORBA::Long NodeID2OfSide2ToMerge)
5103 SMESHDS_Mesh* aMesh = getMeshDS();
5105 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5106 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5107 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5108 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5110 if (!aFirstNode1ToMerge ||
5111 !aFirstNode2ToMerge )
5112 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5113 if (!aSecondNode1ToMerge||
5114 !aSecondNode2ToMerge)
5115 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5117 TIDSortedElemSet aSide1Elems, aSide2Elems;
5118 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5119 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5121 TPythonDump() << "error = " << this << ".SewSideElements( "
5122 << IDsOfSide1Elements << ", "
5123 << IDsOfSide2Elements << ", "
5124 << NodeID1OfSide1ToMerge << ", "
5125 << NodeID1OfSide2ToMerge << ", "
5126 << NodeID2OfSide1ToMerge << ", "
5127 << NodeID2OfSide2ToMerge << ")";
5129 SMESH::SMESH_MeshEditor::Sew_Error error =
5130 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5133 aSecondNode1ToMerge,
5134 aSecondNode2ToMerge));
5137 myMesh->GetMeshDS()->Modified();
5138 myMesh->SetIsModified( true );
5143 //================================================================================
5145 * \brief Set new nodes for given element
5146 * \param ide - element id
5147 * \param newIDs - new node ids
5148 * \retval CORBA::Boolean - true if result is OK
5150 //================================================================================
5152 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5153 const SMESH::long_array& newIDs)
5157 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5158 if(!elem) return false;
5160 int nbn = newIDs.length();
5162 vector<const SMDS_MeshNode*> aNodes(nbn);
5165 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5168 aNodes[nbn1] = aNode;
5171 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5172 << ide << ", " << newIDs << " )";
5174 MESSAGE("ChangeElementNodes");
5175 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5177 myMesh->GetMeshDS()->Modified();
5179 myMesh->SetIsModified( true );
5184 //=======================================================================
5185 //function : ConvertToQuadratic
5187 //=======================================================================
5189 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5191 getEditor().ConvertToQuadratic(theForce3d);
5192 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
5193 myMesh->GetMeshDS()->Modified();
5194 myMesh->SetIsModified( true );
5197 //=======================================================================
5198 //function : ConvertFromQuadratic
5200 //=======================================================================
5202 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5204 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5205 TPythonDump() << this << ".ConvertFromQuadratic()";
5206 myMesh->GetMeshDS()->Modified();
5208 myMesh->SetIsModified( true );
5211 //================================================================================
5213 * \brief Makes a part of the mesh quadratic
5215 //================================================================================
5217 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5218 SMESH::SMESH_IDSource_ptr theObject)
5219 throw (SALOME::SALOME_Exception)
5221 Unexpect aCatch(SALOME_SalomeException);
5223 TIDSortedElemSet elems;
5224 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5226 if ( elems.empty() )
5228 ConvertToQuadratic( theForce3d );
5230 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5232 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5236 getEditor().ConvertToQuadratic(theForce3d, elems);
5239 myMesh->GetMeshDS()->Modified();
5240 myMesh->SetIsModified( true );
5242 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
5245 //================================================================================
5247 * \brief Makes a part of the mesh linear
5249 //================================================================================
5251 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5252 throw (SALOME::SALOME_Exception)
5254 Unexpect aCatch(SALOME_SalomeException);
5256 TIDSortedElemSet elems;
5257 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5259 if ( elems.empty() )
5261 ConvertFromQuadratic();
5263 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5265 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5269 getEditor().ConvertFromQuadratic(elems);
5272 myMesh->GetMeshDS()->Modified();
5273 myMesh->SetIsModified( true );
5275 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5278 //=======================================================================
5279 //function : makeMesh
5280 //purpose : create a named imported mesh
5281 //=======================================================================
5283 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5285 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5286 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5287 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5288 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5289 gen->SetName( meshSO, theMeshName, "Mesh" );
5290 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5292 return mesh._retn();
5295 //=======================================================================
5296 //function : DumpGroupsList
5298 //=======================================================================
5299 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
5300 const SMESH::ListOfGroups * theGroupList)
5302 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
5303 if(isDumpGroupList) {
5304 theDumpPython << theGroupList << " = ";
5308 //================================================================================
5310 \brief Generates the unique group name.
5311 \param thePrefix name prefix
5314 //================================================================================
5315 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5317 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5318 set<string> groupNames;
5320 // Get existing group names
5321 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5322 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5323 if (CORBA::is_nil(aGroup))
5326 CORBA::String_var name = aGroup->GetName();
5327 groupNames.insert( name.in() );
5331 string name = thePrefix;
5334 while (!groupNames.insert(name).second)
5335 name = SMESH_Comment( thePrefix ) << "_" << index;
5340 //================================================================================
5342 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5343 \param theNodes - identifiers of nodes to be doubled
5344 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5345 nodes. If list of element identifiers is empty then nodes are doubled but
5346 they not assigned to elements
5347 \return TRUE if operation has been completed successfully, FALSE otherwise
5348 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5350 //================================================================================
5352 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5353 const SMESH::long_array& theModifiedElems )
5357 list< int > aListOfNodes;
5359 for ( i = 0, n = theNodes.length(); i < n; i++ )
5360 aListOfNodes.push_back( theNodes[ i ] );
5362 list< int > aListOfElems;
5363 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5364 aListOfElems.push_back( theModifiedElems[ i ] );
5366 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5368 myMesh->GetMeshDS()->Modified();
5370 myMesh->SetIsModified( true );
5372 // Update Python script
5373 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5378 //================================================================================
5380 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5381 This method provided for convenience works as DoubleNodes() described above.
5382 \param theNodeId - identifier of node to be doubled.
5383 \param theModifiedElems - identifiers of elements to be updated.
5384 \return TRUE if operation has been completed successfully, FALSE otherwise
5385 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5387 //================================================================================
5389 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5390 const SMESH::long_array& theModifiedElems )
5392 SMESH::long_array_var aNodes = new SMESH::long_array;
5393 aNodes->length( 1 );
5394 aNodes[ 0 ] = theNodeId;
5396 TPythonDump pyDump; // suppress dump by the next line
5398 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5400 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5405 //================================================================================
5407 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5408 This method provided for convenience works as DoubleNodes() described above.
5409 \param theNodes - group of nodes to be doubled.
5410 \param theModifiedElems - group of elements to be updated.
5411 \return TRUE if operation has been completed successfully, FALSE otherwise
5412 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5414 //================================================================================
5416 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5417 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5419 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5422 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5423 SMESH::long_array_var aModifiedElems;
5424 if ( !CORBA::is_nil( theModifiedElems ) )
5425 aModifiedElems = theModifiedElems->GetListOfID();
5428 aModifiedElems = new SMESH::long_array;
5429 aModifiedElems->length( 0 );
5432 TPythonDump pyDump; // suppress dump by the next line
5434 bool done = DoubleNodes( aNodes, aModifiedElems );
5436 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5442 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5443 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5444 * \param theNodes - group of nodes to be doubled.
5445 * \param theModifiedElems - group of elements to be updated.
5446 * \return a new group with newly created nodes
5447 * \sa DoubleNodeGroup()
5449 SMESH::SMESH_Group_ptr
5450 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5451 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5453 SMESH::SMESH_Group_var aNewGroup;
5455 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5456 return aNewGroup._retn();
5459 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5460 SMESH::long_array_var aModifiedElems;
5461 if ( !CORBA::is_nil( theModifiedElems ) )
5462 aModifiedElems = theModifiedElems->GetListOfID();
5464 aModifiedElems = new SMESH::long_array;
5465 aModifiedElems->length( 0 );
5468 TPythonDump pyDump; // suppress dump by the next line
5470 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5473 // Create group with newly created nodes
5474 SMESH::long_array_var anIds = GetLastCreatedNodes();
5475 if (anIds->length() > 0) {
5476 string anUnindexedName (theNodes->GetName());
5477 string aNewName = generateGroupName(anUnindexedName + "_double");
5478 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5479 aNewGroup->Add(anIds);
5480 pyDump << aNewGroup << " = ";
5484 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5485 << theModifiedElems << " )";
5487 return aNewGroup._retn();
5490 //================================================================================
5492 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5493 This method provided for convenience works as DoubleNodes() described above.
5494 \param theNodes - list of groups of nodes to be doubled
5495 \param theModifiedElems - list of groups of elements to be updated.
5496 \return TRUE if operation has been completed successfully, FALSE otherwise
5497 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5499 //================================================================================
5501 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5502 const SMESH::ListOfGroups& theModifiedElems )
5507 std::list< int > aNodes;
5509 for ( i = 0, n = theNodes.length(); i < n; i++ )
5511 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5512 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5514 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5515 for ( j = 0, m = aCurr->length(); j < m; j++ )
5516 aNodes.push_back( aCurr[ j ] );
5520 std::list< int > anElems;
5521 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5523 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5524 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5526 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5527 for ( j = 0, m = aCurr->length(); j < m; j++ )
5528 anElems.push_back( aCurr[ j ] );
5532 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
5535 myMesh->GetMeshDS()->Modified();
5537 myMesh->SetIsModified( true );
5540 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5545 //================================================================================
5547 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5548 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5549 * \param theNodes - group of nodes to be doubled.
5550 * \param theModifiedElems - group of elements to be updated.
5551 * \return a new group with newly created nodes
5552 * \sa DoubleNodeGroups()
5554 //================================================================================
5556 SMESH::SMESH_Group_ptr
5557 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5558 const SMESH::ListOfGroups& theModifiedElems )
5560 SMESH::SMESH_Group_var aNewGroup;
5562 TPythonDump pyDump; // suppress dump by the next line
5564 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5568 // Create group with newly created nodes
5569 SMESH::long_array_var anIds = GetLastCreatedNodes();
5570 if (anIds->length() > 0) {
5571 string anUnindexedName (theNodes[0]->GetName());
5572 string aNewName = generateGroupName(anUnindexedName + "_double");
5573 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5574 aNewGroup->Add(anIds);
5575 pyDump << aNewGroup << " = ";
5579 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5580 << theModifiedElems << " )";
5582 return aNewGroup._retn();
5586 //================================================================================
5588 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5589 \param theElems - the list of elements (edges or faces) to be replicated
5590 The nodes for duplication could be found from these elements
5591 \param theNodesNot - list of nodes to NOT replicate
5592 \param theAffectedElems - the list of elements (cells and edges) to which the
5593 replicated nodes should be associated to.
5594 \return TRUE if operation has been completed successfully, FALSE otherwise
5595 \sa DoubleNodeGroup(), DoubleNodeGroups()
5597 //================================================================================
5599 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5600 const SMESH::long_array& theNodesNot,
5601 const SMESH::long_array& theAffectedElems )
5607 SMESHDS_Mesh* aMeshDS = getMeshDS();
5608 TIDSortedElemSet anElems, aNodes, anAffected;
5609 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5610 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5611 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5613 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5616 myMesh->GetMeshDS()->Modified();
5618 myMesh->SetIsModified( true );
5620 // Update Python script
5621 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5622 << theNodesNot << ", " << theAffectedElems << " )";
5626 //================================================================================
5628 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5629 \param theElems - the list of elements (edges or faces) to be replicated
5630 The nodes for duplication could be found from these elements
5631 \param theNodesNot - list of nodes to NOT replicate
5632 \param theShape - shape to detect affected elements (element which geometric center
5633 located on or inside shape).
5634 The replicated nodes should be associated to affected elements.
5635 \return TRUE if operation has been completed successfully, FALSE otherwise
5636 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5638 //================================================================================
5640 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5641 const SMESH::long_array& theNodesNot,
5642 GEOM::GEOM_Object_ptr theShape )
5648 SMESHDS_Mesh* aMeshDS = getMeshDS();
5649 TIDSortedElemSet anElems, aNodes;
5650 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5651 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5653 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5654 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5657 myMesh->GetMeshDS()->Modified();
5659 myMesh->SetIsModified( true );
5661 // Update Python script
5662 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5663 << theNodesNot << ", " << theShape << " )";
5667 //================================================================================
5669 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5670 \param theElems - group of of elements (edges or faces) to be replicated
5671 \param theNodesNot - group of nodes not to replicated
5672 \param theAffectedElems - group of elements to which the replicated nodes
5673 should be associated to.
5674 \return TRUE if operation has been completed successfully, FALSE otherwise
5675 \sa DoubleNodes(), DoubleNodeGroups()
5677 //================================================================================
5679 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5680 SMESH::SMESH_GroupBase_ptr theNodesNot,
5681 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5683 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5689 SMESHDS_Mesh* aMeshDS = getMeshDS();
5690 TIDSortedElemSet anElems, aNodes, anAffected;
5691 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5692 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5693 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5695 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5698 myMesh->GetMeshDS()->Modified();
5700 myMesh->SetIsModified( true );
5702 // Update Python script
5703 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5704 << theNodesNot << ", " << theAffectedElems << " )";
5709 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5710 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5711 * \param theElems - group of of elements (edges or faces) to be replicated
5712 * \param theNodesNot - group of nodes not to replicated
5713 * \param theAffectedElems - group of elements to which the replicated nodes
5714 * should be associated to.
5715 * \return a new group with newly created elements
5716 * \sa DoubleNodeElemGroup()
5718 SMESH::SMESH_Group_ptr
5719 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5720 SMESH::SMESH_GroupBase_ptr theNodesNot,
5721 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5724 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5728 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5729 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5731 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5733 << theNodesNot << ", "
5734 << theAffectedElems << " )";
5736 return elemGroup._retn();
5739 SMESH::ListOfGroups*
5740 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5741 SMESH::SMESH_GroupBase_ptr theNodesNot,
5742 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5743 CORBA::Boolean theElemGroupNeeded,
5744 CORBA::Boolean theNodeGroupNeeded)
5746 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5747 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5748 aTwoGroups->length( 2 );
5750 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5751 return aTwoGroups._retn();
5756 SMESHDS_Mesh* aMeshDS = getMeshDS();
5757 TIDSortedElemSet anElems, aNodes, anAffected;
5758 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5759 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5760 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5763 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5765 myMesh->GetMeshDS()->Modified();
5771 myMesh->SetIsModified( true );
5773 // Create group with newly created elements
5774 CORBA::String_var elemGroupName = theElems->GetName();
5775 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5776 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5778 SMESH::long_array_var anIds = GetLastCreatedElems();
5779 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5780 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5781 aNewElemGroup->Add(anIds);
5783 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5785 SMESH::long_array_var anIds = GetLastCreatedNodes();
5786 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5787 aNewNodeGroup->Add(anIds);
5791 // Update Python script
5794 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5795 else pyDump << aNewElemGroup << ", ";
5796 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5797 else pyDump << aNewNodeGroup << " ] = ";
5799 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5800 << theNodesNot << ", "
5801 << theAffectedElems << ", "
5802 << theElemGroupNeeded << ", "
5803 << theNodeGroupNeeded <<" )";
5805 aTwoGroups[0] = aNewElemGroup._retn();
5806 aTwoGroups[1] = aNewNodeGroup._retn();
5807 return aTwoGroups._retn();
5810 //================================================================================
5812 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5813 \param theElems - group of of elements (edges or faces) to be replicated
5814 \param theNodesNot - group of nodes not to replicated
5815 \param theShape - shape to detect affected elements (element which geometric center
5816 located on or inside shape).
5817 The replicated nodes should be associated to affected elements.
5818 \return TRUE if operation has been completed successfully, FALSE otherwise
5819 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5821 //================================================================================
5823 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5824 SMESH::SMESH_GroupBase_ptr theNodesNot,
5825 GEOM::GEOM_Object_ptr theShape )
5828 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5834 SMESHDS_Mesh* aMeshDS = getMeshDS();
5835 TIDSortedElemSet anElems, aNodes, anAffected;
5836 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5837 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5839 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5840 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5843 myMesh->GetMeshDS()->Modified();
5845 myMesh->SetIsModified( true );
5847 // Update Python script
5848 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5849 << theNodesNot << ", " << theShape << " )";
5853 //================================================================================
5855 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5856 This method provided for convenience works as DoubleNodes() described above.
5857 \param theElems - list of groups of elements (edges or faces) to be replicated
5858 \param theNodesNot - list of groups of nodes not to replicated
5859 \param theAffectedElems - group of elements to which the replicated nodes
5860 should be associated to.
5861 \return TRUE if operation has been completed successfully, FALSE otherwise
5862 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5864 //================================================================================
5866 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5867 SMESHDS_Mesh* theMeshDS,
5868 TIDSortedElemSet& theElemSet,
5869 const bool theIsNodeGrp)
5871 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5873 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5874 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5875 : aGrp->GetType() != SMESH::NODE ) )
5877 SMESH::long_array_var anIDs = aGrp->GetIDs();
5878 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5883 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5884 const SMESH::ListOfGroups& theNodesNot,
5885 const SMESH::ListOfGroups& theAffectedElems)
5890 SMESHDS_Mesh* aMeshDS = getMeshDS();
5891 TIDSortedElemSet anElems, aNodes, anAffected;
5892 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5893 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5894 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5896 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5899 myMesh->GetMeshDS()->Modified();
5901 myMesh->SetIsModified( true );
5903 // Update Python script
5904 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5905 << &theNodesNot << ", " << &theAffectedElems << " )";
5909 //================================================================================
5911 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5912 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5913 \param theElems - list of groups of elements (edges or faces) to be replicated
5914 \param theNodesNot - list of groups of nodes not to replicated
5915 \param theAffectedElems - group of elements to which the replicated nodes
5916 should be associated to.
5917 * \return a new group with newly created elements
5918 * \sa DoubleNodeElemGroups()
5920 //================================================================================
5922 SMESH::SMESH_Group_ptr
5923 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5924 const SMESH::ListOfGroups& theNodesNot,
5925 const SMESH::ListOfGroups& theAffectedElems)
5928 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
5932 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5933 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5935 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
5937 << theNodesNot << ", "
5938 << theAffectedElems << " )";
5940 return elemGroup._retn();
5943 SMESH::ListOfGroups*
5944 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
5945 const SMESH::ListOfGroups& theNodesNot,
5946 const SMESH::ListOfGroups& theAffectedElems,
5947 CORBA::Boolean theElemGroupNeeded,
5948 CORBA::Boolean theNodeGroupNeeded)
5950 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5951 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5952 aTwoGroups->length( 2 );
5957 SMESHDS_Mesh* aMeshDS = getMeshDS();
5958 TIDSortedElemSet anElems, aNodes, anAffected;
5959 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5960 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5961 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5963 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5966 myMesh->GetMeshDS()->Modified();
5970 myMesh->SetIsModified( true );
5972 // Create group with newly created elements
5973 CORBA::String_var elemGroupName = theElems[0]->GetName();
5974 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5975 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5977 SMESH::long_array_var anIds = GetLastCreatedElems();
5978 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5979 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5980 aNewElemGroup->Add(anIds);
5982 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5984 SMESH::long_array_var anIds = GetLastCreatedNodes();
5985 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5986 aNewNodeGroup->Add(anIds);
5990 // Update Python script
5993 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5994 else pyDump << aNewElemGroup << ", ";
5995 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5996 else pyDump << aNewNodeGroup << " ] = ";
5998 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
5999 << &theNodesNot << ", "
6000 << &theAffectedElems << ", "
6001 << theElemGroupNeeded << ", "
6002 << theNodeGroupNeeded << " )";
6004 aTwoGroups[0] = aNewElemGroup._retn();
6005 aTwoGroups[1] = aNewNodeGroup._retn();
6006 return aTwoGroups._retn();
6009 //================================================================================
6011 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6012 This method provided for convenience works as DoubleNodes() described above.
6013 \param theElems - list of groups of elements (edges or faces) to be replicated
6014 \param theNodesNot - list of groups of nodes not to replicated
6015 \param theShape - shape to detect affected elements (element which geometric center
6016 located on or inside shape).
6017 The replicated nodes should be associated to affected elements.
6018 \return TRUE if operation has been completed successfully, FALSE otherwise
6019 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6021 //================================================================================
6024 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6025 const SMESH::ListOfGroups& theNodesNot,
6026 GEOM::GEOM_Object_ptr theShape )
6031 SMESHDS_Mesh* aMeshDS = getMeshDS();
6032 TIDSortedElemSet anElems, aNodes;
6033 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6034 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6036 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6037 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6040 myMesh->GetMeshDS()->Modified();
6042 myMesh->SetIsModified( true );
6044 // Update Python script
6045 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6046 << &theNodesNot << ", " << theShape << " )";
6050 //================================================================================
6052 \brief Identify the elements that will be affected by node duplication (actual duplication is not performed.
6053 This method is the first step of DoubleNodeElemGroupsInRegion.
6054 \param theElems - list of groups of elements (edges or faces) to be replicated
6055 \param theNodesNot - list of groups of nodes not to replicated
6056 \param theShape - shape to detect affected elements (element which geometric center
6057 located on or inside shape).
6058 The replicated nodes should be associated to affected elements.
6059 \return groups of affected elements
6060 \sa DoubleNodeElemGroupsInRegion()
6062 //================================================================================
6063 SMESH::ListOfGroups*
6064 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6065 const SMESH::ListOfGroups& theNodesNot,
6066 GEOM::GEOM_Object_ptr theShape )
6068 MESSAGE("AffectedElemGroupsInRegion");
6069 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6070 bool isEdgeGroup = false;
6071 bool isFaceGroup = false;
6072 bool isVolumeGroup = false;
6073 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6074 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6075 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6079 ::SMESH_MeshEditor aMeshEditor(myMesh);
6081 SMESHDS_Mesh* aMeshDS = getMeshDS();
6082 TIDSortedElemSet anElems, aNodes;
6083 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6084 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6086 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6087 TIDSortedElemSet anAffected;
6088 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6091 myMesh->GetMeshDS()->Modified();
6095 myMesh->SetIsModified(true);
6097 int lg = anAffected.size();
6098 MESSAGE("lg="<< lg);
6099 SMESH::long_array_var volumeIds = new SMESH::long_array;
6100 volumeIds->length(lg);
6101 SMESH::long_array_var faceIds = new SMESH::long_array;
6102 faceIds->length(lg);
6103 SMESH::long_array_var edgeIds = new SMESH::long_array;
6104 edgeIds->length(lg);
6109 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6110 for (; eIt != anAffected.end(); ++eIt)
6112 const SMDS_MeshElement* anElem = *eIt;
6115 int elemId = anElem->GetID();
6116 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6117 volumeIds[ivol++] = elemId;
6118 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6119 faceIds[iface++] = elemId;
6120 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6121 edgeIds[iedge++] = elemId;
6123 volumeIds->length(ivol);
6124 faceIds->length(iface);
6125 edgeIds->length(iedge);
6127 aNewVolumeGroup->Add(volumeIds);
6128 aNewFaceGroup->Add(faceIds);
6129 aNewEdgeGroup->Add(edgeIds);
6130 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6131 isFaceGroup = (aNewFaceGroup->Size() > 0);
6132 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6142 aListOfGroups->length(nbGroups);
6146 aListOfGroups[i++] = aNewEdgeGroup._retn();
6148 aListOfGroups[i++] = aNewFaceGroup._retn();
6150 aListOfGroups[i++] = aNewVolumeGroup._retn();
6152 // Update Python script
6156 pyDump << aNewEdgeGroup << ", ";
6158 pyDump << aNewFaceGroup << ", ";
6160 pyDump << aNewVolumeGroup << ", ";
6162 pyDump << this << ".AffectedElemGroupsInRegion( " << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6164 return aListOfGroups._retn();
6167 //================================================================================
6169 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6170 The created 2D mesh elements based on nodes of free faces of boundary volumes
6171 \return TRUE if operation has been completed successfully, FALSE otherwise
6173 //================================================================================
6175 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6179 bool aResult = getEditor().Make2DMeshFrom3D();
6180 myMesh->GetMeshDS()->Modified();
6181 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6185 //================================================================================
6187 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6188 * The list of groups must describe a partition of the mesh volumes.
6189 * The nodes of the internal faces at the boundaries of the groups are doubled.
6190 * In option, the internal faces are replaced by flat elements.
6191 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6192 * The flat elements are stored in groups of volumes.
6193 * @param theDomains - list of groups of volumes
6194 * @param createJointElems - if TRUE, create the elements
6195 * @return TRUE if operation has been completed successfully, FALSE otherwise
6197 //================================================================================
6199 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6200 CORBA::Boolean createJointElems )
6201 throw (SALOME::SALOME_Exception)
6203 bool aResult = false;
6208 SMESHDS_Mesh* aMeshDS = getMeshDS();
6210 vector<TIDSortedElemSet> domains;
6213 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6215 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6216 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6218 // if ( aGrp->GetType() != SMESH::VOLUME )
6219 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6220 TIDSortedElemSet domain;
6222 domains.push_back(domain);
6223 SMESH::long_array_var anIDs = aGrp->GetIDs();
6224 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6228 aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6229 // TODO publish the groups of flat elements in study
6231 myMesh->GetMeshDS()->Modified();
6233 // Update Python script
6234 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6235 << ", " << createJointElems << " )";
6237 SMESH_CATCH( SMESH::throwCorbaException );
6242 //================================================================================
6244 * \brief Double nodes on some external faces and create flat elements.
6245 * Flat elements are mainly used by some types of mechanic calculations.
6247 * Each group of the list must be constituted of faces.
6248 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6249 * @param theGroupsOfFaces - list of groups of faces
6250 * @return TRUE if operation has been completed successfully, FALSE otherwise
6252 //================================================================================
6254 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6259 SMESHDS_Mesh* aMeshDS = getMeshDS();
6261 vector<TIDSortedElemSet> faceGroups;
6264 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6266 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6267 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6269 TIDSortedElemSet faceGroup;
6271 faceGroups.push_back(faceGroup);
6272 SMESH::long_array_var anIDs = aGrp->GetIDs();
6273 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6277 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6278 // TODO publish the groups of flat elements in study
6280 myMesh->GetMeshDS()->Modified();
6282 // Update Python script
6283 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6288 * \brief identify all the elements around a geom shape, get the faces delimiting the hole
6289 * Build groups of volume to remove, groups of faces to replace on the skin of the object,
6290 * groups of faces to remove inside the object, (idem edges).
6291 * Build ordered list of nodes at the border of each group of faces to replace (to be used to build a geom subshape)
6293 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6294 GEOM::GEOM_Object_ptr theShape,
6295 const char* groupName,
6296 const SMESH::double_array& theNodesCoords,
6297 SMESH::array_of_long_array_out GroupsOfNodes)
6298 throw (SALOME::SALOME_Exception)
6303 std::vector<std::vector<int> > aListOfListOfNodes;
6304 ::SMESH_MeshEditor aMeshEditor( myMesh );
6306 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6307 if ( !theNodeSearcher )
6308 theNodeSearcher = aMeshEditor.GetNodeSearcher();
6310 vector<double> nodesCoords;
6311 for (int i = 0; i < theNodesCoords.length(); i++)
6313 nodesCoords.push_back( theNodesCoords[i] );
6316 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6317 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6318 nodesCoords, aListOfListOfNodes);
6320 GroupsOfNodes = new SMESH::array_of_long_array;
6321 GroupsOfNodes->length( aListOfListOfNodes.size() );
6322 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6323 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6325 vector<int>& aListOfNodes = *llIt;
6326 vector<int>::iterator lIt = aListOfNodes.begin();;
6327 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6328 aGroup.length( aListOfNodes.size() );
6329 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6330 aGroup[ j ] = (*lIt);
6332 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6335 << ", '" << groupName << "', "
6336 << theNodesCoords << " )";
6338 SMESH_CATCH( SMESH::throwCorbaException );
6342 // issue 20749 ===================================================================
6344 * \brief Creates missing boundary elements
6345 * \param elements - elements whose boundary is to be checked
6346 * \param dimension - defines type of boundary elements to create
6347 * \param groupName - a name of group to store created boundary elements in,
6348 * "" means not to create the group
6349 * \param meshName - a name of new mesh to store created boundary elements in,
6350 * "" means not to create the new mesh
6351 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6352 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6353 * boundary elements will be copied into the new mesh
6354 * \param group - returns the create group, if any
6355 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6357 // ================================================================================
6359 SMESH::SMESH_Mesh_ptr
6360 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6361 SMESH::Bnd_Dimension dim,
6362 const char* groupName,
6363 const char* meshName,
6364 CORBA::Boolean toCopyElements,
6365 CORBA::Boolean toCopyExistingBondary,
6366 SMESH::SMESH_Group_out group)
6370 if ( dim > SMESH::BND_1DFROM2D )
6371 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6373 SMESHDS_Mesh* aMeshDS = getMeshDS();
6375 SMESH::SMESH_Mesh_var mesh_var;
6376 SMESH::SMESH_Group_var group_var;
6380 TIDSortedElemSet elements;
6381 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6382 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6386 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6387 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6389 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6391 // group of new boundary elements
6392 SMESH_Group* smesh_group = 0;
6393 if ( strlen(groupName) )
6395 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6396 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6397 smesh_group = group_i->GetSmeshGroup();
6401 getEditor().MakeBoundaryMesh( elements,
6402 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6406 toCopyExistingBondary);
6409 smesh_mesh->GetMeshDS()->Modified();
6412 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6414 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6415 if ( mesh_var->_is_nil() )
6416 pyDump << myMesh_i->_this() << ", ";
6418 pyDump << mesh_var << ", ";
6419 if ( group_var->_is_nil() )
6420 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6422 pyDump << group_var << " = ";
6423 pyDump << this << ".MakeBoundaryMesh( "
6425 << "SMESH." << dimName[int(dim)] << ", "
6426 << "'" << groupName << "', "
6427 << "'" << meshName<< "', "
6428 << toCopyElements << ", "
6429 << toCopyExistingBondary << ")";
6431 group = group_var._retn();
6432 return mesh_var._retn();
6435 //================================================================================
6437 * \brief Creates missing boundary elements
6438 * \param dimension - defines type of boundary elements to create
6439 * \param groupName - a name of group to store all boundary elements in,
6440 * "" means not to create the group
6441 * \param meshName - a name of a new mesh, which is a copy of the initial
6442 * mesh + created boundary elements; "" means not to create the new mesh
6443 * \param toCopyAll - if true, the whole initial mesh will be copied into
6444 * the new mesh else only boundary elements will be copied into the new mesh
6445 * \param groups - optional groups of elements to make boundary around
6446 * \param mesh - returns the mesh where elements were added to
6447 * \param group - returns the created group, if any
6448 * \retval long - number of added boundary elements
6450 //================================================================================
6452 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6453 const char* groupName,
6454 const char* meshName,
6455 CORBA::Boolean toCopyAll,
6456 const SMESH::ListOfIDSources& groups,
6457 SMESH::SMESH_Mesh_out mesh,
6458 SMESH::SMESH_Group_out group)
6459 throw (SALOME::SALOME_Exception)
6461 Unexpect aCatch(SALOME_SalomeException);
6465 if ( dim > SMESH::BND_1DFROM2D )
6466 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6468 // separate groups belonging to this and other mesh
6469 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6470 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6471 groupsOfThisMesh->length( groups.length() );
6472 groupsOfOtherMesh->length( groups.length() );
6473 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6474 for ( int i = 0; i < groups.length(); ++i )
6476 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6477 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6478 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6480 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6481 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6482 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6484 groupsOfThisMesh->length( nbGroups );
6485 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6490 if ( nbGroupsOfOtherMesh > 0 )
6492 // process groups belonging to another mesh
6493 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6494 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6495 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6496 groupsOfOtherMesh, mesh, group );
6499 SMESH::SMESH_Mesh_var mesh_var;
6500 SMESH::SMESH_Group_var group_var;
6503 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6504 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6508 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6510 /*toCopyGroups=*/false,
6511 /*toKeepIDs=*/true);
6513 mesh_var = makeMesh(meshName);
6515 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6516 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6519 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6520 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6522 // group of boundary elements
6523 SMESH_Group* smesh_group = 0;
6524 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6525 if ( strlen(groupName) )
6527 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6528 group_var = mesh_i->CreateGroup( groupType, groupName );
6529 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6530 smesh_group = group_i->GetSmeshGroup();
6533 TIDSortedElemSet elements;
6535 if ( groups.length() > 0 )
6537 for ( int i = 0; i < nbGroups; ++i )
6540 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6542 SMESH::Bnd_Dimension bdim =
6543 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6544 nbAdded += getEditor().MakeBoundaryMesh( elements,
6545 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6548 /*toCopyElements=*/false,
6549 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6550 /*toAddExistingBondary=*/true,
6551 /*aroundElements=*/true);
6557 nbAdded += getEditor().MakeBoundaryMesh( elements,
6558 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6561 /*toCopyElements=*/false,
6562 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6563 /*toAddExistingBondary=*/true);
6565 tgtMesh->GetMeshDS()->Modified();
6567 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6569 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6570 pyDump << "nbAdded, ";
6571 if ( mesh_var->_is_nil() )
6572 pyDump << myMesh_i->_this() << ", ";
6574 pyDump << mesh_var << ", ";
6575 if ( group_var->_is_nil() )
6576 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6578 pyDump << group_var << " = ";
6579 pyDump << this << ".MakeBoundaryElements( "
6580 << "SMESH." << dimName[int(dim)] << ", "
6581 << "'" << groupName << "', "
6582 << "'" << meshName<< "', "
6583 << toCopyAll << ", "
6586 mesh = mesh_var._retn();
6587 group = group_var._retn();