Salome HOME
Update of CheckDone
[modules/smesh.git] / src / OBJECT / SMESH_PreviewActorsCollection.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, 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
48 SMESH_PreviewActorsCollection::SMESH_PreviewActorsCollection() :
49   mySelector( 0 ), myRenderer( 0 ), myCurrentChunk( 0 ), myChunkSize( 0 ), myIsShown( true )
50 {
51   MESSAGE("SMESH_PreviewActorsCollection - "<<this);
52 }
53
54
55 SMESH_PreviewActorsCollection::~SMESH_PreviewActorsCollection()
56 {
57   MESSAGE("~SMESH_PreviewActorsCollection - "<<this);
58   clearActors();
59 }
60
61 bool SMESH_PreviewActorsCollection::Init( const TopoDS_Shape& theShape,
62                                           const TopoDS_Shape& theMainShape,
63                                           TopAbs_ShapeEnum    theType,
64                                           const QString&      theEntry )
65 {
66   SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
67
68   myType =  theType;
69   myEntry = theEntry;
70   myMainShape = theShape;
71   myMapOfActors.clear();
72   myMapOfShapes.Clear();
73   myIndices.clear();
74   myCurrentChunk = 0;
75   myChunkSize = qMax(1, mgr->integerValue( "SMESH", "preview_actor_chunk_size", 100 ) );
76
77   if ( theShape.IsNull() )
78     return false;
79
80   // Handle( SALOME_InteractiveObject ) anIO = new SALOME_InteractiveObject();
81   // anIO->setEntry( theEntry.toUtf8().constData() );
82
83   // get indexes of selected elements
84   TopExp::MapShapes( theMainShape, myMapOfShapes );
85   TopExp_Explorer exp( theShape, theType );
86   QSet<int> indices;
87   for ( ; exp.More(); exp.Next() )
88     indices << myMapOfShapes.FindIndex( exp.Current() );
89   myIndices = indices.toList();
90   //qSort(myIndices);
91
92   // show current chunk
93   showCurrentChunk();
94
95   return count() > 0;
96 }
97
98 GEOM_Actor* SMESH_PreviewActorsCollection::createActor(const TopoDS_Shape& shape)
99 {
100   GEOM_Actor* actor = GEOM_Actor::New();
101   actor->SetShape( shape, 0, 0 );
102   return actor;
103 }
104
105 GEOM_Actor* SMESH_PreviewActorsCollection::GetActorByIndex(int index)
106 {
107   return myMapOfActors.value( index );
108 }
109
110 bool SMESH_PreviewActorsCollection::IsValidIndex( int index )
111 {
112   return 0 < index && index <= myMapOfShapes.Extent();
113 }
114
115 int SMESH_PreviewActorsCollection::GetIndexByShape( const TopoDS_Shape& theShape )
116 {
117   return myMapOfShapes.FindIndex( theShape );
118 }
119
120 TopoDS_Shape SMESH_PreviewActorsCollection::GetShapeByIndex( int index )
121 {
122   return IsValidIndex( index ) ? myMapOfShapes.FindKey( index ) : TopoDS_Shape();
123 }
124
125 int SMESH_PreviewActorsCollection::NbShapesOfType( TopAbs_ShapeEnum type )
126 {
127   if ( type == TopAbs_SHAPE ) return myMapOfShapes.Extent();
128
129   int nb = 0;
130   for ( int i = 1; i <= myMapOfShapes.Extent(); ++i )
131     nb += ( myMapOfShapes(i).ShapeType() == type );
132
133   return nb;
134 }
135
136 void SMESH_PreviewActorsCollection::SetIndices( const QList<int>& indices)
137 {
138   if ( myIndices != indices )
139   {
140     myIndices = indices;
141     showCurrentChunk();
142   }
143 }
144
145 void SMESH_PreviewActorsCollection::AddToRender(vtkRenderer* theRenderer)
146 {
147   myRenderer = theRenderer;
148
149   QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
150   for ( ; iter != myMapOfActors.end(); ++iter ) {
151     iter.value()->SetVisibility( myIsShown );
152     iter.value()->AddToRender( theRenderer );
153   }
154 }
155
156 void SMESH_PreviewActorsCollection::RemoveFromRender(vtkRenderer* theRenderer)
157 {
158   QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
159   for ( ; iter != myMapOfActors.end(); ++iter )
160     iter.value()->RemoveFromRender( theRenderer );
161 }
162
163 void SMESH_PreviewActorsCollection::SetSelector(SVTK_Selector* theSelector)
164 {
165   mySelector = theSelector;
166 }
167
168 void SMESH_PreviewActorsCollection::HighlightAll( bool theHighlight )
169 {
170   QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
171   for ( ; iter != myMapOfActors.end(); ++iter )
172     iter.value()->Highlight( theHighlight );
173 }
174
175 void SMESH_PreviewActorsCollection::HighlightID( int index )
176 {
177   GEOM_Actor* anActor = GetActorByIndex( index );
178   if ( anActor && !anActor->isHighlighted() )
179     anActor->Highlight( true );
180 }
181
182 void SMESH_PreviewActorsCollection::SetShown( bool shown )
183 {
184   myIsShown = shown;
185   QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
186   for ( ; iter != myMapOfActors.end(); ++iter )
187     iter.value()->SetVisibility( shown );
188 }
189
190 int SMESH_PreviewActorsCollection::count() const
191 {
192   return myIndices.count();
193 }
194
195 int SMESH_PreviewActorsCollection::chunkSize() const
196 {
197   return myChunkSize;
198 }
199
200 int SMESH_PreviewActorsCollection::currentChunk() const
201 {
202   return myCurrentChunk;
203 }
204
205 bool SMESH_PreviewActorsCollection::hasPrevious() const
206 {
207   return chunkSize() > 0 && currentChunk() > 0;
208 }
209
210 bool SMESH_PreviewActorsCollection::hasNext() const
211 {
212   return chunkSize() > 0 && (currentChunk()+1)*chunkSize() < count();
213 }
214
215 void SMESH_PreviewActorsCollection::previous()
216 {
217   if ( !hasPrevious() ) return;
218   myCurrentChunk--;
219   showCurrentChunk();
220 }
221
222 void SMESH_PreviewActorsCollection::next()
223 {
224   if ( !hasNext() ) return;
225   myCurrentChunk++;
226   showCurrentChunk();
227 }
228
229 void SMESH_PreviewActorsCollection::showCurrentChunk()
230 {
231   clearActors();
232   int imin = currentChunk() * chunkSize();
233   int imax = std::min( (currentChunk()+1) * chunkSize(), count() );
234   for ( int i = imin; i < imax; i++ ) {
235     int index = myIndices[i];
236     if ( !index || myMapOfActors.contains( index ) ) continue;
237     TopoDS_Shape s = myMapOfShapes.FindKey( index );
238     if ( s.IsNull() ) continue;
239     // create actor if the index is present
240     if ( GEOM_Actor* anActor = createActor( s.Oriented(TopAbs_FORWARD))) {
241       // Create new entry for actor
242       QString entry = QString( "%1_%2" ).arg( myEntry ).arg( index );
243       // Create interactive object
244       Handle( SALOME_InteractiveObject ) anIO = new SALOME_InteractiveObject();
245       anIO->setEntry( entry.toUtf8().constData() );
246       // Init Actor
247       anActor->SetVectorMode( myType==TopAbs_EDGE );
248       anActor->setIO( anIO );
249       anActor->SetSelector( mySelector );
250       anActor->SetPickable( true );
251       anActor->SetResolveCoincidentTopology( true );
252
253       // Add Actor to the Actors Map
254       myMapOfActors.insert(index, anActor);
255     }
256   }
257   if ( mySelector )
258     mySelector->ClearIObjects();
259   if ( myRenderer )
260     AddToRender( myRenderer );
261 }
262
263 void SMESH_PreviewActorsCollection::clearActors()
264 {
265   if (myRenderer)
266     RemoveFromRender(myRenderer);
267
268   QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
269   for ( ; iter != myMapOfActors.end(); ++iter )
270     if ( GEOM_Actor* anActor = iter.value() )
271       anActor->Delete();
272   myMapOfActors.clear();
273 }