Salome HOME
Copyright update 2020
[modules/smesh.git] / src / OBJECT / SMESH_PreviewActorsCollection.cxx
1 // Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "SMESH_PreviewActorsCollection.h"
21
22 #include <utilities.h>
23
24 // OCC includes
25 #include <TopoDS.hxx>
26 #include <TopExp.hxx>
27 #include <TopExp_Explorer.hxx>
28
29 // VTK includes
30 #include <vtkUnstructuredGrid.h>
31 #include <vtkPlane.h>
32 #include <vtkRenderer.h>
33 #include <vtkProperty.h>
34
35 #include <QSet>
36
37 // GEOM includes
38 #include <GEOM_Actor.h>
39
40 // GUI includes
41 #include <VTKViewer_Actor.h>
42 #include <SVTK_DeviceActor.h>
43 #include <SALOME_InteractiveObject.hxx>
44 #include <SUIT_ResourceMgr.h>
45 #include <SUIT_Session.h>
46
47 #ifdef _DEBUG_
48 static int MYDEBUG = 0;
49 #else
50 static int MYDEBUG = 0;
51 #endif
52
53
54 SMESH_PreviewActorsCollection::SMESH_PreviewActorsCollection() :
55   mySelector( 0 ), myRenderer( 0 ), myCurrentChunk( 0 ), myChunkSize( 0 ), myIsShown( true )
56 {
57   if(MYDEBUG) MESSAGE("SMESH_PreviewActorsCollection - "<<this);
58 }
59
60
61 SMESH_PreviewActorsCollection::~SMESH_PreviewActorsCollection()
62 {
63   if(MYDEBUG) MESSAGE("~SMESH_PreviewActorsCollection - "<<this);
64   clearActors();
65 }
66
67 bool SMESH_PreviewActorsCollection::Init( const TopoDS_Shape& theShape,
68                                           const TopoDS_Shape& theMainShape,
69                                           TopAbs_ShapeEnum    theType,
70                                           const QString&      theEntry )
71 {
72   SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
73
74   myType =  theType;
75   myEntry = theEntry;
76   myMainShape = theShape;
77   myMapOfActors.clear();
78   myMapOfShapes.Clear();
79   myIndices.clear();
80   myCurrentChunk = 0;
81   myChunkSize = qMax(1, mgr->integerValue( "SMESH", "preview_actor_chunk_size", 100 ) );
82
83   if ( theShape.IsNull() )
84     return false;
85
86   // Handle( SALOME_InteractiveObject ) anIO = new SALOME_InteractiveObject();
87   // anIO->setEntry( theEntry.toUtf8().constData() );
88
89   // get indexes of selected elements
90   TopExp::MapShapes( theMainShape, myMapOfShapes );
91   TopExp_Explorer exp( theShape, theType );
92   QSet<int> indices;
93   for ( ; exp.More(); exp.Next() )
94     indices << myMapOfShapes.FindIndex( exp.Current() );
95   myIndices = indices.toList();
96   //qSort(myIndices);
97
98   // show current chunk
99   showCurrentChunk();
100
101   return count() > 0;
102 }
103
104 GEOM_Actor* SMESH_PreviewActorsCollection::createActor(const TopoDS_Shape& shape)
105 {
106   GEOM_Actor* actor = GEOM_Actor::New();
107   actor->SetShape( shape, 0, 0 );
108   return actor;
109 }
110
111 GEOM_Actor* SMESH_PreviewActorsCollection::GetActorByIndex(int index)
112 {
113   return myMapOfActors.value( index );
114 }
115
116 bool SMESH_PreviewActorsCollection::IsValidIndex( int index )
117 {
118   return 0 < index && index <= myMapOfShapes.Extent();
119 }
120
121 int SMESH_PreviewActorsCollection::GetIndexByShape( const TopoDS_Shape& theShape )
122 {
123   return myMapOfShapes.FindIndex( theShape );
124 }
125
126 TopoDS_Shape SMESH_PreviewActorsCollection::GetShapeByIndex( int index )
127 {
128   return IsValidIndex( index ) ? myMapOfShapes.FindKey( index ) : TopoDS_Shape();
129 }
130
131 int SMESH_PreviewActorsCollection::NbShapesOfType( TopAbs_ShapeEnum type )
132 {
133   if ( type == TopAbs_SHAPE ) return myMapOfShapes.Extent();
134
135   int nb = 0;
136   for ( int i = 1; i <= myMapOfShapes.Extent(); ++i )
137     nb += ( myMapOfShapes(i).ShapeType() == type );
138
139   return nb;
140 }
141
142 void SMESH_PreviewActorsCollection::SetIndices( const QList<int>& indices)
143 {
144   if ( myIndices != indices )
145   {
146     myIndices = indices;
147     showCurrentChunk();
148   }
149 }
150
151 void SMESH_PreviewActorsCollection::AddToRender(vtkRenderer* theRenderer)
152 {
153   myRenderer = theRenderer;
154
155   QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
156   for ( ; iter != myMapOfActors.end(); ++iter ) {
157     iter.value()->SetVisibility( myIsShown );
158     iter.value()->AddToRender( theRenderer );
159   }
160 }
161
162 void SMESH_PreviewActorsCollection::RemoveFromRender(vtkRenderer* theRenderer)
163 {
164   QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
165   for ( ; iter != myMapOfActors.end(); ++iter )
166     iter.value()->RemoveFromRender( theRenderer );
167 }
168
169 void SMESH_PreviewActorsCollection::SetSelector(SVTK_Selector* theSelector)
170 {
171   mySelector = theSelector;
172 }
173
174 void SMESH_PreviewActorsCollection::HighlightAll( bool theHighlight )
175 {
176   QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
177   for ( ; iter != myMapOfActors.end(); ++iter )
178     iter.value()->Highlight( theHighlight );
179 }
180
181 void SMESH_PreviewActorsCollection::HighlightID( int index )
182 {
183   GEOM_Actor* anActor = GetActorByIndex( index );
184   if ( anActor && !anActor->isHighlighted() )
185     anActor->Highlight( true );
186 }
187
188 void SMESH_PreviewActorsCollection::SetShown( bool shown )
189 {
190   myIsShown = shown;
191   QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
192   for ( ; iter != myMapOfActors.end(); ++iter )
193     iter.value()->SetVisibility( shown );
194 }
195
196 int SMESH_PreviewActorsCollection::count() const
197 {
198   return myIndices.count();
199 }
200
201 int SMESH_PreviewActorsCollection::chunkSize() const
202 {
203   return myChunkSize;
204 }
205
206 int SMESH_PreviewActorsCollection::currentChunk() const
207 {
208   return myCurrentChunk;
209 }
210
211 bool SMESH_PreviewActorsCollection::hasPrevious() const
212 {
213   return chunkSize() > 0 && currentChunk() > 0;
214 }
215
216 bool SMESH_PreviewActorsCollection::hasNext() const
217 {
218   return chunkSize() > 0 && (currentChunk()+1)*chunkSize() < count();
219 }
220
221 void SMESH_PreviewActorsCollection::previous()
222 {
223   if ( !hasPrevious() ) return;
224   myCurrentChunk--;
225   showCurrentChunk();
226 }
227
228 void SMESH_PreviewActorsCollection::next()
229 {
230   if ( !hasNext() ) return;
231   myCurrentChunk++;
232   showCurrentChunk();
233 }
234
235 void SMESH_PreviewActorsCollection::showCurrentChunk()
236 {
237   clearActors();
238   int imin = currentChunk() * chunkSize();
239   int imax = std::min( (currentChunk()+1) * chunkSize(), count() );
240   for ( int i = imin; i < imax; i++ ) {
241     int index = myIndices[i];
242     if ( !index || myMapOfActors.contains( index ) ) continue;
243     TopoDS_Shape s = myMapOfShapes.FindKey( index );
244     if ( s.IsNull() ) continue;
245     // create actor if the index is present
246     if ( GEOM_Actor* anActor = createActor( s.Oriented(TopAbs_FORWARD))) {
247       // Create new entry for actor
248       QString entry = QString( "%1_%2" ).arg( myEntry ).arg( index );
249       // Create interactive object
250       Handle( SALOME_InteractiveObject ) anIO = new SALOME_InteractiveObject();
251       anIO->setEntry( entry.toUtf8().constData() );
252       // Init Actor
253       anActor->SetVectorMode( myType==TopAbs_EDGE );
254       anActor->setIO( anIO );
255       anActor->SetSelector( mySelector );
256       anActor->SetPickable( true );
257       anActor->SetResolveCoincidentTopology( true );
258
259       // Add Actor to the Actors Map
260       myMapOfActors.insert(index, anActor);
261     }
262   }
263   if ( mySelector )
264     mySelector->ClearIObjects();
265   if ( myRenderer )
266     AddToRender( myRenderer );
267 }
268
269 void SMESH_PreviewActorsCollection::clearActors()
270 {
271   if (myRenderer)
272     RemoveFromRender(myRenderer);
273
274   QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
275   for ( ; iter != myMapOfActors.end(); ++iter )
276     if ( GEOM_Actor* anActor = iter.value() )
277       anActor->Delete();
278   myMapOfActors.clear();
279 }