# non-linear scaling of STL-files along the Z-Axis

I have an STL that is about 400mm in Z.

I would like it to scale for example 2% for the first 100mm and 1% the rest of the 300mm. This should work for objects that are shorter than 400mm but still scale 2% for the first 100mm.

i am willing to use python to solve this issue.

How do i go about to tackle this issue? I just started learning python and i have gotten a hang of the basics, i just downloaded blender and i see great potential to solve this issue with the two combined.

best regards, Oskar Z

• Hello. I'm not sure if you are asking for a way to do this on a single object (which can be done in a couple of ways using 30 seconds of GUI operations), or on a large amount of objects – Nicola Sap Jan 8 at 8:26
• Imagine 12 objects that are 250mm in Z, tightly packed into a volume with a total of 400mm in Z from lowest to highest point of these twelve objects. The volume will need to scale 2% the first 100mm and 1% on the resting 300mm. – Oskar Z Jan 8 at 8:33
• I see, so we are talking about a single STL, which makes a single Object (althought made of disconnected pieces) in Blender? – Nicola Sap Jan 8 at 8:40
• Imagine a 3D-printer with a volume of 200mm X/Y and 400mm Z If i have filled the inside of this bounding box with details with separate STL's (can be combined into one to make it simple) When i am happy with the orientation of all the objects within the desired volume i want to scale the whole volume according to the aforementioned scaling. – Oskar Z Jan 8 at 9:07
• if I get it right, you cannot do it on per-object basis, because some objects can appear above and below the margin (top 100 mm). So, the only way is to combine all the objects to one single mesh, and scale all the vertices based on their Z position. Like scaling with proportional editing with type 'Projected (2D)' and falloff = 'Linear' along Z axis. – Mechanic Jan 8 at 11:13

A "manual" (non scripted) approach could be this:

1. From the header (2.80+) or footer (2.79) of the Viewport, set the pivot point to 3D cursor

2. From the properties menu of the Viewport (N), place your cursor precisely at the 0.1m location (in my case the mesh starts at Z=0 and is 1:1, so it's exactly 0.1m)

3. In blender 2.79: select all the meshes, join them (CtrlJ) and enter edit mode (Tab). In blender 2.80, there's no need to join.

4. From the toolshelf T, choose the Bisect tool (it's under the "Knife" submenu in Blender 2.80). Make a cut roughly through the Z=0.1 plane.

Then open the last-action menu (F6 in 2.79, bottom left of the viewport in 2.80) and set the Plane Point Z = 0.1, Normal X Y Z = 0 0 1.

5. In wireframe/Xray view, box select (B) everything below the line

(Unfortunately I can't think of a more precise way to do this one step!)

6. Scale along Z by 2%: S, Z, 1.02, Enter

7. Invert selection (CtrlI), scale along Z by 1%: S, Z, 1.01, Enter

Here I've done 25% and -10% for a more visible effect:

• thank you so much! this is really helpful. – Oskar Z Jan 11 at 7:25

You would need to import the file first. If this is only about different sized separate objects, that would not be very difficult. You would just need to loop through all the objects in your scene, check their size and scale them accordingly. Could look something like this:

import bpy
from mathutils import Vector

for o in bpy.context.scene.objects: #bpy.context.view_layer.objects in 2.80
if o.dimensions[2] >= 1: # change the 1 to anything (dimensions[2] is Z)
scale = Vector((2,2,2)) # change the scale to anything
o.scale = [a*b for a,b in zip(o.scale, scale)]
else:
scale = Vector((3,3,3)) # change the scale to anything
o.scale = [a*b for a,b in zip(o.scale, scale)]