How to modify the scale of a material applied to a face?

Hello,

I browsed the SketchUp API and couldn’t find how to change the scale of an existing material applied to a face.

With the position_material method I only manage to move the materials but the scale remains the same:

mod = Sketchup.active_model
face = mod.active_entities.grep(Sketchup::Face) do |f|
  material = f.material     
  mapping = [
    Geom::Point3d.new(0,0,0),
    Geom::Point3d.new(20,30,40)
  ]     
  f.position_material(material, mapping, true)     
end

First, I would just like to know how to change the scale of the material applied to the face.

In a second step, the materials will have to make the size of the face.

Thank you in advance for your help.

Rather than 2 points you can pass 4, 6 or 8. 2 just maps a single texture coordinate to a model coordinate, i.e. translates the texture. With 4 points (2 pairs) you can also set rotation and size. With 6 points (3 pairs) you can shear the texture and with 8 (4 pairs) you can set a “perspective” distortion.

2 Likes

Thanks for these informations ene_su,

I’m now trying to match the UV coordinates of my material to the tops of my face.

The goal is that the image scale adapts to the size of the face:

mod = Sketchup.active_model
tw = Sketchup.create_texture_writer
pt3d = []
mod.active_entities.grep(Sketchup::Face) do |f|
  uv_helper = f.get_UVHelper(true, true, tw) 
  f.outer_loop.vertices.each do |vert| 
    uvq = uv_helper.get_front_UVQ(vert.position)
    u = uvq.x / uvq.z
    v = uvq.y / uvq.z
    q = uvq.z / uvq.z
    p = Geom::Point3d.new(u,v,q)
    pt3d << p
  end  
  material = f.material
  f.position_material(material, pt3d, true)         
end

When I apply this method to the selected face, the material is not at the correct scale.

Do you know what is my mistake?

Thank you

I am facing an extremely complex problem!

Fortunately I am not far from achieving my goals. :slight_smile:

Here is a method which allows to send the position of the vertices of the face and the uv coordinates in an array:

mod = Sketchup.active_model
mapping = []
mod.selection.grep(Sketchup::Face) do |f|
  uv_helper = f.get_UVHelper(true, true)
  f.outer_loop.vertices.each do |vert|
    uvq = uv_helper.get_front_UVQ(vert.position)
    u = uvq.x 
    v = uvq.y
    q = uvq.z
    pt3d = vert.position
    mapping << pt3d
    pt2d = Geom::Point3d.new(u,v,q)
    mapping << pt2d
  end
end
p mapping

I can now modify the position of the texture manually in Sketchup.

If I use position_materiel to apply the 3D points stored in the mapping array, the material returns to its original place:

mod.selection.grep(Sketchup::Face) do |f|
  material = f.material
  f.position_material(material, mapping, true) 
end
p mapping

Now I have to figure out how to coordinate the uvs of one face with the vertices of any face.
I spent the day researching and I will continue tomorrow if I have to.

If you have any ideas to help me move forward, that would be really good.

Thank you

I am unable to understand the logic of the UV values obtained from get_front_UVQ.

mod = Sketchup.active_model
mapping = []
mod.selection.grep(Sketchup::Face) do |f|
  uv_helper = f.get_UVHelper(true, true) 
  f.outer_loop.vertices.each do |vert| 
    uvq = uv_helper.get_front_UVQ(vert.position) 
    mapping << vert.position
    mapping << uvq                           
  end
end
p mapping

For two completely identical faces I get different values which makes the equation impossible to solve.
It is likely that uv_tile_at is the solution to the problem but unfortunately this method only exists from SketchUp 2021.1.

I’m going to have to cheat by importing a previously textured face component each time.
I can then resize it to the dimensions of the active faces in order to copy / paste these UV coordinates.

I don’t like to use this kind of solution but I think I have no other choice.

Please add the SketchUp version you are running to your forum profile so readers know what solutions will and will not work for you.

1 Like