How can get UV when material on group?.
You probably cannot.
Materials must be put on the faces of you want to get a UV map.
@francisquitof is most likely correct
Here’s a bit of test code that reports UVs for the first face in the first container in the model.
model = Sketchup.active_model
ents = model.active_entities
grp = ents[0] # assume the first item is a group or component
mat = grp.material
face = grp.definition.entities.grep(Sketchup::Face)[0]
unless face.material = nil
face.material = mat
tw = Sketchup.create_texture_writer
uv_helper = face.get_UVHelper(true, true, tw)
face.outer_loop.vertices.each do |vert|
uvq = uv_helper.get_front_UVQ(vert.position)
# "Normalize" UVQ to UV.
# #x, #y and #z corresponds to U, V and Q respectively,
# as SketchUp re-uses the normal Point3d objects for UVQs
u = uvq.x / uvq.z
v = uvq.y / uvq.z
puts "u=#{u} v=#{v}"
end
#face.material = nil
Sketchup.undo
end # if
2 Likes
This is the way I use now, but I think the efficiency is too low.
I started working out the mathematics producing the projection of the image onto the surface with this model.
1234567890.skp (113.7 KB)
Now I’m waiting for the penny to drop.
1 Like
I solved the calculation under orthographic projection.
def calculate_face_uv_tr(face, mat)
return IDENTITY unless mat
return IDENTITY unless mat.texture
tr = Geom::Transformation.new(ORIGIN, face.normal)
width, height = mat.texture.width, mat.texture.height
uv_tr = Geom::Transformation.scaling(ORIGIN, 1 / width, 1 / height, 0)
uv_tr * tr.inverse
end
1 Like
Well done.
Here’s the way I’m visualizing the question.
Also, there are often two special cases to investigate. What happens when the face normal is a straight up or straight down.
1 Like