Custom scaling of the pelvis?

Hello

Can the pelvis be customised in the same way as the femur:
https://forum.anyscript.org/t/implementation-of-morphed-tlem-2-femur
Since the pelvis STL in AnyBody consists of two unconnected components (left and right hip bone).
pelvisAnyBody

Do you think all the transforms will work (AnyFunTransform3DRBF, AnyFunTransform3DSTL, ...) if the target pelvis also consists of two components?

Kind regards
Max

Hi Max,

It certainly can be customized - you could use the same scaling function for both sides of the pelvis (possibly sacrum too) and that should, in theory, give the required result. As to, which transforms will work - the RBF one should work, but the STL version may and most likely will not work since this region has many thin and disconnected components. I normally stop at the RBF transform, but use slightly more landmarks or same topology STLs (which is just a lot of landmarks for the RBF transform).

Kind regards,
Pavel

Hi Pavel

For the femur, the unscaled TLEM21 STL in the local bone system can be found under:
AMMR\Body\AAUHuman\LegTLEM\TLEM2.1\Seg_RefFrame_STLs\Seg_Femur_R.stl

However the hip bone is missing here.
How can I access the unscaled TLEM21 pelvis in the local bone system as STL in AnyBody?

Kind regards
Max

Hi Max,

Please see this link

Best regards
Søren

Hi Søren

Thanks for the link!

I assume for the later customization, I should export an unscaled version by adding the following lines to Seg.any, right?

      AnyDrawSurf DrwPelvis_Unscaled =
      {
        FileName = ..STL.FilenamePelvis;
        Opacity =  Main.DrawSettings.BonesOpacity.Pelvis;
        RGB = ...ColorRef.Segments;
        // AnyFunTransform3D &Scale = .Scale_Leg_Pelvis ;
      };

Kind regards
Max

Hi Max,

Yes that looks correct.

Best regards
søren

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

Hi Max

Please have a look at this entire post

I think a similar problem was resolved there.

Best regards
Søren

Thanks. It worked. For the pelvis, the

&Main.HumanModel.BodyModel.Trunk.SegmentsLumbar.PelvisSeg.Scale_Trunk_Pelvis.ScaleAfterInterfaceMorphingDef.Scale.T1_Inv

has to be added.

Super thanks for the feedback

This topic was automatically closed 125 days after the last reply. New replies are no longer allowed.