using System.IO; using ACadSharp.Entities; using ACadSharp.IO; using Rozpisky.Dxf; using Rozpisky.Rendering; using Xunit; namespace Rozpisky.Tests; /// /// Šrafa v exportovaném DXF. Vzor musí jít ven i s definičními čarami – DXF je nese uvnitř /// entity HATCH, a bez nich si ho cílový CAD dosadí ze svých .pat, ve svých /// jednotkách a měřítku. Pak vypadá v každém výkresu jinak a většinou tak hustě, že to ani /// nevypadá jako šrafa. A protože se logo do rámečku zmenšuje, musí se s ním zmenšit i vzor. /// public class SrafaExportTesty : IDisposable { private readonly string _soubor = Path.Combine(Path.GetTempPath(), "rozpisky-srafa-" + Guid.NewGuid().ToString("N") + ".dxf"); public void Dispose() { try { File.Delete(_soubor); } catch (IOException) { } GC.SuppressFinalize(this); } /// Přehraje logo do DXF (volitelně přes zmenšení do rámečku) a načte výsledek zpět. private List Kolecko(double meritko) { var dxf = new DxfProfileRenderer(); IProfileRenderer cil = meritko == 1 ? dxf : new TransformRenderer(dxf, meritko, 0, 0); new DxfTemplate(TestData.Logo("md_sfdi.dxf")).Replay(cil); DxfWriter.Write(_soubor, dxf.Document, binary: true); return DxfReader.Read(_soubor).Entities.OfType().ToList(); } /// Rozteč rovnoběžek vzoru = kolmá složka posunu mezi sousedními čarami. private static double Roztec(HatchPattern.Line cara) { double nx = -Math.Sin(cara.Angle), ny = Math.Cos(cara.Angle); return Math.Abs(cara.Offset.X * nx + cara.Offset.Y * ny); } private static double RoztecZdroje() { var zdroj = DxfReader.Read(TestData.Logo("md_sfdi.dxf")) .Entities.OfType().First(h => !h.IsSolid); return Roztec(zdroj.Pattern!.Lines[0]); } [Fact] public void ExportovanaSrafaNeseDefiniciVzoru() { var srafy = Kolecko(meritko: 1).Where(h => !h.IsSolid).ToList(); Assert.NotEmpty(srafy); foreach (var h in srafy) { Assert.Equal("ANSI31", h.Pattern?.Name); Assert.NotNull(h.Pattern); Assert.NotEmpty(h.Pattern!.Lines); // tohle chybělo: vzor šel ven jen jménem } } [Fact] public void RoztecVzoruOdpovidaZdroji() { var srafa = Kolecko(meritko: 1).First(h => !h.IsSolid); Assert.Equal(RoztecZdroje(), Roztec(srafa.Pattern!.Lines[0]), 9); } [Fact] public void ZmensenimLogaSeZmensiIVzor() { // Logo se do rámečku rozpisky vejde jen zmenšené. Kdyby si vzor nechal původní rozteč, // vyšla by v CADu buď plná plocha, nebo pár čar přes celé logo. const double meritko = 0.1; var srafa = Kolecko(meritko).First(h => !h.IsSolid); Assert.Equal(RoztecZdroje() * meritko, Roztec(srafa.Pattern!.Lines[0]), 9); } [Fact] public void MeritkoAUhelZustavajiNeutralni() { // ACadSharp při zápisu násobí rozteč vzoru hodnotou PatternScale, ale při čtení zpátky // nedělí – s nenulovým měřítkem by se vzor s každým kolečkem roztáhl. Efektivní hodnoty // proto nese samotná definice a měřítko s úhlem zůstávají neutrální. var srafa = Kolecko(meritko: 1).First(h => !h.IsSolid); Assert.Equal(1, srafa.PatternScale, 9); Assert.Equal(0, srafa.PatternAngle, 9); } [Fact] public void PlnaVyplnZustavaSolidBezVzoru() { // md_sfdi má všechny šrafy vzorované, plné výplně jsou v ostatních logách. var dxf = new DxfProfileRenderer(); new DxfTemplate(TestData.Logo("exprojekt.dxf")).Replay(dxf); DxfWriter.Write(_soubor, dxf.Document, binary: true); var solidni = DxfReader.Read(_soubor).Entities.OfType().ToList(); Assert.NotEmpty(solidni); foreach (var h in solidni) { Assert.True(h.IsSolid); Assert.Equal("SOLID", h.Pattern?.Name); Assert.Empty(h.Pattern!.Lines); } } }