Mercurial > hg > orthanc
comparison OrthancServer/SliceOrdering.cpp @ 3538:23219b9da4d1
fix ordered-slices route to be closer to 1.5.7 behaviour
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Tue, 15 Oct 2019 09:53:33 +0200 |
parents | 4bced7d1ec20 |
children | f25e84cc5f87 |
comparison
equal
deleted
inserted
replaced
3537:9cc09f4c0fa9 | 3538:23219b9da4d1 |
---|---|
308 | 308 |
309 instances_.reserve(instancesId.size()); | 309 instances_.reserve(instancesId.size()); |
310 for (std::list<std::string>::const_iterator | 310 for (std::list<std::string>::const_iterator |
311 it = instancesId.begin(); it != instancesId.end(); ++it) | 311 it = instancesId.begin(); it != instancesId.end(); ++it) |
312 { | 312 { |
313 std::auto_ptr<Instance> instance(new Instance(index_, *it)); | 313 instances_.push_back(new Instance(index_, *it)); |
314 if (instance->HasPosition() || instance->HasNormal() || instance->HasIndexInSeries()) | |
315 { | |
316 instances_.push_back(instance.release()); | |
317 } | |
318 } | 314 } |
319 } | 315 } |
320 | 316 |
321 | 317 |
322 bool SliceOrdering::SortUsingPositions() | 318 bool SliceOrdering::SortUsingPositions() |
323 { | 319 { |
324 if (instances_.size() <= 1) | 320 if (instances_.size() <= 1) |
325 { | 321 { |
326 // One single instance: It is sorted by default | 322 // One single instance: It is sorted by default |
323 sortedInstances_ = instances_; | |
327 return true; | 324 return true; |
328 } | 325 } |
329 | 326 |
330 if (!hasNormal_) | 327 if (!hasNormal_) |
331 { | 328 { |
332 return false; | 329 return false; |
333 } | 330 } |
334 | 331 |
332 sortedInstances_.clear(); | |
333 | |
334 // consider only the instances with a position | |
335 for (size_t i = 0; i < instances_.size(); i++) | 335 for (size_t i = 0; i < instances_.size(); i++) |
336 { | 336 { |
337 assert(instances_[i] != NULL); | 337 assert(instances_[i] != NULL); |
338 | 338 |
339 if (!instances_[i]->HasPosition() || | 339 if (instances_[i]->HasPosition()) |
340 (instances_[i]->HasNormal() && | 340 { |
341 !IsParallelOrOpposite(instances_[i]->GetNormal(), normal_))) | 341 sortedInstances_.push_back(instances_[i]); |
342 { | 342 } |
343 return false; | 343 } |
344 } | 344 |
345 if (sortedInstances_.size() == 0) | |
346 { | |
347 return false; | |
345 } | 348 } |
346 | 349 |
347 PositionComparator comparator(normal_); | 350 PositionComparator comparator(normal_); |
348 std::sort(instances_.begin(), instances_.end(), comparator); | 351 std::sort(sortedInstances_.begin(), sortedInstances_.end(), comparator); |
349 | 352 |
350 float a = instances_[0]->ComputeRelativePosition(normal_); | 353 float a = sortedInstances_[0]->ComputeRelativePosition(normal_); |
351 for (size_t i = 1; i < instances_.size(); i++) | 354 for (size_t i = 1; i < sortedInstances_.size(); i++) |
352 { | 355 { |
353 float b = instances_[i]->ComputeRelativePosition(normal_); | 356 float b = sortedInstances_[i]->ComputeRelativePosition(normal_); |
354 | 357 |
355 if (std::fabs(b - a) <= 10.0f * std::numeric_limits<float>::epsilon()) | 358 if (std::fabs(b - a) <= 10.0f * std::numeric_limits<float>::epsilon()) |
356 { | 359 { |
357 // Not enough space between two slices along the normal of the volume | 360 // Not enough space between two slices along the normal of the volume |
358 return false; | 361 return false; |
370 bool SliceOrdering::SortUsingIndexInSeries() | 373 bool SliceOrdering::SortUsingIndexInSeries() |
371 { | 374 { |
372 if (instances_.size() <= 1) | 375 if (instances_.size() <= 1) |
373 { | 376 { |
374 // One single instance: It is sorted by default | 377 // One single instance: It is sorted by default |
378 sortedInstances_ = instances_; | |
375 return true; | 379 return true; |
376 } | 380 } |
377 | 381 |
382 sortedInstances_.clear(); | |
383 | |
384 // consider only the instances with an index | |
378 for (size_t i = 0; i < instances_.size(); i++) | 385 for (size_t i = 0; i < instances_.size(); i++) |
379 { | 386 { |
380 assert(instances_[i] != NULL); | 387 assert(instances_[i] != NULL); |
381 if (!instances_[i]->HasIndexInSeries()) | 388 if (instances_[i]->HasIndexInSeries()) |
382 { | 389 { |
383 return false; | 390 sortedInstances_.push_back(instances_[i]); |
384 } | 391 } |
385 } | 392 } |
386 | 393 |
387 std::sort(instances_.begin(), instances_.end(), IndexInSeriesComparator); | 394 if (sortedInstances_.size() == 0) // if we were not able to sort instances because none of them had an index, return all instances in a "random" order |
388 | 395 { |
389 for (size_t i = 1; i < instances_.size(); i++) | 396 sortedInstances_ = instances_; |
390 { | 397 } |
391 if (instances_[i - 1]->GetIndexInSeries() == instances_[i]->GetIndexInSeries()) | 398 else |
392 { | 399 { |
393 // The current "IndexInSeries" occurs 2 times: Not a proper ordering | 400 std::sort(sortedInstances_.begin(), sortedInstances_.end(), IndexInSeriesComparator); |
394 LOG(WARNING) << "This series contains 2 slices with the same index, trying to display it anyway"; | 401 |
395 break; | 402 for (size_t i = 1; i < sortedInstances_.size(); i++) |
403 { | |
404 if (sortedInstances_[i - 1]->GetIndexInSeries() == sortedInstances_[i]->GetIndexInSeries()) | |
405 { | |
406 // The current "IndexInSeries" occurs 2 times: Not a proper ordering | |
407 LOG(WARNING) << "This series contains 2 slices with the same index, trying to display it anyway"; | |
408 break; | |
409 } | |
396 } | 410 } |
397 } | 411 } |
398 | 412 |
399 return true; | 413 return true; |
400 } | 414 } |
429 } | 443 } |
430 } | 444 } |
431 } | 445 } |
432 | 446 |
433 | 447 |
434 const std::string& SliceOrdering::GetInstanceId(size_t index) const | 448 const std::string& SliceOrdering::GetSortedInstanceId(size_t index) const |
435 { | 449 { |
436 if (index >= instances_.size()) | 450 if (index >= sortedInstances_.size()) |
437 { | 451 { |
438 throw OrthancException(ErrorCode_ParameterOutOfRange); | 452 throw OrthancException(ErrorCode_ParameterOutOfRange); |
439 } | 453 } |
440 else | 454 else |
441 { | 455 { |
442 return instances_[index]->GetIdentifier(); | 456 return sortedInstances_[index]->GetIdentifier(); |
443 } | 457 } |
444 } | 458 } |
445 | 459 |
446 | 460 |
447 unsigned int SliceOrdering::GetFramesCount(size_t index) const | 461 unsigned int SliceOrdering::GetSortedInstanceFramesCount(size_t index) const |
448 { | 462 { |
449 if (index >= instances_.size()) | 463 if (index >= sortedInstances_.size()) |
450 { | 464 { |
451 throw OrthancException(ErrorCode_ParameterOutOfRange); | 465 throw OrthancException(ErrorCode_ParameterOutOfRange); |
452 } | 466 } |
453 else | 467 else |
454 { | 468 { |
455 return instances_[index]->GetFramesCount(); | 469 return sortedInstances_[index]->GetFramesCount(); |
456 } | 470 } |
457 } | 471 } |
458 | 472 |
459 | 473 |
460 void SliceOrdering::Format(Json::Value& result) const | 474 void SliceOrdering::Format(Json::Value& result) const |
461 { | 475 { |
462 result = Json::objectValue; | 476 result = Json::objectValue; |
463 result["Type"] = (isVolume_ ? "Volume" : "Sequence"); | 477 result["Type"] = (isVolume_ ? "Volume" : "Sequence"); |
464 | 478 |
465 Json::Value tmp = Json::arrayValue; | 479 Json::Value tmp = Json::arrayValue; |
466 for (size_t i = 0; i < GetInstancesCount(); i++) | 480 for (size_t i = 0; i < GetSortedInstancesCount(); i++) |
467 { | 481 { |
468 tmp.append(GetBasePath(ResourceType_Instance, GetInstanceId(i)) + "/file"); | 482 tmp.append(GetBasePath(ResourceType_Instance, GetSortedInstanceId(i)) + "/file"); |
469 } | 483 } |
470 | 484 |
471 result["Dicom"] = tmp; | 485 result["Dicom"] = tmp; |
472 | 486 |
473 Json::Value slicesShort = Json::arrayValue; | 487 Json::Value slicesShort = Json::arrayValue; |
474 | 488 |
475 tmp.clear(); | 489 tmp.clear(); |
476 for (size_t i = 0; i < GetInstancesCount(); i++) | 490 for (size_t i = 0; i < GetSortedInstancesCount(); i++) |
477 { | 491 { |
478 std::string base = GetBasePath(ResourceType_Instance, GetInstanceId(i)); | 492 std::string base = GetBasePath(ResourceType_Instance, GetSortedInstanceId(i)); |
479 for (size_t j = 0; j < GetFramesCount(i); j++) | 493 for (size_t j = 0; j < GetSortedInstanceFramesCount(i); j++) |
480 { | 494 { |
481 tmp.append(base + "/frames/" + boost::lexical_cast<std::string>(j)); | 495 tmp.append(base + "/frames/" + boost::lexical_cast<std::string>(j)); |
482 } | 496 } |
483 | 497 |
484 Json::Value tmp2 = Json::arrayValue; | 498 Json::Value tmp2 = Json::arrayValue; |
485 tmp2.append(GetInstanceId(i)); | 499 tmp2.append(GetSortedInstanceId(i)); |
486 tmp2.append(0); | 500 tmp2.append(0); |
487 tmp2.append(GetFramesCount(i)); | 501 tmp2.append(GetSortedInstanceFramesCount(i)); |
488 | 502 |
489 slicesShort.append(tmp2); | 503 slicesShort.append(tmp2); |
490 } | 504 } |
491 | 505 |
492 result["Slices"] = tmp; | 506 result["Slices"] = tmp; |