Hello guys, how may i to rotate a texure throught the face using ruby?
I’m trying to create a script that apply a texture on the face but i wish the texture rotate to follow the bigger side of the face.
I have less experience with position material… but, I believe that the condition here ( after entity.make_unique) is not needed, shuld be used for groups too.
Groups in SketchUp are very similar to components, but can from a user point of view be thought of as unique objects. Copying a group in SketchUp will create a group that shares the same definition. SketchUp implicitly makes group unique when edited from the GUI, and from a user point of view groups could be thought of as always being unique.
To honor this behavior, make sure to call #make_unique before modifying a group through the API.
FYI: You can “rotate” an array of UV values in Ruby using Array#rotate() and Array#rotate!(). For UV values this means 90 degrees for each rotation of the values.
I’m trying with just one selected face, it show’s the result “Textura Aplicada (that means it’s worked)”
but the result keep the same
my code example:
def apply_aligned_texture
model = Sketchup.active_model
selection = model.selection
materials = model.materials
active_material = materials.current
# Check if a single face is selected
unless selection.length == 1 && selection.first.is_a?(Sketchup::Face)
puts "Select ONE single face."
return
end
# Check if the active material has a texture
unless active_material&.texture
puts "Select a material with a texture."
return
end
face = selection.first
face.material = active_material
# Identify the longest edge of the face
longest_edge = face.edges.max_by(&:length)
return puts "Error: Could not find a valid edge." unless longest_edge
pt1 = longest_edge.start.position
pt2 = longest_edge.end.position
edge_vector = (pt2 - pt1).normalize
# Create a third point ensuring it is not collinear
normal_vector = face.normal
perpendicular_vector = edge_vector.cross(normal_vector).normalize
if perpendicular_vector.length == 0
puts "Error: Collinear vectors, unable to calculate a valid coordinate system."
return
end
pt3 = pt1.offset(perpendicular_vector, 1.m)
# Create a `UVHelper` to obtain correct UV coordinates
uv_helper = face.get_UVHelper(true, true)
uv1 = uv_helper.get_front_UVQ(pt1)
uv2 = uv_helper.get_front_UVQ(pt2)
uv3 = uv_helper.get_front_UVQ(pt3)
# Normalize UVs (prevent distortion)
def normalize_uv(uv)
uv.x /= uv.z if uv.z != 0
uv.y /= uv.z if uv.z != 0
uv.z = 1
uv
end
uv1 = normalize_uv(uv1)
uv2 = normalize_uv(uv2)
uv3 = normalize_uv(uv3)
# Get the texture dimensions
texture = active_material.texture
texture_width = texture.width
texture_height = texture.height
texture_aspect_ratio = texture_width.to_f / texture_height
# Calculate the aspect ratio of the longest edge
edge_length = longest_edge.length
perpendicular_length = 1.m # Arbitrary length used for the perpendicular vector
face_aspect_ratio = edge_length.to_f / perpendicular_length
# Determine if the texture needs to be rotated
if (texture_aspect_ratio > 1 && face_aspect_ratio < 1) || (texture_aspect_ratio < 1 && face_aspect_ratio > 1)
# Rotate UV coordinates by 90 degrees
uvs = [uv1, uv2, uv3]
# Swap x and y values to simulate rotation
uvs.each do |uv|
uv.x, uv.y = uv.y, uv.x
end
# Reorganize UV coordinates to reflect the rotation
uv1, uv2, uv3 = uvs.rotate(1)
end
# Apply the texture correctly to the face
model.start_operation('Apply Aligned Texture', true)
begin
mapping = [pt1, uv1, pt2, uv2, pt3, uv3]
face.position_material(active_material, mapping, true)
puts "Texture applied successfully!"
rescue => e
puts "Error applying texture: #{e.message}"
ensure
model.commit_operation
end
# Force viewport update
model.active_view.invalidate
end
apply_aligned_texture