Hello
I used the same code for the pelvis customization as for the femurs. However, there are some bugs.
Both meshes do not overlay properly, such as the femurs, and the region of the pubic symphysis is erroneous.
I exported the pelvis STL and customized the vertices, so the mesh topology stays the same.
The following code was used for the custom pelvis scaling:
CustomScalingPelvis.any
// Custom scaling law for the pelvis
HumanModel.Scaling.GeometricalScaling = {
#define CUSTOM_SCALING_PelvisSeg
PelvisSeg = {
AnyFunTransform3D &RegTransformScale = Main.HumanModel.BodyModel.Trunk.SegmentsLumbar.PelvisSeg.Scale;
#include "PelvisScalingFunction.any"
AnyFunTransform3D &ScaleFunction = PelvisScalingFunction.Transform;
};
};
// Show how well the morphing works (green bone is the target geometry)
Main.HumanModel.BodyModel.Trunk.SegmentsLumbar.PelvisSeg = {
AnyFunTransform3D &CustomMarkerScaling = Main.HumanModel.Scaling.GeometricalScaling.PelvisSeg.PelvisScalingFunction.RegistrationTransform;
AnyRefNode SS_STLNode = {
AnySurfSTL PelvisSTL =
{
FileName = Main.HumanModel.Scaling.GeometricalScaling.PelvisSeg.PelvisScalingFunction.TargetSTL;
ScaleXYZ = {1, 1, 1};
AnyFunTransform3D &scale = ..CustomMarkerScaling;
AnyDrawSurf stldraw = {
FileName = .FileName;
AnyFloat ScaleFactor = .....Scaling.GeometricalScaling.PelvisSeg.PelvisScalingFunction.ScaleFactor;
ScaleXYZ = {1, 1, 1}*ScaleFactor;
AnyFunTransform3D &scale = .scale;
RGB = {0,1,0};
Opacity = 1;
};
};
};
};
PelvisScalingFunction.any
/* This file defines a subject-specific morphing law for the pelvis*/
AnyFolder PelvisScalingFunction = {
AnyFloat ScaleFactor = 0.001; // Convert mm to m
// Load unscaled AnyBody TLEM2.1 pelvis
AnyInt NumPoints = 800;
AnyString PelvisSourceFolder = "../../ammr/Body/AAUHuman/LegTLEM/TLEM2.1/";
AnyFileVar SourceSTL = "TLEM21_Pelvis_AnyBody.stl";
AnyInt NumPoints0 = STL_Size(SourceSTL,1)[0];
AnyMatrix SourcePointsUnscaled = STL_Vertices(SourceSTL,iarr(0,floor(NumPoints0/NumPoints),NumPoints0-1),1);
// Load subject-specific adapted AnyBody TLEM2.1 pelvis
AnyString Subject = Main.ModelSetup.SubjectSpecificData.Name;
AnyFileVar TargetSTL = "../Subjects/" + Subject + "/" + Subject + "_TLEM21_Pelvis.stl";
AnyMatrix TargetPointsUnscaled = STL_Vertices(TargetSTL,iarr(0,floor(NumPoints0/NumPoints),NumPoints0-1),1)*ScaleFactor;
AnyFunTransform3DLin Transform = {
ScaleMat = {{1,0,0},{0,1,0},{0,0,1}};
Offset = {0,0,0};
PreTransforms = {&.STLTransform, &.ReverseTransform};
};
AnyFunTransform3DLin2 RegistrationTransform = {
Points0 = .AffineTransform.Points1;
Points1 = ..RegTransformScale(.SourcePointsUnscaled);
Mode = VTK_LANDMARK_RIGIDBODY;
};
AnyFunTransform3DLin2 AffineTransform =
{
//PreTransforms = {};
Points0 = ..TSeg2ScaleFrame(.SourcePointsUnscaled);
Points1 = .TargetPointsUnscaled;
Mode = VTK_LANDMARK_AFFINE;
};
AnyFunTransform3DLin2 ReverseTransform = {
Points0 = .AffineTransform.Points1;
Points1 = .AffineTransform.Points0;
Mode = VTK_LANDMARK_RIGIDBODY;
};
AnyFunTransform3DRBF RBFTransform =
{
PreTransforms = {&.AffineTransform};
RBFDef =
{
Type = RBF_ThinPlate;
Param = 1;
};
Points0 = ..TSeg2ScaleFrame(.SourcePointsUnscaled);
Points1 = .TargetPointsUnscaled;
BoundingBox =
{
Type = BB_Cartesian;
ScaleXYZ = {2, 2, 2};
DivisionFactorXYZ = 5*{1, 1, 1};
};
BoundingBoxOnOff = On;
};
AnyFunTransform3DSTL STLTransform =
{
PreTransforms = {&.RBFTransform};
RBFDef.Type = RBF_ThinPlate;
AnyFixedRefFrame Input = {
AnySurfSTL SourceSurf = {
FileName = ...PelvisSourceFolder + "pelvis";
ScaleXYZ = {1, 1, 1};
AnyFunTransform3D &pre = ....TSeg2ScaleFrame;
};
AnySurfSTL TargetSurf = {
FileName = ...TargetSTL;
ScaleXYZ = {1, 1, 1}*...ScaleFactor;
};
};
SurfaceObjects0 = {&Input.SourceSurf};
SurfaceObjects1 = {&Input.TargetSurf};
NumPoints = 5000; //normally 5000
UseClosestPointMatchingOnOff = Off;
BoundingBox.ScaleXYZ = 5*{1, 1, 1};
BoundingBox.DivisionFactorXYZ = 5*{1, 1, 1};
BoundingBoxOnOff = On;
};
};
Kind regards
Max