TextureWriter filename - empty response
-
I am unable to get TextureWriter.filename to return the texture filename. Using this code:
# Display texture names def display_tex_names tw = Sketchup.create_texture_writer load_textures(tw, Sketchup.active_model.entities) tex_index = 1 while (tex_index <= tw.count) puts(tw.filename(tex_index)) tex_index += 1 end tw.write_all("D;", false) Sketchup.active_model.commit_operation end
outputs zero-length strings (not nil) to the Ruby console.
I know that the TextureWriter object was created successfully and that the texture files have valid names, because the files are written to the specified directory by TextureWriter.write_all. (By implication, the load_textures function is also working properly.)
What is supremely frustrating is that I was able to extract the filenames at one point in my code development, but I made a change and later encountered this problem.
-
What is
load_textures(...)
?
Why not simply use Didier's & Others very-fast-texture-writer code as an example.
http://sketchucation.com/forums/viewtopic.php?p=299463#p299463
Rather than iterate all of the model.entities you can iterate the materials, ignore ones without textures and apply each material to an empty group that you use as the 'source' in the tw ? -
@tig said:
What is
load_textures(...)
?
Why not simply use Didier's & Others very-fast-texture-writer code as an example.
http://sketchucation.com/forums/viewtopic.php?p=299463#p299463
Rather than iterate all of the model.entities you can iterate the materials, ignore ones without textures and apply each material to an empty group that you use as the 'source' in the tw ?load_textures is a recursive function that iterates over all entities:
# Load textures (recursive)) def load_textures( entities ) entities.each do |entity| if entity.is_a?(Sketchup;;Face) $tw.load(entity, true) $tw.load(entity, false) elsif entity.is_a?(Sketchup;;Group) || entity.is_a?(Sketchup;;ComponentInstance) if entity.is_a?(Sketchup;;Group) definition = entity.entities.parent else definition = entity.definition end load_textures(definition.entities) end end end
I did not post it because it (presumably) works.
The problem with very-fast-texture-writer(for me) is that it returns the textures associated with all of the materials, including those not actually used by the entities. I would need to delete these unreferenced textures for my application, which means yet another pass through all the entities.
This still begs the question, however, of why TextureWriter.filename is returning zero-length strings. (I am an expert C++ developer but a neophyte Ruby programmer, so I am not ruling out some obvious oversight on my part.)
-
By iterating every entity in the model and every entity within group/definition entities you are making a lot of unnecessary iterations just to find 'used textures'.
Also the last written version of a texture could be taken from a face that has been UV mapped and so the texture files 'proportions' etc might not be those of the starting texture ?
This is how I would do it.
Iterate model.materials, filtering for only materials that include textures.
Now iterate through each of those in turn, and theniterate then through model entities and group/definition entities [much as your posted example] until you find an entity that is using that material [front & back for faces] as soon as you get a match 'break' the iteration loop - we are keeping the material in the list - if you iterate the whole of the entities collection without a hit you delete the material from your array of textured-materials.
NOW process the remaining array textured-materials with the texturewriter using a temp group like very-fast-texturewriter... It has to be faster that ? -
There appears to be a software defect in the SketchUp API. Loading the textures into TextureWriter and then attempting to access their filenames using TextureWriter.filename(index) returns only empty strings. However, if you call TextureWriter.write_all beforehand:
# Display texture names def display_tex_names $tw = Sketchup.create_texture_writer load_textures(Sketchup.active_model.entities) $tw.write_all("D;", false) tex_index = 1 while (tex_index <= $tw.count) UI.messagebox($tw.filename(tex_index)) tex_index += 1 end Sketchup.active_model.commit_operation end
then the filenames are returned properly.
Confusing matters further, the TextureWriterindices are one-based rather than the expected zero-based array.
Advertisement