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 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
87 using SMESH::TPythonDump;
90 namespace MeshEditor_I {
92 //=============================================================================
94 * \brief Mesh to apply modifications for preview purposes
96 //=============================================================================
98 struct TPreviewMesh: public SMESH_Mesh
100 SMDSAbs_ElementType myPreviewType; // type to show
102 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
103 _isShapeToMesh = (_id =_studyId = 0);
104 _myMeshDS = new SMESHDS_Mesh( _id, true );
105 myPreviewType = previewElements;
108 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
109 //!< Copy a set of elements
110 void Copy(const TIDSortedElemSet & theElements,
111 TIDSortedElemSet& theCopyElements,
112 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
113 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
115 // loop on theIDsOfElements
116 TIDSortedElemSet::const_iterator eIt = theElements.begin();
117 for ( ; eIt != theElements.end(); ++eIt )
119 const SMDS_MeshElement* anElem = *eIt;
120 if ( !anElem ) continue;
121 SMDSAbs_ElementType type = anElem->GetType();
122 if ( type == theAvoidType ||
123 ( theSelectType != SMDSAbs_All && type != theSelectType ))
125 const SMDS_MeshElement* anElemCopy;
126 if ( type == SMDSAbs_Node)
127 anElemCopy = Copy( cast2Node(anElem) );
129 anElemCopy = Copy( anElem );
131 theCopyElements.insert( theCopyElements.end(), anElemCopy );
135 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
137 // copy element nodes
138 int anElemNbNodes = anElem->NbNodes();
139 vector< int > anElemNodesID( anElemNbNodes ) ;
140 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
141 for ( int i = 0; itElemNodes->more(); i++)
143 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
145 anElemNodesID[i] = anElemNode->GetID();
148 // creates a corresponding element on copied nodes
149 SMDS_MeshElement* anElemCopy = 0;
150 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
152 const SMDS_VtkVolume* ph =
153 dynamic_cast<const SMDS_VtkVolume*> (anElem);
155 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
156 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
159 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
166 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
168 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
169 anElemNode->GetID());
171 };// struct TPreviewMesh
173 static SMESH_NodeSearcher * theNodeSearcher = 0;
174 static SMESH_ElementSearcher * theElementSearcher = 0;
176 //=============================================================================
178 * \brief Deleter of theNodeSearcher at any compute event occured
180 //=============================================================================
182 struct TSearchersDeleter : public SMESH_subMeshEventListener
185 string myMeshPartIOR;
187 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
188 "SMESH_MeshEditor_i::TSearchersDeleter"),
190 //!< Delete theNodeSearcher
193 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
194 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
196 typedef map < int, SMESH_subMesh * > TDependsOnMap;
197 //!< The meshod called by submesh: do my main job
198 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
199 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
201 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
203 Unset( sm->GetFather() );
206 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
207 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
209 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
216 myMeshPartIOR = meshPartIOR;
217 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
218 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
219 TDependsOnMap::const_iterator sm;
220 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
221 sm->second->SetEventListener( this, 0, sm->second );
225 //!< delete self from all submeshes
226 void Unset(SMESH_Mesh* mesh)
228 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
229 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
230 TDependsOnMap::const_iterator sm;
231 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
232 sm->second->DeleteEventListener( this );
237 } theSearchersDeleter;
239 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
241 TCollection_AsciiString typeStr;
242 switch ( theMirrorType ) {
243 case SMESH::SMESH_MeshEditor::POINT:
244 typeStr = "SMESH.SMESH_MeshEditor.POINT";
246 case SMESH::SMESH_MeshEditor::AXIS:
247 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
250 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
254 //================================================================================
256 * \brief function for conversion of long_array to TIDSortedElemSet
257 * \param IDs - array of IDs
258 * \param aMesh - mesh
259 * \param aMap - collection to fill
260 * \param aType - element type
262 //================================================================================
264 void arrayToSet(const SMESH::long_array & IDs,
265 const SMESHDS_Mesh* aMesh,
266 TIDSortedElemSet& aMap,
267 const SMDSAbs_ElementType aType = SMDSAbs_All )
269 for (int i=0; i<IDs.length(); i++) {
270 CORBA::Long ind = IDs[i];
271 const SMDS_MeshElement * elem =
272 (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
273 if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
274 aMap.insert( aMap.end(), elem );
277 //================================================================================
279 * \brief Retrieve elements of given type from SMESH_IDSource
281 //================================================================================
283 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
284 const SMESHDS_Mesh* theMeshDS,
285 TIDSortedElemSet& theElemSet,
286 const SMDSAbs_ElementType theType,
287 const bool emptyIfIsMesh=false)
290 if ( CORBA::is_nil( theIDSource ) )
292 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
295 SMESH::long_array_var anIDs = theIDSource->GetIDs();
296 if ( anIDs->length() == 0 )
298 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
299 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
301 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
302 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
308 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
309 return bool(anIDs->length()) == bool(theElemSet.size());
313 //================================================================================
315 * \brief Retrieve nodes from SMESH_IDSource
317 //================================================================================
319 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
320 const SMESHDS_Mesh* theMeshDS,
321 TIDSortedNodeSet& theNodeSet)
324 if ( CORBA::is_nil( theObject ) )
326 SMESH::array_of_ElementType_var types = theObject->GetTypes();
327 SMESH::long_array_var aElementsId = theObject->GetIDs();
328 if ( types->length() == 1 && types[0] == SMESH::NODE)
330 for(int i = 0; i < aElementsId->length(); i++)
331 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
332 theNodeSet.insert( theNodeSet.end(), n);
334 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
336 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
337 while ( nIt->more( ))
338 if( const SMDS_MeshElement * elem = nIt->next() )
339 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
343 for(int i = 0; i < aElementsId->length(); i++)
344 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
345 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
349 //================================================================================
351 * \brief Returns elements connected to the given elements
353 //================================================================================
355 void getElementsAround(const TIDSortedElemSet& theElements,
356 const SMESHDS_Mesh* theMeshDS,
357 TIDSortedElemSet& theElementsAround)
359 if ( theElements.empty() ) return;
361 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
362 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
364 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
365 return; // all the elements are in theElements
368 elemType = SMDSAbs_All;
370 TIDSortedElemSet visitedNodes;
371 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
372 for ( ; elemIt != theElements.end(); ++elemIt )
374 const SMDS_MeshElement* e = *elemIt;
375 int i = e->NbCornerNodes();
378 const SMDS_MeshNode* n = e->GetNode( i );
379 if ( visitedNodes.insert( n ).second )
381 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
382 while ( invIt->more() )
384 const SMDS_MeshElement* elemAround = invIt->next();
385 if ( !theElements.count( elemAround ))
386 theElementsAround.insert( elemAround );
393 //================================================================================
395 * \brief Return a string used to detect change of mesh part on which theElementSearcher
396 * is going to be used
398 //================================================================================
400 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
402 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
403 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
404 // take into account passible group modification
405 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
406 partIOR += SMESH_Comment( type );
410 } // namespace MeshEditor_I
412 using namespace MeshEditor_I;
414 //=============================================================================
418 //=============================================================================
420 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
422 myMesh( &theMesh->GetImpl() ),
424 myIsPreviewMode ( isPreview ),
430 //================================================================================
434 //================================================================================
436 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
438 deleteAuxIDSources();
439 delete myPreviewMesh; myPreviewMesh = 0;
440 delete myPreviewEditor; myPreviewEditor = 0;
443 //================================================================================
445 * \brief Clear members
447 //================================================================================
449 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
451 if ( myIsPreviewMode ) {
452 if ( myPreviewMesh ) myPreviewMesh->Clear();
455 if ( deleteSearchers )
456 TSearchersDeleter::Delete();
458 getEditor().GetError().reset();
459 getEditor().CrearLastCreated();
461 //================================================================================
463 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
464 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
466 //================================================================================
468 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
470 if ( myIsPreviewMode && !myPreviewEditor ) {
471 if ( !myPreviewMesh ) getPreviewMesh();
472 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
474 return myIsPreviewMode ? *myPreviewEditor : myEditor;
477 //================================================================================
479 * \brief Initialize and return myPreviewMesh
480 * \param previewElements - type of elements to show in preview
482 * WARNING: call it once par a method!
484 //================================================================================
486 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
488 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
490 delete myPreviewEditor;
492 delete myPreviewMesh;
493 myPreviewMesh = new TPreviewMesh( previewElements );
495 myPreviewMesh->Clear();
496 return myPreviewMesh;
499 //================================================================================
501 * \brief Now does nothing
503 //================================================================================
505 // void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& )
509 //================================================================================
511 * Return data of mesh edition preview
513 //================================================================================
515 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
517 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
519 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
521 list<int> aNodesConnectivity;
522 typedef map<int, int> TNodesMap;
525 SMESHDS_Mesh* aMeshDS;
526 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
528 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
529 aMeshDS = aMeshPartDS.get();
532 aMeshDS = getEditor().GetMeshDS();
534 int nbEdges = aMeshDS->NbEdges();
535 int nbFaces = aMeshDS->NbFaces();
536 int nbVolum = aMeshDS->NbVolumes();
537 myPreviewData = new SMESH::MeshPreviewStruct();
538 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
541 SMDSAbs_ElementType previewType = SMDSAbs_All;
543 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
544 previewType = aPreviewMesh->myPreviewType;
545 switch ( previewType ) {
546 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
547 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
548 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
553 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
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);
859 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
860 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
862 // Update Python script
863 TPythonDump() << "ballElem = "
864 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
866 myMesh->GetMeshDS()->Modified();
867 myMesh->SetIsModified( true ); // issue 0020693
870 return elem->GetID();
875 //=============================================================================
877 * Create an edge, either linear and quadratic (this is determed
878 * by number of given nodes, two or three)
880 //=============================================================================
882 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
886 int NbNodes = IDsOfNodes.length();
887 SMDS_MeshElement* elem = 0;
890 CORBA::Long index1 = IDsOfNodes[0];
891 CORBA::Long index2 = IDsOfNodes[1];
892 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
893 getMeshDS()->FindNode(index2));
895 // Update Python script
896 TPythonDump() << "edge = " << this << ".AddEdge([ "
897 << index1 << ", " << index2 <<" ])";
900 CORBA::Long n1 = IDsOfNodes[0];
901 CORBA::Long n2 = IDsOfNodes[1];
902 CORBA::Long n12 = IDsOfNodes[2];
903 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
904 getMeshDS()->FindNode(n2),
905 getMeshDS()->FindNode(n12));
906 // Update Python script
907 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
908 <<n1<<", "<<n2<<", "<<n12<<" ])";
911 myMesh->GetMeshDS()->Modified();
913 return myMesh->SetIsModified( true ), elem->GetID();
918 //=============================================================================
922 //=============================================================================
924 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
928 int NbNodes = IDsOfNodes.length();
934 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
935 for (int i = 0; i < NbNodes; i++)
936 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
938 SMDS_MeshElement* elem = 0;
940 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
942 else if (NbNodes == 4) {
943 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
945 else if (NbNodes == 6) {
946 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
949 else if (NbNodes == 8) {
950 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
951 nodes[4], nodes[5], nodes[6], nodes[7]);
953 else if (NbNodes == 9) {
954 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
955 nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
957 else if (NbNodes > 2) {
958 elem = getMeshDS()->AddPolygonalFace(nodes);
961 // Update Python script
962 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
964 myMesh->GetMeshDS()->Modified();
966 return myMesh->SetIsModified( true ), elem->GetID();
971 //=============================================================================
975 //=============================================================================
976 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
980 int NbNodes = IDsOfNodes.length();
981 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
982 for (int i = 0; i < NbNodes; i++)
983 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
985 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
987 // Update Python script
988 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
990 myMesh->GetMeshDS()->Modified();
991 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
994 //=============================================================================
996 * Create volume, either linear and quadratic (this is determed
997 * by number of given nodes)
999 //=============================================================================
1001 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1005 int NbNodes = IDsOfNodes.length();
1006 vector< const SMDS_MeshNode*> n(NbNodes);
1007 for(int i=0;i<NbNodes;i++)
1008 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1010 SMDS_MeshElement* elem = 0;
1013 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1014 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1015 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1016 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1017 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1018 n[6],n[7],n[8],n[9]);
1020 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1021 n[6],n[7],n[8],n[9],n[10],n[11]);
1023 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1024 n[7],n[8],n[9],n[10],n[11],n[12]);
1026 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1027 n[9],n[10],n[11],n[12],n[13],n[14]);
1029 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1030 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1031 n[15],n[16],n[17],n[18],n[19]);
1033 case 27: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],
1036 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1040 // Update Python script
1041 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1043 myMesh->GetMeshDS()->Modified();
1045 return myMesh->SetIsModified( true ), elem->GetID();
1050 //=============================================================================
1052 * AddPolyhedralVolume
1054 //=============================================================================
1055 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1056 const SMESH::long_array & Quantities)
1060 int NbNodes = IDsOfNodes.length();
1061 std::vector<const SMDS_MeshNode*> n (NbNodes);
1062 for (int i = 0; i < NbNodes; i++)
1064 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1065 if (!aNode) return 0;
1069 int NbFaces = Quantities.length();
1070 std::vector<int> q (NbFaces);
1071 for (int j = 0; j < NbFaces; j++)
1072 q[j] = Quantities[j];
1074 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1076 // Update Python script
1077 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1078 << IDsOfNodes << ", " << Quantities << " )";
1079 myMesh->GetMeshDS()->Modified();
1081 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1084 //=============================================================================
1086 * AddPolyhedralVolumeByFaces
1088 //=============================================================================
1090 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1094 int NbFaces = IdsOfFaces.length();
1095 std::vector<const SMDS_MeshNode*> poly_nodes;
1096 std::vector<int> quantities (NbFaces);
1098 for (int i = 0; i < NbFaces; i++) {
1099 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1100 quantities[i] = aFace->NbNodes();
1102 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1103 while (It->more()) {
1104 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1108 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1110 // Update Python script
1111 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1112 << IdsOfFaces << " )";
1113 myMesh->GetMeshDS()->Modified();
1115 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1118 //=============================================================================
1120 // \brief Create 0D elements on all nodes of the given object except those
1121 // nodes on which a 0D element already exists.
1122 // \param theObject object on whose nodes 0D elements will be created.
1123 // \param theGroupName optional name of a group to add 0D elements created
1124 // and/or found on nodes of \a theObject.
1125 // \return an object (a new group or a temporary SMESH_IDSource) holding
1126 // ids of new and/or found 0D elements.
1128 //=============================================================================
1130 SMESH::SMESH_IDSource_ptr
1131 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1132 const char* theGroupName)
1133 throw (SALOME::SALOME_Exception)
1137 SMESH::SMESH_IDSource_var result;
1140 TIDSortedElemSet elements, elems0D;
1141 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1142 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1144 SMESH::long_array_var newElems = new SMESH::long_array;
1145 newElems->length( elems0D.size() );
1146 TIDSortedElemSet::iterator eIt = elems0D.begin();
1147 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1148 newElems[ i ] = (*eIt)->GetID();
1150 SMESH::SMESH_GroupBase_var groupToFill;
1151 if ( theGroupName && strlen( theGroupName ))
1153 // Get existing group named theGroupName
1154 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1155 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1156 SMESH::SMESH_GroupBase_var group = groups[i];
1157 if ( !group->_is_nil() ) {
1158 CORBA::String_var name = group->GetName();
1159 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1160 groupToFill = group;
1165 if ( groupToFill->_is_nil() )
1166 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1167 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1168 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1171 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1173 group_i->Add( newElems );
1174 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1175 pyDump << groupToFill;
1179 result = MakeIDSource( newElems, SMESH::ELEM0D );
1180 pyDump << "elem0DIDs";
1183 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1184 << theObject << ", '" << theGroupName << "' )";
1186 return result._retn();
1189 //=============================================================================
1191 * \brief Bind a node to a vertex
1192 * \param NodeID - node ID
1193 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1194 * \retval boolean - false if NodeID or VertexID is invalid
1196 //=============================================================================
1198 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1199 throw (SALOME::SALOME_Exception)
1201 Unexpect aCatch(SALOME_SalomeException);
1203 SMESHDS_Mesh * mesh = getMeshDS();
1204 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1206 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1208 if ( mesh->MaxShapeIndex() < VertexID )
1209 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1211 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1212 if ( shape.ShapeType() != TopAbs_VERTEX )
1213 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1215 mesh->SetNodeOnVertex( node, VertexID );
1217 myMesh->SetIsModified( true );
1220 //=============================================================================
1222 * \brief Store node position on an edge
1223 * \param NodeID - node ID
1224 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1225 * \param paramOnEdge - parameter on edge where the node is located
1226 * \retval boolean - false if any parameter is invalid
1228 //=============================================================================
1230 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1231 CORBA::Double paramOnEdge)
1232 throw (SALOME::SALOME_Exception)
1234 Unexpect aCatch(SALOME_SalomeException);
1236 SMESHDS_Mesh * mesh = getMeshDS();
1237 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1239 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1241 if ( mesh->MaxShapeIndex() < EdgeID )
1242 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1244 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1245 if ( shape.ShapeType() != TopAbs_EDGE )
1246 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1249 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1250 if ( paramOnEdge < f || paramOnEdge > l )
1251 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1253 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1255 myMesh->SetIsModified( true );
1258 //=============================================================================
1260 * \brief Store node position on a face
1261 * \param NodeID - node ID
1262 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1263 * \param u - U parameter on face where the node is located
1264 * \param v - V parameter on face where the node is located
1265 * \retval boolean - false if any parameter is invalid
1267 //=============================================================================
1269 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1270 CORBA::Double u, CORBA::Double v)
1271 throw (SALOME::SALOME_Exception)
1273 Unexpect aCatch(SALOME_SalomeException);
1275 SMESHDS_Mesh * mesh = getMeshDS();
1276 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1278 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1280 if ( mesh->MaxShapeIndex() < FaceID )
1281 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1283 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1284 if ( shape.ShapeType() != TopAbs_FACE )
1285 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1287 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1288 bool isOut = ( u < surf.FirstUParameter() ||
1289 u > surf.LastUParameter() ||
1290 v < surf.FirstVParameter() ||
1291 v > surf.LastVParameter() );
1295 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1296 << " u( " << surf.FirstUParameter()
1297 << "," << surf.LastUParameter()
1298 << ") v( " << surf.FirstVParameter()
1299 << "," << surf.LastVParameter() << ")" );
1301 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1304 mesh->SetNodeOnFace( node, FaceID, u, v );
1305 myMesh->SetIsModified( true );
1308 //=============================================================================
1310 * \brief Bind a node to a solid
1311 * \param NodeID - node ID
1312 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1313 * \retval boolean - false if NodeID or SolidID is invalid
1315 //=============================================================================
1317 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1318 throw (SALOME::SALOME_Exception)
1320 Unexpect aCatch(SALOME_SalomeException);
1322 SMESHDS_Mesh * mesh = getMeshDS();
1323 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1325 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1327 if ( mesh->MaxShapeIndex() < SolidID )
1328 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1330 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1331 if ( shape.ShapeType() != TopAbs_SOLID &&
1332 shape.ShapeType() != TopAbs_SHELL)
1333 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1335 mesh->SetNodeInVolume( node, SolidID );
1337 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
1340 //=============================================================================
1342 * \brief Bind an element to a shape
1343 * \param ElementID - element ID
1344 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1345 * \retval boolean - false if ElementID or ShapeID is invalid
1347 //=============================================================================
1349 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1350 CORBA::Long ShapeID)
1351 throw (SALOME::SALOME_Exception)
1353 Unexpect aCatch(SALOME_SalomeException);
1355 SMESHDS_Mesh * mesh = getMeshDS();
1356 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1358 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1360 if ( mesh->MaxShapeIndex() < ShapeID )
1361 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1363 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1364 if ( shape.ShapeType() != TopAbs_EDGE &&
1365 shape.ShapeType() != TopAbs_FACE &&
1366 shape.ShapeType() != TopAbs_SOLID &&
1367 shape.ShapeType() != TopAbs_SHELL )
1368 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1370 mesh->SetMeshElementOnShape( elem, ShapeID );
1372 myMesh->SetIsModified( true );
1375 //=============================================================================
1379 //=============================================================================
1381 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1382 CORBA::Long NodeID2)
1386 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1387 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1391 // Update Python script
1392 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1393 << NodeID1 << ", " << NodeID2 << " )";
1396 int ret = getEditor().InverseDiag ( n1, n2 );
1397 myMesh->GetMeshDS()->Modified();
1398 myMesh->SetIsModified( true );
1402 //=============================================================================
1406 //=============================================================================
1408 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1409 CORBA::Long NodeID2)
1413 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1414 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1418 // Update Python script
1419 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1420 << NodeID1 << ", " << NodeID2 << " )";
1423 bool stat = getEditor().DeleteDiag ( n1, n2 );
1425 myMesh->GetMeshDS()->Modified();
1427 myMesh->SetIsModified( true ); // issue 0020693
1433 //=============================================================================
1437 //=============================================================================
1439 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1443 for (int i = 0; i < IDsOfElements.length(); i++)
1445 CORBA::Long index = IDsOfElements[i];
1446 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1448 getEditor().Reorient( elem );
1450 // Update Python script
1451 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1453 myMesh->GetMeshDS()->Modified();
1454 if ( IDsOfElements.length() )
1455 myMesh->SetIsModified( true ); // issue 0020693
1461 //=============================================================================
1465 //=============================================================================
1467 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1471 TPythonDump aTPythonDump; // suppress dump in Reorient()
1473 SMESH::long_array_var anElementsId = theObject->GetIDs();
1474 CORBA::Boolean isDone = Reorient(anElementsId);
1476 // Update Python script
1477 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1482 //=======================================================================
1483 //function : Reorient2D
1484 //purpose : Reorient faces contained in \a the2Dgroup.
1485 // the2Dgroup - the mesh or its part to reorient
1486 // theDirection - desired direction of normal of \a theFace
1487 // theFace - ID of face whose orientation is checked.
1488 // It can be < 1 then \a thePoint is used to find a face.
1489 // thePoint - is used to find a face if \a theFace < 1.
1490 // return number of reoriented elements.
1491 //=======================================================================
1493 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1494 const SMESH::DirStruct& theDirection,
1495 CORBA::Long theFace,
1496 const SMESH::PointStruct& thePoint)
1497 throw (SALOME::SALOME_Exception)
1499 Unexpect aCatch(SALOME_SalomeException);
1501 initData(/*deleteSearchers=*/false);
1503 TIDSortedElemSet elements;
1504 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1505 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1508 const SMDS_MeshElement* face = 0;
1511 face = getMeshDS()->FindElement( theFace );
1513 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1514 if ( face->GetType() != SMDSAbs_Face )
1515 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1519 // create theElementSearcher if needed
1520 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1521 if ( !theElementSearcher )
1523 if ( elements.empty() ) // search in the whole mesh
1525 if ( myMesh->NbFaces() == 0 )
1526 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1528 theElementSearcher = myEditor.GetElementSearcher();
1532 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1533 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1535 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
1539 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1540 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1543 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1544 if ( !elements.empty() && !elements.count( face ))
1545 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1548 const SMESH::PointStruct * P = &theDirection.PS;
1549 gp_Vec dirVec( P->x, P->y, P->z );
1550 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1551 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1553 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1556 myMesh->SetIsModified( true );
1557 myMesh->GetMeshDS()->Modified();
1559 TPythonDump() << this << ".Reorient2D( "
1560 << the2Dgroup << ", "
1561 << theDirection << ", "
1563 << thePoint << " )";
1568 //=============================================================================
1572 //=============================================================================
1573 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1574 SMESH::NumericalFunctor_ptr Criterion,
1575 CORBA::Double MaxAngle)
1579 SMESHDS_Mesh* aMesh = getMeshDS();
1580 TIDSortedElemSet faces;
1581 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1583 SMESH::NumericalFunctor_i* aNumericalFunctor =
1584 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1585 SMESH::Controls::NumericalFunctorPtr aCrit;
1586 if ( !aNumericalFunctor )
1587 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1589 aCrit = aNumericalFunctor->GetNumericalFunctor();
1591 // Update Python script
1592 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1593 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1596 bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle );
1597 myMesh->GetMeshDS()->Modified();
1599 myMesh->SetIsModified( true ); // issue 0020693
1606 //=============================================================================
1610 //=============================================================================
1611 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1612 SMESH::NumericalFunctor_ptr Criterion,
1613 CORBA::Double MaxAngle)
1617 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1618 SMESH::long_array_var anElementsId = theObject->GetIDs();
1619 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1621 SMESH::NumericalFunctor_i* aNumericalFunctor =
1622 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1624 // Update Python script
1625 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1626 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1632 //=============================================================================
1636 //=============================================================================
1637 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1638 SMESH::NumericalFunctor_ptr Criterion)
1642 SMESHDS_Mesh* aMesh = getMeshDS();
1643 TIDSortedElemSet faces;
1644 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1646 SMESH::NumericalFunctor_i* aNumericalFunctor =
1647 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1648 SMESH::Controls::NumericalFunctorPtr aCrit;
1649 if ( !aNumericalFunctor )
1650 aCrit.reset( new SMESH::Controls::AspectRatio() );
1652 aCrit = aNumericalFunctor->GetNumericalFunctor();
1655 // Update Python script
1656 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1658 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1659 myMesh->GetMeshDS()->Modified();
1661 myMesh->SetIsModified( true ); // issue 0020693
1668 //=============================================================================
1672 //=============================================================================
1673 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1674 SMESH::NumericalFunctor_ptr Criterion)
1678 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1680 SMESH::long_array_var anElementsId = theObject->GetIDs();
1681 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1683 SMESH::NumericalFunctor_i* aNumericalFunctor =
1684 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1686 // Update Python script
1687 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1693 //=============================================================================
1697 //=============================================================================
1698 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1699 CORBA::Boolean Diag13)
1703 SMESHDS_Mesh* aMesh = getMeshDS();
1704 TIDSortedElemSet faces;
1705 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1707 // Update Python script
1708 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1709 << IDsOfElements << ", " << Diag13 << " )";
1711 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1712 myMesh->GetMeshDS()->Modified();
1714 myMesh->SetIsModified( true ); // issue 0020693
1722 //=============================================================================
1726 //=============================================================================
1727 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1728 CORBA::Boolean Diag13)
1732 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1734 SMESH::long_array_var anElementsId = theObject->GetIDs();
1735 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1737 // Update Python script
1738 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1739 << theObject << ", " << Diag13 << " )";
1745 //=============================================================================
1749 //=============================================================================
1750 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1751 SMESH::NumericalFunctor_ptr Criterion)
1755 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1756 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1758 SMESH::NumericalFunctor_i* aNumericalFunctor =
1759 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1760 SMESH::Controls::NumericalFunctorPtr aCrit;
1761 if (aNumericalFunctor)
1762 aCrit = aNumericalFunctor->GetNumericalFunctor();
1764 aCrit.reset(new SMESH::Controls::AspectRatio());
1766 return getEditor().BestSplit(quad, aCrit);
1771 //================================================================================
1773 * \brief Split volumic elements into tetrahedrons
1775 //================================================================================
1777 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1778 CORBA::Short methodFlags)
1779 throw (SALOME::SALOME_Exception)
1781 Unexpect aCatch(SALOME_SalomeException);
1785 SMESH::long_array_var anElementsId = elems->GetIDs();
1786 TIDSortedElemSet elemSet;
1787 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
1789 getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1790 myMesh->GetMeshDS()->Modified();
1793 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1794 // myMesh->SetIsModified( true ); // issue 0020693
1796 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1797 << elems << ", " << methodFlags << " )";
1800 //=======================================================================
1803 //=======================================================================
1806 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1807 const SMESH::long_array & IDsOfFixedNodes,
1808 CORBA::Long MaxNbOfIterations,
1809 CORBA::Double MaxAspectRatio,
1810 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1812 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1813 MaxAspectRatio, Method, false );
1817 //=======================================================================
1818 //function : SmoothParametric
1820 //=======================================================================
1823 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1824 const SMESH::long_array & IDsOfFixedNodes,
1825 CORBA::Long MaxNbOfIterations,
1826 CORBA::Double MaxAspectRatio,
1827 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1829 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1830 MaxAspectRatio, Method, true );
1834 //=======================================================================
1835 //function : SmoothObject
1837 //=======================================================================
1840 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1841 const SMESH::long_array & IDsOfFixedNodes,
1842 CORBA::Long MaxNbOfIterations,
1843 CORBA::Double MaxAspectRatio,
1844 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1846 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1847 MaxAspectRatio, Method, false);
1851 //=======================================================================
1852 //function : SmoothParametricObject
1854 //=======================================================================
1857 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1858 const SMESH::long_array & IDsOfFixedNodes,
1859 CORBA::Long MaxNbOfIterations,
1860 CORBA::Double MaxAspectRatio,
1861 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1863 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1864 MaxAspectRatio, Method, true);
1868 //=============================================================================
1872 //=============================================================================
1875 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1876 const SMESH::long_array & IDsOfFixedNodes,
1877 CORBA::Long MaxNbOfIterations,
1878 CORBA::Double MaxAspectRatio,
1879 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1884 SMESHDS_Mesh* aMesh = getMeshDS();
1886 TIDSortedElemSet elements;
1887 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1889 set<const SMDS_MeshNode*> fixedNodes;
1890 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1891 CORBA::Long index = IDsOfFixedNodes[i];
1892 const SMDS_MeshNode * node = aMesh->FindNode(index);
1894 fixedNodes.insert( node );
1896 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1897 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1898 method = ::SMESH_MeshEditor::CENTROIDAL;
1900 getEditor().Smooth(elements, fixedNodes, method,
1901 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1903 myMesh->GetMeshDS()->Modified();
1904 myMesh->SetIsModified( true ); // issue 0020693
1907 // Update Python script
1908 TPythonDump() << "isDone = " << this << "."
1909 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1910 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1911 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1912 << "SMESH.SMESH_MeshEditor."
1913 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1914 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1920 //=============================================================================
1924 //=============================================================================
1927 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1928 const SMESH::long_array & IDsOfFixedNodes,
1929 CORBA::Long MaxNbOfIterations,
1930 CORBA::Double MaxAspectRatio,
1931 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1936 TPythonDump aTPythonDump; // suppress dump in smooth()
1938 SMESH::long_array_var anElementsId = theObject->GetIDs();
1939 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1940 MaxAspectRatio, Method, IsParametric);
1942 // Update Python script
1943 aTPythonDump << "isDone = " << this << "."
1944 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1945 << theObject << ", " << IDsOfFixedNodes << ", "
1946 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1947 << "SMESH.SMESH_MeshEditor."
1948 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1949 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1955 //=============================================================================
1959 //=============================================================================
1961 void SMESH_MeshEditor_i::RenumberNodes()
1963 // Update Python script
1964 TPythonDump() << this << ".RenumberNodes()";
1966 getMeshDS()->Renumber( true );
1970 //=============================================================================
1974 //=============================================================================
1976 void SMESH_MeshEditor_i::RenumberElements()
1978 // Update Python script
1979 TPythonDump() << this << ".RenumberElements()";
1981 getMeshDS()->Renumber( false );
1984 //=======================================================================
1986 * \brief Return groups by their IDs
1988 //=======================================================================
1990 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1994 myMesh_i->CreateGroupServants();
1995 return myMesh_i->GetGroups( *groupIDs );
1998 //=======================================================================
1999 //function : rotationSweep
2001 //=======================================================================
2003 SMESH::ListOfGroups*
2004 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2005 const SMESH::AxisStruct & theAxis,
2006 CORBA::Double theAngleInRadians,
2007 CORBA::Long theNbOfSteps,
2008 CORBA::Double theTolerance,
2009 const bool theMakeGroups,
2010 const SMDSAbs_ElementType theElementType)
2014 TIDSortedElemSet inElements, copyElements;
2015 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2017 TIDSortedElemSet* workElements = & inElements;
2018 bool makeWalls=true;
2019 if ( myIsPreviewMode )
2021 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2022 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2023 workElements = & copyElements;
2024 //makeWalls = false;
2027 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2028 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2030 ::SMESH_MeshEditor::PGroupIDs groupIds =
2031 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2032 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2033 myMesh->GetMeshDS()->Modified();
2035 // myMesh->SetIsModified( true ); -- it does not influence Compute()
2037 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2040 //=======================================================================
2041 //function : RotationSweep
2043 //=======================================================================
2045 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2046 const SMESH::AxisStruct & theAxis,
2047 CORBA::Double theAngleInRadians,
2048 CORBA::Long theNbOfSteps,
2049 CORBA::Double theTolerance)
2051 if ( !myIsPreviewMode ) {
2052 TPythonDump() << this << ".RotationSweep( "
2053 << theIDsOfElements << ", "
2055 << TVar( theAngleInRadians ) << ", "
2056 << TVar( theNbOfSteps ) << ", "
2057 << TVar( theTolerance ) << " )";
2059 rotationSweep(theIDsOfElements,
2067 //=======================================================================
2068 //function : RotationSweepMakeGroups
2070 //=======================================================================
2072 SMESH::ListOfGroups*
2073 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2074 const SMESH::AxisStruct& theAxis,
2075 CORBA::Double theAngleInRadians,
2076 CORBA::Long theNbOfSteps,
2077 CORBA::Double theTolerance)
2079 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2081 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2087 if (!myIsPreviewMode) {
2088 DumpGroupsList(aPythonDump, aGroups);
2089 aPythonDump << this << ".RotationSweepMakeGroups( "
2090 << theIDsOfElements << ", "
2092 << TVar( theAngleInRadians ) << ", "
2093 << TVar( theNbOfSteps ) << ", "
2094 << TVar( theTolerance ) << " )";
2099 //=======================================================================
2100 //function : RotationSweepObject
2102 //=======================================================================
2104 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2105 const SMESH::AxisStruct & theAxis,
2106 CORBA::Double theAngleInRadians,
2107 CORBA::Long theNbOfSteps,
2108 CORBA::Double theTolerance)
2110 if ( !myIsPreviewMode ) {
2111 TPythonDump() << this << ".RotationSweepObject( "
2112 << theObject << ", "
2114 << theAngleInRadians << ", "
2115 << theNbOfSteps << ", "
2116 << theTolerance << " )";
2118 SMESH::long_array_var anElementsId = theObject->GetIDs();
2119 rotationSweep(anElementsId,
2127 //=======================================================================
2128 //function : RotationSweepObject1D
2130 //=======================================================================
2132 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2133 const SMESH::AxisStruct & theAxis,
2134 CORBA::Double theAngleInRadians,
2135 CORBA::Long theNbOfSteps,
2136 CORBA::Double theTolerance)
2138 if ( !myIsPreviewMode ) {
2139 TPythonDump() << this << ".RotationSweepObject1D( "
2140 << theObject << ", "
2142 << TVar( theAngleInRadians ) << ", "
2143 << TVar( theNbOfSteps ) << ", "
2144 << TVar( theTolerance ) << " )";
2146 SMESH::long_array_var anElementsId = theObject->GetIDs();
2147 rotationSweep(anElementsId,
2156 //=======================================================================
2157 //function : RotationSweepObject2D
2159 //=======================================================================
2161 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2162 const SMESH::AxisStruct & theAxis,
2163 CORBA::Double theAngleInRadians,
2164 CORBA::Long theNbOfSteps,
2165 CORBA::Double theTolerance)
2167 if ( !myIsPreviewMode ) {
2168 TPythonDump() << this << ".RotationSweepObject2D( "
2169 << theObject << ", "
2171 << TVar( theAngleInRadians ) << ", "
2172 << TVar( theNbOfSteps ) << ", "
2173 << TVar( theTolerance ) << " )";
2175 SMESH::long_array_var anElementsId = theObject->GetIDs();
2176 rotationSweep(anElementsId,
2185 //=======================================================================
2186 //function : RotationSweepObjectMakeGroups
2188 //=======================================================================
2190 SMESH::ListOfGroups*
2191 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2192 const SMESH::AxisStruct& theAxis,
2193 CORBA::Double theAngleInRadians,
2194 CORBA::Long theNbOfSteps,
2195 CORBA::Double theTolerance)
2197 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2199 SMESH::long_array_var anElementsId = theObject->GetIDs();
2200 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2206 if (!myIsPreviewMode) {
2207 DumpGroupsList(aPythonDump, aGroups);
2208 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2209 << theObject << ", "
2211 << theAngleInRadians << ", "
2212 << theNbOfSteps << ", "
2213 << theTolerance << " )";
2218 //=======================================================================
2219 //function : RotationSweepObject1DMakeGroups
2221 //=======================================================================
2223 SMESH::ListOfGroups*
2224 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2225 const SMESH::AxisStruct& theAxis,
2226 CORBA::Double theAngleInRadians,
2227 CORBA::Long theNbOfSteps,
2228 CORBA::Double theTolerance)
2230 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2232 SMESH::long_array_var anElementsId = theObject->GetIDs();
2233 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2240 if (!myIsPreviewMode) {
2241 DumpGroupsList(aPythonDump, aGroups);
2242 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2243 << theObject << ", "
2245 << TVar( theAngleInRadians ) << ", "
2246 << TVar( theNbOfSteps ) << ", "
2247 << TVar( theTolerance ) << " )";
2252 //=======================================================================
2253 //function : RotationSweepObject2DMakeGroups
2255 //=======================================================================
2257 SMESH::ListOfGroups*
2258 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2259 const SMESH::AxisStruct& theAxis,
2260 CORBA::Double theAngleInRadians,
2261 CORBA::Long theNbOfSteps,
2262 CORBA::Double theTolerance)
2264 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2266 SMESH::long_array_var anElementsId = theObject->GetIDs();
2267 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2274 if (!myIsPreviewMode) {
2275 DumpGroupsList(aPythonDump, aGroups);
2276 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2277 << theObject << ", "
2279 << TVar( theAngleInRadians ) << ", "
2280 << TVar( theNbOfSteps ) << ", "
2281 << TVar( theTolerance ) << " )";
2287 //=======================================================================
2288 //function : extrusionSweep
2290 //=======================================================================
2292 SMESH::ListOfGroups*
2293 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2294 const SMESH::DirStruct & theStepVector,
2295 CORBA::Long theNbOfSteps,
2297 const SMDSAbs_ElementType theElementType)
2305 TIDSortedElemSet elements, copyElements;
2306 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2308 const SMESH::PointStruct * P = &theStepVector.PS;
2309 gp_Vec stepVec( P->x, P->y, P->z );
2311 TIDSortedElemSet* workElements = & elements;
2313 SMDSAbs_ElementType aType = SMDSAbs_Face;
2314 if (theElementType == SMDSAbs_Node)
2316 aType = SMDSAbs_Edge;
2318 if ( myIsPreviewMode ) {
2319 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2320 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2321 workElements = & copyElements;
2322 theMakeGroups = false;
2325 TElemOfElemListMap aHystory;
2326 ::SMESH_MeshEditor::PGroupIDs groupIds =
2327 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2329 myMesh->GetMeshDS()->Modified();
2331 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2333 } catch(Standard_Failure) {
2334 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2335 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
2340 //=======================================================================
2341 //function : ExtrusionSweep
2343 //=======================================================================
2345 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2346 const SMESH::DirStruct & theStepVector,
2347 CORBA::Long theNbOfSteps)
2349 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2350 if (!myIsPreviewMode) {
2351 TPythonDump() << this << ".ExtrusionSweep( "
2352 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2356 //=======================================================================
2357 //function : ExtrusionSweep0D
2359 //=======================================================================
2361 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2362 const SMESH::DirStruct & theStepVector,
2363 CORBA::Long theNbOfSteps)
2365 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2366 if (!myIsPreviewMode) {
2367 TPythonDump() << this << ".ExtrusionSweep0D( "
2368 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2372 //=======================================================================
2373 //function : ExtrusionSweepObject
2375 //=======================================================================
2377 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2378 const SMESH::DirStruct & theStepVector,
2379 CORBA::Long theNbOfSteps)
2381 SMESH::long_array_var anElementsId = theObject->GetIDs();
2382 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2383 if (!myIsPreviewMode) {
2384 TPythonDump() << this << ".ExtrusionSweepObject( "
2385 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2389 //=======================================================================
2390 //function : ExtrusionSweepObject0D
2392 //=======================================================================
2394 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2395 const SMESH::DirStruct & theStepVector,
2396 CORBA::Long theNbOfSteps)
2398 SMESH::long_array_var anElementsId = theObject->GetIDs();
2399 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2400 if ( !myIsPreviewMode ) {
2401 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2402 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2406 //=======================================================================
2407 //function : ExtrusionSweepObject1D
2409 //=======================================================================
2411 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2412 const SMESH::DirStruct & theStepVector,
2413 CORBA::Long theNbOfSteps)
2415 SMESH::long_array_var anElementsId = theObject->GetIDs();
2416 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2417 if ( !myIsPreviewMode ) {
2418 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2419 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2423 //=======================================================================
2424 //function : ExtrusionSweepObject2D
2426 //=======================================================================
2428 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2429 const SMESH::DirStruct & theStepVector,
2430 CORBA::Long theNbOfSteps)
2432 SMESH::long_array_var anElementsId = theObject->GetIDs();
2433 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2434 if ( !myIsPreviewMode ) {
2435 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2436 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2440 //=======================================================================
2441 //function : ExtrusionSweepMakeGroups
2443 //=======================================================================
2445 SMESH::ListOfGroups*
2446 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2447 const SMESH::DirStruct& theStepVector,
2448 CORBA::Long theNbOfSteps)
2450 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2452 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2454 if (!myIsPreviewMode) {
2455 DumpGroupsList(aPythonDump, aGroups);
2456 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2457 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2462 //=======================================================================
2463 //function : ExtrusionSweepMakeGroups0D
2465 //=======================================================================
2467 SMESH::ListOfGroups*
2468 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2469 const SMESH::DirStruct& theStepVector,
2470 CORBA::Long theNbOfSteps)
2472 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2474 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2476 if (!myIsPreviewMode) {
2477 DumpGroupsList(aPythonDump, aGroups);
2478 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2479 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2484 //=======================================================================
2485 //function : ExtrusionSweepObjectMakeGroups
2487 //=======================================================================
2489 SMESH::ListOfGroups*
2490 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2491 const SMESH::DirStruct& theStepVector,
2492 CORBA::Long theNbOfSteps)
2494 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2496 SMESH::long_array_var anElementsId = theObject->GetIDs();
2497 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2499 if (!myIsPreviewMode) {
2500 DumpGroupsList(aPythonDump, aGroups);
2501 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2502 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2507 //=======================================================================
2508 //function : ExtrusionSweepObject0DMakeGroups
2510 //=======================================================================
2512 SMESH::ListOfGroups*
2513 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2514 const SMESH::DirStruct& theStepVector,
2515 CORBA::Long theNbOfSteps)
2517 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2519 SMESH::long_array_var anElementsId = theObject->GetIDs();
2520 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2521 theNbOfSteps, true, SMDSAbs_Node);
2522 if (!myIsPreviewMode) {
2523 DumpGroupsList(aPythonDump, aGroups);
2524 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2525 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2530 //=======================================================================
2531 //function : ExtrusionSweepObject1DMakeGroups
2533 //=======================================================================
2535 SMESH::ListOfGroups*
2536 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2537 const SMESH::DirStruct& theStepVector,
2538 CORBA::Long theNbOfSteps)
2540 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2542 SMESH::long_array_var anElementsId = theObject->GetIDs();
2543 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2544 theNbOfSteps, true, SMDSAbs_Edge);
2545 if (!myIsPreviewMode) {
2546 DumpGroupsList(aPythonDump, aGroups);
2547 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2548 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2553 //=======================================================================
2554 //function : ExtrusionSweepObject2DMakeGroups
2556 //=======================================================================
2558 SMESH::ListOfGroups*
2559 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2560 const SMESH::DirStruct& theStepVector,
2561 CORBA::Long theNbOfSteps)
2563 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2565 SMESH::long_array_var anElementsId = theObject->GetIDs();
2566 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2567 theNbOfSteps, true, SMDSAbs_Face);
2568 if (!myIsPreviewMode) {
2569 DumpGroupsList(aPythonDump, aGroups);
2570 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2571 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2577 //=======================================================================
2578 //function : advancedExtrusion
2580 //=======================================================================
2582 SMESH::ListOfGroups*
2583 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2584 const SMESH::DirStruct & theStepVector,
2585 CORBA::Long theNbOfSteps,
2586 CORBA::Long theExtrFlags,
2587 CORBA::Double theSewTolerance,
2588 const bool theMakeGroups)
2592 TIDSortedElemSet elements;
2593 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2595 const SMESH::PointStruct * P = &theStepVector.PS;
2596 gp_Vec stepVec( P->x, P->y, P->z );
2598 TElemOfElemListMap aHystory;
2599 ::SMESH_MeshEditor::PGroupIDs groupIds =
2600 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2601 theMakeGroups, theExtrFlags, theSewTolerance);
2603 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2606 //=======================================================================
2607 //function : AdvancedExtrusion
2609 //=======================================================================
2611 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2612 const SMESH::DirStruct & theStepVector,
2613 CORBA::Long theNbOfSteps,
2614 CORBA::Long theExtrFlags,
2615 CORBA::Double theSewTolerance)
2617 if ( !myIsPreviewMode ) {
2618 TPythonDump() << "stepVector = " << theStepVector;
2619 TPythonDump() << this << ".AdvancedExtrusion("
2622 << theNbOfSteps << ","
2623 << theExtrFlags << ", "
2624 << theSewTolerance << " )";
2626 advancedExtrusion( theIDsOfElements,
2634 //=======================================================================
2635 //function : AdvancedExtrusionMakeGroups
2637 //=======================================================================
2638 SMESH::ListOfGroups*
2639 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2640 const SMESH::DirStruct& theStepVector,
2641 CORBA::Long theNbOfSteps,
2642 CORBA::Long theExtrFlags,
2643 CORBA::Double theSewTolerance)
2645 if (!myIsPreviewMode) {
2646 TPythonDump() << "stepVector = " << theStepVector;
2648 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2650 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2657 if (!myIsPreviewMode) {
2658 DumpGroupsList(aPythonDump, aGroups);
2659 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2662 << theNbOfSteps << ","
2663 << theExtrFlags << ", "
2664 << theSewTolerance << " )";
2670 //================================================================================
2672 * \brief Convert extrusion error to IDL enum
2674 //================================================================================
2676 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2678 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2682 RETCASE( EXTR_NO_ELEMENTS );
2683 RETCASE( EXTR_PATH_NOT_EDGE );
2684 RETCASE( EXTR_BAD_PATH_SHAPE );
2685 RETCASE( EXTR_BAD_STARTING_NODE );
2686 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2687 RETCASE( EXTR_CANT_GET_TANGENT );
2689 return SMESH::SMESH_MeshEditor::EXTR_OK;
2693 //=======================================================================
2694 //function : extrusionAlongPath
2696 //=======================================================================
2697 SMESH::ListOfGroups*
2698 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2699 SMESH::SMESH_Mesh_ptr thePathMesh,
2700 GEOM::GEOM_Object_ptr thePathShape,
2701 CORBA::Long theNodeStart,
2702 CORBA::Boolean theHasAngles,
2703 const SMESH::double_array & theAngles,
2704 CORBA::Boolean theHasRefPoint,
2705 const SMESH::PointStruct & theRefPoint,
2706 const bool theMakeGroups,
2707 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2708 const SMDSAbs_ElementType theElementType)
2710 MESSAGE("extrusionAlongPath");
2713 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2714 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2717 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2719 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2720 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2722 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2723 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2727 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2729 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2733 TIDSortedElemSet elements;
2734 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2736 list<double> angles;
2737 for (int i = 0; i < theAngles.length(); i++) {
2738 angles.push_back( theAngles[i] );
2741 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2743 int nbOldGroups = myMesh->NbGroup();
2745 ::SMESH_MeshEditor::Extrusion_Error error =
2746 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2747 theHasAngles, angles, false,
2748 theHasRefPoint, refPnt, theMakeGroups );
2749 myMesh->GetMeshDS()->Modified();
2750 theError = convExtrError( error );
2752 if ( theMakeGroups ) {
2753 list<int> groupIDs = myMesh->GetGroupIds();
2754 list<int>::iterator newBegin = groupIDs.begin();
2755 std::advance( newBegin, nbOldGroups ); // skip old groups
2756 groupIDs.erase( groupIDs.begin(), newBegin );
2757 return getGroups( & groupIDs );
2763 //=======================================================================
2764 //function : extrusionAlongPathX
2766 //=======================================================================
2767 SMESH::ListOfGroups*
2768 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2769 SMESH::SMESH_IDSource_ptr Path,
2770 CORBA::Long NodeStart,
2771 CORBA::Boolean HasAngles,
2772 const SMESH::double_array& Angles,
2773 CORBA::Boolean LinearVariation,
2774 CORBA::Boolean HasRefPoint,
2775 const SMESH::PointStruct& RefPoint,
2777 const SMDSAbs_ElementType ElementType,
2778 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2780 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2784 list<double> angles;
2785 for (int i = 0; i < Angles.length(); i++) {
2786 angles.push_back( Angles[i] );
2788 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2789 int nbOldGroups = myMesh->NbGroup();
2791 if ( Path->_is_nil() ) {
2792 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2796 TIDSortedElemSet elements, copyElements;
2797 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
2799 TIDSortedElemSet* workElements = &elements;
2801 if ( myIsPreviewMode )
2803 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2804 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
2805 workElements = & copyElements;
2809 ::SMESH_MeshEditor::Extrusion_Error error;
2811 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2814 SMDS_MeshNode* aNodeStart =
2815 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2816 if ( !aNodeStart ) {
2817 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2820 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2821 HasAngles, angles, LinearVariation,
2822 HasRefPoint, refPnt, MakeGroups );
2823 myMesh->GetMeshDS()->Modified();
2825 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2828 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2829 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2830 SMDS_MeshNode* aNodeStart =
2831 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2832 if ( !aNodeStart ) {
2833 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2836 SMESH_subMesh* aSubMesh =
2837 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2838 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2839 HasAngles, angles, LinearVariation,
2840 HasRefPoint, refPnt, MakeGroups );
2841 myMesh->GetMeshDS()->Modified();
2843 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2845 // path as group of 1D elements
2851 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2855 Error = convExtrError( error );
2858 list<int> groupIDs = myMesh->GetGroupIds();
2859 list<int>::iterator newBegin = groupIDs.begin();
2860 std::advance( newBegin, nbOldGroups ); // skip old groups
2861 groupIDs.erase( groupIDs.begin(), newBegin );
2862 return getGroups( & groupIDs );
2868 //=======================================================================
2869 //function : ExtrusionAlongPath
2871 //=======================================================================
2872 SMESH::SMESH_MeshEditor::Extrusion_Error
2873 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2874 SMESH::SMESH_Mesh_ptr thePathMesh,
2875 GEOM::GEOM_Object_ptr thePathShape,
2876 CORBA::Long theNodeStart,
2877 CORBA::Boolean theHasAngles,
2878 const SMESH::double_array & theAngles,
2879 CORBA::Boolean theHasRefPoint,
2880 const SMESH::PointStruct & theRefPoint)
2882 MESSAGE("ExtrusionAlongPath");
2883 if ( !myIsPreviewMode ) {
2884 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2885 << theIDsOfElements << ", "
2886 << thePathMesh << ", "
2887 << thePathShape << ", "
2888 << theNodeStart << ", "
2889 << theHasAngles << ", "
2890 << theAngles << ", "
2891 << theHasRefPoint << ", "
2892 << "SMESH.PointStruct( "
2893 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2894 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2895 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2897 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2898 extrusionAlongPath( theIDsOfElements,
2911 //=======================================================================
2912 //function : ExtrusionAlongPathObject
2914 //=======================================================================
2915 SMESH::SMESH_MeshEditor::Extrusion_Error
2916 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2917 SMESH::SMESH_Mesh_ptr thePathMesh,
2918 GEOM::GEOM_Object_ptr thePathShape,
2919 CORBA::Long theNodeStart,
2920 CORBA::Boolean theHasAngles,
2921 const SMESH::double_array & theAngles,
2922 CORBA::Boolean theHasRefPoint,
2923 const SMESH::PointStruct & theRefPoint)
2925 if ( !myIsPreviewMode ) {
2926 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2927 << theObject << ", "
2928 << thePathMesh << ", "
2929 << thePathShape << ", "
2930 << theNodeStart << ", "
2931 << theHasAngles << ", "
2932 << theAngles << ", "
2933 << theHasRefPoint << ", "
2934 << "SMESH.PointStruct( "
2935 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2936 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2937 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2939 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2940 SMESH::long_array_var anElementsId = theObject->GetIDs();
2941 extrusionAlongPath( anElementsId,
2954 //=======================================================================
2955 //function : ExtrusionAlongPathObject1D
2957 //=======================================================================
2958 SMESH::SMESH_MeshEditor::Extrusion_Error
2959 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2960 SMESH::SMESH_Mesh_ptr thePathMesh,
2961 GEOM::GEOM_Object_ptr thePathShape,
2962 CORBA::Long theNodeStart,
2963 CORBA::Boolean theHasAngles,
2964 const SMESH::double_array & theAngles,
2965 CORBA::Boolean theHasRefPoint,
2966 const SMESH::PointStruct & theRefPoint)
2968 if ( !myIsPreviewMode ) {
2969 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2970 << theObject << ", "
2971 << thePathMesh << ", "
2972 << thePathShape << ", "
2973 << theNodeStart << ", "
2974 << theHasAngles << ", "
2975 << theAngles << ", "
2976 << theHasRefPoint << ", "
2977 << "SMESH.PointStruct( "
2978 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2979 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2980 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2982 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2983 SMESH::long_array_var anElementsId = theObject->GetIDs();
2984 extrusionAlongPath( anElementsId,
2998 //=======================================================================
2999 //function : ExtrusionAlongPathObject2D
3001 //=======================================================================
3002 SMESH::SMESH_MeshEditor::Extrusion_Error
3003 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3004 SMESH::SMESH_Mesh_ptr thePathMesh,
3005 GEOM::GEOM_Object_ptr thePathShape,
3006 CORBA::Long theNodeStart,
3007 CORBA::Boolean theHasAngles,
3008 const SMESH::double_array & theAngles,
3009 CORBA::Boolean theHasRefPoint,
3010 const SMESH::PointStruct & theRefPoint)
3012 if ( !myIsPreviewMode ) {
3013 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3014 << theObject << ", "
3015 << thePathMesh << ", "
3016 << thePathShape << ", "
3017 << theNodeStart << ", "
3018 << theHasAngles << ", "
3019 << theAngles << ", "
3020 << theHasRefPoint << ", "
3021 << "SMESH.PointStruct( "
3022 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3023 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3024 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3026 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3027 SMESH::long_array_var anElementsId = theObject->GetIDs();
3028 extrusionAlongPath( anElementsId,
3043 //=======================================================================
3044 //function : ExtrusionAlongPathMakeGroups
3046 //=======================================================================
3047 SMESH::ListOfGroups*
3048 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3049 SMESH::SMESH_Mesh_ptr thePathMesh,
3050 GEOM::GEOM_Object_ptr thePathShape,
3051 CORBA::Long theNodeStart,
3052 CORBA::Boolean theHasAngles,
3053 const SMESH::double_array& theAngles,
3054 CORBA::Boolean theHasRefPoint,
3055 const SMESH::PointStruct& theRefPoint,
3056 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3058 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3060 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3070 if (!myIsPreviewMode) {
3071 bool isDumpGroups = aGroups && aGroups->length() > 0;
3073 aPythonDump << "(" << aGroups << ", error)";
3075 aPythonDump <<"error";
3077 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3078 << theIDsOfElements << ", "
3079 << thePathMesh << ", "
3080 << thePathShape << ", "
3081 << theNodeStart << ", "
3082 << theHasAngles << ", "
3083 << theAngles << ", "
3084 << theHasRefPoint << ", "
3085 << "SMESH.PointStruct( "
3086 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3087 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3088 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3093 //=======================================================================
3094 //function : ExtrusionAlongPathObjectMakeGroups
3096 //=======================================================================
3097 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3098 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3099 SMESH::SMESH_Mesh_ptr thePathMesh,
3100 GEOM::GEOM_Object_ptr thePathShape,
3101 CORBA::Long theNodeStart,
3102 CORBA::Boolean theHasAngles,
3103 const SMESH::double_array& theAngles,
3104 CORBA::Boolean theHasRefPoint,
3105 const SMESH::PointStruct& theRefPoint,
3106 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3108 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3110 SMESH::long_array_var anElementsId = theObject->GetIDs();
3111 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3122 if (!myIsPreviewMode) {
3123 bool isDumpGroups = aGroups && aGroups->length() > 0;
3125 aPythonDump << "(" << aGroups << ", error)";
3127 aPythonDump <<"error";
3129 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3130 << theObject << ", "
3131 << thePathMesh << ", "
3132 << thePathShape << ", "
3133 << theNodeStart << ", "
3134 << theHasAngles << ", "
3135 << theAngles << ", "
3136 << theHasRefPoint << ", "
3137 << "SMESH.PointStruct( "
3138 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3139 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3140 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3145 //=======================================================================
3146 //function : ExtrusionAlongPathObject1DMakeGroups
3148 //=======================================================================
3149 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3150 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3151 SMESH::SMESH_Mesh_ptr thePathMesh,
3152 GEOM::GEOM_Object_ptr thePathShape,
3153 CORBA::Long theNodeStart,
3154 CORBA::Boolean theHasAngles,
3155 const SMESH::double_array& theAngles,
3156 CORBA::Boolean theHasRefPoint,
3157 const SMESH::PointStruct& theRefPoint,
3158 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3160 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3162 SMESH::long_array_var anElementsId = theObject->GetIDs();
3163 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3175 if (!myIsPreviewMode) {
3176 bool isDumpGroups = aGroups && aGroups->length() > 0;
3178 aPythonDump << "(" << aGroups << ", error)";
3180 aPythonDump << "error";
3182 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3183 << theObject << ", "
3184 << thePathMesh << ", "
3185 << thePathShape << ", "
3186 << theNodeStart << ", "
3187 << theHasAngles << ", "
3188 << theAngles << ", "
3189 << theHasRefPoint << ", "
3190 << "SMESH.PointStruct( "
3191 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3192 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3193 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3198 //=======================================================================
3199 //function : ExtrusionAlongPathObject2DMakeGroups
3201 //=======================================================================
3202 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3203 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3204 SMESH::SMESH_Mesh_ptr thePathMesh,
3205 GEOM::GEOM_Object_ptr thePathShape,
3206 CORBA::Long theNodeStart,
3207 CORBA::Boolean theHasAngles,
3208 const SMESH::double_array& theAngles,
3209 CORBA::Boolean theHasRefPoint,
3210 const SMESH::PointStruct& theRefPoint,
3211 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3213 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3215 SMESH::long_array_var anElementsId = theObject->GetIDs();
3216 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3228 if (!myIsPreviewMode) {
3229 bool isDumpGroups = aGroups && aGroups->length() > 0;
3231 aPythonDump << "(" << aGroups << ", error)";
3233 aPythonDump << "error";
3235 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3236 << theObject << ", "
3237 << thePathMesh << ", "
3238 << thePathShape << ", "
3239 << theNodeStart << ", "
3240 << theHasAngles << ", "
3241 << theAngles << ", "
3242 << theHasRefPoint << ", "
3243 << "SMESH.PointStruct( "
3244 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3245 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3246 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3252 //=======================================================================
3253 //function : ExtrusionAlongPathObjX
3255 //=======================================================================
3256 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3257 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3258 SMESH::SMESH_IDSource_ptr Path,
3259 CORBA::Long NodeStart,
3260 CORBA::Boolean HasAngles,
3261 const SMESH::double_array& Angles,
3262 CORBA::Boolean LinearVariation,
3263 CORBA::Boolean HasRefPoint,
3264 const SMESH::PointStruct& RefPoint,
3265 CORBA::Boolean MakeGroups,
3266 SMESH::ElementType ElemType,
3267 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3269 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3271 SMESH::long_array_var anElementsId = Object->GetIDs();
3272 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3281 (SMDSAbs_ElementType)ElemType,
3284 if (!myIsPreviewMode) {
3285 bool isDumpGroups = aGroups && aGroups->length() > 0;
3287 aPythonDump << "(" << *aGroups << ", error)";
3289 aPythonDump << "error";
3291 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3294 << NodeStart << ", "
3295 << HasAngles << ", "
3296 << TVar( Angles ) << ", "
3297 << LinearVariation << ", "
3298 << HasRefPoint << ", "
3299 << "SMESH.PointStruct( "
3300 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3301 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3302 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3303 << MakeGroups << ", "
3304 << ElemType << " )";
3310 //=======================================================================
3311 //function : ExtrusionAlongPathX
3313 //=======================================================================
3314 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3315 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3316 SMESH::SMESH_IDSource_ptr Path,
3317 CORBA::Long NodeStart,
3318 CORBA::Boolean HasAngles,
3319 const SMESH::double_array& Angles,
3320 CORBA::Boolean LinearVariation,
3321 CORBA::Boolean HasRefPoint,
3322 const SMESH::PointStruct& RefPoint,
3323 CORBA::Boolean MakeGroups,
3324 SMESH::ElementType ElemType,
3325 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3327 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3329 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3338 (SMDSAbs_ElementType)ElemType,
3341 if (!myIsPreviewMode) {
3342 bool isDumpGroups = aGroups && aGroups->length() > 0;
3344 aPythonDump << "(" << *aGroups << ", error)";
3346 aPythonDump <<"error";
3348 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3349 << IDsOfElements << ", "
3351 << NodeStart << ", "
3352 << HasAngles << ", "
3353 << TVar( Angles ) << ", "
3354 << LinearVariation << ", "
3355 << HasRefPoint << ", "
3356 << "SMESH.PointStruct( "
3357 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3358 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3359 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3360 << MakeGroups << ", "
3361 << ElemType << " )";
3367 //================================================================================
3369 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3370 * of given angles along path steps
3371 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3372 * which proceeds the extrusion
3373 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3374 * is used to define the sub-mesh for the path
3376 //================================================================================
3378 SMESH::double_array*
3379 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3380 GEOM::GEOM_Object_ptr thePathShape,
3381 const SMESH::double_array & theAngles)
3383 SMESH::double_array_var aResult = new SMESH::double_array();
3384 int nbAngles = theAngles.length();
3385 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3387 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3388 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3389 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3390 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3391 return aResult._retn();
3392 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3393 if ( nbSteps == nbAngles )
3395 aResult.inout() = theAngles;
3399 aResult->length( nbSteps );
3400 double rAn2St = double( nbAngles ) / double( nbSteps );
3401 double angPrev = 0, angle;
3402 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3404 double angCur = rAn2St * ( iSt+1 );
3405 double angCurFloor = floor( angCur );
3406 double angPrevFloor = floor( angPrev );
3407 if ( angPrevFloor == angCurFloor )
3408 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3411 int iP = int( angPrevFloor );
3412 double angPrevCeil = ceil(angPrev);
3413 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3415 int iC = int( angCurFloor );
3416 if ( iC < nbAngles )
3417 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3419 iP = int( angPrevCeil );
3421 angle += theAngles[ iC ];
3423 aResult[ iSt ] = angle;
3428 // Update Python script
3429 TPythonDump() << "rotAngles = " << theAngles;
3430 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3431 << thePathMesh << ", "
3432 << thePathShape << ", "
3435 return aResult._retn();
3439 //=======================================================================
3442 //=======================================================================
3444 SMESH::ListOfGroups*
3445 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3446 const SMESH::AxisStruct & theAxis,
3447 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3448 CORBA::Boolean theCopy,
3450 ::SMESH_Mesh* theTargetMesh)
3454 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3455 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3457 if ( theTargetMesh )
3461 switch ( theMirrorType ) {
3462 case SMESH::SMESH_MeshEditor::POINT:
3463 aTrsf.SetMirror( P );
3465 case SMESH::SMESH_MeshEditor::AXIS:
3466 aTrsf.SetMirror( gp_Ax1( P, V ));
3469 aTrsf.SetMirror( gp_Ax2( P, V ));
3472 TIDSortedElemSet copyElements;
3473 TIDSortedElemSet* workElements = & theElements;
3475 if ( myIsPreviewMode )
3477 TPreviewMesh * tmpMesh = getPreviewMesh();
3478 tmpMesh->Copy( theElements, copyElements);
3479 if ( !theCopy && !theTargetMesh )
3481 TIDSortedElemSet elemsAround, elemsAroundCopy;
3482 getElementsAround( theElements, getMeshDS(), elemsAround );
3483 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3485 workElements = & copyElements;
3486 theMakeGroups = false;
3489 ::SMESH_MeshEditor::PGroupIDs groupIds =
3490 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3492 if ( theCopy && !myIsPreviewMode)
3494 if ( theTargetMesh )
3496 theTargetMesh->GetMeshDS()->Modified();
3500 myMesh->GetMeshDS()->Modified();
3501 myMesh->SetIsModified( true );
3504 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3507 //=======================================================================
3510 //=======================================================================
3512 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3513 const SMESH::AxisStruct & theAxis,
3514 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3515 CORBA::Boolean theCopy)
3517 if ( !myIsPreviewMode ) {
3518 TPythonDump() << this << ".Mirror( "
3519 << theIDsOfElements << ", "
3521 << mirrorTypeName(theMirrorType) << ", "
3524 if ( theIDsOfElements.length() > 0 )
3526 TIDSortedElemSet elements;
3527 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3528 mirror(elements, theAxis, theMirrorType, theCopy, false);
3533 //=======================================================================
3534 //function : MirrorObject
3536 //=======================================================================
3538 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3539 const SMESH::AxisStruct & theAxis,
3540 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3541 CORBA::Boolean theCopy)
3543 if ( !myIsPreviewMode ) {
3544 TPythonDump() << this << ".MirrorObject( "
3545 << theObject << ", "
3547 << mirrorTypeName(theMirrorType) << ", "
3550 TIDSortedElemSet elements;
3552 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3554 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3555 mirror(elements, theAxis, theMirrorType, theCopy, false);
3558 //=======================================================================
3559 //function : MirrorMakeGroups
3561 //=======================================================================
3563 SMESH::ListOfGroups*
3564 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3565 const SMESH::AxisStruct& theMirror,
3566 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3568 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3570 SMESH::ListOfGroups * aGroups = 0;
3571 if ( theIDsOfElements.length() > 0 )
3573 TIDSortedElemSet elements;
3574 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3575 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3577 if (!myIsPreviewMode) {
3578 DumpGroupsList(aPythonDump, aGroups);
3579 aPythonDump << this << ".MirrorMakeGroups( "
3580 << theIDsOfElements << ", "
3581 << theMirror << ", "
3582 << mirrorTypeName(theMirrorType) << " )";
3587 //=======================================================================
3588 //function : MirrorObjectMakeGroups
3590 //=======================================================================
3592 SMESH::ListOfGroups*
3593 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3594 const SMESH::AxisStruct& theMirror,
3595 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3597 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3599 SMESH::ListOfGroups * aGroups = 0;
3600 TIDSortedElemSet elements;
3601 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3602 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3604 if (!myIsPreviewMode)
3606 DumpGroupsList(aPythonDump,aGroups);
3607 aPythonDump << this << ".MirrorObjectMakeGroups( "
3608 << theObject << ", "
3609 << theMirror << ", "
3610 << mirrorTypeName(theMirrorType) << " )";
3615 //=======================================================================
3616 //function : MirrorMakeMesh
3618 //=======================================================================
3620 SMESH::SMESH_Mesh_ptr
3621 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3622 const SMESH::AxisStruct& theMirror,
3623 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3624 CORBA::Boolean theCopyGroups,
3625 const char* theMeshName)
3627 SMESH_Mesh_i* mesh_i;
3628 SMESH::SMESH_Mesh_var mesh;
3629 { // open new scope to dump "MakeMesh" command
3630 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3632 TPythonDump pydump; // to prevent dump at mesh creation
3634 mesh = makeMesh( theMeshName );
3635 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3636 if (mesh_i && theIDsOfElements.length() > 0 )
3638 TIDSortedElemSet elements;
3639 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3640 mirror(elements, theMirror, theMirrorType,
3641 false, theCopyGroups, & mesh_i->GetImpl());
3642 mesh_i->CreateGroupServants();
3645 if (!myIsPreviewMode) {
3646 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3647 << theIDsOfElements << ", "
3648 << theMirror << ", "
3649 << mirrorTypeName(theMirrorType) << ", "
3650 << theCopyGroups << ", '"
3651 << theMeshName << "' )";
3656 if (!myIsPreviewMode && mesh_i)
3657 mesh_i->GetGroups();
3659 return mesh._retn();
3662 //=======================================================================
3663 //function : MirrorObjectMakeMesh
3665 //=======================================================================
3667 SMESH::SMESH_Mesh_ptr
3668 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3669 const SMESH::AxisStruct& theMirror,
3670 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3671 CORBA::Boolean theCopyGroups,
3672 const char* theMeshName)
3674 SMESH_Mesh_i* mesh_i;
3675 SMESH::SMESH_Mesh_var mesh;
3676 { // open new scope to dump "MakeMesh" command
3677 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3679 TPythonDump pydump; // to prevent dump at mesh creation
3681 mesh = makeMesh( theMeshName );
3682 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3683 TIDSortedElemSet elements;
3685 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3687 mirror(elements, theMirror, theMirrorType,
3688 false, theCopyGroups, & mesh_i->GetImpl());
3689 mesh_i->CreateGroupServants();
3691 if (!myIsPreviewMode) {
3692 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3693 << theObject << ", "
3694 << theMirror << ", "
3695 << mirrorTypeName(theMirrorType) << ", "
3696 << theCopyGroups << ", '"
3697 << theMeshName << "' )";
3702 if (!myIsPreviewMode && mesh_i)
3703 mesh_i->GetGroups();
3705 return mesh._retn();
3708 //=======================================================================
3709 //function : translate
3711 //=======================================================================
3713 SMESH::ListOfGroups*
3714 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3715 const SMESH::DirStruct & theVector,
3716 CORBA::Boolean theCopy,
3718 ::SMESH_Mesh* theTargetMesh)
3722 if ( theTargetMesh )
3726 const SMESH::PointStruct * P = &theVector.PS;
3727 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3729 TIDSortedElemSet copyElements;
3730 TIDSortedElemSet* workElements = &theElements;
3732 if ( myIsPreviewMode )
3734 TPreviewMesh * tmpMesh = getPreviewMesh();
3735 tmpMesh->Copy( theElements, copyElements);
3736 if ( !theCopy && !theTargetMesh )
3738 TIDSortedElemSet elemsAround, elemsAroundCopy;
3739 getElementsAround( theElements, getMeshDS(), elemsAround );
3740 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3742 workElements = & copyElements;
3743 theMakeGroups = false;
3746 ::SMESH_MeshEditor::PGroupIDs groupIds =
3747 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3749 if ( theCopy && !myIsPreviewMode )
3751 if ( theTargetMesh )
3753 theTargetMesh->GetMeshDS()->Modified();
3757 myMesh->GetMeshDS()->Modified();
3758 myMesh->SetIsModified( true );
3762 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3765 //=======================================================================
3766 //function : Translate
3768 //=======================================================================
3770 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3771 const SMESH::DirStruct & theVector,
3772 CORBA::Boolean theCopy)
3774 if (!myIsPreviewMode) {
3775 TPythonDump() << this << ".Translate( "
3776 << theIDsOfElements << ", "
3777 << theVector << ", "
3780 if (theIDsOfElements.length()) {
3781 TIDSortedElemSet elements;
3782 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3783 translate(elements, theVector, theCopy, false);
3787 //=======================================================================
3788 //function : TranslateObject
3790 //=======================================================================
3792 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3793 const SMESH::DirStruct & theVector,
3794 CORBA::Boolean theCopy)
3796 if (!myIsPreviewMode) {
3797 TPythonDump() << this << ".TranslateObject( "
3798 << theObject << ", "
3799 << theVector << ", "
3802 TIDSortedElemSet elements;
3804 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3806 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3807 translate(elements, theVector, theCopy, false);
3810 //=======================================================================
3811 //function : TranslateMakeGroups
3813 //=======================================================================
3815 SMESH::ListOfGroups*
3816 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3817 const SMESH::DirStruct& theVector)
3819 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3821 SMESH::ListOfGroups * aGroups = 0;
3822 if (theIDsOfElements.length()) {
3823 TIDSortedElemSet elements;
3824 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3825 aGroups = translate(elements,theVector,true,true);
3827 if (!myIsPreviewMode) {
3828 DumpGroupsList(aPythonDump, aGroups);
3829 aPythonDump << this << ".TranslateMakeGroups( "
3830 << theIDsOfElements << ", "
3831 << theVector << " )";
3836 //=======================================================================
3837 //function : TranslateObjectMakeGroups
3839 //=======================================================================
3841 SMESH::ListOfGroups*
3842 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3843 const SMESH::DirStruct& theVector)
3845 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3847 SMESH::ListOfGroups * aGroups = 0;
3848 TIDSortedElemSet elements;
3849 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3850 aGroups = translate(elements, theVector, true, true);
3852 if (!myIsPreviewMode) {
3853 DumpGroupsList(aPythonDump, aGroups);
3854 aPythonDump << this << ".TranslateObjectMakeGroups( "
3855 << theObject << ", "
3856 << theVector << " )";
3861 //=======================================================================
3862 //function : TranslateMakeMesh
3864 //=======================================================================
3866 SMESH::SMESH_Mesh_ptr
3867 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3868 const SMESH::DirStruct& theVector,
3869 CORBA::Boolean theCopyGroups,
3870 const char* theMeshName)
3872 SMESH_Mesh_i* mesh_i;
3873 SMESH::SMESH_Mesh_var mesh;
3875 { // open new scope to dump "MakeMesh" command
3876 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3878 TPythonDump pydump; // to prevent dump at mesh creation
3880 mesh = makeMesh( theMeshName );
3881 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3883 if ( mesh_i && theIDsOfElements.length() )
3885 TIDSortedElemSet elements;
3886 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3887 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3888 mesh_i->CreateGroupServants();
3891 if ( !myIsPreviewMode ) {
3892 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3893 << theIDsOfElements << ", "
3894 << theVector << ", "
3895 << theCopyGroups << ", '"
3896 << theMeshName << "' )";
3901 if (!myIsPreviewMode && mesh_i)
3902 mesh_i->GetGroups();
3904 return mesh._retn();
3907 //=======================================================================
3908 //function : TranslateObjectMakeMesh
3910 //=======================================================================
3912 SMESH::SMESH_Mesh_ptr
3913 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3914 const SMESH::DirStruct& theVector,
3915 CORBA::Boolean theCopyGroups,
3916 const char* theMeshName)
3918 SMESH_Mesh_i* mesh_i;
3919 SMESH::SMESH_Mesh_var mesh;
3920 { // open new scope to dump "MakeMesh" command
3921 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3923 TPythonDump pydump; // to prevent dump at mesh creation
3924 mesh = makeMesh( theMeshName );
3925 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3927 TIDSortedElemSet elements;
3929 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3931 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3932 mesh_i->CreateGroupServants();
3934 if ( !myIsPreviewMode ) {
3935 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3936 << theObject << ", "
3937 << theVector << ", "
3938 << theCopyGroups << ", '"
3939 << theMeshName << "' )";
3944 if (!myIsPreviewMode && mesh_i)
3945 mesh_i->GetGroups();
3947 return mesh._retn();
3950 //=======================================================================
3953 //=======================================================================
3955 SMESH::ListOfGroups*
3956 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3957 const SMESH::AxisStruct & theAxis,
3958 CORBA::Double theAngle,
3959 CORBA::Boolean theCopy,
3961 ::SMESH_Mesh* theTargetMesh)
3965 if ( theTargetMesh )
3968 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3969 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3972 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3974 TIDSortedElemSet copyElements;
3975 TIDSortedElemSet* workElements = &theElements;
3976 if ( myIsPreviewMode ) {
3977 TPreviewMesh * tmpMesh = getPreviewMesh();
3978 tmpMesh->Copy( theElements, copyElements );
3979 if ( !theCopy && !theTargetMesh )
3981 TIDSortedElemSet elemsAround, elemsAroundCopy;
3982 getElementsAround( theElements, getMeshDS(), elemsAround );
3983 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3985 workElements = ©Elements;
3986 theMakeGroups = false;
3989 ::SMESH_MeshEditor::PGroupIDs groupIds =
3990 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3992 if ( theCopy && !myIsPreviewMode)
3994 if ( theTargetMesh )
3996 theTargetMesh->GetMeshDS()->Modified();
4000 myMesh->GetMeshDS()->Modified();
4001 myMesh->SetIsModified( true );
4005 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4008 //=======================================================================
4011 //=======================================================================
4013 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4014 const SMESH::AxisStruct & theAxis,
4015 CORBA::Double theAngle,
4016 CORBA::Boolean theCopy)
4018 if (!myIsPreviewMode) {
4019 TPythonDump() << this << ".Rotate( "
4020 << theIDsOfElements << ", "
4022 << TVar( theAngle ) << ", "
4025 if (theIDsOfElements.length() > 0)
4027 TIDSortedElemSet elements;
4028 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4029 rotate(elements,theAxis,theAngle,theCopy,false);
4033 //=======================================================================
4034 //function : RotateObject
4036 //=======================================================================
4038 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4039 const SMESH::AxisStruct & theAxis,
4040 CORBA::Double theAngle,
4041 CORBA::Boolean theCopy)
4043 if ( !myIsPreviewMode ) {
4044 TPythonDump() << this << ".RotateObject( "
4045 << theObject << ", "
4047 << TVar( theAngle ) << ", "
4050 TIDSortedElemSet elements;
4051 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4052 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4053 rotate(elements,theAxis,theAngle,theCopy,false);
4056 //=======================================================================
4057 //function : RotateMakeGroups
4059 //=======================================================================
4061 SMESH::ListOfGroups*
4062 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4063 const SMESH::AxisStruct& theAxis,
4064 CORBA::Double theAngle)
4066 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4068 SMESH::ListOfGroups * aGroups = 0;
4069 if (theIDsOfElements.length() > 0)
4071 TIDSortedElemSet elements;
4072 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4073 aGroups = rotate(elements,theAxis,theAngle,true,true);
4075 if (!myIsPreviewMode) {
4076 DumpGroupsList(aPythonDump, aGroups);
4077 aPythonDump << this << ".RotateMakeGroups( "
4078 << theIDsOfElements << ", "
4080 << TVar( theAngle ) << " )";
4085 //=======================================================================
4086 //function : RotateObjectMakeGroups
4088 //=======================================================================
4090 SMESH::ListOfGroups*
4091 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4092 const SMESH::AxisStruct& theAxis,
4093 CORBA::Double theAngle)
4095 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4097 SMESH::ListOfGroups * aGroups = 0;
4098 TIDSortedElemSet elements;
4099 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4100 aGroups = rotate(elements, theAxis, theAngle, true, true);
4102 if (!myIsPreviewMode) {
4103 DumpGroupsList(aPythonDump, aGroups);
4104 aPythonDump << this << ".RotateObjectMakeGroups( "
4105 << theObject << ", "
4107 << TVar( theAngle ) << " )";
4112 //=======================================================================
4113 //function : RotateMakeMesh
4115 //=======================================================================
4117 SMESH::SMESH_Mesh_ptr
4118 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4119 const SMESH::AxisStruct& theAxis,
4120 CORBA::Double theAngleInRadians,
4121 CORBA::Boolean theCopyGroups,
4122 const char* theMeshName)
4124 SMESH::SMESH_Mesh_var mesh;
4125 SMESH_Mesh_i* mesh_i;
4127 { // open new scope to dump "MakeMesh" command
4128 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4130 TPythonDump pydump; // to prevent dump at mesh creation
4132 mesh = makeMesh( theMeshName );
4133 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4135 if ( mesh_i && theIDsOfElements.length() > 0 )
4137 TIDSortedElemSet elements;
4138 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4139 rotate(elements, theAxis, theAngleInRadians,
4140 false, theCopyGroups, & mesh_i->GetImpl());
4141 mesh_i->CreateGroupServants();
4143 if ( !myIsPreviewMode ) {
4144 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4145 << theIDsOfElements << ", "
4147 << TVar( theAngleInRadians ) << ", "
4148 << theCopyGroups << ", '"
4149 << theMeshName << "' )";
4154 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4155 mesh_i->GetGroups();
4157 return mesh._retn();
4160 //=======================================================================
4161 //function : RotateObjectMakeMesh
4163 //=======================================================================
4165 SMESH::SMESH_Mesh_ptr
4166 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4167 const SMESH::AxisStruct& theAxis,
4168 CORBA::Double theAngleInRadians,
4169 CORBA::Boolean theCopyGroups,
4170 const char* theMeshName)
4172 SMESH::SMESH_Mesh_var mesh;
4173 SMESH_Mesh_i* mesh_i;
4175 {// open new scope to dump "MakeMesh" command
4176 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4178 TPythonDump pydump; // to prevent dump at mesh creation
4179 mesh = makeMesh( theMeshName );
4180 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4182 TIDSortedElemSet elements;
4184 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4186 rotate(elements, theAxis, theAngleInRadians,
4187 false, theCopyGroups, & mesh_i->GetImpl());
4188 mesh_i->CreateGroupServants();
4190 if ( !myIsPreviewMode ) {
4191 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4192 << theObject << ", "
4194 << TVar( theAngleInRadians ) << ", "
4195 << theCopyGroups << ", '"
4196 << theMeshName << "' )";
4201 if (!myIsPreviewMode && mesh_i)
4202 mesh_i->GetGroups();
4204 return mesh._retn();
4207 //=======================================================================
4210 //=======================================================================
4212 SMESH::ListOfGroups*
4213 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4214 const SMESH::PointStruct& thePoint,
4215 const SMESH::double_array& theScaleFact,
4216 CORBA::Boolean theCopy,
4218 ::SMESH_Mesh* theTargetMesh)
4221 if ( theScaleFact.length() < 1 )
4222 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4223 if ( theScaleFact.length() == 2 )
4224 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4226 if ( theTargetMesh )
4229 TIDSortedElemSet elements;
4230 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4231 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4236 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4237 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4239 double tol = std::numeric_limits<double>::max();
4241 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4242 0, S[1], 0, thePoint.y * (1-S[1]),
4243 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4245 TIDSortedElemSet copyElements;
4246 TIDSortedElemSet* workElements = &elements;
4247 if ( myIsPreviewMode )
4249 TPreviewMesh * tmpMesh = getPreviewMesh();
4250 tmpMesh->Copy( elements, copyElements);
4251 if ( !theCopy && !theTargetMesh )
4253 TIDSortedElemSet elemsAround, elemsAroundCopy;
4254 getElementsAround( elements, getMeshDS(), elemsAround );
4255 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4257 workElements = & copyElements;
4258 theMakeGroups = false;
4261 ::SMESH_MeshEditor::PGroupIDs groupIds =
4262 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4264 if ( theCopy && !myIsPreviewMode )
4266 if ( theTargetMesh )
4268 theTargetMesh->GetMeshDS()->Modified();
4272 myMesh->GetMeshDS()->Modified();
4273 myMesh->SetIsModified( true );
4277 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4280 //=======================================================================
4283 //=======================================================================
4285 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4286 const SMESH::PointStruct& thePoint,
4287 const SMESH::double_array& theScaleFact,
4288 CORBA::Boolean theCopy)
4290 if ( !myIsPreviewMode ) {
4291 TPythonDump() << this << ".Scale( "
4292 << theObject << ", "
4294 << TVar( theScaleFact ) << ", "
4297 scale(theObject, thePoint, theScaleFact, theCopy, false);
4301 //=======================================================================
4302 //function : ScaleMakeGroups
4304 //=======================================================================
4306 SMESH::ListOfGroups*
4307 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4308 const SMESH::PointStruct& thePoint,
4309 const SMESH::double_array& theScaleFact)
4311 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4313 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4314 if (!myIsPreviewMode) {
4315 DumpGroupsList(aPythonDump, aGroups);
4316 aPythonDump << this << ".Scale("
4319 << TVar( theScaleFact ) << ",True,True)";
4325 //=======================================================================
4326 //function : ScaleMakeMesh
4328 //=======================================================================
4330 SMESH::SMESH_Mesh_ptr
4331 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4332 const SMESH::PointStruct& thePoint,
4333 const SMESH::double_array& theScaleFact,
4334 CORBA::Boolean theCopyGroups,
4335 const char* theMeshName)
4337 SMESH_Mesh_i* mesh_i;
4338 SMESH::SMESH_Mesh_var mesh;
4339 { // open new scope to dump "MakeMesh" command
4340 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4342 TPythonDump pydump; // to prevent dump at mesh creation
4343 mesh = makeMesh( theMeshName );
4344 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4348 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4349 mesh_i->CreateGroupServants();
4351 if ( !myIsPreviewMode )
4352 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4353 << theObject << ", "
4355 << TVar( theScaleFact ) << ", "
4356 << theCopyGroups << ", '"
4357 << theMeshName << "' )";
4361 if (!myIsPreviewMode && mesh_i)
4362 mesh_i->GetGroups();
4364 return mesh._retn();
4368 //=======================================================================
4369 //function : FindCoincidentNodes
4371 //=======================================================================
4373 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4374 SMESH::array_of_long_array_out GroupsOfNodes)
4378 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4379 TIDSortedNodeSet nodes; // no input nodes
4380 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4382 GroupsOfNodes = new SMESH::array_of_long_array;
4383 GroupsOfNodes->length( aListOfListOfNodes.size() );
4384 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4385 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4386 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4387 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4388 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4389 aGroup.length( aListOfNodes.size() );
4390 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4391 aGroup[ j ] = (*lIt)->GetID();
4393 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4394 << Tolerance << " )";
4397 //=======================================================================
4398 //function : FindCoincidentNodesOnPart
4400 //=======================================================================
4401 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4402 CORBA::Double Tolerance,
4403 SMESH::array_of_long_array_out GroupsOfNodes)
4407 TIDSortedNodeSet nodes;
4408 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4410 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4412 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4414 GroupsOfNodes = new SMESH::array_of_long_array;
4415 GroupsOfNodes->length( aListOfListOfNodes.size() );
4416 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4417 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4419 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4420 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4421 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4422 aGroup.length( aListOfNodes.size() );
4423 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4424 aGroup[ j ] = (*lIt)->GetID();
4426 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4428 << Tolerance << " )";
4431 //================================================================================
4433 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4434 * ExceptSubMeshOrGroups
4436 //================================================================================
4438 void SMESH_MeshEditor_i::
4439 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4440 CORBA::Double theTolerance,
4441 SMESH::array_of_long_array_out theGroupsOfNodes,
4442 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4446 TIDSortedNodeSet nodes;
4447 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4449 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4451 TIDSortedNodeSet exceptNodes;
4452 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4453 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4454 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4455 nodes.erase( *avoidNode );
4457 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4459 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4461 theGroupsOfNodes = new SMESH::array_of_long_array;
4462 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4463 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4464 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4466 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4467 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4468 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4469 aGroup.length( aListOfNodes.size() );
4470 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4471 aGroup[ j ] = (*lIt)->GetID();
4473 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4475 << theTolerance << ", "
4476 << theExceptSubMeshOrGroups << " )";
4479 //=======================================================================
4480 //function : MergeNodes
4482 //=======================================================================
4484 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4488 SMESHDS_Mesh* aMesh = getMeshDS();
4490 TPythonDump aTPythonDump;
4491 aTPythonDump << this << ".MergeNodes([";
4492 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4493 for (int i = 0; i < GroupsOfNodes.length(); i++)
4495 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4496 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4497 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4498 for ( int j = 0; j < aNodeGroup.length(); j++ )
4500 CORBA::Long index = aNodeGroup[ j ];
4501 const SMDS_MeshNode * node = aMesh->FindNode(index);
4503 aListOfNodes.push_back( node );
4505 if ( aListOfNodes.size() < 2 )
4506 aListOfListOfNodes.pop_back();
4508 if ( i > 0 ) aTPythonDump << ", ";
4509 aTPythonDump << aNodeGroup;
4511 getEditor().MergeNodes( aListOfListOfNodes );
4513 aTPythonDump << "])";
4514 myMesh->GetMeshDS()->Modified();
4515 myMesh->SetIsModified( true );
4518 //=======================================================================
4519 //function : FindEqualElements
4521 //=======================================================================
4522 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4523 SMESH::array_of_long_array_out GroupsOfElementsID)
4527 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4528 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4530 TIDSortedElemSet elems;
4531 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4533 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4534 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4536 GroupsOfElementsID = new SMESH::array_of_long_array;
4537 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4539 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4540 aListOfListOfElementsID.begin();
4541 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4543 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4544 list<int>& listOfIDs = *arraysIt;
4545 aGroup.length( listOfIDs.size() );
4546 list<int>::iterator idIt = listOfIDs.begin();
4547 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4548 aGroup[ k ] = *idIt;
4551 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4556 //=======================================================================
4557 //function : MergeElements
4559 //=======================================================================
4561 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4565 TPythonDump aTPythonDump;
4566 aTPythonDump << this << ".MergeElements( [";
4568 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4570 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4571 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4572 aListOfListOfElementsID.push_back( list< int >() );
4573 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4574 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4575 CORBA::Long id = anElemsIDGroup[ j ];
4576 aListOfElemsID.push_back( id );
4578 if ( aListOfElemsID.size() < 2 )
4579 aListOfListOfElementsID.pop_back();
4580 if ( i > 0 ) aTPythonDump << ", ";
4581 aTPythonDump << anElemsIDGroup;
4584 getEditor().MergeElements(aListOfListOfElementsID);
4585 myMesh->GetMeshDS()->Modified();
4586 myMesh->SetIsModified( true );
4588 aTPythonDump << "] )";
4591 //=======================================================================
4592 //function : MergeEqualElements
4594 //=======================================================================
4596 void SMESH_MeshEditor_i::MergeEqualElements()
4600 getEditor().MergeEqualElements();
4602 myMesh->GetMeshDS()->Modified();
4604 TPythonDump() << this << ".MergeEqualElements()";
4607 //=============================================================================
4609 * Move the node to a given point
4611 //=============================================================================
4613 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4618 initData(/*deleteSearchers=*/false);
4620 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4624 if ( theNodeSearcher )
4625 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4627 if ( myIsPreviewMode ) // make preview data
4629 // in a preview mesh, make edges linked to a node
4630 TPreviewMesh& tmpMesh = *getPreviewMesh();
4631 TIDSortedElemSet linkedNodes;
4632 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4633 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4634 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4635 for ( ; nIt != linkedNodes.end(); ++nIt )
4637 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4638 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4642 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4643 // fill preview data
4645 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4646 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4648 getMeshDS()->MoveNode(node, x, y, z);
4650 if ( !myIsPreviewMode )
4652 // Update Python script
4653 TPythonDump() << "isDone = " << this << ".MoveNode( "
4654 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4655 myMesh->GetMeshDS()->Modified();
4656 myMesh->SetIsModified( true );
4662 //================================================================================
4664 * \brief Return ID of node closest to a given point
4666 //================================================================================
4668 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4672 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4674 if ( !theNodeSearcher ) {
4675 theNodeSearcher = myEditor.GetNodeSearcher();
4678 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4679 return node->GetID();
4684 //================================================================================
4686 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4687 * move the node closest to the point to point's location and return ID of the node
4689 //================================================================================
4691 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4694 CORBA::Long theNodeID)
4696 // We keep theNodeSearcher until any mesh modification:
4697 // 1) initData() deletes theNodeSearcher at any edition,
4698 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4700 initData(/*deleteSearchers=*/false);
4702 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4704 int nodeID = theNodeID;
4705 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
4706 if ( !node ) // preview moving node
4708 if ( !theNodeSearcher ) {
4709 theNodeSearcher = myEditor.GetNodeSearcher();
4712 node = theNodeSearcher->FindClosestTo( p );
4715 nodeID = node->GetID();
4716 if ( myIsPreviewMode ) // make preview data
4718 // in a preview mesh, make edges linked to a node
4719 TPreviewMesh tmpMesh = *getPreviewMesh();
4720 TIDSortedElemSet linkedNodes;
4721 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4722 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4723 for ( ; nIt != linkedNodes.end(); ++nIt )
4725 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4726 tmpMesh.Copy( &edge );
4729 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4731 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4732 // fill preview data
4734 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4736 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4740 getMeshDS()->MoveNode(node, x, y, z);
4744 if ( !myIsPreviewMode )
4746 TPythonDump() << "nodeID = " << this
4747 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4748 << ", " << nodeID << " )";
4750 myMesh->GetMeshDS()->Modified();
4751 myMesh->SetIsModified( true );
4757 //=======================================================================
4759 * Return elements of given type where the given point is IN or ON.
4761 * 'ALL' type means elements of any type excluding nodes
4763 //=======================================================================
4765 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4768 SMESH::ElementType type)
4770 SMESH::long_array_var res = new SMESH::long_array;
4771 vector< const SMDS_MeshElement* > foundElems;
4773 theSearchersDeleter.Set( myMesh );
4774 if ( !theElementSearcher ) {
4775 theElementSearcher = myEditor.GetElementSearcher();
4777 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4778 SMDSAbs_ElementType( type ),
4780 res->length( foundElems.size() );
4781 for ( int i = 0; i < foundElems.size(); ++i )
4782 res[i] = foundElems[i]->GetID();
4784 if ( !myIsPreviewMode ) // call from tui
4785 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4794 //=======================================================================
4795 //function : FindAmongElementsByPoint
4796 //purpose : Searching among the given elements, return elements of given type
4797 // where the given point is IN or ON.
4798 // 'ALL' type means elements of any type excluding nodes
4799 //=======================================================================
4802 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4806 SMESH::ElementType type)
4808 SMESH::long_array_var res = new SMESH::long_array;
4810 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4811 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4812 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4813 type != types[0] ) // but search of elements of dim > 0
4816 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4817 return FindElementsByPoint( x,y,z, type );
4819 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4821 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4822 if ( !theElementSearcher )
4824 // create a searcher from elementIDs
4825 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4826 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4828 if ( !idSourceToSet( elementIDs, meshDS, elements,
4829 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4832 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4833 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4835 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
4838 vector< const SMDS_MeshElement* > foundElems;
4840 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4841 SMDSAbs_ElementType( type ),
4843 res->length( foundElems.size() );
4844 for ( int i = 0; i < foundElems.size(); ++i )
4845 res[i] = foundElems[i]->GetID();
4847 if ( !myIsPreviewMode ) // call from tui
4848 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4849 << elementIDs << ", "
4858 //=======================================================================
4859 //function : GetPointState
4860 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4861 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4862 //=======================================================================
4864 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4868 theSearchersDeleter.Set( myMesh );
4869 if ( !theElementSearcher ) {
4870 theElementSearcher = myEditor.GetElementSearcher();
4872 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4875 //=======================================================================
4876 //function : convError
4878 //=======================================================================
4880 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4882 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4886 RETCASE( SEW_BORDER1_NOT_FOUND );
4887 RETCASE( SEW_BORDER2_NOT_FOUND );
4888 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4889 RETCASE( SEW_BAD_SIDE_NODES );
4890 RETCASE( SEW_VOLUMES_TO_SPLIT );
4891 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4892 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4893 RETCASE( SEW_BAD_SIDE1_NODES );
4894 RETCASE( SEW_BAD_SIDE2_NODES );
4896 return SMESH::SMESH_MeshEditor::SEW_OK;
4899 //=======================================================================
4900 //function : SewFreeBorders
4902 //=======================================================================
4904 SMESH::SMESH_MeshEditor::Sew_Error
4905 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4906 CORBA::Long SecondNodeID1,
4907 CORBA::Long LastNodeID1,
4908 CORBA::Long FirstNodeID2,
4909 CORBA::Long SecondNodeID2,
4910 CORBA::Long LastNodeID2,
4911 CORBA::Boolean CreatePolygons,
4912 CORBA::Boolean CreatePolyedrs)
4916 SMESHDS_Mesh* aMesh = getMeshDS();
4918 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4919 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4920 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4921 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4922 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4923 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4925 if (!aBorderFirstNode ||
4926 !aBorderSecondNode||
4928 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4929 if (!aSide2FirstNode ||
4930 !aSide2SecondNode ||
4932 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4934 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4935 << FirstNodeID1 << ", "
4936 << SecondNodeID1 << ", "
4937 << LastNodeID1 << ", "
4938 << FirstNodeID2 << ", "
4939 << SecondNodeID2 << ", "
4940 << LastNodeID2 << ", "
4941 << CreatePolygons<< ", "
4942 << CreatePolyedrs<< " )";
4944 SMESH::SMESH_MeshEditor::Sew_Error error =
4945 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4956 myMesh->GetMeshDS()->Modified();
4957 myMesh->SetIsModified( true );
4963 //=======================================================================
4964 //function : SewConformFreeBorders
4966 //=======================================================================
4968 SMESH::SMESH_MeshEditor::Sew_Error
4969 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4970 CORBA::Long SecondNodeID1,
4971 CORBA::Long LastNodeID1,
4972 CORBA::Long FirstNodeID2,
4973 CORBA::Long SecondNodeID2)
4977 SMESHDS_Mesh* aMesh = getMeshDS();
4979 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4980 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4981 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4982 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4983 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4984 const SMDS_MeshNode* aSide2ThirdNode = 0;
4986 if (!aBorderFirstNode ||
4987 !aBorderSecondNode||
4989 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4990 if (!aSide2FirstNode ||
4992 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4994 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4995 << FirstNodeID1 << ", "
4996 << SecondNodeID1 << ", "
4997 << LastNodeID1 << ", "
4998 << FirstNodeID2 << ", "
4999 << SecondNodeID2 << " )";
5001 SMESH::SMESH_MeshEditor::Sew_Error error =
5002 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5012 myMesh->GetMeshDS()->Modified();
5013 myMesh->SetIsModified( true );
5019 //=======================================================================
5020 //function : SewBorderToSide
5022 //=======================================================================
5024 SMESH::SMESH_MeshEditor::Sew_Error
5025 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5026 CORBA::Long SecondNodeIDOnFreeBorder,
5027 CORBA::Long LastNodeIDOnFreeBorder,
5028 CORBA::Long FirstNodeIDOnSide,
5029 CORBA::Long LastNodeIDOnSide,
5030 CORBA::Boolean CreatePolygons,
5031 CORBA::Boolean CreatePolyedrs)
5035 SMESHDS_Mesh* aMesh = getMeshDS();
5037 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5038 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5039 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5040 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5041 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5042 const SMDS_MeshNode* aSide2ThirdNode = 0;
5044 if (!aBorderFirstNode ||
5045 !aBorderSecondNode||
5047 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5048 if (!aSide2FirstNode ||
5050 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5052 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5053 << FirstNodeIDOnFreeBorder << ", "
5054 << SecondNodeIDOnFreeBorder << ", "
5055 << LastNodeIDOnFreeBorder << ", "
5056 << FirstNodeIDOnSide << ", "
5057 << LastNodeIDOnSide << ", "
5058 << CreatePolygons << ", "
5059 << CreatePolyedrs << ") ";
5061 SMESH::SMESH_MeshEditor::Sew_Error error =
5062 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5073 myMesh->GetMeshDS()->Modified();
5074 myMesh->SetIsModified( true );
5080 //=======================================================================
5081 //function : SewSideElements
5083 //=======================================================================
5085 SMESH::SMESH_MeshEditor::Sew_Error
5086 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5087 const SMESH::long_array& IDsOfSide2Elements,
5088 CORBA::Long NodeID1OfSide1ToMerge,
5089 CORBA::Long NodeID1OfSide2ToMerge,
5090 CORBA::Long NodeID2OfSide1ToMerge,
5091 CORBA::Long NodeID2OfSide2ToMerge)
5095 SMESHDS_Mesh* aMesh = getMeshDS();
5097 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5098 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5099 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5100 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5102 if (!aFirstNode1ToMerge ||
5103 !aFirstNode2ToMerge )
5104 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5105 if (!aSecondNode1ToMerge||
5106 !aSecondNode2ToMerge)
5107 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5109 TIDSortedElemSet aSide1Elems, aSide2Elems;
5110 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5111 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5113 TPythonDump() << "error = " << this << ".SewSideElements( "
5114 << IDsOfSide1Elements << ", "
5115 << IDsOfSide2Elements << ", "
5116 << NodeID1OfSide1ToMerge << ", "
5117 << NodeID1OfSide2ToMerge << ", "
5118 << NodeID2OfSide1ToMerge << ", "
5119 << NodeID2OfSide2ToMerge << ")";
5121 SMESH::SMESH_MeshEditor::Sew_Error error =
5122 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5125 aSecondNode1ToMerge,
5126 aSecondNode2ToMerge));
5129 myMesh->GetMeshDS()->Modified();
5130 myMesh->SetIsModified( true );
5135 //================================================================================
5137 * \brief Set new nodes for given element
5138 * \param ide - element id
5139 * \param newIDs - new node ids
5140 * \retval CORBA::Boolean - true if result is OK
5142 //================================================================================
5144 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5145 const SMESH::long_array& newIDs)
5149 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5150 if(!elem) return false;
5152 int nbn = newIDs.length();
5154 vector<const SMDS_MeshNode*> aNodes(nbn);
5157 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5160 aNodes[nbn1] = aNode;
5163 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5164 << ide << ", " << newIDs << " )";
5166 MESSAGE("ChangeElementNodes");
5167 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5169 myMesh->GetMeshDS()->Modified();
5171 myMesh->SetIsModified( true );
5176 //=======================================================================
5177 //function : ConvertToQuadratic
5179 //=======================================================================
5181 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5183 getEditor().ConvertToQuadratic(theForce3d);
5184 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
5185 myMesh->GetMeshDS()->Modified();
5186 myMesh->SetIsModified( true );
5189 //=======================================================================
5190 //function : ConvertFromQuadratic
5192 //=======================================================================
5194 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5196 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5197 TPythonDump() << this << ".ConvertFromQuadratic()";
5198 myMesh->GetMeshDS()->Modified();
5200 myMesh->SetIsModified( true );
5203 //================================================================================
5205 * \brief Makes a part of the mesh quadratic
5207 //================================================================================
5209 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5210 SMESH::SMESH_IDSource_ptr theObject)
5211 throw (SALOME::SALOME_Exception)
5213 Unexpect aCatch(SALOME_SalomeException);
5215 TIDSortedElemSet elems;
5216 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5218 if ( elems.empty() )
5220 ConvertToQuadratic( theForce3d );
5222 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5224 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5228 getEditor().ConvertToQuadratic(theForce3d, elems);
5231 myMesh->GetMeshDS()->Modified();
5232 myMesh->SetIsModified( true );
5234 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
5237 //================================================================================
5239 * \brief Makes a part of the mesh linear
5241 //================================================================================
5243 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5244 throw (SALOME::SALOME_Exception)
5246 Unexpect aCatch(SALOME_SalomeException);
5248 TIDSortedElemSet elems;
5249 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5251 if ( elems.empty() )
5253 ConvertFromQuadratic();
5255 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5257 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5261 getEditor().ConvertFromQuadratic(elems);
5264 myMesh->GetMeshDS()->Modified();
5265 myMesh->SetIsModified( true );
5267 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5270 //=======================================================================
5271 //function : makeMesh
5272 //purpose : create a named imported mesh
5273 //=======================================================================
5275 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5277 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5278 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5279 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5280 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5281 gen->SetName( meshSO, theMeshName, "Mesh" );
5282 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5284 return mesh._retn();
5287 //=======================================================================
5288 //function : DumpGroupsList
5290 //=======================================================================
5291 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
5292 const SMESH::ListOfGroups * theGroupList)
5294 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
5295 if(isDumpGroupList) {
5296 theDumpPython << theGroupList << " = ";
5300 //================================================================================
5302 \brief Generates the unique group name.
5303 \param thePrefix name prefix
5306 //================================================================================
5307 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5309 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5310 set<string> groupNames;
5312 // Get existing group names
5313 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5314 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5315 if (CORBA::is_nil(aGroup))
5318 CORBA::String_var name = aGroup->GetName();
5319 groupNames.insert( name.in() );
5323 string name = thePrefix;
5326 while (!groupNames.insert(name).second)
5327 name = SMESH_Comment( thePrefix ) << "_" << index;
5332 //================================================================================
5334 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5335 \param theNodes - identifiers of nodes to be doubled
5336 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5337 nodes. If list of element identifiers is empty then nodes are doubled but
5338 they not assigned to elements
5339 \return TRUE if operation has been completed successfully, FALSE otherwise
5340 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5342 //================================================================================
5344 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5345 const SMESH::long_array& theModifiedElems )
5349 list< int > aListOfNodes;
5351 for ( i = 0, n = theNodes.length(); i < n; i++ )
5352 aListOfNodes.push_back( theNodes[ i ] );
5354 list< int > aListOfElems;
5355 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5356 aListOfElems.push_back( theModifiedElems[ i ] );
5358 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5360 myMesh->GetMeshDS()->Modified();
5362 myMesh->SetIsModified( true );
5364 // Update Python script
5365 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5370 //================================================================================
5372 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5373 This method provided for convenience works as DoubleNodes() described above.
5374 \param theNodeId - identifier of node to be doubled.
5375 \param theModifiedElems - identifiers of elements to be updated.
5376 \return TRUE if operation has been completed successfully, FALSE otherwise
5377 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5379 //================================================================================
5381 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5382 const SMESH::long_array& theModifiedElems )
5384 SMESH::long_array_var aNodes = new SMESH::long_array;
5385 aNodes->length( 1 );
5386 aNodes[ 0 ] = theNodeId;
5388 TPythonDump pyDump; // suppress dump by the next line
5390 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5392 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5397 //================================================================================
5399 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5400 This method provided for convenience works as DoubleNodes() described above.
5401 \param theNodes - group of nodes to be doubled.
5402 \param theModifiedElems - group of elements to be updated.
5403 \return TRUE if operation has been completed successfully, FALSE otherwise
5404 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5406 //================================================================================
5408 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5409 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5411 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5414 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5415 SMESH::long_array_var aModifiedElems;
5416 if ( !CORBA::is_nil( theModifiedElems ) )
5417 aModifiedElems = theModifiedElems->GetListOfID();
5420 aModifiedElems = new SMESH::long_array;
5421 aModifiedElems->length( 0 );
5424 TPythonDump pyDump; // suppress dump by the next line
5426 bool done = DoubleNodes( aNodes, aModifiedElems );
5428 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5434 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5435 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5436 * \param theNodes - group of nodes to be doubled.
5437 * \param theModifiedElems - group of elements to be updated.
5438 * \return a new group with newly created nodes
5439 * \sa DoubleNodeGroup()
5441 SMESH::SMESH_Group_ptr
5442 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5443 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5445 SMESH::SMESH_Group_var aNewGroup;
5447 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5448 return aNewGroup._retn();
5451 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5452 SMESH::long_array_var aModifiedElems;
5453 if ( !CORBA::is_nil( theModifiedElems ) )
5454 aModifiedElems = theModifiedElems->GetListOfID();
5456 aModifiedElems = new SMESH::long_array;
5457 aModifiedElems->length( 0 );
5460 TPythonDump pyDump; // suppress dump by the next line
5462 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5465 // Create group with newly created nodes
5466 SMESH::long_array_var anIds = GetLastCreatedNodes();
5467 if (anIds->length() > 0) {
5468 string anUnindexedName (theNodes->GetName());
5469 string aNewName = generateGroupName(anUnindexedName + "_double");
5470 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5471 aNewGroup->Add(anIds);
5472 pyDump << aNewGroup << " = ";
5476 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5477 << theModifiedElems << " )";
5479 return aNewGroup._retn();
5482 //================================================================================
5484 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5485 This method provided for convenience works as DoubleNodes() described above.
5486 \param theNodes - list of groups of nodes to be doubled
5487 \param theModifiedElems - list of groups of elements to be updated.
5488 \return TRUE if operation has been completed successfully, FALSE otherwise
5489 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5491 //================================================================================
5493 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5494 const SMESH::ListOfGroups& theModifiedElems )
5499 std::list< int > aNodes;
5501 for ( i = 0, n = theNodes.length(); i < n; i++ )
5503 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5504 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5506 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5507 for ( j = 0, m = aCurr->length(); j < m; j++ )
5508 aNodes.push_back( aCurr[ j ] );
5512 std::list< int > anElems;
5513 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5515 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5516 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5518 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5519 for ( j = 0, m = aCurr->length(); j < m; j++ )
5520 anElems.push_back( aCurr[ j ] );
5524 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
5527 myMesh->GetMeshDS()->Modified();
5529 myMesh->SetIsModified( true );
5532 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5537 //================================================================================
5539 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5540 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5541 * \param theNodes - group of nodes to be doubled.
5542 * \param theModifiedElems - group of elements to be updated.
5543 * \return a new group with newly created nodes
5544 * \sa DoubleNodeGroups()
5546 //================================================================================
5548 SMESH::SMESH_Group_ptr
5549 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5550 const SMESH::ListOfGroups& theModifiedElems )
5552 SMESH::SMESH_Group_var aNewGroup;
5554 TPythonDump pyDump; // suppress dump by the next line
5556 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5560 // Create group with newly created nodes
5561 SMESH::long_array_var anIds = GetLastCreatedNodes();
5562 if (anIds->length() > 0) {
5563 string anUnindexedName (theNodes[0]->GetName());
5564 string aNewName = generateGroupName(anUnindexedName + "_double");
5565 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5566 aNewGroup->Add(anIds);
5567 pyDump << aNewGroup << " = ";
5571 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5572 << theModifiedElems << " )";
5574 return aNewGroup._retn();
5578 //================================================================================
5580 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5581 \param theElems - the list of elements (edges or faces) to be replicated
5582 The nodes for duplication could be found from these elements
5583 \param theNodesNot - list of nodes to NOT replicate
5584 \param theAffectedElems - the list of elements (cells and edges) to which the
5585 replicated nodes should be associated to.
5586 \return TRUE if operation has been completed successfully, FALSE otherwise
5587 \sa DoubleNodeGroup(), DoubleNodeGroups()
5589 //================================================================================
5591 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5592 const SMESH::long_array& theNodesNot,
5593 const SMESH::long_array& theAffectedElems )
5599 SMESHDS_Mesh* aMeshDS = getMeshDS();
5600 TIDSortedElemSet anElems, aNodes, anAffected;
5601 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5602 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5603 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5605 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5608 myMesh->GetMeshDS()->Modified();
5610 myMesh->SetIsModified( true );
5612 // Update Python script
5613 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5614 << theNodesNot << ", " << theAffectedElems << " )";
5618 //================================================================================
5620 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5621 \param theElems - the list of elements (edges or faces) to be replicated
5622 The nodes for duplication could be found from these elements
5623 \param theNodesNot - list of nodes to NOT replicate
5624 \param theShape - shape to detect affected elements (element which geometric center
5625 located on or inside shape).
5626 The replicated nodes should be associated to affected elements.
5627 \return TRUE if operation has been completed successfully, FALSE otherwise
5628 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5630 //================================================================================
5632 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5633 const SMESH::long_array& theNodesNot,
5634 GEOM::GEOM_Object_ptr theShape )
5640 SMESHDS_Mesh* aMeshDS = getMeshDS();
5641 TIDSortedElemSet anElems, aNodes;
5642 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5643 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5645 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5646 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5649 myMesh->GetMeshDS()->Modified();
5651 myMesh->SetIsModified( true );
5653 // Update Python script
5654 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5655 << theNodesNot << ", " << theShape << " )";
5659 //================================================================================
5661 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5662 \param theElems - group of of elements (edges or faces) to be replicated
5663 \param theNodesNot - group of nodes not to replicated
5664 \param theAffectedElems - group of elements to which the replicated nodes
5665 should be associated to.
5666 \return TRUE if operation has been completed successfully, FALSE otherwise
5667 \sa DoubleNodes(), DoubleNodeGroups()
5669 //================================================================================
5671 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5672 SMESH::SMESH_GroupBase_ptr theNodesNot,
5673 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5675 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5681 SMESHDS_Mesh* aMeshDS = getMeshDS();
5682 TIDSortedElemSet anElems, aNodes, anAffected;
5683 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5684 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5685 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5687 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5690 myMesh->GetMeshDS()->Modified();
5692 myMesh->SetIsModified( true );
5694 // Update Python script
5695 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5696 << theNodesNot << ", " << theAffectedElems << " )";
5701 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5702 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5703 * \param theElems - group of of elements (edges or faces) to be replicated
5704 * \param theNodesNot - group of nodes not to replicated
5705 * \param theAffectedElems - group of elements to which the replicated nodes
5706 * should be associated to.
5707 * \return a new group with newly created elements
5708 * \sa DoubleNodeElemGroup()
5710 SMESH::SMESH_Group_ptr
5711 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5712 SMESH::SMESH_GroupBase_ptr theNodesNot,
5713 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5716 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5720 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5721 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5723 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5725 << theNodesNot << ", "
5726 << theAffectedElems << " )";
5728 return elemGroup._retn();
5731 SMESH::ListOfGroups*
5732 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5733 SMESH::SMESH_GroupBase_ptr theNodesNot,
5734 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5735 CORBA::Boolean theElemGroupNeeded,
5736 CORBA::Boolean theNodeGroupNeeded)
5738 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5739 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5740 aTwoGroups->length( 2 );
5742 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5743 return aTwoGroups._retn();
5748 SMESHDS_Mesh* aMeshDS = getMeshDS();
5749 TIDSortedElemSet anElems, aNodes, anAffected;
5750 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5751 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5752 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5755 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5757 myMesh->GetMeshDS()->Modified();
5763 myMesh->SetIsModified( true );
5765 // Create group with newly created elements
5766 CORBA::String_var elemGroupName = theElems->GetName();
5767 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5768 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5770 SMESH::long_array_var anIds = GetLastCreatedElems();
5771 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5772 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5773 aNewElemGroup->Add(anIds);
5775 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5777 SMESH::long_array_var anIds = GetLastCreatedNodes();
5778 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5779 aNewNodeGroup->Add(anIds);
5783 // Update Python script
5786 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5787 else pyDump << aNewElemGroup << ", ";
5788 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5789 else pyDump << aNewNodeGroup << " ] = ";
5791 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5792 << theNodesNot << ", "
5793 << theAffectedElems << ", "
5794 << theElemGroupNeeded << ", "
5795 << theNodeGroupNeeded <<" )";
5797 aTwoGroups[0] = aNewElemGroup._retn();
5798 aTwoGroups[1] = aNewNodeGroup._retn();
5799 return aTwoGroups._retn();
5802 //================================================================================
5804 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5805 \param theElems - group of of elements (edges or faces) to be replicated
5806 \param theNodesNot - group of nodes not to replicated
5807 \param theShape - shape to detect affected elements (element which geometric center
5808 located on or inside shape).
5809 The replicated nodes should be associated to affected elements.
5810 \return TRUE if operation has been completed successfully, FALSE otherwise
5811 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5813 //================================================================================
5815 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5816 SMESH::SMESH_GroupBase_ptr theNodesNot,
5817 GEOM::GEOM_Object_ptr theShape )
5820 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5826 SMESHDS_Mesh* aMeshDS = getMeshDS();
5827 TIDSortedElemSet anElems, aNodes, anAffected;
5828 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5829 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5831 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5832 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5835 myMesh->GetMeshDS()->Modified();
5837 myMesh->SetIsModified( true );
5839 // Update Python script
5840 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5841 << theNodesNot << ", " << theShape << " )";
5845 //================================================================================
5847 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5848 This method provided for convenience works as DoubleNodes() described above.
5849 \param theElems - list of groups of elements (edges or faces) to be replicated
5850 \param theNodesNot - list of groups of nodes not to replicated
5851 \param theAffectedElems - group of elements to which the replicated nodes
5852 should be associated to.
5853 \return TRUE if operation has been completed successfully, FALSE otherwise
5854 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5856 //================================================================================
5858 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5859 SMESHDS_Mesh* theMeshDS,
5860 TIDSortedElemSet& theElemSet,
5861 const bool theIsNodeGrp)
5863 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5865 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5866 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5867 : aGrp->GetType() != SMESH::NODE ) )
5869 SMESH::long_array_var anIDs = aGrp->GetIDs();
5870 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5875 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5876 const SMESH::ListOfGroups& theNodesNot,
5877 const SMESH::ListOfGroups& theAffectedElems)
5882 SMESHDS_Mesh* aMeshDS = getMeshDS();
5883 TIDSortedElemSet anElems, aNodes, anAffected;
5884 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5885 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5886 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5888 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5891 myMesh->GetMeshDS()->Modified();
5893 myMesh->SetIsModified( true );
5895 // Update Python script
5896 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5897 << &theNodesNot << ", " << &theAffectedElems << " )";
5901 //================================================================================
5903 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5904 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5905 \param theElems - list of groups of elements (edges or faces) to be replicated
5906 \param theNodesNot - list of groups of nodes not to replicated
5907 \param theAffectedElems - group of elements to which the replicated nodes
5908 should be associated to.
5909 * \return a new group with newly created elements
5910 * \sa DoubleNodeElemGroups()
5912 //================================================================================
5914 SMESH::SMESH_Group_ptr
5915 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5916 const SMESH::ListOfGroups& theNodesNot,
5917 const SMESH::ListOfGroups& theAffectedElems)
5920 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
5924 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5925 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5927 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
5929 << theNodesNot << ", "
5930 << theAffectedElems << " )";
5932 return elemGroup._retn();
5935 SMESH::ListOfGroups*
5936 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
5937 const SMESH::ListOfGroups& theNodesNot,
5938 const SMESH::ListOfGroups& theAffectedElems,
5939 CORBA::Boolean theElemGroupNeeded,
5940 CORBA::Boolean theNodeGroupNeeded)
5942 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5943 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5944 aTwoGroups->length( 2 );
5949 SMESHDS_Mesh* aMeshDS = getMeshDS();
5950 TIDSortedElemSet anElems, aNodes, anAffected;
5951 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5952 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5953 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5955 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5958 myMesh->GetMeshDS()->Modified();
5962 myMesh->SetIsModified( true );
5964 // Create group with newly created elements
5965 CORBA::String_var elemGroupName = theElems[0]->GetName();
5966 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5967 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5969 SMESH::long_array_var anIds = GetLastCreatedElems();
5970 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5971 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5972 aNewElemGroup->Add(anIds);
5974 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5976 SMESH::long_array_var anIds = GetLastCreatedNodes();
5977 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5978 aNewNodeGroup->Add(anIds);
5982 // Update Python script
5985 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5986 else pyDump << aNewElemGroup << ", ";
5987 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5988 else pyDump << aNewNodeGroup << " ] = ";
5990 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
5991 << &theNodesNot << ", "
5992 << &theAffectedElems << ", "
5993 << theElemGroupNeeded << ", "
5994 << theNodeGroupNeeded << " )";
5996 aTwoGroups[0] = aNewElemGroup._retn();
5997 aTwoGroups[1] = aNewNodeGroup._retn();
5998 return aTwoGroups._retn();
6001 //================================================================================
6003 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6004 This method provided for convenience works as DoubleNodes() described above.
6005 \param theElems - list of groups of elements (edges or faces) to be replicated
6006 \param theNodesNot - list of groups of nodes not to replicated
6007 \param theShape - shape to detect affected elements (element which geometric center
6008 located on or inside shape).
6009 The replicated nodes should be associated to affected elements.
6010 \return TRUE if operation has been completed successfully, FALSE otherwise
6011 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6013 //================================================================================
6016 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6017 const SMESH::ListOfGroups& theNodesNot,
6018 GEOM::GEOM_Object_ptr theShape )
6023 SMESHDS_Mesh* aMeshDS = getMeshDS();
6024 TIDSortedElemSet anElems, aNodes;
6025 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6026 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6028 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6029 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6032 myMesh->GetMeshDS()->Modified();
6034 myMesh->SetIsModified( true );
6036 // Update Python script
6037 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6038 << &theNodesNot << ", " << theShape << " )";
6042 //================================================================================
6044 \brief Identify the elements that will be affected by node duplication (actual duplication is not performed.
6045 This method is the first step of DoubleNodeElemGroupsInRegion.
6046 \param theElems - list of groups of elements (edges or faces) to be replicated
6047 \param theNodesNot - list of groups of nodes not to replicated
6048 \param theShape - shape to detect affected elements (element which geometric center
6049 located on or inside shape).
6050 The replicated nodes should be associated to affected elements.
6051 \return groups of affected elements
6052 \sa DoubleNodeElemGroupsInRegion()
6054 //================================================================================
6055 SMESH::ListOfGroups*
6056 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6057 const SMESH::ListOfGroups& theNodesNot,
6058 GEOM::GEOM_Object_ptr theShape )
6060 MESSAGE("AffectedElemGroupsInRegion");
6061 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6062 bool isEdgeGroup = false;
6063 bool isFaceGroup = false;
6064 bool isVolumeGroup = false;
6065 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6066 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6067 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6071 ::SMESH_MeshEditor aMeshEditor(myMesh);
6073 SMESHDS_Mesh* aMeshDS = getMeshDS();
6074 TIDSortedElemSet anElems, aNodes;
6075 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6076 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6078 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6079 TIDSortedElemSet anAffected;
6080 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6083 myMesh->GetMeshDS()->Modified();
6087 myMesh->SetIsModified(true);
6089 int lg = anAffected.size();
6090 MESSAGE("lg="<< lg);
6091 SMESH::long_array_var volumeIds = new SMESH::long_array;
6092 volumeIds->length(lg);
6093 SMESH::long_array_var faceIds = new SMESH::long_array;
6094 faceIds->length(lg);
6095 SMESH::long_array_var edgeIds = new SMESH::long_array;
6096 edgeIds->length(lg);
6101 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6102 for (; eIt != anAffected.end(); ++eIt)
6104 const SMDS_MeshElement* anElem = *eIt;
6107 int elemId = anElem->GetID();
6108 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6109 volumeIds[ivol++] = elemId;
6110 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6111 faceIds[iface++] = elemId;
6112 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6113 edgeIds[iedge++] = elemId;
6115 volumeIds->length(ivol);
6116 faceIds->length(iface);
6117 edgeIds->length(iedge);
6119 aNewVolumeGroup->Add(volumeIds);
6120 aNewFaceGroup->Add(faceIds);
6121 aNewEdgeGroup->Add(edgeIds);
6122 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6123 isFaceGroup = (aNewFaceGroup->Size() > 0);
6124 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6134 aListOfGroups->length(nbGroups);
6138 aListOfGroups[i++] = aNewEdgeGroup._retn();
6140 aListOfGroups[i++] = aNewFaceGroup._retn();
6142 aListOfGroups[i++] = aNewVolumeGroup._retn();
6144 // Update Python script
6148 pyDump << aNewEdgeGroup << ", ";
6150 pyDump << aNewFaceGroup << ", ";
6152 pyDump << aNewVolumeGroup << ", ";
6154 pyDump << this << ".AffectedElemGroupsInRegion( " << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6156 return aListOfGroups._retn();
6159 //================================================================================
6161 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6162 The created 2D mesh elements based on nodes of free faces of boundary volumes
6163 \return TRUE if operation has been completed successfully, FALSE otherwise
6165 //================================================================================
6167 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6171 bool aResult = getEditor().Make2DMeshFrom3D();
6172 myMesh->GetMeshDS()->Modified();
6173 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6177 //================================================================================
6179 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6180 * The list of groups must describe a partition of the mesh volumes.
6181 * The nodes of the internal faces at the boundaries of the groups are doubled.
6182 * In option, the internal faces are replaced by flat elements.
6183 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6184 * The flat elements are stored in groups of volumes.
6185 * @param theDomains - list of groups of volumes
6186 * @param createJointElems - if TRUE, create the elements
6187 * @return TRUE if operation has been completed successfully, FALSE otherwise
6189 //================================================================================
6191 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6192 CORBA::Boolean createJointElems )
6193 throw (SALOME::SALOME_Exception)
6198 SMESHDS_Mesh* aMeshDS = getMeshDS();
6200 vector<TIDSortedElemSet> domains;
6203 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6205 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6206 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6208 // if ( aGrp->GetType() != SMESH::VOLUME )
6209 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6210 TIDSortedElemSet domain;
6212 domains.push_back(domain);
6213 SMESH::long_array_var anIDs = aGrp->GetIDs();
6214 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6218 bool aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6219 // TODO publish the groups of flat elements in study
6221 myMesh->GetMeshDS()->Modified();
6223 // Update Python script
6224 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6225 << ", " << createJointElems << " )";
6229 //================================================================================
6231 * \brief Double nodes on some external faces and create flat elements.
6232 * Flat elements are mainly used by some types of mechanic calculations.
6234 * Each group of the list must be constituted of faces.
6235 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6236 * @param theGroupsOfFaces - list of groups of faces
6237 * @return TRUE if operation has been completed successfully, FALSE otherwise
6239 //================================================================================
6241 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6246 SMESHDS_Mesh* aMeshDS = getMeshDS();
6248 vector<TIDSortedElemSet> faceGroups;
6251 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6253 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6254 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6256 TIDSortedElemSet faceGroup;
6258 faceGroups.push_back(faceGroup);
6259 SMESH::long_array_var anIDs = aGrp->GetIDs();
6260 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6264 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6265 // TODO publish the groups of flat elements in study
6267 myMesh->GetMeshDS()->Modified();
6269 // Update Python script
6270 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6275 * \brief identify all the elements around a geom shape, get the faces delimiting the hole
6276 * Build groups of volume to remove, groups of faces to replace on the skin of the object,
6277 * groups of faces to remove inside the object, (idem edges).
6278 * Build ordered list of nodes at the border of each group of faces to replace (to be used to build a geom subshape)
6280 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6281 GEOM::GEOM_Object_ptr theShape,
6282 const char* groupName,
6283 const SMESH::double_array& theNodesCoords,
6284 SMESH::array_of_long_array_out GroupsOfNodes)
6285 throw (SALOME::SALOME_Exception)
6288 std::vector<std::vector<int> > aListOfListOfNodes;
6289 ::SMESH_MeshEditor aMeshEditor( myMesh );
6291 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6292 if ( !theNodeSearcher )
6293 theNodeSearcher = aMeshEditor.GetNodeSearcher();
6295 vector<double> nodesCoords;
6296 for (int i = 0; i < theNodesCoords.length(); i++)
6298 nodesCoords.push_back( theNodesCoords[i] );
6301 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6302 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName, nodesCoords, aListOfListOfNodes);
6304 GroupsOfNodes = new SMESH::array_of_long_array;
6305 GroupsOfNodes->length( aListOfListOfNodes.size() );
6306 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6307 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6309 vector<int>& aListOfNodes = *llIt;
6310 vector<int>::iterator lIt = aListOfNodes.begin();;
6311 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6312 aGroup.length( aListOfNodes.size() );
6313 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6314 aGroup[ j ] = (*lIt);
6316 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6317 << radius << ", " << theShape << ", " << ", " << groupName << ", " << theNodesCoords << " )";
6321 // issue 20749 ===================================================================
6323 * \brief Creates missing boundary elements
6324 * \param elements - elements whose boundary is to be checked
6325 * \param dimension - defines type of boundary elements to create
6326 * \param groupName - a name of group to store created boundary elements in,
6327 * "" means not to create the group
6328 * \param meshName - a name of new mesh to store created boundary elements in,
6329 * "" means not to create the new mesh
6330 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6331 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6332 * boundary elements will be copied into the new mesh
6333 * \param group - returns the create group, if any
6334 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6336 // ================================================================================
6338 SMESH::SMESH_Mesh_ptr
6339 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6340 SMESH::Bnd_Dimension dim,
6341 const char* groupName,
6342 const char* meshName,
6343 CORBA::Boolean toCopyElements,
6344 CORBA::Boolean toCopyExistingBondary,
6345 SMESH::SMESH_Group_out group)
6349 if ( dim > SMESH::BND_1DFROM2D )
6350 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6352 SMESHDS_Mesh* aMeshDS = getMeshDS();
6354 SMESH::SMESH_Mesh_var mesh_var;
6355 SMESH::SMESH_Group_var group_var;
6359 TIDSortedElemSet elements;
6360 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6361 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6365 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6366 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6368 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6370 // group of new boundary elements
6371 SMESH_Group* smesh_group = 0;
6372 if ( strlen(groupName) )
6374 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6375 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6376 smesh_group = group_i->GetSmeshGroup();
6380 getEditor().MakeBoundaryMesh( elements,
6381 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6385 toCopyExistingBondary);
6388 smesh_mesh->GetMeshDS()->Modified();
6391 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6393 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6394 if ( mesh_var->_is_nil() )
6395 pyDump << myMesh_i->_this() << ", ";
6397 pyDump << mesh_var << ", ";
6398 if ( group_var->_is_nil() )
6399 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6401 pyDump << group_var << " = ";
6402 pyDump << this << ".MakeBoundaryMesh( "
6404 << "SMESH." << dimName[int(dim)] << ", "
6405 << "'" << groupName << "', "
6406 << "'" << meshName<< "', "
6407 << toCopyElements << ", "
6408 << toCopyExistingBondary << ")";
6410 group = group_var._retn();
6411 return mesh_var._retn();
6414 //================================================================================
6416 * \brief Creates missing boundary elements
6417 * \param dimension - defines type of boundary elements to create
6418 * \param groupName - a name of group to store all boundary elements in,
6419 * "" means not to create the group
6420 * \param meshName - a name of a new mesh, which is a copy of the initial
6421 * mesh + created boundary elements; "" means not to create the new mesh
6422 * \param toCopyAll - if true, the whole initial mesh will be copied into
6423 * the new mesh else only boundary elements will be copied into the new mesh
6424 * \param groups - optional groups of elements to make boundary around
6425 * \param mesh - returns the mesh where elements were added to
6426 * \param group - returns the created group, if any
6427 * \retval long - number of added boundary elements
6429 //================================================================================
6431 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6432 const char* groupName,
6433 const char* meshName,
6434 CORBA::Boolean toCopyAll,
6435 const SMESH::ListOfIDSources& groups,
6436 SMESH::SMESH_Mesh_out mesh,
6437 SMESH::SMESH_Group_out group)
6438 throw (SALOME::SALOME_Exception)
6440 Unexpect aCatch(SALOME_SalomeException);
6444 if ( dim > SMESH::BND_1DFROM2D )
6445 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6447 // separate groups belonging to this and other mesh
6448 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6449 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6450 groupsOfThisMesh->length( groups.length() );
6451 groupsOfOtherMesh->length( groups.length() );
6452 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6453 for ( int i = 0; i < groups.length(); ++i )
6455 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6456 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6457 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6459 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6460 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6461 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6463 groupsOfThisMesh->length( nbGroups );
6464 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6469 if ( nbGroupsOfOtherMesh > 0 )
6471 // process groups belonging to another mesh
6472 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6473 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6474 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6475 groupsOfOtherMesh, mesh, group );
6478 SMESH::SMESH_Mesh_var mesh_var;
6479 SMESH::SMESH_Group_var group_var;
6482 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6483 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6487 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6489 /*toCopyGroups=*/false,
6490 /*toKeepIDs=*/true);
6492 mesh_var = makeMesh(meshName);
6494 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6495 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6498 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6499 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6501 // group of boundary elements
6502 SMESH_Group* smesh_group = 0;
6503 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6504 if ( strlen(groupName) )
6506 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6507 group_var = mesh_i->CreateGroup( groupType, groupName );
6508 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6509 smesh_group = group_i->GetSmeshGroup();
6512 TIDSortedElemSet elements;
6514 if ( groups.length() > 0 )
6516 for ( int i = 0; i < nbGroups; ++i )
6519 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6521 SMESH::Bnd_Dimension bdim =
6522 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6523 nbAdded += getEditor().MakeBoundaryMesh( elements,
6524 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6527 /*toCopyElements=*/false,
6528 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6529 /*toAddExistingBondary=*/true,
6530 /*aroundElements=*/true);
6536 nbAdded += getEditor().MakeBoundaryMesh( elements,
6537 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6540 /*toCopyElements=*/false,
6541 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6542 /*toAddExistingBondary=*/true);
6544 tgtMesh->GetMeshDS()->Modified();
6546 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6548 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6549 pyDump << "nbAdded, ";
6550 if ( mesh_var->_is_nil() )
6551 pyDump << myMesh_i->_this() << ", ";
6553 pyDump << mesh_var << ", ";
6554 if ( group_var->_is_nil() )
6555 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6557 pyDump << group_var << " = ";
6558 pyDump << this << ".MakeBoundaryElements( "
6559 << "SMESH." << dimName[int(dim)] << ", "
6560 << "'" << groupName << "', "
6561 << "'" << meshName<< "', "
6562 << toCopyAll << ", "
6565 mesh = mesh_var._retn();
6566 group = group_var._retn();