47 lines
2.4 KiB
Ruby
47 lines
2.4 KiB
Ruby
# frozen_string_literal: true
|
||
|
||
# Regenerate only the stand, preserving the source model and its print files.
|
||
# Usage: bundle exec ruby script/generate_stand.rb CONFIG NEW_OUTPUT_DIRECTORY
|
||
require "bundler/setup"
|
||
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
||
require "moon_model"
|
||
|
||
abort "Usage: #{$PROGRAM_NAME} CONFIG NEW_OUTPUT_DIRECTORY" unless ARGV.length == 2
|
||
source, output = ARGV.map { |path| File.expand_path(path) }
|
||
abort "Output already exists: #{output}; choose a new directory" if File.exist?(output)
|
||
config = MoonModel::Config.new(YAML.safe_load_file(source, aliases: false))
|
||
sizing = MoonModel::Sizing.calculate(config, MoonModel::DataSet.new, validate_safety: false)
|
||
profile = { "envelope_mm" => sizing.final_envelope_mm, "minimum_radius_mm" => sizing.minimum_radius_mm,
|
||
"maximum_radius_mm" => sizing.maximum_radius_mm }
|
||
result = MoonModel::Stand.build(config, profile)
|
||
FileUtils.mkdir_p(File.dirname(output))
|
||
temporary = Dir.mktmpdir(".stand-", File.dirname(output))
|
||
begin
|
||
MoonModel::ThreeMF.write(File.join(temporary, "orbital_triskelion_stand.3mf"), [result.mesh],
|
||
metadata: { "Part" => "material-unassigned stand", "SourceConfig" => source }, palette: config["palette"])
|
||
config.save(File.join(temporary, "config.yml"))
|
||
File.write(File.join(temporary, "statistics.json"), JSON.pretty_generate(result.statistics) + "\n")
|
||
File.write(File.join(temporary, "README.md"), <<~MD)
|
||
# Revised orbital stand
|
||
|
||
Generated from `#{source}`. The source Moon and original stand were not modified.
|
||
|
||
Three curved stems fork toward neighboring pads; each concave pad joins two branches.
|
||
The mesh is one connected, watertight, material-unassigned solid.
|
||
Dimensions: #{result.statistics["dimensions_mm"].map { |v| format("%.2f", v) }.join(" × ")} mm.
|
||
|
||
#{result.statistics["print_guidance"]}
|
||
Inspect the sliced layer preview before printing. Start with build-plate-only supports;
|
||
adjust local support painting beneath the cradles if automatic supports wrap around them.
|
||
The generator reports geometric overhangs, not a guarantee of a slicer's support layout.
|
||
|
||
The dish follows the conservative lunar sphere; terrain peaks may still limit actual contact.
|
||
See `statistics.json` for sizing, clearance, connectivity, and overhang measurements.
|
||
MD
|
||
File.rename(temporary, output)
|
||
ensure
|
||
FileUtils.remove_entry(temporary) if File.directory?(temporary)
|
||
end
|
||
puts output
|
||
puts JSON.pretty_generate(result.statistics)
|