Ruby script for Texture positioning

Hey everyone,

I’m trying to write a simple Ruby script that does the following:

  • Takes a material named "TestTexture" from the model
  • Applies it to a face I select
  • Aligns and stretches the texture so it fits exactly to the face’s bounding rectangle
  • Starts from the lower-left corner, aligned with the face orientation

What I’ve already tried:

  • Using face.position_material(material, pt0, pt1, pt2) with 3 valid Point3d
  • Ensuring the points are not collinear, and lie within the face plane
  • Using clean bounding box points (face.bounds.min) and offsetting by axes
  • Also tried projecting from face center using face.normal, xaxis, yaxis
  • Even tried using 8-argument version of position_material (with UVs) — which isn’t supported
  • Attempted to work with face.uv_set — turns out not exposed in Ruby API
  • Also tried using UVHelper to assist with coordinate mapping

No matter what I try, position_material almost always throws this error:

ArgumentError: Cannot convert argument to Geom::Vector3d

Any ideas or sample code would be a huge help :folded_hands:
Thanks in advance!

I believe that the UV coordinates start from the top left corner.

In my testing it appears that the documentation is lacking. The UV coordinates in face.position_material are scale factors between 0.0 and 1,0.

See these other topics:

It isn’t? … Is an exception raised?

We cannot help much without a test model file and a minimal test script demonstrating the issue."

1 Like

OMG!
After years of positioning textures manually (where the red pin always marked the origin at the lower-left corner), I never even considered that position_material’s UV mapping starts from the top-left.

Thank you for pointing that out!

That is what I thought from testing. But I am not so sure now.

The API documentation is not absolutely clear.

What has me questioning it now, is Sketchup::ImageRep#color_ar_uv() which says:

The #color_at_uv method returns a color corresponding to the UV texture coordinates. 0.0, 0.0 maps to the bottom left and 1.0, 1.0 to the top right of the image.

(Emboldening by me.)

Since an ImageRep is the internal representation of material textures, this may be a good “clue”.

Also, look at Geom::PolygonMesh#set_uv()and it’s example snippet.

The API docs could use a little primer of UVs and SketchUp geometry in the Files section.


I think @thomthom has a UV helper / inspection utility that may help in development.

1 Like