comparison Framework/Layers/DicomStructureSetRendererFactory.cpp @ 123:ed0003f6102c wasm

dynamic loading of rt-struct renderers
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 07 Oct 2017 13:11:12 +0200
parents e3433dabfb8d
children 44fc253d4876
comparison
equal deleted inserted replaced
122:e3433dabfb8d 123:ed0003f6102c
19 **/ 19 **/
20 20
21 21
22 #include "DicomStructureSetRendererFactory.h" 22 #include "DicomStructureSetRendererFactory.h"
23 23
24 #include "../Toolbox/MessagingToolbox.h"
25
24 #include <Core/OrthancException.h> 26 #include <Core/OrthancException.h>
25 27
26 namespace OrthancStone 28 namespace OrthancStone
27 { 29 {
28 class DicomStructureSetRendererFactory::Renderer : public ILayerRenderer 30 class DicomStructureSetRendererFactory::Renderer : public ILayerRenderer
68 return true; 70 return true;
69 } 71 }
70 }; 72 };
71 73
72 74
75 class DicomStructureSetRendererFactory::Operation : public Orthanc::IDynamicObject
76 {
77 public:
78 enum Type
79 {
80 Type_LoadStructureSet,
81 Type_LookupSopInstanceUid,
82 Type_LoadReferencedSlice
83 };
84
85 private:
86 Type type_;
87 std::string value_;
88
89 public:
90 Operation(Type type,
91 const std::string& value) :
92 type_(type),
93 value_(value)
94 {
95 }
96
97 Type GetType() const
98 {
99 return type_;
100 }
101
102 const std::string& GetIdentifier() const
103 {
104 return value_;
105 }
106 };
107
108
109 void DicomStructureSetRendererFactory::NotifyError(const std::string& uri,
110 Orthanc::IDynamicObject* payload)
111 {
112 // TODO
113 }
114
115
116 void DicomStructureSetRendererFactory::NotifySuccess(const std::string& uri,
117 const void* answer,
118 size_t answerSize,
119 Orthanc::IDynamicObject* payload)
120 {
121 std::auto_ptr<Operation> op(dynamic_cast<Operation*>(payload));
122
123 switch (op->GetType())
124 {
125 case Operation::Type_LoadStructureSet:
126 {
127 OrthancPlugins::FullOrthancDataset dataset(answer, answerSize);
128 structureSet_.reset(new DicomStructureSet(dataset));
129
130 std::set<std::string> instances;
131 structureSet_->GetReferencedInstances(instances);
132
133 for (std::set<std::string>::const_iterator it = instances.begin();
134 it != instances.end(); ++it)
135 {
136 orthanc_.SchedulePostRequest(*this, "/tools/lookup", *it,
137 new Operation(Operation::Type_LookupSopInstanceUid, *it));
138 }
139
140 break;
141 }
142
143 case Operation::Type_LookupSopInstanceUid:
144 {
145 Json::Value lookup;
146
147 if (MessagingToolbox::ParseJson(lookup, answer, answerSize))
148 {
149 if (lookup.type() != Json::arrayValue ||
150 lookup.size() != 1 ||
151 !lookup[0].isMember("Type") ||
152 !lookup[0].isMember("Path") ||
153 lookup[0]["Type"].type() != Json::stringValue ||
154 lookup[0]["ID"].type() != Json::stringValue ||
155 lookup[0]["Type"].asString() != "Instance")
156 {
157 throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
158 }
159
160 const std::string& instance = lookup[0]["ID"].asString();
161 orthanc_.ScheduleGetRequest(*this, "/instances/" + instance + "/tags",
162 new Operation(Operation::Type_LoadReferencedSlice, instance));
163 }
164 else
165 {
166 // TODO
167 }
168
169 break;
170 }
171
172 case Operation::Type_LoadReferencedSlice:
173 {
174 OrthancPlugins::FullOrthancDataset dataset(answer, answerSize);
175
176 Orthanc::DicomMap slice;
177 MessagingToolbox::ConvertDataset(slice, dataset);
178 structureSet_->AddReferencedSlice(slice);
179
180 LayerSourceBase::NotifyContentChange();
181
182 break;
183 }
184
185 default:
186 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
187 }
188 }
189
190
191 DicomStructureSetRendererFactory::DicomStructureSetRendererFactory(IWebService& orthanc,
192 const std::string& instance) :
193 orthanc_(orthanc)
194 {
195 const std::string uri = "/instances/" + instance + "/tags?ignore-length=3006-0050";
196 orthanc_.ScheduleGetRequest(*this, uri, new Operation(Operation::Type_LoadStructureSet, instance));
197 }
198
199
73 void DicomStructureSetRendererFactory::ScheduleLayerCreation(const CoordinateSystem3D& viewportSlice) 200 void DicomStructureSetRendererFactory::ScheduleLayerCreation(const CoordinateSystem3D& viewportSlice)
74 { 201 {
75 bool isOpposite; 202 bool isOpposite;
76 if (GeometryToolbox::IsParallelOrOpposite(isOpposite, viewportSlice.GetNormal(), structureSet_.GetNormal())) 203 if (structureSet_.get() != NULL &&
77 { 204 GeometryToolbox::IsParallelOrOpposite(isOpposite,
78 NotifyLayerReady(new Renderer(structureSet_, viewportSlice), viewportSlice, false); 205 viewportSlice.GetNormal(),
206 structureSet_->GetNormal()))
207 {
208 NotifyLayerReady(new Renderer(*structureSet_, viewportSlice), viewportSlice, false);
79 } 209 }
80 } 210 }
81 } 211 }