scale and dim ob ?

i want to change the dim of ob to convert to metric or imperial

now i can change the scale value in N panel with script but when i print it it does not have the same value ?

how does it work?



for obj in bpy.context.scene.objects:
 if obj.type == 'MESH':
  data = obj.data

  print ('ob name =',obj.name)
  print ('before ob scale =',obj.scale, ' dim=',obj.dimensions)
  print ()
#  obj.scale *= metrictofeet
  obj.scale *= imperialtometric
  print ('after ob scale =',obj.scale, ' dim=',obj.dimensions)
 
  print ()



have to test by changing the dim instead

thanks

What is your output?

After your PM I wrote:


import bpy

objs = bpy.context.selected_objects
if len(objs) > 0:
    for o in objs:
        o.matrix_basis*=o.matrix_basis.Scale(0.0254, 4, (1,0,0))
        o.matrix_basis*=o.matrix_basis.Scale(0.0254, 4, (0,1,0))
        o.matrix_basis*=o.matrix_basis.Scale(0.0254, 4, (0,0,1))

I ran it on a default cube, then ran your print statement and got:

>>> o = bpy.context.object
>>> print (‘after ob scale =’,o.scale, ’ dim=’,o.dimensions)
after ob scale = <Vector (0.0254, 0.0254, 0.0254)> dim= <Vector (0.0508, 0.0508, 0.0508)>

*= scale should work as well actually, maybe scene.update() is required?

porblem is that i entered objects in BU = Metric but values where in feet
so i need to modify the dimensions so that when i go into imperial mode i get the same values!
hope your following here!

what is the n panel scale value?

let say that in bu mode you have the cube 2 meters dim scale=1

i need to make the dim = 2 ft when in imperial mode

so this means i have to change the dimensions of the ob like 2 /3.2808
so that when i change mode to imperial i have 2 feet !

how do you change the dimensions of the ob and not the scale !

thanks

i thnk it needs to be Ctrl-a after changing the scale
so that N panel is updated with the real values

how do you do this with bpy ?

or may be is there a transform using bpy ?

not bpy.ops

thanks

well, it really depends on how you want this to work:

1 - change scale of objects, so that their scale/dimension gets like it should.

2 - change mesh data itself, so that dimension gets like it should

#1:
ob.scale *= 1 / 3.2808399

#2:
ob.data.transform(Matrix.Scale(1/3.2808399, 4))

did a new test and to see the proper dimensions in N panel
i also needed to ctrl-A the objects
then the re scaled values are showing the right values in feet or metric in N panel window

but again wondering here if the object already has a scale or if the scene has a scale value how this would change things!

also using this world transform what does the 4 means or do here ?

thanks

you really don’t have to apply transformations, my both code snippets work fine…

there is a scene scale property:
scene.unit_settings.scale_length

so you could change from BU/metric to imperial and change that scale to 1/3.2808399 (look at the grid to see what’s going on)

but that scale_length property doesn’t change when you switch between unit systems

Scale(factor, size, axis)
… classmethod:: Scale(factor, size, axis)
Create a matrix representing a scaling.
:arg factor: The factor of scaling to apply.
:type factor: float
:arg size: The size of the scale matrix to construct [2, 4].
:type size: int
:arg axis: Direction to influence scale. (optional).
:type axis: :class:Vector
:return: A new scale matrix.
:rtype: :class:Matrix

Mesh.transform() requires a 4x4 matrix!

did a test with may objects in scene
from inches to feet and seems to do the right conversion

only problem is that it changes the origins but amd the object all all re located somewhere else

not certain if it is possible to correct that ?

let say that you have plate in front of a cube after conversion object are not where they should be

i can upload a sample file if needed to show this effect !
let me know

any ideas?

thanks

interesting yeah…

i usually use Mesh.transform() for meshes generated by Object.to_mesh(), which got their origin at global 0,0,0

maybe you need to move the origin to 0,0,0 before transforming…

But you could also use bpy.ops:

  • select all objects
  • scale by factor x

well one way i found
may be join the related different objects together then the scaling would be done for one object and all parts would then stay where they should be

and i can re calculate the origin

thanks

grouping is a good idea, parent to an empty at 0,0,0 and scale - this hack was already recommended in a case, if one wants to transform with a certain pivot point. If you call the bpy.ops.transform.resize() operator, it won’t respect your pivot settings and doesn’t have a pivot argument. So the only chance is to use temp group…

joining keeps things together and in the relative location

only problem is the large scale factor which is huge and things get so smaller they get very far away from each other

or locations don’t change but dimensions do and difficult to see in viewport
have to select from outliner and bring then back closer to origin

thanks