Mesh Parts are live!

If you’re using Blender, this script may be useful for you to perfectly realign (probably multiple) meshes the way they were originally were placed in Blender rather than eyeballing it all the time.~~~

Select a single object in Blender (merge objects if you export multiple at the same time, the Studio mesh importer does the same as far as I know anyway), then run this script in Blender:

Use this code instead: Mesh Parts are live!

OLD/ORIGINAL CODE BELOW

import bpy

export_scale = .01 # configure your fbx export scale in Blender here
import_scale = .01

outp_script = """
local sel = game.Selection:Get();
assert(#sel == 2);
local meshPart = sel[1];
local anchorPart = sel[2];
if (anchorPart:IsA("MeshPart")) then
    meshPart, anchorPart = anchorPart, meshPart;
end
meshPart.CFrame = anchorPart.CFrame * CFrame.new({:.20f}, {:.20f}, {:.20f});
"""

scale = export_scale / import_scale
for obj in bpy.data.objects:
    if obj.select and obj.type == 'MESH':
        dims = obj.dimensions
        mesh = obj.data
        vertices_world = [(obj.matrix_world * vert.co) for vert in mesh.vertices]
        offx = (min([vec.x for vec in vertices_world]) + dims.x * .5) * scale
        offy = (min([vec.y for vec in vertices_world]) + dims.y * .5) * scale
        offz = (min([vec.z for vec in vertices_world]) + dims.z * .5) * scale
        # note: blender has the Z-axis pointing up
        bpy.context.window_manager.clipboard = outp_script.format(offx, offz, -offy)

After doing this, it will copy a Lua script to your system clipboard. In Studio, select both your MeshPart you want to align and another normal BasePart you want to base its alignment on. Then paste and run the Lua script in Studio’s command bar, which will move the selected MeshPart such that it is offset and rotated from the normal BasePart as it were in Blender from the world origin (this alignment BasePart is thus basically the Blender world origin).

If you align multiple MeshParts to the same BasePart this way, you get perfect alignment.

Bit of a messy workflow, but maybe it’s useful to someone else too ;).

3 Likes

That sounds incredible, but i’m a scrub when it comes to scripting. Could you make a quick video tutorial? I’d be extremely thankful. :smiley:

So if i understand correctly, you use the script in both blender and studio?

The original (Python) script is only used in Blender, but that script outputs a Lua script to the system clipboard, which you can paste into Studio’s command bar to actually update the MeshPart CFrame. That generated script changes depending on the bounding box your objects have in Blender.

1 Like

Just select what you want to be mesh, then right click and “export selection”. It will be an .obj file so use some program to export it to .fbx. Remember about 5000 poly limit.

Where is “export selection”

Untitled.png

when I right click on something I want mesh I only see this. I saw export selection once, but I was never able to recreate it.

You need to right click the object in the explorer :P

1 Like

Thanks a million!

While working on my bike i came into this problem, i need to make the cluster that size but cant resize it below 0.2, what do i do now?

You can throw the mesh/texture id into a specialmesh instead and scale that using the mesh’s Scale property if you want.

1 Like

I’ve tried with filemeshes, it doesnt work!

Then you’re doing it wrong

Wasnt doing anything wrong, turned out that i had my camera inside the mesh and couldnt see it… :joy: :joy:

I am not sure if that’ll work, but I would try to use model resize plugin.

SpecialMeshes have a Scale property which you can adjust to make the mesh bigger/smaller, so no need for a plugin like that.

2 Likes

There you go, meshes truly are amazing!

14 Likes

So I tried your script and this is what happens

The result is supposed to be like this

But it ends up looking like this

Is it because of the

export_scale = .01 # configure your fbx export scale in Blender here
import_scale = .01

If so how would I determine those scales?

TL:DR the script doesn’t move the object, and if it does it barley moves it at all.

2 Likes

The export scale is determined by this value during export:

Roblox sees 1 “blender unit” as 100 studs, which is the .01 fixed import scale.
This all assumes you do actually use the blender units (“None”).

Should note that I’ve figured the dimensions of the object used in the script are object-space, not world-space, so if you have applied either a rotation or scale object transformation (in object mode), you should apply those first before running the script. I’ll probably change the script itself later to compute a proper world-space AABB later on, but that could cause issues too with the positioning.

1 Like

If anyone else still cares enough to use my technique for properly aligning meshes ( :stuck_out_tongue: ), here’s an updated script to be used in Blender which computes the bounds properly.

import bpy
from mathutils import Vector

export_scale = .01 # configure your fbx export scale in Blender here
import_scale = .01 # do NOT edit this value, only the export_scale above!!!

outp_script = """
local sel = game.Selection:Get();
assert(#sel == 2);
local meshPart = sel[1];
local anchorPart = sel[2];
if (anchorPart:IsA("MeshPart")) then
    meshPart, anchorPart = anchorPart, meshPart;
end
meshPart.CFrame = anchorPart.CFrame * CFrame.new({:.20f}, {:.20f}, {:.20f});
"""

scale = export_scale / import_scale
for obj in bpy.data.objects:
    if obj.select and obj.type == 'MESH':
        dims = obj.dimensions
        mesh = obj.data
        vertices_world = [(obj.matrix_world * vert.co) for vert in mesh.vertices]
        
        # compute world space bounds of the selected object 
        minvec = Vector()
        maxvec = Vector()
        for axis in ['x', 'y', 'z']:
            setattr(minvec, axis, min([getattr(vec, axis) for vec in vertices_world]) * scale)
            setattr(maxvec, axis, max([getattr(vec, axis) for vec in vertices_world]) * scale)
        
        offsetvec = (minvec + maxvec) * .5
        
        # note: blender has the Z-axis pointing up
        bpy.context.window_manager.clipboard = outp_script.format(offsetvec.x, offsetvec.z, -offsetvec.y)
5 Likes

I think the reason that uploading meshes is free is because too many things can mess up: flipped normals, missing textures, bad smoothing, etc. It would cost the dev too much to re-upload (I think it took me over a dozen tries just to get the mesh I was uploading to appear correctly). As for audio, it’s pretty safe to say that what you’re uploading is what you’re getting in-game. Also, I think they’re planning on making the payments for audio uploads tiered.