How to Scale A node Using FBX SDK python or C+

Hi comunity.

In this moment I’m Working in a project using Fbx Files for get mesh for my Game Engine, after I need to draw this Mesh. For now I can get the mesh, the vertices and spaces points and draw normality but I need to scaling this meshes before drawing, I know, I can make that, Multiply the matrix or spaces Points by a Scaling MAtrix. but reading the python classes, FBxNode Class have LclScaling.Set(fbxDouble3) here is and example using cubeMan in python

Sorry for my english but please Try to help me

import fbx
import sys
import numpy as np
filepath = 'cubeMan.fbx'
manager = fbx.FbxManager.Create()
importer = fbx.FbxImporter.Create(manager, 'myImporter')
status = importer.Initialize( filepath )

list = []
if status == False:
    print('FbxImporter initialization failed.')
    print('Error: %s' % importer.GetLastErrorString())
    sys.exit()


scene = fbx.FbxScene.Create( manager, 'myScene' )
importer.Import(scene)
importer.Destroy()
a = scene.GetNodeCount()


for i in range(0, a):
    b = scene.GetNode(i)#Obtengo los nodos del archivo FBX
    print(b.GetName())#Imprimo cada uno de los nodos


#Scaling Here doesn't work
t = fbx.FbxDouble3(0.5, 0.5, 0.5)
b = scene.GetNode(1)
b.LclScaling.Set(t)
k = b.LclScaling.Get()
print(*k, 'here')
f = b.GetGeometry()
print(f.GetControlPointAt(0))

c = scene.GetGeometry(0)#Obtengo la geometria de la malla 0
c.GetPolygonVertices()#De esta maneta obtengo los vertices, la triangulacion de la malla
for i in range(0, c.GetControlPointsCount()):#Obtengo los puntos en el espacio de la malla
        list1 = []
        q = c.GetControlPointAt(i)#obtengo XYZ el vector fbx4
        list1.append(q[0])
        list1.append(q[1])
        list1.append(q[2])
        list.append(list1)
n = np.array(list, np.float32)
print(n)


in the line 28 to 32 I get the first node, after I scale by fbx.double3(0.5, 0.5, 0.5), inmediatily I print the new values but when I get the geometry of that node the values is the same of the original values, Values no change.

Please I need to do that, I’m trying this for too many days I can’t do that Need help. sorry for my english is not my first language

An FBX Scene is structured something like a Maya file, with a separation between the transform hierarchy and the individual geometries. When finally rendered the vertex positions will be transformed but they are stored in their original positions:


In this example (from the SDK docs) no matter what you do to the transform cubeNode the contents of cube will be the same, even though the rendered results will appear different.

If you need the final position of the vertices you’d need to get the world space matrix using EvaluateGlobalTransform() on the node and then multiply the positions of the vertices by that matrix.

1 Like

Hi

friend Thank you for the answer really Thank you so much.

In this moment I have it almost ready, please Read…

import fbx
import sys

import numpy as np
filepath = 'cubeMan.fbx'
manager = fbx.FbxManager.Create()
importer = fbx.FbxImporter.Create(manager, 'myImporter')
status = importer.Initialize( filepath )

list = []
if status == False:
    print('FbxImporter initialization failed.')
    print('Error: %s' % importer.GetLastErrorString())
    sys.exit()


scene = fbx.FbxScene.Create( manager, 'myScene' )
importer.Import(scene)

a = scene.GetNodeCount()

for i in range(0, a):
    b = scene.GetNode(i)#Obtengo los nodos del archivo FBX
    print(b.GetName(), b.GetChildCount())#Imprimo cada uno de los nodos
    if(b.GetChildCount()>=1):
        for i in range(0, b.GetChildCount()):
            #print(b.GetChild(i))
            k = b.GetChild(i)
            print(k.GetName(), 'child of ', b.GetName())


lScalingM = fbx.FbxMatrix()
lScalingM.SetIdentity()


#Here I just print the identity Matrix
"""
#Here I just print the matrix
for i in range(0, 4):
    print(*lScalingM[i], 'matrix')
"""


b = scene.GetNode(1)
"""
for i in range(0, 4):
    print(*b.EvaluateGlobalTransform()[i])

    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 
"""

b.ScalingActive.Set(1)#Active Scaleing in Chest Parent Node
px = fbx.FbxDouble3(0.5, 0.5, 0.5)#Vector of Scaling in Chest Node
b.LclScaling.Set(px)#Set Escaling Vector In Chest Node
translation_vector = fbx.FbxVector4(0.0, 0.0, 0.0, 1.0)#Translation Vector
rotation_vector = fbx.FbxVector4(0.0, 0.0, 0.0, 1.0)#Rotation Vector
Lscaling = fbx.FbxVector4(b.LclScaling.Get())# Lscaling =


lScalingM.SetTRS(translation_vector, rotation_vector, Lscaling)#Set Scale Matrix in LScalingM
for i in range(0, 4):
    print(*lScalingM[i], 'matrix 2')
#Here print My Scaling Matrix in lScalingM
"""
0.5 0.0 -0.0 0.0 
0.0 0.5 0.0 0.0
0.0 0.0 0.5 0.0 
0.0 0.0 0.0 1.0 
"""

for i in range(0, 4):
    print(*b.EvaluateGlobalTransform()[i])
"""
0.5 0.0 0.0 0.0
0.0 0.5 0.0 0.0
0.0 0.0 0.5 0.0
0.0 2.8306769954489877 0.0 1.0  --->>> 'Here My first problem' It must be 0.0, 0.0, 0.0, 1.0 but the 4 component is ignored (y)
"""
#'Here I just print the Sacaling Matrix'


l = b.GetGeometry()
print(l.GetControlPointsCount())
print(l.GetControlPointAt(0))


importer.Destroy()

I I already have the Scaling Matrix in EvaluateGlobalTransform() of my chest Node in variable “b” Chest is the parent of the all Nodes of the CubeMan Object. I also have other Scaling Matrix in “lScalingM” variable. My problem if I want to Scaling In this moment I need to take each vértices of each Node and multiply by my Scaling Matrix, I do this question because chest it’s the parent, is there any way to multiply all the object by my Scaling Matrix, I know do this in numpy array, but I think there is so easy form to do that in fbx. Thank you so much for the help

Hi Again Friend

I have applied the scaling matrix for the position

TransforMatrix = fbx.FbxMatrix(b.EvaluateGlobalTransform())

list = []
l = b.GetGeometry()
for i in range(0, l.GetControlPointsCount()):
    list1 = []
    FbxPosition = l.GetControlPointAt(i)
    e = TransforMatrix.MultNormalize(FbxPosition)
    list1.append(e[0])
    list1.append(e[1])
    list1.append(e[2])
    list.append(list1)
n = np.array(list, np.float32)
print(n)

do I need to make the same for each Child Node ? I think there is another easy way for this ? This is for my game engine

You’ll need to decide between scaling the vertices – which happens in the local coordinates system of the FBXNode – and scaling the Nodes themselves.

Some of this will depend on your game engine. but generally if you scale a Node you are scaling its children as well so you won’t need to scale all of the items, just the topmost one in the hierarchy. If you only want to scale one item you need scale down the children to keep their sizes.

If you’re scaling the vertices, you’ll be scaling them in the local coordinate system of the node they belong to – if that coordinate system is rotated or scaled, you may not get what you expect.

The difference between scaling the node and scaling the vertices is the difference between using the scale tool on an entire object in Maya or Blender, and grabbing the individual vertices and scaling them that way.