1 // Copyright (C) 2007-2014 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, or (at your option) any later version.
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
23 // SMESH SMESHGUI : GUI for SMESH component
24 // File : SMESHGUI_VTKUtils.cxx
25 // Author : Open CASCADE S.A.S.
28 #include "SMESHGUI_VTKUtils.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_Filter.h"
33 #include "SMESH_ControlsDef.hxx"
35 #include <SMESH_Actor.h>
36 #include <SMESH_ActorUtils.h>
37 #include "SMESH_NodeLabelActor.h"
38 #include "SMESH_CellLabelActor.h"
39 #include <SMESH_ObjectDef.h>
40 #include <SMDS_Mesh.hxx>
42 // SALOME GUI includes
43 #include <SUIT_Desktop.h>
44 #include <SUIT_Session.h>
45 #include <SUIT_MessageBox.h>
46 #include <SUIT_ViewManager.h>
47 #include <SUIT_ResourceMgr.h>
49 #include <SALOME_ListIO.hxx>
50 #include <SALOME_ListIteratorOfListIO.hxx>
52 #include <SVTK_Selector.h>
53 #include <SVTK_ViewModel.h>
54 #include <SVTK_ViewWindow.h>
56 #include <VTKViewer_Algorithm.h>
58 #include <LightApp_SelectionMgr.h>
59 #include <SalomeApp_Application.h>
60 #include <SalomeApp_Study.h>
62 // SALOME KERNEL includes
63 #include <utilities.h>
66 #include <SALOMEconfig.h>
67 #include CORBA_CLIENT_HEADER(SMESH_Mesh)
68 #include CORBA_CLIENT_HEADER(SMESH_Group)
72 #include <vtkRenderer.h>
73 #include <vtkActorCollection.h>
74 #include <vtkUnstructuredGrid.h>
77 #include <TColStd_IndexedMapOfInteger.hxx>
78 #include <Standard_ErrorHandler.hxx>
79 #include <ProjLib.hxx>
82 #include <gce_MakePln.hxx>
83 #include <gce_MakeLin.hxx>
84 #include <GeomAPI_IntCS.hxx>
85 #include <Geom_Line.hxx>
86 #include <Geom_Plane.hxx>
90 typedef std::map<TKeyOfVisualObj,TVisualObjPtr> TVisualObjCont;
91 static TVisualObjCont VISUAL_OBJ_CONT;
93 //=============================================================================
95 * \brief Allocate some memory at construction and release it at destruction.
96 * Is used to be able to continue working after mesh generation or visualization
97 * break due to lack of memory
99 //=============================================================================
104 MemoryReserve(): myBuf( new char[1024*1024*1] ){} // 1M
105 void Free() { if (myBuf) { delete [] myBuf; myBuf = 0; }}
106 ~MemoryReserve() { Free(); }
108 static MemoryReserve* theVISU_MemoryReserve = new MemoryReserve;
110 //================================================================================
112 * \brief Remove VisualObj and its actor from all views
114 //================================================================================
116 void RemoveVisualObjectWithActors( const char* theEntry, bool fromAllViews )
118 SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>(SUIT_Session::session()->activeApplication());
121 SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
124 ViewManagerList aList;
127 app->viewManagers(SVTK_Viewer::Type() , aList);
129 SUIT_ViewManager* aVM = app->getViewManager(SVTK_Viewer::Type(), true);
133 bool actorRemoved = false;
134 ViewManagerList::ConstIterator it = aList.begin();
135 SUIT_ViewManager* aViewManager = 0;
136 for( ; it!=aList.end();it++) {
138 QVector<SUIT_ViewWindow*> views = aViewManager->getViews();
139 for ( int iV = 0; iV < views.count(); ++iV ) {
140 if ( SMESH_Actor* actor = FindActorByEntry( views[iV], theEntry)) {
141 if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
142 vtkWnd->RemoveActor(actor);
151 int aStudyId = aViewManager->study()->id();
152 TVisualObjCont::key_type aKey(aStudyId,theEntry);
153 TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
154 if(anIter != VISUAL_OBJ_CONT.end()) {
155 // for unknown reason, object destructor is not called, so clear object manually
156 anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
157 anIter->second->GetUnstructuredGrid()->SetPoints(0);
159 VISUAL_OBJ_CONT.erase(aKey);
163 aStudy->setVisibilityState(theEntry, Qtx::HiddenState);
165 //================================================================================
167 * \brief Remove all VisualObjs and their actors from all views
169 //================================================================================
171 void RemoveAllObjectsWithActors()
173 SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
174 ( SUIT_Session::session()->activeApplication() );
176 ViewManagerList viewMgrs = app->viewManagers();
177 for ( int iM = 0; iM < viewMgrs.count(); ++iM ) {
178 SUIT_ViewManager* aViewManager = viewMgrs.at( iM );
179 if ( aViewManager && aViewManager->getType() == SVTK_Viewer::Type()) {
180 QVector<SUIT_ViewWindow*> views = aViewManager->getViews();
181 for ( int iV = 0; iV < views.count(); ++iV ) {
182 if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
183 vtkRenderer *aRenderer = vtkWnd->getRenderer();
184 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
185 vtkActorCollection *actors = aCopy.GetActors();
186 for (int i = 0; i < actors->GetNumberOfItems(); ++i ) {
187 // size of actors changes inside the loop
188 if (SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(actors->GetItemAsObject(i)))
190 vtkWnd->RemoveActor(actor);
198 TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin();
199 for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) {
200 // for unknown reason, object destructor is not called, so clear object manually
201 anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
202 anIter->second->GetUnstructuredGrid()->SetPoints(0);
204 VISUAL_OBJ_CONT.clear();
207 //================================================================================
209 * \brief Remove all VisualObjs of a study
211 //================================================================================
213 void RemoveVisuData(int studyID)
215 SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
216 ( SUIT_Session::session()->activeApplication() );
218 ViewManagerList viewMgrs = app->viewManagers();
219 for ( int iM = 0; iM < viewMgrs.count(); ++iM ) {
220 SUIT_ViewManager* aViewManager = viewMgrs.at( iM );
221 if ( aViewManager && aViewManager->getType() == SVTK_Viewer::Type() &&
222 aViewManager->study()->id() == studyID ) {
223 QVector<SUIT_ViewWindow*> views = aViewManager->getViews();
224 for ( int iV = 0; iV < views.count(); ++iV ) {
225 if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
226 vtkRenderer *aRenderer = vtkWnd->getRenderer();
227 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
228 vtkActorCollection *actors = aCopy.GetActors();
229 for (int i = 0; i < actors->GetNumberOfItems(); ++i ) {
230 // size of actors changes inside the loop
231 if(SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(actors->GetItemAsObject(i)))
233 vtkWnd->RemoveActor(actor);
241 TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin();
242 for ( ; anIter != VISUAL_OBJ_CONT.end(); ) {
243 int curId = anIter->first.first;
244 if ( curId == studyID ) {
245 // for unknown reason, object destructor is not called, so clear object manually
246 anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
247 anIter->second->GetUnstructuredGrid()->SetPoints(0);
248 VISUAL_OBJ_CONT.erase( anIter++ ); // anIter++ returns a copy of self before incrementing
256 //================================================================================
258 * \brief Notify the user on problems during visualization
260 //================================================================================
262 void OnVisuException()
265 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
268 // PAL16774 (Crash after display of many groups). Salome sometimes crashes just
269 // after or at showing this message, so we do an additional check of available memory
270 // char* buf = new char[100*1024];
272 SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
273 QObject::tr("SMESH_VISU_PROBLEM"));
275 // no more memory at all: last resort
276 MESSAGE_BEGIN ( "SMESHGUI_VTKUtils::OnVisuException(), exception even at showing a message!!!" <<
277 std::endl << "Try to remove all visual data..." );
278 if (theVISU_MemoryReserve) {
279 delete theVISU_MemoryReserve;
280 theVISU_MemoryReserve = 0;
282 RemoveAllObjectsWithActors();
283 SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
284 QObject::tr("SMESH_VISU_PROBLEM_CLEAR"));
285 MESSAGE_END ( "...done" );
288 //================================================================================
290 * \brief Returns an updated visual object
292 //================================================================================
294 TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry, bool nulData){
295 TVisualObjPtr aVisualObj;
296 TVisualObjCont::key_type aKey(theStudyId,theEntry);
298 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
301 TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
302 if(anIter != VISUAL_OBJ_CONT.end()){
303 aVisualObj = anIter->second;
305 SalomeApp_Application* app =
306 dynamic_cast<SalomeApp_Application*>( SMESHGUI::activeStudy()->application() );
307 _PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS();
308 _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry);
310 _PTR(GenericAttribute) anAttr;
311 if(aSObj->FindAttribute(anAttr,"AttributeIOR")){
312 _PTR(AttributeIOR) anIOR = anAttr;
313 CORBA::String_var aVal = anIOR->Value().c_str();
314 CORBA::Object_var anObj = app->orb()->string_to_object( aVal.in() );
315 if(!CORBA::is_nil(anObj)){
316 //Try narrow to SMESH_Mesh interface
317 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj);
318 if(!aMesh->_is_nil()){
319 aVisualObj.reset(new SMESH_MeshObj(aMesh));
320 TVisualObjCont::value_type aValue(aKey,aVisualObj);
321 VISUAL_OBJ_CONT.insert(aValue);
323 //Try narrow to SMESH_Group interface
324 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj);
325 if(!aGroup->_is_nil()){
326 _PTR(SObject) aFatherSObj = aSObj->GetFather();
327 if(!aFatherSObj) return aVisualObj;
328 aFatherSObj = aFatherSObj->GetFather();
329 if(!aFatherSObj) return aVisualObj;
330 CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
331 TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
332 if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
333 aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj));
334 TVisualObjCont::value_type aValue(aKey,aVisualObj);
335 VISUAL_OBJ_CONT.insert(aValue);
338 //Try narrow to SMESH_subMesh interface
339 SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj);
340 if(!aSubMesh->_is_nil()){
341 _PTR(SObject) aFatherSObj = aSObj->GetFather();
342 if(!aFatherSObj) return aVisualObj;
343 aFatherSObj = aFatherSObj->GetFather();
344 if(!aFatherSObj) return aVisualObj;
345 CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
346 TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
347 if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
348 aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj));
349 TVisualObjCont::value_type aValue(aKey,aVisualObj);
350 VISUAL_OBJ_CONT.insert(aValue);
358 INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!");
359 return TVisualObjPtr();
362 bool objModified = false;
365 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
368 //MESSAGE("GetVisualObj");
370 objModified = aVisualObj->NulData();
372 objModified = aVisualObj->Update();
376 MESSAGE ( "Exception in SMESHGUI_VTKUtils::GetVisualObj()" );
378 RemoveVisualObjectWithActors( theEntry ); // remove this object
385 // PAL16631. Mesurements showed that to show aVisualObj in SHADING(default) mode,
386 // ~5 times more memory is used than it occupies.
387 // Warn the user if there is less free memory than 30 sizes of a grid
388 // TODO: estimate memory usage in other modes and take current mode into account
389 int freeMB = SMDS_Mesh::CheckMemory(true);
390 int usedMB = aVisualObj->GetUnstructuredGrid()->GetActualMemorySize() / 1024;
391 MESSAGE("SMESHGUI_VTKUtils::GetVisualObj(), freeMB=" << freeMB << ", usedMB=" <<usedMB);
392 if ( freeMB > 0 && usedMB * 5 > freeMB ) {
393 bool continu = false;
394 if ( usedMB * 3 > freeMB )
395 // even dont try to show
396 SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
397 QObject::tr("SMESH_NO_MESH_VISUALIZATION"));
399 // there is a chance to succeed
400 continu = SUIT_MessageBox::warning
401 (SMESHGUI::desktop(),
402 QObject::tr("SMESH_WRN_WARNING"),
403 QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"),
404 SUIT_MessageBox::Yes | SUIT_MessageBox::No,
405 SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes;
407 // remove the corresponding actors from all views
408 RemoveVisualObjectWithActors( theEntry );
418 /*! Return active view window, if it instantiates SVTK_ViewWindow class,
419 * overwise find or create corresponding view window, make it active and return it.
420 * \note Active VVTK_ViewWindow can be returned, because it inherits SVTK_ViewWindow.
422 SVTK_ViewWindow* GetViewWindow (const SalomeApp_Module* theModule,
423 bool createIfNotFound)
425 SalomeApp_Application* anApp;
427 anApp = theModule->getApp();
429 anApp = dynamic_cast<SalomeApp_Application*>
430 (SUIT_Session::session()->activeApplication());
433 if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow()))
436 SUIT_ViewManager* aViewManager =
437 anApp->getViewManager(SVTK_Viewer::Type(), createIfNotFound);
439 if (SUIT_ViewWindow* aViewWindow = aViewManager->getActiveView()) {
440 if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow)) {
441 aViewWindow->raise();
442 aViewWindow->setFocus();
451 SVTK_ViewWindow* FindVtkViewWindow (SUIT_ViewManager* theMgr,
452 SUIT_ViewWindow * theWindow)
457 QVector<SUIT_ViewWindow*> views = theMgr->getViews();
458 if( views.contains( theWindow ) )
459 return GetVtkViewWindow( theWindow );
464 SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow* theWindow){
465 return dynamic_cast<SVTK_ViewWindow*>(theWindow);
468 /* SUIT_ViewWindow* GetActiveWindow()
470 SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
473 SUIT_ViewManager* mgr = app->activeViewManager();
475 return mgr->getActiveView();
480 SVTK_ViewWindow* GetCurrentVtkView(){
481 return GetVtkViewWindow( GetActiveWindow() );
485 void RepaintCurrentView()
487 if (SVTK_ViewWindow* wnd = GetCurrentVtkView())
490 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
493 wnd->getRenderer()->Render();
498 MESSAGE ( "Exception in SMESHGUI_VTKUtils::RepaintCurrentView()" );
505 void RepaintViewWindow(SVTK_ViewWindow* theWindow)
508 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
511 theWindow->getRenderer()->Render();
512 theWindow->Repaint();
516 MESSAGE ( "Exception in SMESHGUI_VTKUtils::RepaintViewWindow(SVTK_ViewWindow*)" );
522 void RenderViewWindow(SVTK_ViewWindow* theWindow)
525 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
528 theWindow->getRenderer()->Render();
529 theWindow->Repaint();
533 MESSAGE ( "Exception in SMESHGUI_VTKUtils::RenderViewWindow(SVTK_ViewWindow*)" );
540 if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){
542 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
550 MESSAGE ( "Exception in SMESHGUI_VTKUtils::FitAll()" );
558 SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow,
559 const char* theEntry)
561 if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
562 vtkRenderer *aRenderer = aViewWindow->getRenderer();
563 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
564 vtkActorCollection *aCollection = aCopy.GetActors();
565 aCollection->InitTraversal();
566 while(vtkActor *anAct = aCollection->GetNextActor()){
567 if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
568 if(anActor->hasIO()){
569 Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
570 if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){
581 SMESH_Actor* FindActorByEntry(const char* theEntry){
582 return FindActorByEntry(GetActiveWindow(),theEntry);
586 SMESH_Actor* FindActorByObject(CORBA::Object_ptr theObject){
587 SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
591 if(!CORBA::is_nil(theObject)){
592 _PTR(Study) aStudy = GetActiveStudyDocument();
593 CORBA::String_var anIOR = app->orb()->object_to_string( theObject );
594 _PTR(SObject) aSObject = aStudy->FindObjectIOR(anIOR.in());
596 CORBA::String_var anEntry = aSObject->GetID().c_str();
597 return FindActorByEntry(anEntry.in());
604 SMESH_Actor* CreateActor(_PTR(Study) theStudy,
605 const char* theEntry,
608 SMESH_Actor *anActor = NULL;
609 CORBA::Long anId = theStudy->StudyId();
610 if(TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)){
611 _PTR(SObject) aSObj = theStudy->FindObjectID(theEntry);
613 _PTR(GenericAttribute) anAttr;
614 if(aSObj->FindAttribute(anAttr,"AttributeName")){
615 _PTR(AttributeName) aName = anAttr;
616 std::string aNameVal = aName->Value();
617 anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear);
620 SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( aSObj ));
621 if(!CORBA::is_nil(aGroup) && anActor)
625 SMESH::GetColor( "SMESH", "fill_color", c, deltaF, "0,170,255|-100" );
626 SMESH::GetColor( "SMESH", "volume_color", c, deltaV, "255,0,170|-100" );
627 c = SMESH::GetColor( "SMESH", "default_grp_color", c );
628 SALOMEDS::Color aColor = aGroup->GetColor();
629 if( !( aColor.R > 0 || aColor.G > 0 || aColor.B > 0 ))
632 aColor.G = c.greenF();
633 aColor.B = c.blueF();
634 aGroup->SetColor( aColor );
636 if( aGroup->GetType() == SMESH::NODE )
637 anActor->SetNodeColor( aColor.R, aColor.G, aColor.B );
638 else if( aGroup->GetType() == SMESH::EDGE )
639 anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B );
640 else if( aGroup->GetType() == SMESH::ELEM0D )
641 anActor->Set0DColor( aColor.R, aColor.G, aColor.B );
642 else if( aGroup->GetType() == SMESH::BALL )
643 anActor->SetBallColor( aColor.R, aColor.G, aColor.B );
644 else if( aGroup->GetType() == SMESH::VOLUME )
645 anActor->SetVolumeColor( aColor.R, aColor.G, aColor.B, deltaV );
647 anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, deltaF );
651 MESSAGE("CreateActor " << anActor);
653 if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() )
654 aSMESHGUI->addActorAsObserver( anActor );
659 void DisplayActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
660 if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
662 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
665 MESSAGE("DisplayActor " << theActor);
666 vtkWnd->AddActor(theActor);
671 MESSAGE ( "Exception in SMESHGUI_VTKUtils::DisplayActor()" );
679 void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
680 if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
681 MESSAGE("RemoveActor " << theActor);
682 vtkWnd->RemoveActor(theActor);
683 if(theActor->hasIO()){
684 Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
685 if(anIO->hasEntry()){
686 std::string anEntry = anIO->getEntry();
687 SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
688 int aStudyId = aStudy->id();
689 TVisualObjCont::key_type aKey(aStudyId,anEntry);
690 VISUAL_OBJ_CONT.erase(aKey);
698 //================================================================================
700 * \brief Return true if there are no SMESH actors in a view
702 //================================================================================
704 bool noSmeshActors(SUIT_ViewWindow *theWnd)
706 if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWnd)) {
707 vtkRenderer *aRenderer = aViewWindow->getRenderer();
708 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
709 vtkActorCollection *aCollection = aCopy.GetActors();
710 aCollection->InitTraversal();
711 while(vtkActor *anAct = aCollection->GetNextActor())
712 if(dynamic_cast<SMESH_Actor*>(anAct))
718 bool UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
720 //MESSAGE("UpdateView");
722 SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd);
726 SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd);
730 SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
737 vtkRenderer *aRenderer = aViewWnd->getRenderer();
738 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
739 vtkActorCollection *aCollection = aCopy.GetActors();
740 aCollection->InitTraversal();
744 while (vtkActor *anAct = aCollection->GetNextActor()) {
745 if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
746 MESSAGE("--- display " << anActor);
747 anActor->SetVisibility(true);
749 if(anActor->hasIO()){
750 Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
751 if(anIO->hasEntry()){
752 aStudy->setVisibilityState(anIO->getEntry(), Qtx::ShownState);
761 //MESSAGE("---case eDisplayOnly");
762 while (vtkActor *anAct = aCollection->GetNextActor()) {
763 if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
764 //MESSAGE("--- erase " << anActor);
765 anActor->SetVisibility(false);
768 aStudy->setVisibilityStateForAll(Qtx::HiddenState);
771 if (SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)) {
775 //MESSAGE("--- display " << anActor);
777 anActor->SetVisibility(true);
778 if (theAction == eDisplayOnly) aRenderer->ResetCameraClippingRange();
779 aStudy->setVisibilityState(theEntry, Qtx::ShownState);
782 //MESSAGE("--- erase " << anActor);
783 anActor->SetVisibility(false);
784 aStudy->setVisibilityState(theEntry, Qtx::HiddenState);
793 SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(theWnd->getViewManager()->study());
794 _PTR(Study) aDocument = aStudy->studyDS();
795 // Pass non-visual objects (hypotheses, etc.), return true in this case
796 CORBA::Long anId = aDocument->StudyId();
797 TVisualObjPtr aVisualObj;
798 if ( (aVisualObj = GetVisualObj(anId,theEntry)) && aVisualObj->IsValid())
800 if ((anActor = CreateActor(aDocument,theEntry,true))) {
801 bool needFitAll = noSmeshActors(theWnd); // fit for the first object only
802 DisplayActor(theWnd,anActor);
803 aStudy->setVisibilityState(theEntry, Qtx::ShownState);
804 // FitAll(); - PAL16770(Display of a group performs an automatic fit all)
805 if (needFitAll) FitAll();
821 bool UpdateView(EDisplaing theAction, const char* theEntry){
822 //MESSAGE("UpdateView");
823 SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() );
824 SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() );
825 SUIT_ViewWindow *aWnd = app->activeViewManager()->getActiveView();
826 return UpdateView(aWnd,theAction,theEntry);
830 if(SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView()){
831 LightApp_SelectionMgr* mgr = SMESHGUI::selectionMgr();
832 SALOME_ListIO selected; mgr->selectedObjects( selected );
834 if( selected.Extent() == 0){
835 vtkRenderer* aRenderer = aWnd->getRenderer();
836 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
837 vtkActorCollection *aCollection = aCopy.GetActors();
838 aCollection->InitTraversal();
839 while(vtkActor *anAct = aCollection->GetNextActor()){
840 if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
842 if (!Update(anActor->getIO(),anActor->GetVisibility()))
843 break; // avoid multiple warinings if visu failed
847 SALOME_ListIteratorOfListIO anIter( selected );
848 for( ; anIter.More(); anIter.Next()){
849 Handle(SALOME_InteractiveObject) anIO = anIter.Value();
850 if ( !Update(anIO,true) )
851 break; // avoid multiple warinings if visu failed
854 RepaintCurrentView();
859 bool Update(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
862 _PTR(Study) aStudy = GetActiveStudyDocument();
863 CORBA::Long anId = aStudy->StudyId();
864 if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry())) {
866 UpdateView(SMESH::eDisplay,theIO->getEntry());
872 bool UpdateNulData(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
874 MESSAGE("UpdateNulData");
875 _PTR(Study) aStudy = GetActiveStudyDocument();
876 CORBA::Long anId = aStudy->StudyId();
877 if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry(), true)) {
879 UpdateView(SMESH::eDisplay,theIO->getEntry());
885 void UpdateSelectionProp( SMESHGUI* theModule ) {
889 SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( theModule->application() );
892 MESSAGE( "UpdateSelectionProp: Application is null" );
896 SUIT_ViewManager* vm = app->activeViewManager();
899 MESSAGE( "UpdateSelectionProp: View manager is null" );
903 QVector<SUIT_ViewWindow*> views = vm->getViews();
905 SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( theModule );
908 MESSAGE( "UpdateSelectionProp: Resource manager is null" );
912 QColor aHiColor = mgr->colorValue( "SMESH", "selection_object_color", Qt::white ),
913 aSelColor = mgr->colorValue( "SMESH", "selection_element_color", Qt::yellow ),
914 aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan );
916 int aElem0DSize = mgr->integerValue("SMESH", "elem0d_size", 5);
917 int aBallSize = mgr->integerValue("SMESH", "ball_elem_size", 5);
918 int aLineWidth = mgr->integerValue("SMESH", "element_width", 1);
919 int maxSize = aElem0DSize;
920 if (aElem0DSize > maxSize) maxSize = aElem0DSize;
921 if (aLineWidth > maxSize) maxSize = aLineWidth;
922 if (aBallSize > maxSize) maxSize = aBallSize;
924 double SP1 = mgr->doubleValue( "SMESH", "selection_precision_node", 0.025 ),
925 SP2 = mgr->doubleValue( "SMESH", "selection_precision_element", 0.001 ),
926 SP3 = mgr->doubleValue( "SMESH", "selection_precision_object", 0.025 );
928 for ( int i=0, n=views.count(); i<n; i++ ){
929 // update VTK viewer properties
930 if(SVTK_ViewWindow* aVtkView = GetVtkViewWindow( views[i] )){
931 // mesh element selection
932 aVtkView->SetSelectionProp(aSelColor.red()/255.,
933 aSelColor.green()/255.,
934 aSelColor.blue()/255.);
936 aVtkView->SetSelectionTolerance(SP1, SP2, SP3);
939 aVtkView->SetPreselectionProp(aPreColor.red()/255.,
940 aPreColor.green()/255.,
941 aPreColor.blue()/255.);
943 vtkRenderer* aRenderer = aVtkView->getRenderer();
944 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
945 vtkActorCollection *aCollection = aCopy.GetActors();
946 aCollection->InitTraversal();
947 while(vtkActor *anAct = aCollection->GetNextActor()){
948 if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
949 anActor->SetHighlightColor(aHiColor.red()/255.,
950 aHiColor.green()/255.,
951 aHiColor.blue()/255.);
952 anActor->SetPreHighlightColor(aPreColor.red()/255.,
953 aPreColor.green()/255.,
954 aPreColor.blue()/255.);
962 void UpdateFontProp( SMESHGUI* theModule )
964 if ( !theModule ) return;
966 SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( theModule->application() );
969 SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( theModule );
972 double anRGBNd[3] = {1,1,1};
973 SMESH::GetColor( "SMESH", "numbering_node_color", anRGBNd[0], anRGBNd[1], anRGBNd[2], QColor( 255, 255, 255 ) );
975 SMESH::LabelFont aFamilyNd = SMESH::FntTimes;
977 bool anItalicNd = false;
978 bool aShadowNd = false;
980 if ( mgr->hasValue( "SMESH", "numbering_node_font" ) ) {
981 QFont f = mgr->fontValue( "SMESH", "numbering_node_font" );
982 if ( f.family() == "Arial" ) aFamilyNd = SMESH::FntArial;
983 else if ( f.family() == "Courier" ) aFamilyNd = SMESH::FntCourier;
984 else if ( f.family() == "Times" ) aFamilyNd = SMESH::FntTimes;
986 anItalicNd = f.italic();
987 aShadowNd = f.overline();
988 aSizeNd = f.pointSize();
991 double anRGBEl[3] = {0,1,0};
992 SMESH::GetColor( "SMESH", "numbering_elem_color", anRGBEl[0], anRGBEl[1], anRGBEl[2], QColor( 0, 255, 0 ) );
994 SMESH::LabelFont aFamilyEl = SMESH::FntTimes;
996 bool anItalicEl = false;
997 bool aShadowEl = false;
999 if ( mgr->hasValue( "SMESH", "numbering_elem_font" ) ) {
1000 QFont f = mgr->fontValue( "SMESH", "numbering_elem_font" );
1002 if ( f.family() == "Arial" ) aFamilyEl = SMESH::FntArial;
1003 else if ( f.family() == "Courier" ) aFamilyEl = SMESH::FntCourier;
1004 else if ( f.family() == "Times" ) aFamilyEl = SMESH::FntTimes;
1006 anItalicEl = f.italic();
1007 aShadowEl = f.overline();
1008 aSizeEl = f.pointSize();
1011 ViewManagerList vmList;
1012 app->viewManagers( SVTK_Viewer::Type(), vmList );
1013 foreach ( SUIT_ViewManager* vm, vmList ) {
1014 QVector<SUIT_ViewWindow*> views = vm->getViews();
1015 foreach ( SUIT_ViewWindow* vw, views ) {
1016 // update VTK viewer properties
1017 if ( SVTK_ViewWindow* aVtkView = GetVtkViewWindow( vw ) ) {
1019 vtkRenderer* aRenderer = aVtkView->getRenderer();
1020 VTK::ActorCollectionCopy aCopy( aRenderer->GetActors() );
1021 vtkActorCollection* aCollection = aCopy.GetActors();
1022 aCollection->InitTraversal();
1023 while ( vtkActor* anAct = aCollection->GetNextActor() ) {
1024 if ( SMESH_NodeLabelActor* anActor = dynamic_cast< SMESH_NodeLabelActor* >( anAct ) ) {
1025 anActor->SetFontProperties( aFamilyNd, aSizeNd, aBoldNd, anItalicNd, aShadowNd, anRGBNd[0], anRGBNd[1], anRGBNd[2] );
1027 else if ( SMESH_CellLabelActor* anActor = dynamic_cast< SMESH_CellLabelActor* >( anAct ) ) {
1028 anActor->SetFontProperties( aFamilyEl, aSizeEl, aBoldEl, anItalicEl, aShadowEl, anRGBEl[0], anRGBEl[1], anRGBEl[2] );
1031 aVtkView->Repaint( false );
1037 //----------------------------------------------------------------------------
1039 GetSelector(SUIT_ViewWindow *theWindow)
1041 if(SVTK_ViewWindow* aWnd = GetVtkViewWindow(theWindow))
1042 return aWnd->GetSelector();
1047 void SetFilter(const Handle(VTKViewer_Filter)& theFilter,
1048 SVTK_Selector* theSelector)
1051 theSelector->SetFilter(theFilter);
1054 Handle(VTKViewer_Filter) GetFilter(int theId, SVTK_Selector* theSelector)
1056 return theSelector->GetFilter(theId);
1059 bool IsFilterPresent(int theId, SVTK_Selector* theSelector)
1061 return theSelector->IsFilterPresent(theId);
1064 void RemoveFilter(int theId, SVTK_Selector* theSelector)
1066 theSelector->RemoveFilter(theId);
1069 void RemoveFilters(SVTK_Selector* theSelector)
1071 for ( int id = SMESH::NodeFilter; theSelector && id < SMESH::LastFilter; id++ )
1072 theSelector->RemoveFilter( id );
1075 bool IsValid(SALOME_Actor* theActor, int theCellId,
1076 SVTK_Selector* theSelector)
1078 return theSelector->IsValid(theActor,theCellId);
1082 //----------------------------------------------------------------------------
1083 void SetPointRepresentation(bool theIsVisible){
1084 if(SVTK_ViewWindow* aViewWindow = GetCurrentVtkView()){
1085 vtkRenderer *aRenderer = aViewWindow->getRenderer();
1086 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
1087 vtkActorCollection *aCollection = aCopy.GetActors();
1088 aCollection->InitTraversal();
1089 while(vtkActor *anAct = aCollection->GetNextActor()){
1090 if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
1091 if(anActor->GetVisibility()){
1092 anActor->SetPointRepresentation(theIsVisible);
1096 RepaintCurrentView();
1101 void SetPickable(SMESH_Actor* theActor){
1102 if(SVTK_ViewWindow* aWnd = GetCurrentVtkView()){
1103 int anIsAllPickable = (theActor == NULL);
1104 vtkRenderer *aRenderer = aWnd->getRenderer();
1105 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
1106 vtkActorCollection *aCollection = aCopy.GetActors();
1107 aCollection->InitTraversal();
1108 while(vtkActor *anAct = aCollection->GetNextActor()){
1109 if(SALOME_Actor *anActor = dynamic_cast<SALOME_Actor*>(anAct)){
1110 if(anActor->GetVisibility()){
1111 anActor->SetPickable(anIsAllPickable);
1116 theActor->SetPickable(!anIsAllPickable);
1117 RepaintCurrentView();
1122 //----------------------------------------------------------------------------
1123 int GetNameOfSelectedSortedNodes( SMDSAbs_EntityType theElementType,
1124 SVTK_Selector* theSelector,
1125 SMESH_Actor* theActor,
1130 TColStd_IndexedMapOfInteger aMapIndex;
1131 Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
1132 theSelector->GetIndex(anIO, aMapIndex);
1134 SMDS_Mesh* aMesh = 0;
1136 aMesh = theActor->GetObject()->GetMesh();
1138 std::vector<SMESH_TNodeXYZ> aVectorOfNode;
1139 std::list<int> aListOfId;
1140 int aSize = aMapIndex.Extent();
1141 for( int i = 1 ; i <= aSize; i++) {
1142 SMESH_TNodeXYZ aCurNode = aMesh->FindNode( aMapIndex(i) );
1143 aVectorOfNode.push_back( aCurNode );
1144 aListOfId.push_back( aCurNode._node->GetID() );
1146 SMESH_TNodeXYZ aFirstNode;
1148 aFirstNode = aVectorOfNode[0];
1150 std::list<int> aResultListId;
1151 switch ( theElementType ) {
1155 case SMDSEntity_Ball:
1158 case SMDSEntity_Edge:
1159 case SMDSEntity_Quad_Edge:
1162 case SMDSEntity_Triangle:
1163 case SMDSEntity_Quad_Triangle:
1164 case SMDSEntity_BiQuad_Triangle:
1167 case SMDSEntity_Quadrangle:
1168 case SMDSEntity_Quad_Quadrangle:
1169 case SMDSEntity_BiQuad_Quadrangle:
1171 if ( myNbNodes <= aSize ) {
1172 aVectorOfNode.resize( myNbNodes );
1173 aVectorOfNode[0] = aVectorOfNode[theShift % myNbNodes];
1174 aVectorOfNode[theShift % myNbNodes] = aFirstNode;
1175 GetSortedNodesOnPolygon( aVectorOfNode, aResultListId );
1178 case SMDSEntity_Polygon:
1181 aVectorOfNode[0] = aVectorOfNode[theShift % aVectorOfNode.size()];
1182 aVectorOfNode[theShift % aVectorOfNode.size()] = aFirstNode;
1184 GetSortedNodesOnPolygon( aVectorOfNode, aResultListId );
1186 case SMDSEntity_Tetra:
1187 case SMDSEntity_Quad_Tetra:
1190 case SMDSEntity_Pyramid:
1191 case SMDSEntity_Quad_Pyramid:
1193 if ( myNbNodes <= aSize ) {
1194 aVectorOfNode.resize( myNbNodes );
1195 aVectorOfNode[0] = aVectorOfNode[theShift % myNbNodes];
1196 aVectorOfNode[theShift % myNbNodes] = aFirstNode;
1197 GetSortedNodesOnPyramid( aVectorOfNode, aResultListId );
1200 case SMDSEntity_Hexa:
1201 case SMDSEntity_Quad_Hexa:
1202 case SMDSEntity_TriQuad_Hexa:
1204 if ( myNbNodes <= aSize ) {
1205 aVectorOfNode.resize( myNbNodes );
1206 aVectorOfNode[0] = aVectorOfNode[theShift % myNbNodes];
1207 aVectorOfNode[theShift % myNbNodes] = aFirstNode;
1208 GetSortedNodesOnPrism( aVectorOfNode, aResultListId );
1211 case SMDSEntity_Penta:
1212 case SMDSEntity_Quad_Penta:
1214 if ( myNbNodes <= aSize ) {
1215 aVectorOfNode.resize( myNbNodes );
1216 aVectorOfNode[0] = aVectorOfNode[theShift % myNbNodes];
1217 aVectorOfNode[theShift % myNbNodes] = aFirstNode;
1218 GetSortedNodesOnPrism( aVectorOfNode, aResultListId );
1221 case SMDSEntity_Hexagonal_Prism:
1223 if ( myNbNodes <= aSize ) {
1224 aVectorOfNode.resize( myNbNodes );
1225 aVectorOfNode[0] = aVectorOfNode[theShift % myNbNodes];
1226 aVectorOfNode[theShift % myNbNodes] = aFirstNode;
1227 GetSortedNodesOnPrism( aVectorOfNode, aResultListId );
1233 if( myNbNodes > 0 ) {
1234 if ( myNbNodes <= 3 || myNbNodes > aSize || theElementType == SMDSEntity_Tetra )
1235 aResultListId = aListOfId;
1236 if ( myNbNodes < aSize ) {
1237 if ( aResultListId.size() == 0 )
1239 aVectorOfNode.resize( myNbNodes );
1240 aResultListId.resize( myNbNodes );
1243 std::list<int>::iterator anIter = aResultListId.begin();
1245 for( ; anIter != aResultListId.end(); anIter++ ) {
1246 theName += QString(" %1").arg( *anIter );
1248 if ( myNbNodes <= 3 || myNbNodes > aSize || theElementType == SMDSEntity_Tetra )
1250 return aVectorOfNode.size();
1252 int GetNameOfSelectedNodes(SVTK_Selector* theSelector,
1253 const Handle(SALOME_InteractiveObject)& theIO,
1257 TColStd_IndexedMapOfInteger aMapIndex;
1258 theSelector->GetIndex(theIO,aMapIndex);
1260 for(int i = 1; i <= aMapIndex.Extent(); i++)
1261 theName += QString(" %1").arg(aMapIndex(i));
1263 return aMapIndex.Extent();
1266 int GetNameOfSelectedElements(SVTK_Selector* theSelector,
1267 const Handle(SALOME_InteractiveObject)& theIO,
1271 TColStd_IndexedMapOfInteger aMapIndex;
1272 theSelector->GetIndex(theIO,aMapIndex);
1274 typedef std::set<int> TIdContainer;
1275 TIdContainer anIdContainer;
1276 for( int i = 1; i <= aMapIndex.Extent(); i++)
1277 anIdContainer.insert(aMapIndex(i));
1279 TIdContainer::const_iterator anIter = anIdContainer.begin();
1280 for( ; anIter != anIdContainer.end(); anIter++)
1281 theName += QString(" %1").arg(*anIter);
1283 return aMapIndex.Extent();
1287 int GetEdgeNodes(SVTK_Selector* theSelector,
1288 const TVisualObjPtr& theVisualObject,
1292 const SALOME_ListIO& selected = theSelector->StoredIObjects();
1294 if ( selected.Extent() != 1 )
1297 Handle(SALOME_InteractiveObject) anIO = selected.First();
1298 if ( anIO.IsNull() || !anIO->hasEntry() )
1301 TColStd_IndexedMapOfInteger aMapIndex;
1302 theSelector->GetIndex( anIO, aMapIndex );
1303 if ( aMapIndex.Extent() != 2 )
1306 int anObjId = -1, anEdgeNum = -1;
1307 for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
1308 int aVal = aMapIndex( i );
1312 anEdgeNum = abs( aVal ) - 1;
1315 if ( anObjId == -1 || anEdgeNum == -1 )
1318 return theVisualObject->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
1321 //----------------------------------------------------------------------------
1322 int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr,
1323 const Handle(SALOME_InteractiveObject)& theIO,
1327 if(theIO->hasEntry()){
1328 if(FindActorByEntry(theIO->getEntry())){
1329 TColStd_IndexedMapOfInteger aMapIndex;
1330 theMgr->GetIndexes(theIO,aMapIndex);
1331 for(int i = 1; i <= aMapIndex.Extent(); i++){
1332 theName += QString(" %1").arg(aMapIndex(i));
1334 return aMapIndex.Extent();
1340 int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr, QString& theName){
1342 SALOME_ListIO selected; theMgr->selectedObjects( selected );
1343 if(selected.Extent() == 1){
1344 Handle(SALOME_InteractiveObject) anIO = selected.First();
1345 return GetNameOfSelectedNodes(theMgr,anIO,theName);
1351 int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr,
1352 const Handle(SALOME_InteractiveObject)& theIO,
1356 if(theIO->hasEntry()){
1357 if(FindActorByEntry(theIO->getEntry())){
1358 TColStd_IndexedMapOfInteger aMapIndex;
1359 theMgr->GetIndexes(theIO,aMapIndex);
1360 typedef std::set<int> TIdContainer;
1361 TIdContainer anIdContainer;
1362 for( int i = 1; i <= aMapIndex.Extent(); i++)
1363 anIdContainer.insert(aMapIndex(i));
1364 TIdContainer::const_iterator anIter = anIdContainer.begin();
1365 for( ; anIter != anIdContainer.end(); anIter++){
1366 theName += QString(" %1").arg(*anIter);
1368 return aMapIndex.Extent();
1375 int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr, QString& theName)
1378 SALOME_ListIO selected; theMgr->selectedObjects( selected );
1380 if( selected.Extent() == 1){
1381 Handle(SALOME_InteractiveObject) anIO = selected.First();
1382 return GetNameOfSelectedElements(theMgr,anIO,theName);
1387 int GetSelected(LightApp_SelectionMgr* theMgr,
1388 TColStd_IndexedMapOfInteger& theMap,
1389 const bool theIsElement)
1392 SALOME_ListIO selected; theMgr->selectedObjects( selected );
1394 if ( selected.Extent() == 1 )
1396 Handle(SALOME_InteractiveObject) anIO = selected.First();
1397 if ( anIO->hasEntry() ) {
1398 theMgr->GetIndexes( anIO, theMap );
1401 return theMap.Extent();
1405 int GetEdgeNodes( LightApp_SelectionMgr* theMgr, int& theId1, int& theId2 )
1407 SALOME_ListIO selected; theMgr->selectedObjects( selected );
1409 if ( selected.Extent() != 1 )
1412 Handle(SALOME_InteractiveObject) anIO = selected.First();
1413 if ( anIO.IsNull() || !anIO->hasEntry() )
1416 SMESH_Actor *anActor = SMESH::FindActorByEntry( anIO->getEntry() );
1420 TColStd_IndexedMapOfInteger aMapIndex;
1421 theMgr->GetIndexes( anIO, aMapIndex );
1422 if ( aMapIndex.Extent() != 2 )
1425 int anObjId = -1, anEdgeNum = -1;
1426 for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
1427 int aVal = aMapIndex( i );
1431 anEdgeNum = abs( aVal );
1434 if ( anObjId == -1 || anEdgeNum == -1 )
1437 return anActor->GetObject()->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
1440 void SetControlsPrecision( const long theVal )
1442 if( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView() )
1444 vtkRenderer *aRenderer = aWnd->getRenderer();
1445 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
1446 vtkActorCollection *aCollection = aCopy.GetActors();
1447 aCollection->InitTraversal();
1449 while ( vtkActor *anAct = aCollection->GetNextActor())
1451 if ( SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>( anAct ) )
1453 anActor->SetControlsPrecision( theVal );
1454 anActor->SetControlMode( anActor->GetControlMode() );
1461 //----------------------------------------------------------------------------
1462 // internal function
1463 void ComputeBoundsParam( double theBounds[6],
1464 double theDirection[3],
1465 double theMinPnt[3],
1466 double& theMaxBoundPrj,
1467 double& theMinBoundPrj )
1469 //Enlarge bounds in order to avoid conflicts of precision
1470 for(int i = 0; i < 6; i += 2){
1471 static double EPS = 1.0E-3;
1472 double aDelta = (theBounds[i+1] - theBounds[i])*EPS;
1473 theBounds[i] -= aDelta;
1474 theBounds[i+1] += aDelta;
1477 double aBoundPoints[8][3] = { {theBounds[0],theBounds[2],theBounds[4]},
1478 {theBounds[1],theBounds[2],theBounds[4]},
1479 {theBounds[0],theBounds[3],theBounds[4]},
1480 {theBounds[1],theBounds[3],theBounds[4]},
1481 {theBounds[0],theBounds[2],theBounds[5]},
1482 {theBounds[1],theBounds[2],theBounds[5]},
1483 {theBounds[0],theBounds[3],theBounds[5]},
1484 {theBounds[1],theBounds[3],theBounds[5]}};
1487 theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
1488 theMinBoundPrj = theMaxBoundPrj;
1489 for(int i = 1; i < 8; i++){
1490 double aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
1491 if(theMaxBoundPrj < aTmp){
1492 theMaxBoundPrj = aTmp;
1495 if(theMinBoundPrj > aTmp){
1496 theMinBoundPrj = aTmp;
1499 double *aMinPnt = aBoundPoints[aMaxId];
1500 theMinPnt[0] = aMinPnt[0];
1501 theMinPnt[1] = aMinPnt[1];
1502 theMinPnt[2] = aMinPnt[2];
1505 // internal function
1506 void DistanceToPosition( double theBounds[6],
1507 double theDirection[3],
1511 double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
1512 ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
1513 double aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
1514 thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
1515 thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
1516 thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
1519 // internal function (currently unused, left just in case)
1520 void PositionToDistance( double theBounds[6],
1521 double theDirection[3],
1525 double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
1526 ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
1527 double aPrj = vtkMath::Dot(theDirection,thePos);
1528 theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
1531 bool ComputeClippingPlaneParameters( std::list<vtkActor*> theActorList,
1532 double theNormal[3],
1534 double theBounds[6],
1535 double theOrigin[3] )
1537 bool anIsOk = false;
1538 anIsOk = ComputeBounds( theActorList, theBounds );
1544 DistanceToPosition( theBounds, theNormal, theDist, theOrigin );
1547 bool CreatePlaneOnThreePoints( const gp_Pnt& thePoint1,
1548 const gp_Pnt& thePoint2,
1549 const gp_Pnt& thePoint3,
1552 gp_Vec aVec1, aVec2;
1553 aVec1 = gp_Vec( thePoint1, thePoint2 );
1554 aVec2 = gp_Vec( thePoint1, thePoint3 );
1555 double anAngle = aVec1.Angle( aVec2 );
1556 bool isOnStraight = ( anAngle != 0 && anAngle != M_PI );
1557 if ( isOnStraight ) {
1558 gce_MakePln aMakePln (thePoint1, thePoint2, thePoint3);
1559 if ( aMakePln.IsDone() ) {
1560 thePlane = aMakePln.Value();
1563 return isOnStraight;
1566 void FindNbLowestPoint( std::list<gp_Pnt2d> theList, gp_Pnt2d& theNode )
1568 std::list<gp_Pnt2d>::iterator anIter = theList.begin();
1569 gp_Pnt2d aNode = gp_Pnt2d ( (*anIter).X(), (*anIter).Y());
1570 for( ; anIter != theList.end(); anIter++ ) {
1571 if ( (*anIter).Y() < aNode.Y() || ( (*anIter).Y() == aNode.Y() && (*anIter).X() < aNode.X() ) )
1577 static bool CompareNodeOfAngleAndDist (const TNodeOfAngleAndDist& first, const TNodeOfAngleAndDist& second )
1579 if ( first.second.second == 0 )
1581 if ( second.second.second == 0 )
1583 if ( first.second.first == 0 && second.second.first == 0 )
1584 if ( first.second.second > second.second.second )
1588 if ( first.second.first < second.second.first ||
1589 ( first.second.first == second.second.first && first.second.second >= second.second.second ) )
1594 static bool CompareNodeOfDist (const TNodeOfAngleAndDist& first, const TNodeOfAngleAndDist& second )
1596 if ( first.second.second < second.second.second )
1601 static bool CompareDistOfPlane ( const TNodeOfDistToPlaneAndDist& first, const TNodeOfDistToPlaneAndDist& second )
1603 if ( first.second.first == 0 && second.second.first != 0 )
1605 if ( first.second.first != 0 && second.second.first == 0 )
1607 if ( first.second.first < second.second.first ||
1608 ( first.second.first != 0 && second.second.first != 0 &&
1609 first.second.first == second.second.first && first.second.second > second.second.second ) )
1614 static bool CompareDistOfPlaneById ( const TIdOfDistToPlaneAndDist& first, const TIdOfDistToPlaneAndDist& second )
1616 if ( first.second.first == 0 && second.second.first != 0 )
1618 if ( first.second.first != 0 && second.second.first == 0 )
1620 if ( first.second.first < second.second.first ||
1621 ( first.second.first != 0 && second.second.first != 0 &&
1622 first.second.first == second.second.first && first.second.second > second.second.second ) )
1627 static bool CompareDistForCorrectPlane ( const TNodeOfDist& first, const TNodeOfDist& second )
1629 if ( first.second < second.second ) return true;
1633 bool IsNotPlaneIntersection( std::vector<SMESH_TNodeXYZ>& theVector, const gp_Pln& thePlane )
1635 double A, B, C, D, aCur;
1636 thePlane.Coefficients(A, B, C, D);
1638 for ( int i = 0 ; i < (int)theVector.size(); ++i ) {
1639 aCur = A * theVector[i]._xyz[0] + B * theVector[i]._xyz[1] + C * theVector[i]._xyz[2] + D;
1642 if ( aPlus == -1 && aCur != 0 )
1643 aPlus = ( aCur < 0 ) ? 0 : 1;
1644 if ( aPlus > -1 && aPlus != ( aCur < 0 ) ? 0 : 1 )
1650 bool GetNextCombination ( std::vector<int>& theVector1, std::vector<int>& theVector2, int theNbPoint )
1652 int aSize = (int)theVector1.size();
1653 for ( int i = aSize - 1; i >= 0; --i ) {
1654 if ( theVector1[i] < theNbPoint - aSize + i ) {
1656 for ( int j = i + 1; j < aSize; ++j )
1657 theVector1[j] = theVector1[j-1] + 1;
1661 for ( int k = 0; k < theNbPoint; ++k ) {
1664 if( k == theVector1[it] ) {
1671 theVector2[it2] = k;
1673 if ( it2 == (int)theVector2.size() )
1682 bool Get2BasePlane( std::vector<SMESH_TNodeXYZ>& theVector,
1683 std::vector<SMESH_TNodeXYZ>& thePlane1,
1684 std::vector<SMESH_TNodeXYZ>& thePlane2 )
1686 int aSize = (int)theVector.size() / 2;
1687 if ( aSize < 3 || (int)theVector.size() % 2 != 0 )
1690 int anArr2[2 * aSize - 3];
1691 for (int i = 0; i < 3 ; i++) {
1694 for (int i = 0; i < 2 * aSize - 3 ; i++) {
1697 int aNbSwapFirstPoint = 0;
1698 while ( thePlane1.empty() && thePlane2.empty() && aNbSwapFirstPoint < aSize * 2 ) {
1699 std::vector<int> anIndexPlane1( anArr1, anArr1 + 3 );
1700 std::vector<int> anIndexPlane2( anArr2, anArr2 + 2 * aSize - 3);
1701 int aNbCombination = 0;
1703 double aSumMin = -1;
1704 int aMaxCombination = 0;
1707 for (int i = 1; i < 2 * aSize - 1; i++ ) {
1708 aMaxCombination += i;
1710 while ( aNbCombination < aMaxCombination ) {
1712 double aSumMinDist1 = 0;
1713 double aSumMinDist2 = 0;
1714 std::vector<SMESH_TNodeXYZ> aVectorOfPoint;
1715 for(int i = 0; i < 2 * aSize - 3; i++) {
1716 aVectorOfPoint.push_back(theVector[anIndexPlane2[i]]);
1718 bool isCorrectPlane = false;
1719 bool isCreatePlane = CreatePlaneOnThreePoints( gp_Pnt(theVector[anIndexPlane1[0]]._xyz[0], theVector[anIndexPlane1[0]]._xyz[1], theVector[anIndexPlane1[0]]._xyz[2]),
1720 gp_Pnt(theVector[anIndexPlane1[1]]._xyz[0], theVector[anIndexPlane1[1]]._xyz[1], theVector[anIndexPlane1[1]]._xyz[2]),
1721 gp_Pnt(theVector[anIndexPlane1[2]]._xyz[0], theVector[anIndexPlane1[2]]._xyz[1], theVector[anIndexPlane1[2]]._xyz[2]),
1723 if ( isCreatePlane ) {
1724 isCorrectPlane = IsNotPlaneIntersection( aVectorOfPoint, aPlane );
1726 if ( !isCorrectPlane ) {
1727 GetNextCombination( anIndexPlane1, anIndexPlane2, 2*aSize );
1731 std::vector<int> anIndexCorrectPlane1;
1732 std::vector<int> anIndexCorrectPlane2;
1734 for (int i = 0; i < aSize ; i++) {
1735 anIndexCorrectPlane1.push_back( anIndexPlane1[i] );
1736 anIndexCorrectPlane2.push_back( anIndexPlane2[i] );
1740 std::list<TIdOfDistToPlaneAndDist> aListBaseOfPoint;
1741 TIdOfDistToPlaneAndDist aCurDistOfPlane;
1742 for (int i = 0; i < 2 * aSize - 3; i++ ) {
1743 aCurDistOfPlane.second.first = aPlane.Distance( gp_Pnt( theVector[anIndexPlane2[i]]._xyz[0], theVector[anIndexPlane2[i]]._xyz[1], theVector[anIndexPlane2[i]]._xyz[2] ));
1744 if ( aCurDistOfPlane.second.first == 0 )
1745 aCurDistOfPlane.second.second = 0;
1747 double aCurDist = 0;
1748 for (int j = 0; j < 3; j++) {
1749 aCurDist += pow( theVector[anIndexPlane1[j]]._xyz[0] - theVector[anIndexPlane2[i]]._xyz[0], 2.0 ) +
1750 pow( theVector[anIndexPlane1[j]]._xyz[1] - theVector[anIndexPlane2[i]]._xyz[1], 2.0 ) +
1751 pow( theVector[anIndexPlane1[j]]._xyz[2] - theVector[anIndexPlane2[i]]._xyz[2], 2.0 );
1753 aCurDistOfPlane.second.second = aCurDist;
1755 aCurDistOfPlane.first = anIndexPlane2[i];
1756 aListBaseOfPoint.push_back( aCurDistOfPlane );
1758 aListBaseOfPoint.sort( CompareDistOfPlaneById );
1759 std::list<TIdOfDistToPlaneAndDist>::iterator anIterDist = aListBaseOfPoint.begin();
1760 for (int i = 0; i < 3; i++) {
1761 anIndexCorrectPlane1.push_back( anIndexPlane1[i] );
1763 for (int i = 0; i < aSize - 3; i++, anIterDist++) {
1764 anIndexCorrectPlane1.push_back((*anIterDist).first);
1766 for (int i = 0; i < 2 * aSize - 3 ; i++) {
1767 anIterDist = aListBaseOfPoint.begin();
1768 bool isFinded = false;
1769 for (int j = 0; j < aSize - 3; j++, anIterDist++) {
1770 if ( anIndexPlane2[i] == (*anIterDist).first ) {
1776 anIndexCorrectPlane2.push_back( anIndexPlane2[i] );
1779 double aCurDist1, aCurDist2, aMinDist1, aMinDist2, aSumDist1, aSumDist2, aSumDistBase1, aSumDistBase2;
1780 bool isCorrect2Base = true;
1781 aSumDist1 = aSumDistBase1 = aSumDist2 = aSumDistBase2 = 0;
1782 for( int i = 0 ; i < aSize ; i++ ) {
1785 for(int j = 0 ; j < aSize ; j++ ) {
1786 aCurDist1 = pow( theVector[anIndexCorrectPlane1[i]]._xyz[0] - theVector[anIndexCorrectPlane2[j]]._xyz[0], 2.0 ) +
1787 pow( theVector[anIndexCorrectPlane1[i]]._xyz[1] - theVector[anIndexCorrectPlane2[j]]._xyz[1], 2.0 ) +
1788 pow( theVector[anIndexCorrectPlane1[i]]._xyz[2] - theVector[anIndexCorrectPlane2[j]]._xyz[2], 2.0 );
1789 aCurDist2 = pow( theVector[anIndexCorrectPlane1[j]]._xyz[0] - theVector[anIndexCorrectPlane2[i]]._xyz[0], 2.0 ) +
1790 pow( theVector[anIndexCorrectPlane1[j]]._xyz[1] - theVector[anIndexCorrectPlane2[i]]._xyz[1], 2.0 ) +
1791 pow( theVector[anIndexCorrectPlane1[j]]._xyz[2] - theVector[anIndexCorrectPlane2[i]]._xyz[2], 2.0 );
1792 aSumDistBase1 += pow( theVector[anIndexCorrectPlane1[i]]._xyz[0] - theVector[anIndexCorrectPlane1[j]]._xyz[0], 2.0 ) +
1793 pow( theVector[anIndexCorrectPlane1[i]]._xyz[1] - theVector[anIndexCorrectPlane1[j]]._xyz[1], 2.0 ) +
1794 pow( theVector[anIndexCorrectPlane1[i]]._xyz[2] - theVector[anIndexCorrectPlane1[j]]._xyz[2], 2.0 );
1795 aSumDistBase2 += pow( theVector[anIndexCorrectPlane2[i]]._xyz[0] - theVector[anIndexCorrectPlane2[j]]._xyz[0], 2.0 ) +
1796 pow( theVector[anIndexCorrectPlane2[i]]._xyz[1] - theVector[anIndexCorrectPlane2[j]]._xyz[1], 2.0 ) +
1797 pow( theVector[anIndexCorrectPlane2[i]]._xyz[2] - theVector[anIndexCorrectPlane2[j]]._xyz[2], 2.0 );
1798 if ( aCurDist1 < aMinDist1 || aMinDist1 == 0)
1799 aMinDist1 = aCurDist1;
1800 if ( aCurDist2 < aMinDist2 || aMinDist2 == 0)
1801 aMinDist2 = aCurDist2;
1802 aSumDist1 += aCurDist1;
1803 aSumDist2 += aCurDist2;
1805 aSumMinDist1 += aMinDist1;
1806 aSumDist1 -= aMinDist1;
1807 aSumMinDist2 += aMinDist2;
1808 aSumDist2 -= aMinDist2;
1810 isCorrect2Base = ( aSumDistBase1 + aSumDistBase2 <= aSumDist1 + aSumDist2 );
1811 if ( isCorrect2Base && ( aSumMinDist1 == aSumMinDist2 || ( aSumMinDist1 + aSumMinDist2 ) > aMax || aMax == 0 ||
1812 ( (aSumMinDist1 + aSumMinDist2 ) == aMax && ( (aSumDist1 + aSumDist2 - aSumDistBase1 - aSumDistBase2) < aSumMin || aSumMin == -1 ) ) ) ) {
1813 aMax = aSumMinDist1 + aSumMinDist2;
1814 aSumMin = aSumDist1 + aSumDist2 - aSumDistBase1 - aSumDistBase2;
1817 for(int i = 0; i < aSize; i++) {
1818 thePlane1.push_back(theVector[anIndexCorrectPlane1[i]]);
1819 thePlane2.push_back(theVector[anIndexCorrectPlane2[i]]);
1822 if ( aSumMinDist1 == aSumMinDist2 )
1824 if ( !GetNextCombination( anIndexPlane1, anIndexPlane2, 2 * aSize) )
1828 if ( thePlane1.empty() && thePlane2.empty() ) {
1829 aNbSwapFirstPoint++;
1830 SMESH_TNodeXYZ aPoint;
1831 aPoint = theVector[0];
1832 theVector[0] = theVector[aNbSwapFirstPoint];
1833 theVector[aNbSwapFirstPoint] = aPoint;
1836 if ( thePlane1.empty() && thePlane2.empty() )
1841 bool GetCorrectSequenceOfId( std::vector<SMESH_TNodeXYZ>& theVector )
1843 std::list<gp_Pnt2d> aListProjection;
1845 int aSize = (int)theVector.size();
1849 bool isCreatePlane = false;
1850 for (int i = 0; i < aSize - 1; i++ ) {
1851 isCreatePlane = CreatePlaneOnThreePoints( gp_Pnt( theVector[i]._xyz[0], theVector[i]._xyz[1], theVector[i]._xyz[2] ),
1852 gp_Pnt( theVector[i+1]._xyz[0], theVector[i+1]._xyz[1], theVector[i+1]._xyz[2] ),
1853 gp_Pnt( theVector[i+2]._xyz[0], theVector[i+2]._xyz[1], theVector[i+2]._xyz[2] ), aPlane );
1857 if ( !isCreatePlane )
1859 for ( int i = 0; i < aSize; i++) {
1860 aCurPoint = ProjLib::Project( aPlane, gp_Pnt( theVector[i]._xyz[0], theVector[i]._xyz[1], theVector[i]._xyz[2] ));
1861 aListProjection.push_back( aCurPoint );
1863 std::list<TNodeOfAngleAndDist> aListIdOfAngleAndDist;
1864 TNodeOfAngleAndDist aCurIdOfAngleAndDist;
1865 FindNbLowestPoint( aListProjection, aCurPoint);
1866 std::list<gp_Pnt2d>::iterator anIter2d = aListProjection.begin();
1868 gp_Vec2d aAxisVec = gp_Vec2d( 1, 0 );
1869 for( int i = 0 ; anIter2d != aListProjection.end(); anIter2d++, i++) {
1870 aCurVec = gp_Vec2d( (*anIter2d).X() - aCurPoint.X(), (*anIter2d).Y() - aCurPoint.Y() );
1871 aCurIdOfAngleAndDist.first = theVector[i];
1872 if ( (*anIter2d).X() == aCurPoint.X() && (*anIter2d).Y() == aCurPoint.Y() )
1873 aCurIdOfAngleAndDist.second.first = 0;
1875 double anAngle = aAxisVec.Angle( aCurVec );
1876 double anRoundAngle = anAngle * 100000;
1877 int anIntAngle = anRoundAngle + 0.5;
1878 anRoundAngle = (double) anIntAngle / 100000;
1879 aCurIdOfAngleAndDist.second.first = anRoundAngle;
1881 aCurIdOfAngleAndDist.second.second = pow( (*anIter2d).X() - aCurPoint.X(), 2.0 ) +
1882 pow( (*anIter2d).Y() - aCurPoint.Y(), 2.0 ) +
1883 pow( aPlane.Distance( gp_Pnt( theVector[i]._xyz[0], theVector[i]._xyz[1], theVector[i]._xyz[2] )), 2.0 );
1884 aListIdOfAngleAndDist.push_back( aCurIdOfAngleAndDist );
1886 aListIdOfAngleAndDist.sort( CompareNodeOfAngleAndDist );
1887 std::list<TNodeOfAngleAndDist>::iterator anIter = aListIdOfAngleAndDist.begin();
1888 std::list<TNodeOfAngleAndDist> aListResult;
1891 for(int i = 0 ; anIter != aListIdOfAngleAndDist.end(); anIter++, i++) {
1892 if ( anAngle == (*anIter).second.first && anAngle != 0 ) {
1896 if ( ( anAngle > (*anIter).second.first && anAngle != 0 ) || i > 1)
1898 if ( (*anIter).second.first > 0 )
1899 anAngle = (*anIter).second.first;
1902 anIter = aListIdOfAngleAndDist.begin();
1903 for( ; anIter != aListIdOfAngleAndDist.end(); anIter++) {
1904 if ( anAngle == (*anIter).second.first)
1905 aListResult.push_back( *anIter );
1906 else if ( anAngle < (*anIter).second.first)
1912 aListResult.sort(CompareNodeOfDist);
1913 anIter = aListIdOfAngleAndDist.begin();
1915 for( ; anIter != aListIdOfAngleAndDist.end(); anIter++) {
1916 if ( !isSort && anAngle == (*anIter).second.first ){
1917 for( std::list<TNodeOfAngleAndDist>::iterator anIter2 = aListResult.begin() ; anIter2 != aListResult.end(); anIter2++) {
1918 theVector.push_back((*anIter2).first);
1922 if ( isSort && anAngle != 0 && anAngle == (*anIter).second.first )
1924 theVector.push_back((*anIter).first);
1930 void GetCorrectSequenceTwoPlaneOfId( std::vector<SMESH_TNodeXYZ>& thePlane1, std::vector<SMESH_TNodeXYZ>& thePlane2, std::list<int>& theResultListId )
1932 int anIndex1, anIndex2, aShift = 0;
1934 std::pair<int, double> aShiftOfDist;
1935 int aSize = (int)thePlane1.size();
1936 aShiftOfDist.first = aShiftOfDist.second = 0;
1938 int anArr2[aSize - 3];
1939 for (int i = 0; i < 3 ; i++) {
1942 for (int i = 0; i < aSize - 3 ; i++) {
1945 std::vector<int> anIndexPlane1( anArr1, anArr1 + 3 );
1946 std::vector<int> anIndexPlane2( anArr2, anArr2 + aSize - 3);
1947 std::vector<int> anIndexCorrectPlane;
1948 std::vector<SMESH_TNodeXYZ> theNewPlane;
1949 std::vector<SMESH_TNodeXYZ> theCorrectPlane;
1951 GetCorrectSequenceOfId ( thePlane1 );
1954 anIndexCorrectPlane.clear();
1955 std::vector<SMESH_TNodeXYZ> theNewPlane;
1956 for (int i = 0; i < 3; i++) {
1957 anIndexCorrectPlane.push_back( anIndexPlane1[i] );
1959 for (int i = 0; i < aSize - 3; i++) {
1960 anIndexCorrectPlane.push_back( anIndexPlane2[i] );
1962 for (int i = 0; i < aSize; i++) {
1963 theNewPlane.push_back( thePlane2[anIndexCorrectPlane[i]] );
1966 if ( GetCorrectSequenceOfId ( theNewPlane ) )
1968 std::vector<double> aVectorSum;
1969 while ( aShift != 2 * aSize ) {
1972 ( aShift < aSize ) ? anIndex2 = 0 : anIndex2 = aSize - 1;
1973 while ( ( aShift < aSize && anIndex2 < aSize ) || ( aShift >= aSize && anIndex2 >= 0 ) ) {
1974 aCurSum += pow( thePlane1[anIndex1]._xyz[0] - theNewPlane[ ( anIndex2 + aShift ) % aSize ]._xyz[0], 2.0 ) +
1975 pow( thePlane1[anIndex1]._xyz[1] - theNewPlane[ ( anIndex2 + aShift ) % aSize ]._xyz[1], 2.0 ) +
1976 pow( thePlane1[anIndex1]._xyz[2] - theNewPlane[ ( anIndex2 + aShift ) % aSize ]._xyz[2], 2.0 );
1977 ( aShift < aSize ) ? anIndex2++ : anIndex2--;
1980 aVectorSum.push_back( aCurSum );
1983 double aCurSumMin = 0;
1984 std::pair<int, double> aCurShiftOfDist;
1985 aCurShiftOfDist.first = aCurShiftOfDist.second = 0;
1986 for ( int i = 0; i < (int)aVectorSum.size(); i++ ) {
1987 if ( aVectorSum[i] < aCurShiftOfDist.second || aCurShiftOfDist.second == 0 ) {
1988 aCurShiftOfDist.first = i;
1989 aCurShiftOfDist.second = aVectorSum[i];
1992 if ( aCurShiftOfDist.second <= aShiftOfDist.second || aShiftOfDist.second == 0){
1993 aShiftOfDist = aCurShiftOfDist;
1994 theCorrectPlane = theNewPlane;
1997 if ( !GetNextCombination( anIndexPlane1, anIndexPlane2, aSize) )
2000 thePlane2 = theCorrectPlane;
2001 aShift = aShiftOfDist.first;
2003 theResultListId.clear();
2004 ( aShift < aSize ) ? anIndex2 = 0 : anIndex2 = aSize - 1;
2005 while ( anIndex1 != aSize ) {
2006 theResultListId.push_back(thePlane1[anIndex1]._node->GetID());
2009 while ( ( aShift < aSize && anIndex2 < aSize ) || ( aShift >= aSize && anIndex2 >= 0 ) ) {
2010 theResultListId.push_back( thePlane2[( anIndex2 + aShift ) % aSize]._node->GetID() );
2011 ( aShift < aSize ) ? anIndex2++ : anIndex2--;
2015 void GetSortedNodesOnPolygon( std::vector<SMESH_TNodeXYZ>& theVectorOfNode, std::list<int>& theResultListId )
2017 GetCorrectSequenceOfId ( theVectorOfNode );
2018 for (int i = 0; i < theVectorOfNode.size(); i++) {
2019 theResultListId.push_back( theVectorOfNode[i]._node->GetID() );
2023 void GetSortedNodesOnPrism( std::vector<SMESH_TNodeXYZ>& theVectorOfNode, std::list<int>& theResultListId )
2025 int aSize = (int)theVectorOfNode.size();
2026 if ( aSize < 6 && aSize % 2 == 0)
2028 std::vector<SMESH_TNodeXYZ> aPlane1, aPlane2;
2029 if ( Get2BasePlane( theVectorOfNode, aPlane1, aPlane2 ) ) {
2030 GetCorrectSequenceTwoPlaneOfId( aPlane1, aPlane2, theResultListId);
2034 void GetSortedNodesOnPyramid( std::vector<SMESH_TNodeXYZ>& theVectorOfNode, std::list<int>& theResultListId )
2036 int aSize = (int)theVectorOfNode.size();
2040 bool isCreatePlane, isCorrectPlane;
2043 while ( aNumPlane != aSize ) {
2044 isCreatePlane = CreatePlaneOnThreePoints( gp_Pnt( theVectorOfNode[aNumPlane]._xyz[0], theVectorOfNode[aNumPlane]._xyz[1], theVectorOfNode[aNumPlane]._xyz[2] ),
2045 gp_Pnt( theVectorOfNode[(aNumPlane + 1) % aSize]._xyz[0], theVectorOfNode[(aNumPlane + 1) % aSize]._xyz[1], theVectorOfNode[(aNumPlane + 1) % aSize]._xyz[2] ),
2046 gp_Pnt( theVectorOfNode[(aNumPlane + 2) % aSize]._xyz[0], theVectorOfNode[(aNumPlane + 2) % aSize]._xyz[1], theVectorOfNode[(aNumPlane + 2) % aSize]._xyz[2] ), aPlane );
2047 isCorrectPlane = false;
2048 std::vector<SMESH_TNodeXYZ> aVectorOfPoint;
2049 if ( isCreatePlane ) {
2050 for(int j = 0; j < aSize - 3; j++) {
2051 aVectorOfPoint.push_back(theVectorOfNode[(aNumPlane + j + 3) % aSize]);
2053 isCorrectPlane = IsNotPlaneIntersection( aVectorOfPoint, aPlane );
2055 if ( !isCorrectPlane ) {
2059 std::vector<SMESH_TNodeXYZ> aVectorBaseOfPoint;
2060 std::list<TNodeOfDistToPlaneAndDist> aListBaseOfPoint;
2061 TNodeOfDistToPlaneAndDist aCurDistOfPlane;
2062 aListBaseOfPoint.clear();
2063 for (int i = 0; i < aSize; i++ ) {
2064 aCurDistOfPlane.second.first = aPlane.Distance( gp_Pnt( theVectorOfNode[i]._xyz[0], theVectorOfNode[i]._xyz[1], theVectorOfNode[i]._xyz[2] ));
2065 if ( aCurDistOfPlane.second.first == 0 )
2066 aCurDistOfPlane.second.second = 0;
2068 double aCurDist = 0;
2069 for (int j = 0; j < 3; j++) {
2070 aCurDist += pow( theVectorOfNode[(aNumPlane + j) % aSize]._xyz[0] - theVectorOfNode[i]._xyz[0], 2.0 ) +
2071 pow( theVectorOfNode[(aNumPlane + j) % aSize]._xyz[1] - theVectorOfNode[i]._xyz[1], 2.0 ) +
2072 pow( theVectorOfNode[(aNumPlane + j) % aSize]._xyz[2] - theVectorOfNode[i]._xyz[2], 2.0 );
2074 aCurDistOfPlane.second.second = aCurDist;
2076 aCurDistOfPlane.first = theVectorOfNode[i];
2077 aListBaseOfPoint.push_back( aCurDistOfPlane );
2079 aListBaseOfPoint.sort( CompareDistOfPlane );
2080 std::list<TNodeOfDistToPlaneAndDist>::iterator anIterDist = aListBaseOfPoint.begin();
2081 for (; anIterDist != aListBaseOfPoint.end(); anIterDist++ ) {
2082 aVectorBaseOfPoint.push_back((*anIterDist).first);
2084 SMESH_TNodeXYZ aTopNode = aVectorBaseOfPoint.back();
2085 aVectorBaseOfPoint.resize( aVectorBaseOfPoint.size() - 1);
2088 std::list<TNodeOfDist> aListBaseCorrect;
2089 for (int i = 0; i < aSize - 1; i++) {
2090 aCur = pow( aVectorBaseOfPoint[i]._xyz[0] - aTopNode._xyz[0], 2.0 ) +
2091 pow( aVectorBaseOfPoint[i]._xyz[1] - aTopNode._xyz[1], 2.0 ) +
2092 pow( aVectorBaseOfPoint[i]._xyz[2] - aTopNode._xyz[2], 2.0 );
2093 aListBaseCorrect.push_back(std::make_pair(aVectorBaseOfPoint[i], aCur) );
2095 bool isCorrectTop = true;
2096 for (int i = 0; i < aSize - 1; i++) {
2097 isCreatePlane = CreatePlaneOnThreePoints( gp_Pnt( aVectorBaseOfPoint[i]._xyz[0], aVectorBaseOfPoint[i]._xyz[1], aVectorBaseOfPoint[i]._xyz[2] ),
2098 gp_Pnt( aVectorBaseOfPoint[(i+1) % (aSize - 1)]._xyz[0], aVectorBaseOfPoint[(i+1) % (aSize - 1)]._xyz[1], aVectorBaseOfPoint[(i+1) % (aSize - 1)]._xyz[2] ),
2099 gp_Pnt( aVectorBaseOfPoint[(i+2) % (aSize - 1)]._xyz[0], aVectorBaseOfPoint[(i+2) % (aSize - 1)]._xyz[1], aVectorBaseOfPoint[(i+2) % (aSize - 1)]._xyz[2] ), aPlane );
2100 if ( isCreatePlane ) {
2101 aCur = aPlane.Distance( gp_Pnt( aTopNode._xyz[0], aTopNode._xyz[1], aTopNode._xyz[2] ));
2103 isCorrectTop = false;
2110 if ( ( isCorrectTop || aSum == 0 ) && ( aMax == 0 || aSum > aMax ) ) {
2111 aListBaseCorrect.sort(CompareDistForCorrectPlane);
2112 aVectorBaseOfPoint.clear();
2113 std::list<TNodeOfDist>::iterator anIter = aListBaseCorrect.begin();
2114 for ( ; anIter != aListBaseCorrect.end(); anIter++) {
2115 aVectorBaseOfPoint.push_back((*anIter).first);
2117 GetCorrectSequenceOfId( aVectorBaseOfPoint );
2119 theResultListId.clear();
2120 for (int i = 0; i < aVectorBaseOfPoint.size(); i++) {
2121 theResultListId.push_back( aVectorBaseOfPoint[i]._node->GetID() );
2123 theResultListId.push_back( aTopNode._node->GetID() );
2129 bool ComputeBounds( std::list<vtkActor*> theActorList,
2130 double theBounds[6])
2132 bool anIsOk = false;
2133 theBounds[0] = theBounds[2] = theBounds[4] = VTK_DOUBLE_MAX;
2134 theBounds[1] = theBounds[3] = theBounds[5] = -VTK_DOUBLE_MAX;
2135 std::list<vtkActor*>::iterator anIter = theActorList.begin();
2136 for( ; anIter != theActorList.end(); anIter++ ) {
2137 if( vtkActor* aVTKActor = *anIter ) {
2138 if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
2140 anActor->GetUnstructuredGrid()->GetBounds( aBounds );
2141 theBounds[0] = std::min( theBounds[0], aBounds[0] );
2142 theBounds[1] = std::max( theBounds[1], aBounds[1] );
2143 theBounds[2] = std::min( theBounds[2], aBounds[2] );
2144 theBounds[3] = std::max( theBounds[3], aBounds[3] );
2145 theBounds[4] = std::min( theBounds[4], aBounds[4] );
2146 theBounds[5] = std::max( theBounds[5], aBounds[5] );
2154 #ifndef DISABLE_PLOT2DVIEWER
2155 //================================================================================
2157 * \brief Find all SMESH_Actor's in the View Window.
2158 * If actor constains Plot2d_Histogram object remove it from each Plot2d Viewer.
2160 //================================================================================
2162 void ClearPlot2Viewers( SUIT_ViewWindow* theWindow ) {
2163 if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
2164 vtkRenderer *aRenderer = aViewWindow->getRenderer();
2165 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
2166 vtkActorCollection *aCollection = aCopy.GetActors();
2167 aCollection->InitTraversal();
2168 while(vtkActor *anAct = aCollection->GetNextActor()){
2169 if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
2170 if(anActor->hasIO() && anActor->GetPlot2Histogram() ){
2171 ProcessIn2DViewers(anActor,RemoveFrom2dViewer);
2180 } // end of namespace SMESH