# frozen_string_literal: true require "test_helper" class GeometryTest < Minitest::Test def setup @data = MoonModel::DataSet.new end def test_solid_one_piece_is_a_closed_outer_volume_without_inner_surface solid = structure("solid") hollow = structure("hollow") assert solid.valid? assert_manifold solid assert_equal hollow.triangles.length / 2, solid.triangles.length assert_equal hollow.vertices.length / 2, solid.vertices.length end def test_solid_single_color_grid_remains_manifold config = config_for("solid", "grid" => { "enabled" => true, "depth_mm" => 0.4 }) mesh = MoonModel::Geometry.build(config, @data).parts.first[:meshes].first assert mesh.valid? assert_manifold mesh end def test_segmented_output_is_hollow_even_when_solid_is_requested config = config_for("solid", "purpose" => "box", "assembly" => "eight_piece") result = MoonModel::Geometry.build(config, @data) assert result.segmented? assert_equal "hollow", result.statistics["interior"] end private def structure(interior) MoonModel::Geometry.build(config_for(interior), @data).parts.first[:meshes].first end def config_for(interior, extra = {}) MoonModel::Config.new({ "size" => { "value" => 40 }, "shell" => { "interior" => interior }, "resolution" => { "longitude_segments" => 24 } }.merge(extra)) end def assert_manifold(mesh) edge_uses = Hash.new(0) mesh.triangles.each do |triangle| triangle.each_index do |index| edge_uses[[triangle[index], triangle[(index + 1) % 3]].sort] += 1 end end assert edge_uses.values.all? { |count| count == 2 }, "every edge must belong to exactly two faces" end end