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;