diff --git a/Modules/Filtering/SplitComponents/CMakeLists.txt b/Modules/Filtering/SplitComponents/CMakeLists.txt new file mode 100644 index 000000000000..7172c118dbae --- /dev/null +++ b/Modules/Filtering/SplitComponents/CMakeLists.txt @@ -0,0 +1,9 @@ +project(SplitComponents) + +if(POLICY CMP135) + cmake_policy(SET CMP135 NEW) +endif() + +# set(SplitComponents_LIBRARIES SplitComponents) # header-only module, so no libraries + +itk_module_impl() diff --git a/Modules/Filtering/SplitComponents/LICENSE b/Modules/Filtering/SplitComponents/LICENSE new file mode 100644 index 000000000000..62589edd12a3 --- /dev/null +++ b/Modules/Filtering/SplitComponents/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Modules/Filtering/SplitComponents/README.md b/Modules/Filtering/SplitComponents/README.md new file mode 100644 index 000000000000..289f740b4a01 --- /dev/null +++ b/Modules/Filtering/SplitComponents/README.md @@ -0,0 +1,41 @@ +# SplitComponents + +In-tree ITK module providing `itk::SplitComponentsImageFilter` — a +filter that splits a vector / covariant-vector / symmetric-second-rank- +tensor image into one scalar component image per pixel-component. +Useful for visualising, post-processing, or independently filtering +the channels of multi-component images. + +## Origin + +Ingested from the standalone remote module +[**InsightSoftwareConsortium/ITKSplitComponents**](https://github.com/InsightSoftwareConsortium/ITKSplitComponents) +on 2026-05-05, at upstream commit +[`94fde65c`](https://github.com/InsightSoftwareConsortium/ITKSplitComponents/commit/94fde65cae6883c9a0f1508c37c501c2ad989cdd). +The upstream repository will be archived read-only after this PR +merges; it remains reachable at the URL above. + +## What lives here + +Per the v4 ingestion strategy (see +`Utilities/Maintenance/RemoteModuleIngest/INGESTION_STRATEGY_v4.md`), +only paths matching the narrow whitelist +(`Utilities/Maintenance/RemoteModuleIngest/whitelists/SplitComponents.list`) +crossed the merge boundary: + +- `include/` — public C++ headers (header-only module; no `src/`). +- `test/` — CTest drivers and content-link stubs. +- `wrapping/` — Python wrapping descriptors. +- `CMakeLists.txt`, `itk-module.cmake` — module metadata. +- `LICENSE` — original Apache-2.0 license text. + +Upstream-only artifacts (CI dashboards, packaging, `apps/`, +`article/`, `binder/`, `examples/`, `images/`, `.github/`, +`pyproject.toml`, etc.) were explicitly excluded; the upstream +commit graph and authorship history are otherwise preserved through +a `--no-ff --allow-unrelated-histories` Mode-A merge. + +## Building + +SplitComponents is enabled by default once `Module_SplitComponents=ON` +is set; in CI it is enabled via `pyproject.toml`'s `configure-ci` task. diff --git a/Modules/Filtering/SplitComponents/include/itkSplitComponentsImageFilter.h b/Modules/Filtering/SplitComponents/include/itkSplitComponentsImageFilter.h new file mode 100644 index 000000000000..40a89b2ae111 --- /dev/null +++ b/Modules/Filtering/SplitComponents/include/itkSplitComponentsImageFilter.h @@ -0,0 +1,106 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#ifndef itkSplitComponentsImageFilter_h +#define itkSplitComponentsImageFilter_h + +#include "itkFixedArray.h" +#include "itkImageToImageFilter.h" + +namespace itk +{ + +/** \class SplitComponentsImageFilter + * + * \brief Extract components of an Image with multi-component pixels. + * + * This class extracts components of itk::Image of itk::Vector's + * itk::CovariantVector, itk::SymmetricSecondRankTensor, or other classes that + * have the same interface. The interface must implement ValueType operator[] ( + * unsigned int ). + * + * It puts an image on every output corresponding to each component. + * + * \ingroup SplitComponents + * + * \sa VectorImageToImageAdaptor + * \sa Vector + * \sa CovariantVector + * \sa SymmetricSecondRankTensor + * \sa DiffusionTensor3D + * \sa NthElementImageAdaptor + */ +template +class ITK_TEMPLATE_EXPORT SplitComponentsImageFilter : public ImageToImageFilter +{ +public: + ITK_DISALLOW_COPY_AND_MOVE(SplitComponentsImageFilter); + + /** ImageDimension enumeration. */ + static constexpr unsigned int ImageDimension = TInputImage::ImageDimension; + /** Components enumeration. */ + static constexpr unsigned int Components = TComponents; + + /** Image types. */ + using InputImageType = TInputImage; + using OutputImageType = TOutputImage; + using InputPixelType = typename InputImageType::PixelType; + using OutputPixelType = typename OutputImageType::PixelType; + using OutputRegionType = typename OutputImageType::RegionType; + + /** Standard class type alias. */ + using Self = SplitComponentsImageFilter; + using Superclass = ImageToImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; + + using ComponentsMaskType = FixedArray; + + /** Run-time type information (and related methods). */ + itkOverrideGetNameOfClassMacro(SplitComponentsImageFilter); + + /** Method of creation through the object factory. */ + itkNewMacro(Self); + + /** Set/Get the components mask. The mask is as long as the number of + * components, and only values in the mask that evaluate are true will be + * populated in the output. The default is all true. */ + itkSetMacro(ComponentsMask, ComponentsMaskType); + itkGetConstReferenceMacro(ComponentsMask, ComponentsMaskType); + +protected: + SplitComponentsImageFilter(); + ~SplitComponentsImageFilter() override = default; + + /** Do not allocate outputs that we will not populate. */ + void + AllocateOutputs() override; + + void + DynamicThreadedGenerateData(const OutputRegionType & outputRegion) override; + +private: + ComponentsMaskType m_ComponentsMask; +}; + +} // end namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkSplitComponentsImageFilter.hxx" +#endif + +#endif diff --git a/Modules/Filtering/SplitComponents/include/itkSplitComponentsImageFilter.hxx b/Modules/Filtering/SplitComponents/include/itkSplitComponentsImageFilter.hxx new file mode 100644 index 000000000000..86cedb07515b --- /dev/null +++ b/Modules/Filtering/SplitComponents/include/itkSplitComponentsImageFilter.hxx @@ -0,0 +1,110 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#ifndef itkSplitComponentsImageFilter_hxx +#define itkSplitComponentsImageFilter_hxx + + +#include "itkImageRegionConstIterator.h" +#include "itkImageRegionIterator.h" + +namespace itk +{ + +template +SplitComponentsImageFilter::SplitComponentsImageFilter() +{ + this->m_ComponentsMask.Fill(true); + + this->SetNumberOfIndexedOutputs(Components); + + // ImageSource only does this for the first output. + for (unsigned int i = 1; i < Components; i++) + { + this->SetNthOutput(i, this->MakeOutput(i)); + } + + this->DynamicMultiThreadingOn(); +} + + +template +void +SplitComponentsImageFilter::AllocateOutputs() +{ + using ImageBaseType = ImageBase; + typename ImageBaseType::Pointer outputPtr; + + // Allocate the output memory as with ImageSource + unsigned int ii = 0; + for (OutputDataObjectIterator it(this); !it.IsAtEnd(); ++it, ++ii) + { + // Check whether the output is an image of the appropriate + // dimension (use ProcessObject's version of the GetInput() + // method since it returns the input as a pointer to a + // DataObject as opposed to the subclass version which + // static_casts the input to an TInputImage). + outputPtr = dynamic_cast(it.GetOutput()); + + if (outputPtr && this->m_ComponentsMask[ii]) + { + outputPtr->SetBufferedRegion(outputPtr->GetRequestedRegion()); + outputPtr->Allocate(); + } + } +} + + +template +void +SplitComponentsImageFilter::DynamicThreadedGenerateData( + const OutputRegionType & outputRegion) +{ + typename InputImageType::ConstPointer input = this->GetInput(); + ProcessObject::DataObjectPointerArray outputs = this->GetOutputs(); + const ComponentsMaskType componentsMask = this->m_ComponentsMask; + + using OutputIteratorType = ImageRegionIterator; + ImageRegionConstIterator inIt(input, outputRegion); + std::vector outIts(Components); + for (unsigned int ii = 0; ii < Components; ++ii) + { + if (componentsMask[ii]) + { + OutputIteratorType outIt(dynamic_cast(outputs[ii].GetPointer()), outputRegion); + outIt.GoToBegin(); + outIts[ii] = outIt; + } + } + InputPixelType inputPixel; + for (inIt.GoToBegin(); !inIt.IsAtEnd(); ++inIt) + { + inputPixel = inIt.Get(); + for (unsigned int ii = 0; ii < Components; ++ii) + { + if (componentsMask[ii]) + { + outIts[ii].Set(static_cast(inputPixel[ii])); + ++(outIts[ii]); + } + } + } +} + +} // end namespace itk + +#endif diff --git a/Modules/Filtering/SplitComponents/itk-module.cmake b/Modules/Filtering/SplitComponents/itk-module.cmake new file mode 100644 index 000000000000..c8820178073b --- /dev/null +++ b/Modules/Filtering/SplitComponents/itk-module.cmake @@ -0,0 +1,20 @@ +# the top-level README is used for describing this module, just +# re-used it for documentation here +get_filename_component(MY_CURRENT_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +file(READ "${MY_CURRENT_DIR}/README.md" DOCUMENTATION) + +# itk_module() defines the module dependencies in SplitComponents +# The testing module in SplitComponents depends on ITKTestKernel +# By convention those modules outside of ITK are not prefixed with +# ITK. + +# define the dependencies of the include module and the tests +itk_module( + SplitComponents + DEPENDS + ITKCommon + TEST_DEPENDS + ITKTestKernel + DESCRIPTION "${DOCUMENTATION}" + EXCLUDE_FROM_DEFAULT +) diff --git a/Modules/Filtering/SplitComponents/test/Baseline/itkSplitComponentsImageFilterTestBaseline0.mha.cid b/Modules/Filtering/SplitComponents/test/Baseline/itkSplitComponentsImageFilterTestBaseline0.mha.cid new file mode 100644 index 000000000000..ed8a272d63dd --- /dev/null +++ b/Modules/Filtering/SplitComponents/test/Baseline/itkSplitComponentsImageFilterTestBaseline0.mha.cid @@ -0,0 +1 @@ +bafkreiamxu2cy6vfjc6t5fsvcdaeqn36chmnpnimtcnlxnmy5z3tjmaghe diff --git a/Modules/Filtering/SplitComponents/test/Baseline/itkSplitComponentsImageFilterTestBaseline1.mha.cid b/Modules/Filtering/SplitComponents/test/Baseline/itkSplitComponentsImageFilterTestBaseline1.mha.cid new file mode 100644 index 000000000000..19ace7c16bcc --- /dev/null +++ b/Modules/Filtering/SplitComponents/test/Baseline/itkSplitComponentsImageFilterTestBaseline1.mha.cid @@ -0,0 +1 @@ +bafkreif3tkgmecbfvioj3ijohqdre77nfzf6foimlcxlscr5ud54qsooqe diff --git a/Modules/Filtering/SplitComponents/test/CMakeLists.txt b/Modules/Filtering/SplitComponents/test/CMakeLists.txt new file mode 100644 index 000000000000..011863b43be5 --- /dev/null +++ b/Modules/Filtering/SplitComponents/test/CMakeLists.txt @@ -0,0 +1,17 @@ +itk_module_test() +set(SplitComponentsTests itkSplitComponentsImageFilterTest.cxx) +createtestdriver( SplitComponents "${SplitComponents-Test_LIBRARIES}" "${SplitComponentsTests}") + +itk_add_test( + NAME itkSplitComponentsImageFilterTest + COMMAND + SplitComponentsTestDriver + --compare + DATA{Baseline/itkSplitComponentsImageFilterTestBaseline0.mha} + itkSplitComponentsImageFilterTestOutput0.mha + --compare + DATA{Baseline/itkSplitComponentsImageFilterTestBaseline1.mha} + itkSplitComponentsImageFilterTestOutput1.mha + itkSplitComponentsImageFilterTest + itkSplitComponentsImageFilterTestOutput +) diff --git a/Modules/Filtering/SplitComponents/test/itkSplitComponentsImageFilterTest.cxx b/Modules/Filtering/SplitComponents/test/itkSplitComponentsImageFilterTest.cxx new file mode 100644 index 000000000000..580cb2483acf --- /dev/null +++ b/Modules/Filtering/SplitComponents/test/itkSplitComponentsImageFilterTest.cxx @@ -0,0 +1,131 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#include "itkImage.h" +#include "itkImageFileWriter.h" +#include "itkImageRegionIteratorWithIndex.h" +#include "itkVector.h" + +#include + +#include "itkSplitComponentsImageFilter.h" + +int +itkSplitComponentsImageFilterTest(int argc, char * argv[]) +{ + if (argc < 2) + { + std::cerr << "Usage: " << argv[0]; + std::cerr << " outputImagePrefix "; + std::cerr << std::endl; + return EXIT_FAILURE; + } + + constexpr unsigned int Dimension = 2; + using PixelType = signed short; + using OutputImageType = itk::Image; + using VectorType = itk::Vector; + using InputImageType = itk::Image; + + // Size in every dimension of the output image. + constexpr unsigned int sizes = 100; + + InputImageType::Pointer input = InputImageType::New(); + + using RegionType = InputImageType::RegionType; + RegionType region; + RegionType::IndexType index; + index.Fill(0); + region.SetIndex(index); + RegionType::SizeType size; + for (unsigned int i = 0; i < Dimension; i++) + { + size[i] = sizes; + } + region.SetSize(size); + + input->SetRegions(region); + input->Allocate(); + + itk::ImageRegionIteratorWithIndex it(input, region); + VectorType vector; + for (it.GoToBegin(); !it.IsAtEnd(); ++it) + { + index = it.GetIndex(); + vector[0] = index[0]; + vector[1] = index[1]; + it.Set(vector); + } + + using FilterType = itk::SplitComponentsImageFilter; + FilterType::Pointer filter = FilterType::New(); + filter->SetInput(input); + + using WriterType = itk::ImageFileWriter; + WriterType::Pointer writer = WriterType::New(); + + std::ostringstream ostr; + try + { + ostr << argv[1] << 0 << ".mha"; + writer->SetFileName(ostr.str()); + writer->SetInput(filter->GetOutput()); + writer->Update(); + + ostr.str(""); + ostr << argv[1] << 1 << ".mha"; + writer->SetFileName(ostr.str()); + writer->SetInput(filter->GetOutput(1)); + writer->Update(); + } + catch (itk::ExceptionObject & ex) + { + std::cerr << "Exception caught!" << std::endl; + std::cerr << ex << std::endl; + return EXIT_FAILURE; + } + + using ComponentsMaskType = FilterType::ComponentsMaskType; + ComponentsMaskType componentsMask(false); + componentsMask[1] = true; + const ComponentsMaskType oldComponents = filter->GetComponentsMask(); + if (oldComponents[0] != true) + { + std::cerr << "Did not get the expected default ComponentsMask." << std::endl; + return EXIT_FAILURE; + } + filter->SetComponentsMask(componentsMask); + const ComponentsMaskType newComponents = filter->GetComponentsMask(); + if (newComponents[0] != false) + { + std::cerr << "Did not get the expected modified ComponentsMask." << std::endl; + return EXIT_FAILURE; + } + + try + { + filter->Update(); + } + catch (itk::ExceptionObject & ex) + { + std::cerr << "Exception caught!" << std::endl; + std::cerr << ex << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/Modules/Filtering/SplitComponents/wrapping/CMakeLists.txt b/Modules/Filtering/SplitComponents/wrapping/CMakeLists.txt new file mode 100644 index 000000000000..7703111ef33c --- /dev/null +++ b/Modules/Filtering/SplitComponents/wrapping/CMakeLists.txt @@ -0,0 +1,3 @@ +itk_wrap_module(SplitComponents) +itk_auto_load_submodules() +itk_end_wrap_module() diff --git a/Modules/Filtering/SplitComponents/wrapping/itkSplitComponentsImageFilter.wrap b/Modules/Filtering/SplitComponents/wrapping/itkSplitComponentsImageFilter.wrap new file mode 100644 index 000000000000..bb6b88890dd3 --- /dev/null +++ b/Modules/Filtering/SplitComponents/wrapping/itkSplitComponentsImageFilter.wrap @@ -0,0 +1,71 @@ +itk_wrap_class("itk::SplitComponentsImageFilter" POINTER) + +# Vector -> scalar +set(types ${WRAP_ITK_INT}) +if(ITK_WRAP_vector_float) + list(APPEND types "F") +endif() +if(ITK_WRAP_vector_double) + list(APPEND types "D") +endif() +foreach(d ${ITK_WRAP_IMAGE_DIMS}) + foreach(t ${types}) + if(DEFINED ITKT_IV${t}${d}${d}) + itk_wrap_template( + "${ITKM_IV${t}${d}${d}}${ITKM_I${t}${d}}" + "${ITKT_IV${t}${d}${d}}, ${ITKT_I${t}${d}}" + ) + endif() + endforeach() +endforeach() + +# CovariantVector -> scalar +set(types ${WRAP_ITK_INT}) +if(ITK_WRAP_covariant_vector_float) + list(APPEND types "F") +endif() +if(ITK_WRAP_covariant_vector_double) + list(APPEND types "D") +endif() +foreach(d ${ITK_WRAP_IMAGE_DIMS}) + foreach(t ${types}) + if(DEFINED ITKT_ICV${t}${d}${d}) + itk_wrap_template( + "${ITKM_ICV${t}${d}${d}}${ITKM_I${t}${d}}" + "itk::Image, ${d}>, ${ITKT_I${t}${d}}" + ) + endif() + endforeach() +endforeach() + +# VectorImage -> scalar +unique(types "${WRAP_ITK_SCALAR}") +foreach(d ${ITK_WRAP_IMAGE_DIMS}) + foreach(t ${types}) + itk_wrap_template("${ITKM_VI${t}${d}}${ITKM_I${t}${d}}" "${ITKT_VI${t}${d}},${ITKT_I${t}${d}}") + endforeach() +endforeach() + +# RGB(A) -> scalar +if(ITK_WRAP_rgb_unsigned_char AND ITK_WRAP_unsigned_char) + foreach(d ${ITK_WRAP_IMAGE_DIMS}) + itk_wrap_template("I${ITKM_RGBUC}${d}I${ITKM_UC}${d}3" "itk::Image<${ITKT_RGBUC},${d}>,itk::Image<${ITKT_UC},${d}>,3") + endforeach() +endif() +if(ITK_WRAP_rgb_unsigned_short AND ITK_WRAP_unsigned_short) + foreach(d ${ITK_WRAP_IMAGE_DIMS}) + itk_wrap_template("I${ITKM_RGBUS}${d}I${ITKM_US}${d}3" "itk::Image<${ITKT_RGBUS},${d}>,itk::Image<${ITKT_US},${d}>,3") + endforeach() +endif() +if(ITK_WRAP_rgba_unsigned_char AND ITK_WRAP_unsigned_char) + foreach(d ${ITK_WRAP_IMAGE_DIMS}) + itk_wrap_template("I${ITKM_RGBAUC}${d}I${ITKM_UC}${d}3" "itk::Image<${ITKT_RGBAUC},${d}>,itk::Image<${ITKT_UC},${d}>,4") + endforeach() +endif() +if(ITK_WRAP_rgba_unsigned_short AND ITK_WRAP_unsigned_short) + foreach(d ${ITK_WRAP_IMAGE_DIMS}) + itk_wrap_template("I${ITKM_RGBAUS}${d}I${ITKM_US}${d}3" "itk::Image<${ITKT_RGBAUS},${d}>,itk::Image<${ITKT_US},${d}>,4") + endforeach() +endif() + +itk_end_wrap_class() diff --git a/Modules/Remote/SplitComponents.remote.cmake b/Modules/Remote/SplitComponents.remote.cmake deleted file mode 100644 index 7bd2a7b3bc26..000000000000 --- a/Modules/Remote/SplitComponents.remote.cmake +++ /dev/null @@ -1,54 +0,0 @@ -#-- # Grading Level Criteria Report -#-- EVALUATION DATE: 2020-03-01 -#-- EVALUATORS: [<>,<>] -#-- -#-- ## Compliance level 5 star (AKA ITK main modules, or remote modules that could become core modules) -#-- - [ ] Widespread community dependance -#-- - [ ] Above 90% code coverage -#-- - [ ] CI dashboards and testing monitored rigorously -#-- - [ ] Key API features are exposed in wrapping interface -#-- - [ ] All requirements of Levels 4,3,2,1 -#-- -#-- ## Compliance Level 4 star (Very high-quality code, perhaps small community dependance) -#-- - [ ] Meets all ITK code style standards -#-- - [ ] No external requirements beyond those needed by ITK proper -#-- - [ ] Builds and passes tests on all supported platforms within 1 month of each core tagged release -#-- - [ ] Windows Shared Library Build with Visual Studio -#-- - [ ] Mac with clang compiller -#-- - [ ] Linux with gcc compiler -#-- - [ ] Active developer community dedicated to maintaining code-base -#-- - [ ] 75% code coverage demonstrated for testing suite -#-- - [ ] Continuous integration testing performed -#-- - [ ] All requirements of Levels 3,2,1 -#-- -#-- ## Compliance Level 3 star (Quality beta code) -#-- - [ ] API | executable interface is considered mostly stable and feature complete -#-- - [ ] 10% C0-code coverage demonstrated for testing suite -#-- - [ ] Some tests exist and pass on at least some platform -#-- - [X] All requirements of Levels 2,1 -#-- -#-- ## Compliance Level 2 star (Alpha code feature API development or niche community/execution environment dependance ) -#-- - [X] Compiles for at least 1 niche set of execution envirionments, and perhaps others -#-- (may depend on specific external tools like a java environment, or specific external libraries to work ) -#-- - [X] All requirements of Levels 1 -#-- -#-- ## Compliance Level 1 star (Pre-alpha features under development and code of unknown quality) -#-- - [X] Code complies on at least 1 platform -#-- -#-- ## Compliance Level 0 star ( Code/Feature of known poor-quality or deprecated status ) -#-- - [ ] Code reviewed and explicitly identified as not recommended for use -#-- -#-- ### Please document here any justification for the criteria above -# Code style enforced by clang-format on 2020-02-19, and clang-tidy modernizations completed - -# Contact: Matt McCormick -itk_fetch_module( - SplitComponents - "This module contains filter called -itk::SplitComponentsImageFilter. This filter generates component images from an -itk::Image of, for example, itk::Vector, itk::CovariantVector, or -itk::SymmetricSecondRankTensor. https://doi.org/10.54294/4c92vb" - MODULE_COMPLIANCE_LEVEL 2 - GIT_REPOSITORY https://github.com/InsightSoftwareConsortium/ITKSplitComponents.git - GIT_TAG 7a1e19d1f798e58929344f69dcd371b82c28fba7 - ) diff --git a/pyproject.toml b/pyproject.toml index 52c56027848e..dc52f518a37d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,6 +60,7 @@ cmd = '''cmake -DModule_LabelErodeDilate:BOOL=ON -DModule_MeshNoise:BOOL=ON -DModule_MGHIO:BOOL=ON + -DModule_SplitComponents:BOOL=ON -DITK_COMPUTER_MEMORY_SIZE:STRING=11 -DModule_StructuralSimilarity:BOOL=ON''' description = "Configure ITK for CI (with ccache compiler launcher)"