This is a simple .skm material file management browser that runs on windows.
The principle of implementation is to read the user’s stored .skm folder, generate menus and display .skm thumbnails.
Users can click on the thumbnail to apply the material to the scene object.
The customization part of this plugin:
TMP_THUMBNAIL_BASE_DIR = “D:/_iFile/tem” #Thumbnail storage location
map5 = [“D:/_iFile/Maps”] # Directory of .skm files
The current interactive experience is not very good, there are mainly the following problems:
1、Only display the first level menu , can not support multi-level menu .
2, a menu menu display content for the current menu contains all the contents of the sub-folder , can not be good at all levels of the menu to display their own content.
I look forward to understanding the optimization of friends to help
require 'sketchup.rb'
require 'extensions.rb'
# Attempt to load the rubyzip library
begin
require 'zip'
rescue LoadError # If loading fails, try installing the rubyzip library
puts "The rubyzip library is not installed, trying to install..."
system("gem install rubyzip")
require 'zip'
end
class Lite_maplib
TMP_THUMBNAIL_BASE_DIR = "D:/_iFile/tem" #Thumbnail storage location
IMAGE_EXTENSIONS = ['.jpg', '.png', '.skm']
def initialize
@count = 0
end
def maplib
model = Sketchup.active_model
map = []
map5 = ["D:/_iFile/Maps"] # Directory of .skm files
map5.each do |hmn|
map << hmn.rstrip if File.exist?(hmn.rstrip)
end
map_path2 = []
map.each do |path|
Dir.glob("#{path}/*").select { |dir| File.directory?(dir) }.each do |subfolder|
all = load_images_and_skm_files(subfolder)
map_path2 << [all, File.basename(subfolder), subfolder] if all.any?
@count += all.size
end
end
menu, pic = generate_html_content(map_path2)
html = generate_html(menu, pic)
show_dialog(html)
setup_callbacks
end
def load_images_and_skm_files(subfolder)
all1 = Dir.glob("#{subfolder}/**/*.jpg")
all2 = Dir.glob("#{subfolder}/**/*.png")
allskm = Dir.glob("#{subfolder}/*.skm")
all1 + all2 + allskm
end
def generate_html_content(map_path2)
menu = ""
pic = ""
map_path2.each_with_index do |folder, index|
menu << %(<li onclick="showFolderContents('#{index}')"><a href="#"> #{folder[1]} </a></li>\n)
pic << %(<div class="xl-box" id="folder-#{index}" style="display:#{index == 0 ? 'block' : 'none'}">\n)
folder[0].each do |image|
pic << generate_image_html(image)
end
pic << %(</div>\n)
end
[menu, pic]
end
def generate_image_html(image)
file_type = File.extname(image)
absolute_path = File.expand_path(image) # Get absolute path
if [".jpg", ".png"].include?(file_type)
%(<input type="image" id="#{absolute_path}" src="#{absolute_path}" title="#{File.basename(image)}" width="80" height="80" onclick="return getid(this.id)" value="#{absolute_path}">\n)
elsif file_type == ".skm"
thumbnails = extract_skm(image)
if thumbnails.any?
%(<input type="image" src="#{thumbnails[0]}" title="#{File.basename(image)}"width="80" height="80" onclick="return applyMaterial('#{absolute_path}')">\n)
else
puts "Thumbnail not found: #{image}"
""
end
else
""
end
end
def generate_html(menu, pic)
%Q[
<!DOCTYPE html>
<html>
<head>
<title>maplib</title>
<meta charset="utf-8">
</head>
<style>
* {}
a {text-decoration: none;color:#ccc;}
body, html {margin: 0;padding: 0;height: 100%;background-color: #444;}
.container {display: flex;height: 100%;}
.nav {width: 150px;padding: 10px;box-sizing: border-box;background-color: #515151;}
.main {flex: 1;padding: 20px;box-sizing: border-box;}
ul {padding-inline-start: 5px;font-family: "YaHei", "Microsoft YaHei", sans-serif;}
li {height: 30px;box-sizing: border-box;list-style: none;}
ul li a{display:block;width:100%;}
ul li a:hover{color:#fff;}
.xl-box {display: none;}
</style>
<body>
<div class="container">
<div class="nav">
<ul class="ul">
#{menu}
</ul>
</div>
<div class="main">
<div>
#{pic}
</div>
</div>
</div>
<script>
function getid(id) {
var user_input1 = document.getElementById(id);
sketchup.getUserInput01(user_input1.value);
}
function applyMaterial(skm_path) {
console.log("Applying material from: " + skm_path); // 输出路径
var skm_name = skm_path.split('/').pop();
sketchup.applyMaterial(skm_path); // 传递绝对路径
}
function showFolderContents(folderIndex) {
var boxes = document.getElementsByClassName("xl-box");
for (var i = 0; i < boxes.length; i++) {
boxes[i].style.display = "none";
}
var activeBox = document.getElementById("folder-" + folderIndex);
if (activeBox) {
activeBox.style.display = "block";
}
}
document.addEventListener("DOMContentLoaded", function() {
showFolderContents(0);
});
</script>
</body>
</html>
]
end
def show_dialog(html)
$dlg = UI::HtmlDialog.new({
dialog_title: "Lite maplib (AllSKM#{@count})",
preferences_key: "Cgmg_map_dlg",
scrollable: true,
resizable: true,
width: 600,
height: 600,
style: UI::HtmlDialog::STYLE_DIALOG
})
$dlg.set_html(html)
$dlg.show
$dlg.bring_to_front
end
def setup_callbacks
$dlg.add_action_callback("getUserInput01") { |action_context, user_input1|
maplib_Paint = File.basename(user_input1, File.extname(user_input1))
model = Sketchup.active_model
materials = model.materials
unless materials[maplib_Paint]
material = materials.add(maplib_Paint)
material.texture = user_input1
end
materials.current = materials[maplib_Paint]
Sketchup.send_action('selectPaintTool:')
}
$dlg.add_action_callback("applyMaterial") { |action_context, skm_path|
skm_path = File.expand_path(skm_path)
puts "Received skm path: #{skm_path}" # Output received path
load_skm_material(skm_path)
}
end
def load_skm_material(skm_path)
model = Sketchup.active_model
materials = model.materials
skm_name = File.basename(skm_path, File.extname(skm_path))
puts "Path to the material file to try to load: #{skm_path}"
if File.exist?(skm_path)
begin
load_file(skm_path, "Loading material")
rescue => e
puts "Failed to load material file: #{e.message}"
return
end
material = materials[skm_name]
if material
materials.current = material
Sketchup.send_action('selectPaintTool:')
puts "Applied Materials: #{skm_name}"
else
puts "Material does not exist: #{skm_name}"
end
else
puts "File does not exist: #{skm_path}"
end
end
def extract_skm(skm_path)
skm_dir = File.dirname(skm_path)
skm_name = File.basename(skm_path, '.skm')
thumbnail_dir = File.join(TMP_THUMBNAIL_BASE_DIR, skm_name)
Dir.mkdir(thumbnail_dir) unless Dir.exist?(thumbnail_dir)
thumbnail_path = File.join(thumbnail_dir, "doc_thumbnail.png")
# 检查缩略图是否已经存在
if File.exist?(thumbnail_path)
puts "Thumbnail already exists: #{thumbnail_path}"
return [thumbnail_path]
else
thumbnails = []
Zip::File.open(skm_path) do |zip_file|
zip_file.each do |entry|
if entry.name == "doc_thumbnail.png"
File.delete(thumbnail_path) if File.exist?(thumbnail_path)
entry.extract(thumbnail_path)
thumbnails << thumbnail_path
puts "Extracted successfully: #{thumbnail_path}"
end
end
end
thumbnails
end
end
def load_file(path, _status)
model = Sketchup.active_model
material = model.materials.load(path)
model.materials.current = material
UI.start_timer(0.1) { Sketchup.send_action("selectPaintTool:") }
end
end
menu = UI.menu('Extensions')
menu.add_item("lite map lib") { Lite_maplib.new.maplib }