0
$\begingroup$

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

$\endgroup$
  • $\begingroup$ 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 $\endgroup$ – Nicola Sap Jan 8 at 8:26
  • $\begingroup$ 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. $\endgroup$ – Oskar Z Jan 8 at 8:33
  • $\begingroup$ I see, so we are talking about a single STL, which makes a single Object (althought made of disconnected pieces) in Blender? $\endgroup$ – Nicola Sap Jan 8 at 8:40
  • $\begingroup$ 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. $\endgroup$ – Oskar Z Jan 8 at 9:07
  • $\begingroup$ 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. $\endgroup$ – Mechanic Jan 8 at 11:13
0
$\begingroup$

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

    enter image description here

  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)

    enter image description here

  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.

    enter image description here

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

    enter image description here

    (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:

    enter image description here

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

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)]
$\endgroup$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.