---------------------------------------------------------------------------- * Function to be overloaded for each supported input grid data sets. * This function will return true if 2 input block structures are adjacent, false otherwise. */
| 863 | * This function will return true if 2 input block structures are adjacent, false otherwise. |
| 864 | */ |
| 865 | bool SynchronizeGridExtents( |
| 866 | const ::ImageDataBlockStructure& localBlockStructure, ::ImageDataBlockStructure& blockStructure) |
| 867 | { |
| 868 | // Images are spatially defined by origin, spacing, dimension, and orientation. |
| 869 | // We make sure that they all connect well using those values. |
| 870 | const ::VectorType& localOrigin = localBlockStructure.Origin; |
| 871 | const ::VectorType& localSpacing = localBlockStructure.Spacing; |
| 872 | const ::QuaternionType& localQ = localBlockStructure.OrientationQuaternion; |
| 873 | const ::ExtentType& localExtent = localBlockStructure.Extent; |
| 874 | int localDim = localBlockStructure.DataDimension; |
| 875 | |
| 876 | const ::ExtentType& extent = blockStructure.Extent; |
| 877 | ::ExtentType& shiftedExtent = blockStructure.ShiftedExtent; |
| 878 | const ::QuaternionType& q = blockStructure.OrientationQuaternion; |
| 879 | const ::VectorType& spacing = blockStructure.Spacing; |
| 880 | int dim = blockStructure.DataDimension; |
| 881 | |
| 882 | // We skip if dimension, spacing or quaternions don't match |
| 883 | // spacing == localSpacing <=> dot(spacing, localSpacing) == norm(localSpacing)^2 |
| 884 | // q == localQ <=> dot(q, localQ) == 1 (both are unitary quaternions) |
| 885 | if (extent[0] > extent[1] || extent[2] > extent[3] || extent[4] > extent[5] || dim != localDim || |
| 886 | !vtkMathUtilities::NearlyEqual( |
| 887 | vtkMath::Dot(spacing, localSpacing), vtkMath::SquaredNorm(localSpacing)) || |
| 888 | !(std::fabs(vtkMath::Dot<double, 4>(q.GetData(), localQ.GetData()) - 1.0) < VTK_DBL_EPSILON)) |
| 889 | { |
| 890 | return false; |
| 891 | } |
| 892 | |
| 893 | // We reposition extent all together so we have a unified extent framework with the current |
| 894 | // neighbor. |
| 895 | const ::VectorType& origin = blockStructure.Origin; |
| 896 | int originDiff[3] = { static_cast<int>(std::lround((origin[0] - localOrigin[0]) / spacing[0])), |
| 897 | static_cast<int>(std::lround((origin[1] - localOrigin[1]) / spacing[1])), |
| 898 | static_cast<int>(std::lround((origin[2] - localOrigin[2]) / spacing[2])) }; |
| 899 | |
| 900 | shiftedExtent[0] = extent[0] + originDiff[0]; |
| 901 | shiftedExtent[1] = extent[1] + originDiff[0]; |
| 902 | shiftedExtent[2] = extent[2] + originDiff[1]; |
| 903 | shiftedExtent[3] = extent[3] + originDiff[1]; |
| 904 | shiftedExtent[4] = extent[4] + originDiff[2]; |
| 905 | shiftedExtent[5] = extent[5] + originDiff[2]; |
| 906 | |
| 907 | return ::AreExtentsAdjacent(shiftedExtent, localExtent); |
| 908 | } |
| 909 | |
| 910 | //============================================================================ |
| 911 | template <bool IsIntegerT> |
no test coverage detected