comparison Samples/Common/RtViewer.h @ 1383:ab871499ed30

SingleFrameViewer: refactored file locations + names to share files for RtViewer
author Benjamin Golinvaux <bgo@osimis.io>
date Mon, 27 Apr 2020 10:01:03 +0200
parents
children dfb48f0794b1
comparison
equal deleted inserted replaced
1382:9d138883be66 1383:ab871499ed30
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21 #include <Framework/Viewport/SdlViewport.h>
22 #include <Framework/Loaders/GenericLoadersContext.h>
23 #include <Framework/Messages/IObserver.h>
24 #include <Framework/Messages/IMessageEmitter.h>
25 #include <Framework/Oracle/OracleCommandExceptionMessage.h>
26 #include <Framework/Scene2DViewport/ViewportController.h>
27 #include <Framework/Volumes/DicomVolumeImage.h>
28 #include <Framework/Oracle/ThreadedOracle.h>
29 #include <Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.h>
30 #include <Framework/Loaders/OrthancMultiframeVolumeLoader.h>
31 #include <Framework/Loaders/DicomStructureSetLoader.h>
32
33 #include <Framework/Messages/ObserverBase.h>
34
35 #include <boost/enable_shared_from_this.hpp>
36 #include <boost/thread.hpp>
37 #include <boost/noncopyable.hpp>
38
39 #include <SDL.h>
40
41 namespace OrthancStone
42 {
43 class OpenGLCompositor;
44 class IVolumeSlicer;
45 class ILayerStyleConfigurator;
46 class DicomStructureSetLoader;
47 class IOracle;
48 class ThreadedOracle;
49 class VolumeSceneLayerSource;
50 class SdlOpenGLViewport;
51
52 enum RtViewerGuiTool
53 {
54 RtViewerGuiTool_Rotate = 0,
55 RtViewerGuiTool_Pan,
56 RtViewerGuiTool_Zoom,
57 RtViewerGuiTool_LineMeasure,
58 RtViewerGuiTool_CircleMeasure,
59 RtViewerGuiTool_AngleMeasure,
60 RtViewerGuiTool_EllipseMeasure,
61 RtViewerGuiTool_LAST
62 };
63
64 const char* MeasureToolToString(size_t i);
65
66 static const unsigned int FONT_SIZE_0 = 32;
67 static const unsigned int FONT_SIZE_1 = 24;
68
69 class Scene2D;
70 class UndoStack;
71
72 /**
73 This application subclasses IMessageEmitter to use a mutex before forwarding Oracle messages (that
74 can be sent from multiple threads)
75 */
76 class RtViewerApp : public ObserverBase<RtViewerApp>
77 , public IMessageEmitter
78 {
79 public:
80
81
82 void PrepareScene();
83 void Run();
84 void SetInfoDisplayMessage(std::string key, std::string value);
85 void DisableTracker();
86
87 void HandleApplicationEvent(const SDL_Event& event);
88
89 /**
90 This method is called when the scene transform changes. It allows to
91 recompute the visual elements whose content depend upon the scene transform
92 */
93 void OnSceneTransformChanged(
94 const ViewportController::SceneTransformChanged& message);
95
96 /**
97 This method will ask the VolumeSceneLayerSource, that are responsible to
98 generated 2D content based on a volume and a cutting plane, to regenerate
99 it. This is required if the volume itself changes (during loading) or if
100 the cutting plane is changed
101 */
102 void UpdateLayers();
103
104 void Refresh();
105
106 virtual void EmitMessage(boost::weak_ptr<IObserver> observer,
107 const IMessage& message) ORTHANC_OVERRIDE
108 {
109 try
110 {
111 boost::unique_lock<boost::shared_mutex> lock(mutex_);
112 oracleObservable_.EmitMessage(observer, message);
113 }
114 catch (Orthanc::OrthancException& e)
115 {
116 LOG(ERROR) << "Exception while emitting a message: " << e.What();
117 throw;
118 }
119 }
120
121 static boost::shared_ptr<RtViewerApp> Create();
122 void RegisterMessages();
123
124 protected:
125 RtViewerApp();
126
127 private:
128 #if 1
129 // if threaded (not wasm)
130 IObservable oracleObservable_;
131 ThreadedOracle oracle_;
132 boost::shared_mutex mutex_; // to serialize messages from the ThreadedOracle
133 #endif
134
135 void SelectNextTool();
136
137 /**
138 This returns a random point in the canvas part of the scene, but in
139 scene coordinates
140 */
141 ScenePoint2D GetRandomPointInScene() const;
142
143 boost::shared_ptr<IFlexiblePointerTracker> TrackerHitTest(const PointerEvent& e);
144
145 boost::shared_ptr<IFlexiblePointerTracker> CreateSuitableTracker(
146 const SDL_Event& event,
147 const PointerEvent& e);
148
149 void TakeScreenshot(
150 const std::string& target,
151 unsigned int canvasWidth,
152 unsigned int canvasHeight);
153
154 /**
155 This adds the command at the top of the undo stack
156 */
157 //void Commit(boost::shared_ptr<TrackerCommand> cmd);
158 void Undo();
159 void Redo();
160
161
162 void Handle(const DicomVolumeImage::GeometryReadyMessage& message);
163 void Handle(const OracleCommandExceptionMessage& message);
164
165 // TODO: wire this
166 void HandleCTLoaded(const OrthancSeriesVolumeProgressiveLoader::VolumeImageReadyInHighQuality& message);
167 void HandleCTContentUpdated(const OrthancStone::DicomVolumeImage::ContentUpdatedMessage& message);
168 void HandleDoseLoaded(const OrthancStone::DicomVolumeImage::ContentUpdatedMessage& message);
169 void HandleStructuresReady(const OrthancStone::DicomStructureSetLoader::StructuresReady& message);
170 void HandleStructuresUpdated(const OrthancStone::DicomStructureSetLoader::StructuresUpdated& message);
171
172 void SetCtVolume(
173 int depth,
174 const boost::shared_ptr<IVolumeSlicer>& volume,
175 ILayerStyleConfigurator* style);
176
177 void SetDoseVolume(
178 int depth,
179 const boost::shared_ptr<IVolumeSlicer>& volume,
180 ILayerStyleConfigurator* style);
181
182 void SetStructureSet(
183 int depth,
184 const boost::shared_ptr<DicomStructureSetLoader>& volume);
185
186 private:
187 void DisplayFloatingCtrlInfoText(const PointerEvent& e);
188 void DisplayInfoText();
189 void HideInfoText();
190 void RetrieveGeometry();
191 void FitContent();
192
193 private:
194 boost::shared_ptr<GenericLoadersContext> loadersContext_;
195 boost::shared_ptr<VolumeSceneLayerSource> ctVolumeLayerSource_, doseVolumeLayerSource_, structLayerSource_;
196 boost::shared_ptr<OrthancStone::IGeometryProvider> geometryProvider_;
197 std::vector<OrthancStone::CoordinateSystem3D> planes_;
198 size_t currentPlane_;
199
200 VolumeProjection projection_;
201
202 std::map<std::string, std::string> infoTextMap_;
203 boost::shared_ptr<IFlexiblePointerTracker> activeTracker_;
204
205 static const int LAYER_POSITION = 150;
206
207 int TEXTURE_2x2_1_ZINDEX;
208 int TEXTURE_1x1_ZINDEX;
209 int TEXTURE_2x2_2_ZINDEX;
210 int LINESET_1_ZINDEX;
211 int LINESET_2_ZINDEX;
212 int FLOATING_INFOTEXT_LAYER_ZINDEX;
213 int FIXED_INFOTEXT_LAYER_ZINDEX;
214
215 RtViewerGuiTool currentTool_;
216 boost::shared_ptr<UndoStack> undoStack_;
217 boost::shared_ptr<SdlOpenGLViewport> viewport_;
218 };
219
220 }
221
222
223