Dear AnyBody Forum,
I'm trying to use a custom-scaled scapula which I obtained after morphing the AnyBody standing-model scapula to fit my patient-specific scapula. The scapula seems to have transformed well, however the glenohumeral joint is squashed into the scapula (I've included an images for a left scapula example below). The glenoid cavity appears to be mostly reasonably well-defined, however the joint center is too medial.
I have noticed this in multiple different patient-specific scapulas, as well as on both the right and left sides. Does anyone know why this is?
Because this example patient is much smaller than the standard model, I've included a uniform scaling function, then a custom scaling of the scapula:
// Uniform Scaling
#define BM_SCALING _SCALING_UNIFORM_
#path BM_SCALING_ANTHRO_FILE "Model\AnyFamily\AnyManUniform.any"
// Custom Scaling
#include "Model\CustomScaling.any"
The custom scaling function used a source and a target STL. The linear scaling of *0.001 is to bring the externally transformed STLs from [mm] dimensions back to the AnyBody [m] scale. I use a 3DSTL transformation and an inverse transformation to bring the subject specific scapula into the correct placement:
AnyIntVar NumPointsRBF = 700;
AnyFolder MyScalingFunction_LeftScapula = {
AnyFunTransform3DIdentity ScaleFunction = {
PreTransforms = {&.STLTransform, &.ReverseTransform};
};
AnyFunTransform3DLin2 AffineTransform = {
AnyFileVar SourceSTL = FilePathCompleteOf(..Source.FilenameScapula) + ".stl";
AnyFileVar TargetSTL = FilePathCompleteOf(..Target.FilenameScapula) + ".stl";
AnyMatrix Points0unscaled = STL_Vertices(SourceSTL, iarr(0, STL_Size(SourceSTL, 1)[0] - 1), 1)*0.001;
Points0 = ..TSeg2ScaleFrame(Points0unscaled);
Points1 = STL_Vertices(TargetSTL, iarr(0, STL_Size(TargetSTL, 1)[0] - 1), 1)*0.001;
Mode = VTK_LANDMARK_AFFINE;
};
AnyFunTransform3DLin2 ReverseTransform = {
Points0 = .AffineTransform.Points1;
Points1 = .AffineTransform.Points0;
Mode = VTK_LANDMARK_RIGIDBODY;
};
AnyFunTransform3DSTL STLTransform=
{
PreTransforms = {&.AffineTransform};
RBFDef.Type = RBF_ThinPlate;
//RBFDef.Param = 0.2;
AnyFixedRefFrame ref = {
AnySurfSTL source = {
FileName = ....Source.FilenameScapula;
ScaleXYZ = {1, 1, 1}*0.001;
AnyFunTransform3D &pre = ....TSeg2ScaleFrame;
};
AnySurfSTL target = {
FileName = ....Target.FilenameScapula;
ScaleXYZ = {1, 1, 1}*0.001;
};
};
SurfaceObjects0 = {&ref.source};
SurfaceObjects1 = {&ref.target};
NumPoints = ..NumPointsRBF*2;
UseClosestPointMatchingOnOff = On;
//UseSurfaceCorrespondence = On;
BoundingBox.ScaleXYZ = 10*{1, 1, 1};
BoundingBox.DivisionFactorXYZ = 10*{1, 1, 1};
BoundingBoxOnOff = On;
};
};
Thank you very much for any help or suggestions.
Best,
Alex