Mercurial > hg > orthanc-stl
comparison Sources/Plugin.cpp @ 50:bf4c4e4e7198 nexus
added route /stl/create-nexus
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 17 May 2024 17:16:07 +0200 |
parents | a70fc4846be1 |
children | 40a093f90be6 |
comparison
equal
deleted
inserted
replaced
49:0a408a81fb15 | 50:bf4c4e4e7198 |
---|---|
51 #endif | 51 #endif |
52 | 52 |
53 #define ORTHANC_PLUGIN_NAME "stl" | 53 #define ORTHANC_PLUGIN_NAME "stl" |
54 | 54 |
55 | 55 |
56 #if ORTHANC_ENABLE_NEXUS == 1 | |
57 static const char* const ORTHANC_STL_PRIVATE_CREATOR = "OrthancSTL"; | |
58 static const char* const ORTHANC_STL_MANUFACTURER = "ORTHANC^STL"; | |
59 static const uint16_t ORTHANC_STL_PRIVATE_GROUP = 0x4205u; | |
60 static const uint16_t ORTHANC_STL_CREATOR_ELEMENT = 0x0010u; | |
61 static const uint16_t ORTHANC_STL_NEXUS_ELEMENT = 0x1001u; | |
62 static const Orthanc::DicomTag DICOM_TAG_CREATOR_VERSION_UID(0x0008, 0x9123); | |
63 #endif | |
64 | |
65 | |
56 // Forward declaration | 66 // Forward declaration |
57 void ReadStaticAsset(std::string& target, | 67 void ReadStaticAsset(std::string& target, |
58 const std::string& path); | 68 const std::string& path); |
59 | 69 |
60 | 70 |
118 } | 128 } |
119 }; | 129 }; |
120 | 130 |
121 | 131 |
122 static ResourcesCache cache_; | 132 static ResourcesCache cache_; |
123 static bool hasCreateDicomStl_; | |
124 | 133 |
125 void ServeFile(OrthancPluginRestOutput* output, | 134 void ServeFile(OrthancPluginRestOutput* output, |
126 const char* url, | 135 const char* url, |
127 const OrthancPluginHttpRequest* request) | 136 const OrthancPluginHttpRequest* request) |
128 { | 137 { |
876 OrthancPluginSetHttpHeader(context, output, "Content-Type", "application/octet-stream"); | 885 OrthancPluginSetHttpHeader(context, output, "Content-Type", "application/octet-stream"); |
877 | 886 |
878 OrthancPluginSendHttpStatus(context, output, 206 /* partial content */, part.c_str(), part.size()); | 887 OrthancPluginSendHttpStatus(context, output, 206 /* partial content */, part.c_str(), part.size()); |
879 } | 888 } |
880 | 889 |
890 | |
891 static const char* GetCreatorVersionUid(const std::string& version) | |
892 { | |
893 /** | |
894 * Each version of the STL plugin must provide a different value for | |
895 * the CreatorVersionUID (0008,9123) tag. A new UID can be generated | |
896 * by typing: | |
897 * | |
898 * $ python -c 'import pydicom; print(pydicom.uid.generate_uid())' | |
899 * | |
900 **/ | |
901 | |
902 if (version == "mainline") | |
903 { | |
904 return "1.2.826.0.1.3680043.8.498.90514926286349109728701975613711986292"; | |
905 } | |
906 else | |
907 { | |
908 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
909 } | |
910 } | |
911 | |
912 | |
913 void DicomizeNexusModel(OrthancPluginRestOutput* output, | |
914 const char* url, | |
915 const OrthancPluginHttpRequest* request) | |
916 { | |
917 static const char* KEY_CONTENT = "Content"; | |
918 static const char* KEY_PARENT = "Parent"; | |
919 static const char* KEY_TAGS = "Tags"; | |
920 static const char* KEY_PRIVATE_CREATOR = "PrivateCreator"; | |
921 | |
922 OrthancPluginContext* context = OrthancPlugins::GetGlobalContext(); | |
923 | |
924 if (request->method != OrthancPluginHttpMethod_Post) | |
925 { | |
926 OrthancPluginSendMethodNotAllowed(context, output, "POST"); | |
927 return; | |
928 } | |
929 | |
930 Json::Value body; | |
931 if (!Orthanc::Toolbox::ReadJson(body, request->body, request->bodySize) || | |
932 body.type() != Json::objectValue || | |
933 !body.isMember(KEY_TAGS) || | |
934 body[KEY_TAGS].type() != Json::objectValue) | |
935 { | |
936 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest); | |
937 } | |
938 | |
939 if (!body.isMember(KEY_CONTENT) || | |
940 body[KEY_CONTENT].type() != Json::stringValue) | |
941 { | |
942 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, | |
943 "POST body missing string field \"" + std::string(KEY_CONTENT) + "\""); | |
944 } | |
945 | |
946 std::string nexus; | |
947 Orthanc::Toolbox::DecodeBase64(nexus, body[KEY_CONTENT].asString()); | |
948 | |
949 std::string raw; | |
950 Orthanc::Toolbox::EncodeDataUriScheme(raw, "application/octet-stream", nexus); | |
951 | |
952 Json::Value creationBody = Json::objectValue; | |
953 | |
954 creationBody[KEY_TAGS] = body[KEY_TAGS]; | |
955 creationBody[KEY_TAGS][Orthanc::DICOM_TAG_MANUFACTURER.Format()] = ORTHANC_STL_MANUFACTURER; | |
956 creationBody[KEY_TAGS][Orthanc::DICOM_TAG_SOP_CLASS_UID.Format()] = "1.2.840.10008.5.1.4.1.1.66"; | |
957 creationBody[KEY_TAGS][Orthanc::DICOM_TAG_MODALITY.Format()] = "OT"; | |
958 creationBody[KEY_TAGS][DICOM_TAG_CREATOR_VERSION_UID.Format()] = GetCreatorVersionUid(ORTHANC_STL_VERSION); | |
959 creationBody[KEY_TAGS][Orthanc::DicomTag(ORTHANC_STL_PRIVATE_GROUP, ORTHANC_STL_CREATOR_ELEMENT).Format()] = ORTHANC_STL_PRIVATE_CREATOR; | |
960 creationBody[KEY_TAGS][Orthanc::DicomTag(ORTHANC_STL_PRIVATE_GROUP, ORTHANC_STL_NEXUS_ELEMENT).Format()] = raw; | |
961 creationBody[KEY_PRIVATE_CREATOR] = ORTHANC_STL_PRIVATE_CREATOR; | |
962 | |
963 if (body.isMember(KEY_PARENT)) | |
964 { | |
965 creationBody[KEY_PARENT] = body[KEY_PARENT]; | |
966 } | |
967 | |
968 std::string bodyString; | |
969 Orthanc::Toolbox::WriteFastJson(bodyString, creationBody); | |
970 | |
971 std::string result; | |
972 if (OrthancPlugins::RestApiPost(result, "/tools/create-dicom", | |
973 bodyString.empty() ? NULL : bodyString.c_str(), | |
974 bodyString.size(), false)) | |
975 { | |
976 OrthancPluginAnswerBuffer(context, output, result.empty() ? NULL : result.c_str(), | |
977 result.size(), "application/json"); | |
978 } | |
979 else | |
980 { | |
981 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest); | |
982 } | |
983 } | |
984 | |
881 #endif | 985 #endif |
882 | 986 |
883 | 987 |
884 extern "C" | 988 extern "C" |
885 { | 989 { |
908 Orthanc::Logging::Initialize(context); | 1012 Orthanc::Logging::Initialize(context); |
909 #endif | 1013 #endif |
910 | 1014 |
911 Orthanc::InitializeFramework("", false); | 1015 Orthanc::InitializeFramework("", false); |
912 | 1016 |
913 hasCreateDicomStl_ = OrthancPlugins::CheckMinimalOrthancVersion(1, 12, 1); | 1017 const bool hasCreateDicomStl_ = OrthancPlugins::CheckMinimalOrthancVersion(1, 12, 1); |
914 LOG(WARNING) << "Hello!"; | |
915 | 1018 |
916 if (!hasCreateDicomStl_) | 1019 if (!hasCreateDicomStl_) |
917 { | 1020 { |
918 LOG(WARNING) << "Your version of Orthanc (" << std::string(context->orthancVersion) | 1021 LOG(WARNING) << "Your version of Orthanc (" << std::string(context->orthancVersion) |
919 << ") is insufficient to create DICOM STL, it should be above 1.12.1"; | 1022 << ") is insufficient to create DICOM STL, it should be above 1.12.1"; |
933 | 1036 |
934 #if ORTHANC_ENABLE_NEXUS == 1 | 1037 #if ORTHANC_ENABLE_NEXUS == 1 |
935 nexusCache_.SetMaximumSize(512 * 1024 * 1024); // Cache of 512MB for Nexus | 1038 nexusCache_.SetMaximumSize(512 * 1024 * 1024); // Cache of 512MB for Nexus |
936 OrthancPlugins::RegisterRestCallback<ExtractNexusModel>("/instances/([0-9a-f-]+)/nexus", true); | 1039 OrthancPlugins::RegisterRestCallback<ExtractNexusModel>("/instances/([0-9a-f-]+)/nexus", true); |
937 OrthancPlugins::RegisterRestCallback<ServeNexusAssets>("/stl/nexus/(.*)", true); | 1040 OrthancPlugins::RegisterRestCallback<ServeNexusAssets>("/stl/nexus/(.*)", true); |
1041 | |
1042 const bool hasCreateNexus_ = OrthancPlugins::CheckMinimalOrthancVersion(1, 9, 4); | |
1043 | |
1044 if (hasCreateNexus_) | |
1045 { | |
1046 OrthancPlugins::RegisterRestCallback<DicomizeNexusModel>("/stl/create-nexus", true); | |
1047 | |
1048 if (OrthancPluginRegisterPrivateDictionaryTag( | |
1049 context, ORTHANC_STL_PRIVATE_GROUP, ORTHANC_STL_CREATOR_ELEMENT, OrthancPluginValueRepresentation_LO, | |
1050 "PrivateCreator", 1, 1, ORTHANC_STL_PRIVATE_CREATOR) != OrthancPluginErrorCode_Success || | |
1051 OrthancPluginRegisterPrivateDictionaryTag( | |
1052 context, ORTHANC_STL_PRIVATE_GROUP, ORTHANC_STL_NEXUS_ELEMENT, OrthancPluginValueRepresentation_OB, | |
1053 "NexusData", 1, 1, ORTHANC_STL_PRIVATE_CREATOR) != OrthancPluginErrorCode_Success) | |
1054 { | |
1055 LOG(ERROR) << "Cannot register the private DICOM tags for handling Nexus"; | |
1056 } | |
1057 } | |
1058 else | |
1059 { | |
1060 LOG(WARNING) << "Your version of Orthanc (" << std::string(context->orthancVersion) | |
1061 << ") is insufficient to create DICOM-ize Nexus models, it should be above 1.9.4"; | |
1062 } | |
938 #endif | 1063 #endif |
939 | 1064 |
940 OrthancPlugins::OrthancConfiguration globalConfiguration; | 1065 OrthancPlugins::OrthancConfiguration globalConfiguration; |
941 OrthancPlugins::OrthancConfiguration configuration; | 1066 OrthancPlugins::OrthancConfiguration configuration; |
942 globalConfiguration.GetSection(configuration, "STL"); | 1067 globalConfiguration.GetSection(configuration, "STL"); |