comparison Samples/Sdl/RtViewer/RtViewerSdl.cpp @ 1393:27e0a00bd3e8

RtViewer SingleFrameViewer OK : wasm SDL single viewport other viewports ongoing
author Benjamin Golinvaux <bgo@osimis.io>
date Wed, 29 Apr 2020 15:54:18 +0200
parents ffdb82850e98
children 3e644f6fadd4
comparison
equal deleted inserted replaced
1392:ffdb82850e98 1393:27e0a00bd3e8
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/ 19 **/
20 20
21 #include "RtViewer.h" 21 #include "RtViewer.h"
22 #include "../SdlHelpers.h" 22 #include "../SdlHelpers.h"
23 #include "SampleHelpers.h" 23
24 24 // Stone of Orthanc includes
25 #include <Framework/Loaders/GenericLoadersContext.h>
26 #include <Framework/OpenGL/SdlOpenGLContext.h>
25 #include <Framework/StoneException.h> 27 #include <Framework/StoneException.h>
26 #include <Framework/StoneInitialization.h> 28 #include <Framework/StoneInitialization.h>
27 29
28 #include <Framework/OpenGL/SdlOpenGLContext.h> 30 // Orthanc (a.o. for screenshot capture)
31 #include <Core/Images/Image.h>
32 #include <Core/Images/ImageProcessing.h>
33 #include <Core/Images/PngWriter.h>
34
29 35
30 #include <boost/program_options.hpp> 36 #include <boost/program_options.hpp>
37 #include <boost/shared_ptr.hpp>
38
39 // #include <boost/pointer_cast.hpp> this include might be necessary in more recent boost versions
40
31 #include <SDL.h> 41 #include <SDL.h>
32 42
33 #include <string> 43 #include <string>
34 44
35 static void GLAPIENTRY 45 static void GLAPIENTRY
49 } 59 }
50 } 60 }
51 61
52 namespace OrthancStone 62 namespace OrthancStone
53 { 63 {
64 void RtViewerApp::CreateViewport()
65 {
66 // False means we do NOT let Windows treat this as a legacy application that needs to be scaled
67 viewport_ = SdlOpenGLViewport::Create("CT RTDOSE RTSTRUCT viewer", 1024, 1024, false);
68 }
69
54 void RtViewerApp::ProcessOptions(int argc, char* argv[]) 70 void RtViewerApp::ProcessOptions(int argc, char* argv[])
55 { 71 {
56 namespace po = boost::program_options; 72 namespace po = boost::program_options;
57 po::options_description desc("Usage:"); 73 po::options_description desc("Usage:");
58 74
82 catch (std::exception& e) 98 catch (std::exception& e)
83 { 99 {
84 std::cerr << "Please check your command line options! (\"" << e.what() << "\")" << std::endl; 100 std::cerr << "Please check your command line options! (\"" << e.what() << "\")" << std::endl;
85 } 101 }
86 102
87 if (vm.count("loglevel") > 0) 103 for (po::variables_map::iterator it = vm.begin(); it != vm.end(); ++it)
88 { 104 {
89 std::string logLevel = vm["loglevel"].as<std::string>(); 105 std::string key = it->first;
90 OrthancStoneHelpers::SetLogLevel(logLevel); 106 const po::variable_value& value = it->second;
91 } 107 const std::string& strValue = value.as<std::string>();
92 108 SetArgument(key, strValue);
93 if (vm.count("orthanc") > 0)
94 {
95 // maybe check URL validity here
96 orthancUrl_ = vm["orthanc"].as<std::string>();
97 }
98
99 if (vm.count("ctseries") > 0)
100 {
101 ctSeriesId_ = vm["ctseries"].as<std::string>();
102 }
103
104 if (vm.count("rtdose") > 0)
105 {
106 doseInstanceId_ = vm["rtdose"].as<std::string>();
107 }
108
109 if (vm.count("rtstruct") > 0)
110 {
111 rtStructInstanceId_ = vm["rtstruct"].as<std::string>();
112 } 109 }
113 } 110 }
114 111
115 void RtViewerApp::RunSdl(int argc, char* argv[]) 112 void RtViewerApp::RunSdl(int argc, char* argv[])
116 { 113 {
137 134
138 /** 135 /**
139 Create the shared loaders context 136 Create the shared loaders context
140 */ 137 */
141 loadersContext_.reset(new GenericLoadersContext(1, 4, 1)); 138 loadersContext_.reset(new GenericLoadersContext(1, 4, 1));
142 loadersContext_->StartOracle(); 139
140 // we are in SDL --> downcast to concrete type
141 boost::shared_ptr<GenericLoadersContext> loadersContext = boost::dynamic_pointer_cast<GenericLoadersContext>(loadersContext_);
142
143 /**
144 Url of the Orthanc instance
145 Typically, in a native application (Qt, SDL), it will be an absolute URL like "http://localhost:8042". In
146 wasm on the browser, it could be an absolute URL, provided you do not have cross-origin problems, or a relative
147 URL. In our wasm samples, it is set to "..", because we set up either a reverse proxy or an Orthanc ServeFolders
148 plugin that serves the main web application from an URL like "http://localhost:8042/rtviewer" (with ".." leading
149 to the main Orthanc root URL)
150 */
151 std::string orthancUrl = arguments_["orthanc"];
152
153 {
154 Orthanc::WebServiceParameters p;
155 if (HasArgument("orthanc"))
156 {
157 p.SetUrl(orthancUrl);
158 }
159 if (HasArgument("user"))
160 {
161 ORTHANC_ASSERT(HasArgument("password"));
162 p.SetCredentials(GetArgument("user"), GetArgument("password"));
163 }
164 else
165 {
166 ORTHANC_ASSERT(!HasArgument("password"));
167 }
168 loadersContext->SetOrthancParameters(p);
169 }
170
171 loadersContext->StartOracle();
143 172
144 /** 173 /**
145 It is very important that the Oracle (responsible for network I/O) be started before creating and firing the 174 It is very important that the Oracle (responsible for network I/O) be started before creating and firing the
146 loaders, for any command scheduled by the loader before the oracle is started will be lost. 175 loaders, for any command scheduled by the loader before the oracle is started will be lost.
147 */ 176 */
148 PrepareLoadersAndSlicers(); 177 PrepareLoadersAndSlicers();
149 178
150 OrthancStone::DefaultViewportInteractor interactor; 179 DefaultViewportInteractor interactor;
151 180
152 OrthancStoneHelpers::SdlRunLoop(viewport_, interactor); 181 boost::shared_ptr<SdlViewport> viewport = boost::dynamic_pointer_cast<SdlViewport>(viewport_);
153 182
154 loadersContext_->StopOracle(); 183 OrthancStoneHelpers::SdlRunLoop(viewport, interactor);
155 } 184
185 loadersContext->StopOracle();
186 }
187
188 void RtViewerApp::TakeScreenshot(const std::string& target,
189 unsigned int canvasWidth,
190 unsigned int canvasHeight)
191 {
192 std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
193 ViewportController& controller = lock->GetController();
194 Scene2D& scene = controller.GetScene();
195
196 CairoCompositor compositor(canvasWidth, canvasHeight);
197 compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE_0, Orthanc::Encoding_Latin1);
198 compositor.Refresh(scene);
199
200 Orthanc::ImageAccessor canvas;
201 compositor.GetCanvas().GetReadOnlyAccessor(canvas);
202
203 Orthanc::Image png(Orthanc::PixelFormat_RGB24, canvas.GetWidth(), canvas.GetHeight(), false);
204 Orthanc::ImageProcessing::Convert(png, canvas);
205
206 Orthanc::PngWriter writer;
207 writer.WriteToFile(target, png);
208 }
209
156 210
157 #if 0 211 #if 0
158 void RtViewerApp::HandleApplicationEvent( 212 void RtViewerApp::HandleApplicationEvent(
159 const SDL_Event& event) 213 const SDL_Event& event)
160 { 214 {