Transform/Morph defined Points in 3D Model to dynamic Datapoints

Hello everyone,

I’m working with a 3D model I found on Sketchfab (Link) and need some guidance on how to adjust it effectively. The model has four specific points I want to align; these are currently marked in purple within the 3D viewer for clarity. These points include the symphysis, left and right ischial spines, and the coccyx.

I’ve already prepared the coordinates for corresponding points in a CSV file, each marked in white and detailed with their X, Y, and Z coordinates. My objective is to morph or transform the purple-marked points on my model so that they match perfectly with the white points from the CSV file.


Is there a specific tool or software, that can facilitate this type of transformation/morph?
Any tips or suggestions on how to proceed would be very helpful.


import React, {useEffect } from 'react';
import * as THREE from 'three'
import { useGLTF, Center, BBAnchor} from '@react-three/drei'
import { GLTF } from 'three-stdlib'

import {useGridFunctionStore} from "../../services/zustand/GridFunctionStore.ts";


type GLTFResult = GLTF & {
    nodes: {
        Object_2: THREE.Mesh
        Object_3: THREE.Mesh
        Sphere: THREE.Mesh
        Sphere_1: THREE.Mesh
        Sphere_2: THREE.Mesh
        Sphere_3: THREE.Mesh
    }
    materials: {
        ['Scene_-_Root']: THREE.MeshStandardMaterial
        ['Scene_-_Root']: THREE.MeshStandardMaterial
    }
}

interface PelvisProps{
    pos: [number, number, number];
    rot: [number, number, number];
    dynamic: boolean;
    opacityParameter: number;
}
export const Pelvis: React.FC<PelvisProps> = React.memo(({ pos, rot, dynamic, opacityParameter, ...props }) => {
    const { nodes, materials } = useGLTF('/female_new.glb') as GLTFResult
    const {model_opacity} = useGridFunctionStore();
    const lightIntensity: number = 2;

    materials['Scene_-_Root'].transparent = true;
    materials['Scene_-_Root'].opacity = model_opacity / 100;

    return (
            <group {...props} dispose={null}>
                <directionalLight position={[100, 0, 100]} intensity={lightIntensity}/>
                <directionalLight position={[100, 0, -100]} intensity={lightIntensity}/>
                <directionalLight position={[-100, 0, 100]} intensity={lightIntensity}/>
                <directionalLight position={[-100, 0, -100]} intensity={lightIntensity}/>
                <directionalLight position={[0, 100, 0]} intensity={lightIntensity}/>
                <directionalLight position={[0, -100, 0]} intensity={lightIntensity}/>

                    <group scale={[1,1,1]}>

                        <mesh position={[0,0,0]}><sphereGeometry args={[0.8, 32, 32]}/><meshStandardMaterial color={"purple"}/></mesh>
                        <mesh position={[-55, 27, 57]}><sphereGeometry args={[0.8, 32, 32]}/><meshStandardMaterial color={"purple"}/></mesh>
                        <mesh position={[-57, 28, -55]}><sphereGeometry args={[0.8, 32, 32]}/><meshStandardMaterial color={"purple"}/></mesh>
                        <mesh position={[-98, 40, -0]}><sphereGeometry args={[0.8, 32, 32]}/><meshStandardMaterial color={"purple"}/></mesh>
                        
                            <Center rotation={rot} position={[-35, 80, 2]}>
                                <group scale={[1,1,1]}>
                                    <group {...props} dispose={null}>
                                        <mesh geometry={nodes.Object_3.geometry} material={materials['Scene_-_Root']}/>
                                    </group>
                                </group>
                            </Center>
                    </group>


            </group>
    )
})

useGLTF.preload('/female_lower_poly.glb')

Thank you in advance for your assistance!

Usually you would solve this transformation with ICP (iterative approximation) or Kabsch (closed-form solution) algorithms.

I don’t remember if there is a Kabsch implementation for threejs, but you can try reading this post with a series of 3js demos to understand the steps involved. Specifically please see this function: KabshEnvironment.js

ICP takes a different approach - iterative. I wrote a simple implementation for three.js some years ago, I can’t find it now in my github, but its gotta be somewhere :sweat_smile:

An, and oc all of this is for finding the transformation in realtime within threejs; if offline is ok you can use CloudCompare / MeshLab for this

1 Like