educelab / volume-cartographer

Volumetric processing toolkit and C++ libraries for the recovery and restoration of damaged cultural materials
GNU General Public License v3.0
63 stars 22 forks source link

Add new transform types and utility functions #69

Closed csparker247 closed 11 months ago

csparker247 commented 12 months ago

Follow-up to #67 which adds IdentityTransform and CompositeTransform, as well as various new transform-related QoL features.

Identity transforms

New IdentityTransform class which doesn't apply any transform to the inputs. Useful for explicitly defining a map between two coordinate spaces that are inherently aligned.

auto tfm = IdentityTransform::New();
auto res = tfm->applyPoint({5, 10, 15});  // {5, 10, 15}

Example transform file:

{
  "type": "Transform3D",
  "source": "20231128010200",
  "target": "20231127120000",
  "transform-type": "IdentityTransform"
}

Composite transforms

New CompositeTransform class which stores a list of transforms. When applied, each transform in the list is applied in sequence:

// create a composite transform
auto tfm = CompositeTransform::New();

// add a translation to the composite transform
auto a = AffineTransform::New();
a->translate(1, 2, 3);
tfm->push_back(a);

// add a scale to the composite
a->reset();
a->scale(5);
tfm->push_back(a);

// apply to a point
tfm->applyPoint({0, 0, 0});  // {5, 10, 15}

If the transforms are all composable, the transform can be simplified with the CompositeTransform::simplify() member function:

// create a composite transform
auto tfm = CompositeTransform::New();

// set up an affine transform
auto a = AffineTransform::New();
a->translate(1, 2, 3);

tfm->push_back(a);                         // forward translate       
tfm->push_back(IdentityTransform::New());  // no-op transform
tfm->push_back(a->invert());               // undo translate

// simplify
tfm->size();      // contains 3 transforms
tfm->simplify();
tfm->size();      // contains 1 transform

// apply to a point
tfm->applyPoint({0, 0, 0});  // {0, 0, 0}

Example transform file:

{
  "type": "Transform3D",
  "source": "20231128010200",
  "target": "20231127120000",
  "transform-type": "CompositeTransform",
  "transform-stack": [
    {
      "type": "Transform3D",
      "source": "not-used",
      "target": "not-used",
      "transform-type": "AffineTransform",
      "params": [[1.0, 0.0, 0.0, 0.0],
                 [0.0, 1.0, 0.0, 0.0],
                 [0.0, 0.0, 1.0, 0.0],
                 [0.0, 0.0, 0.0, 1.0]]
    }
  ]
}

Other changes