Module: TT::Material
- Defined in:
- TT_Lib2/materials.rb
Overview
Collection of Material methods.
Class Method Summary collapse
-
.get_current(model = Sketchup.active_model) ⇒ Sketchup::Material
Because SketchUp will bugsplat if a material selected from the library is used this method attempts to add the material to the model.
-
.in_model?(material, model = Sketchup.active_model) ⇒ Boolean
When the user clicks on a material in the materials browser
model.materials.current
will return a material that does not exist in the model. -
.remove(material, model = Sketchup.active_model) ⇒ Boolean
Safely removes a material from a model.
Class Method Details
.get_current(model = Sketchup.active_model) ⇒ Sketchup::Material
Do not use within a start_operation block. This method uses a temporary operation which will break any already initiated operations.
Because SketchUp will bugsplat if a material selected from the library is used this method attempts to add the material to the model.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'TT_Lib2/materials.rb', line 45 def self.get_current( model = Sketchup.active_model ) materials = model.materials m = materials.current return m if m.nil? # Check if material already exists. If it does - reuse it. name = m.name if x = materials[ name ] if x.color.to_i == m.color.to_i && x.alpha == m.alpha # No texture applied. if x.texture.nil? && m.texture.nil? materials.current = x return x end x_basename = File.basename( x.texture.filename ) m_basename = File.basename( m.texture.filename ) if m_basename == m.texture.filename # If the texture only have a filename - not a path. if x_basename == m.texture.filename && x.texture.width == m.texture.width && x.texture.height == m.texture.height materials.current = x return x end else # If the texture only have a filename with full path. if x.texture.filename == m.texture.filename && x.texture.width == m.texture.width && x.texture.height == m.texture.height materials.current = x return x end end else end end # Transfer name and colour. new_material = materials.add( name ) new_material.color = m.color new_material.alpha = m.alpha # Any textures require special attention. If the filename contains a valid # path to an existing file nothing special needs to be done. # # But if the filename refers to a non-existing file it needs to be written # out to a temp file. This is where things become a bit risky and hacky. # Because TextureWriter doesn't accept Material objects the orphan material # needs to be temporarily applied to the model (risky). # # Materials from SketchUp's default library only contains the name of the # file without any paths. This is because the texture is located only within # the.skm. if m.texture filename = m.texture.filename if File.exist?( filename ) new_material.texture = filename else # Create temp file to write the texture to. temp_path = TT::System.temp_path temp_folder = File.join( temp_path, 'tt_su_tmp_mtl' ) temp_filename = File.basename( filename ) temp_file = File.join( temp_folder, temp_filename ) unless File.exist?( temp_folder ) Dir.mkdir( temp_folder ) end # Create temp group with the orphan material and write it out. # # Wrap within start_operation and clean up with abort_operation so it # doesn't end up in the undo stack. # # (!) This means this method should not occur within any other # start_operation blocks - as operations cannot be nested. tw = Sketchup.create_texture_writer model.start_operation( 'Extract Orphan Material' ) begin g = model.entities.add_group g.material = m tw.load( g ) tw.write( g, temp_file ) ensure model.abort_operation end # Load texture to material and clean up. new_material.texture = temp_file File.delete( temp_file ) end new_material.texture.size = [ m.texture.width, m.texture.height ] end materials.current = new_material new_material end |
.in_model?(material, model = Sketchup.active_model) ⇒ Boolean
When the user clicks on a material in the materials browser
model.materials.current
will return a material that does not
exist in the model. It is possible to apply this material to entities in
the model, but it will evetually BugSplat.
This method checks if a given material exist in the model and is safe to use.
28 29 30 31 32 |
# File 'TT_Lib2/materials.rb', line 28 def self.in_model?( material, model = Sketchup.active_model ) #model.materials.any? { |m| m == material } # This is probably just as good to write. Is this wrapper method needed? model.materials.include?( material ) end |
.remove(material, model = Sketchup.active_model) ⇒ Boolean
Safely removes a material from a model.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'TT_Lib2/materials.rb', line 143 def self.remove( material, model = Sketchup.active_model ) # SketchUp 8.0M1 introduced model.materials.remove, which turned out to be # bugged. It didn't remove the material from the entities in the model - # leaving the model with rouge invalid materials. # To work around this all entities are processed before the method is called. # The workaround for older versions also require this to be done. for e in model.entities e.material = nil if e.respond_to?( :material ) && e.material == material e.back_material = nil if e.respond_to?( :back_material ) && e.back_material == material end for d in model.definitions next if d.image? for e in d.entities e.material = nil if e.respond_to?( :material ) && e.material == material e.back_material = nil if e.respond_to?( :back_material ) && e.back_material == material end end materials = model.materials if materials.respond_to?( :remove ) materials.remove( material ) else # Workaround for SketchUp versions older than 8.0M1. Add all materials # except the one to be removed to temporary groups and purge the materials. temp_group = model.entities.add_group for m in model.materials next if m == material g = temp_group.add_group g.material = material end materials.purge_unused temp_group.erase! true end end |