[general]
name=Isoliner3D
qgisMinimumVersion=3.16
qgisMaximumVersion=4.99
description=Standalone 3D viewer and bed/block-model toolset: surfaces, watertight bed bodies, boreholes, polyhedra, reserves. Автономный 3D-просмотр поверхностей, тел пластов, скважин и полиэдров, плюс подсчёт запасов по блочной модели.
about=A standalone 3D viewer for geological surfaces and bodies in QGIS, independent of the built-in 3D map. Renders project rasters as triangular-mesh surfaces (each horizon in its own colour, with vertical exaggeration and Z spacing), builds watertight bed bodies from multiband grids (band 1 roof, band 2 bottom), draws boreholes as coloured stems with collar masts and labels, shows a section plane with a bright section trace, and displays polyhedral / TIN / MultiPolygon Z bodies. Click-query prints layer name, coordinates, all band values and thickness. Colouring by palette, custom colour, own band, an external raster or a real map texture with shading: an orthophoto, a basemap or a styled geological map. A section drawing is draped onto the section ribbon, several sections at once. A Processing group of seven bed and block-model tools computes thickness, volume and reserves from a bed grid. PNG snapshot for reports. A companion to the Isoliner kriging and contouring toolset (plugins.qgis.org/plugins/grid_isolines) and to Topoliner, topology cleaning (plugins.qgis.org/plugins/topoliner). pyqtgraph and PyOpenGL are bundled - nothing to install. Companion to the Isoliner kriging toolset. Developed with the support of Inform++ LLC (www.informpp.ru).
    .
    Автономный 3D-просмотр геологических поверхностей и тел в QGIS, не зависящий от штатного 3D-вида. Растры проекта рисуются треугольными мешами (каждый горизонт своим цветом, с вертикальным преувеличением и разносом по Z), из многоканальных гридов строятся водонепроницаемые тела пластов (канал 1 - кровля, канал 2 - подошва), скважины показываются цветными стволами с мачтами и подписями, плоскость разреза даёт яркий след сечения, а полиэдры / TIN / MultiPolygon Z отображаются объёмными телами. Клик по сцене печатает имя слоя, координаты, значения всех каналов и мощность. Окраска палитрой, своим цветом, собственным каналом, внешним растром или настоящей текстурой карты с затенением: ортофото, подложка, геологическая карта со своей символикой. На ленту разреза накладывается чертёж, несколько разрезов сразу. Группа Processing из семи инструментов пласта и блочной модели считает мощность, объём и запасы по гриду пласта. Снимок PNG для отчётов. Спутник набора кригинга и изолиний Isoliner (plugins.qgis.org/plugins/grid_isolines) и чистки топологии Topoliner (plugins.qgis.org/plugins/topoliner). pyqtgraph и PyOpenGL идут в комплекте - устанавливать ничего не нужно. Спутник набора кригинга Isoliner. Разработано при поддержке ООО «Информ++» (www.informpp.ru).
version=0.68.0
author=ООО «Информ++»
email=xbbster@gmail.com
homepage=https://github.com/Valery35/qgis-isoliner3d
tracker=https://github.com/Valery35/qgis-isoliner3d/issues
repository=https://github.com/Valery35/qgis-isoliner3d
tags=3d,visualization,surfaces,geology,mesh,boreholes,cross-section,polyhedral,tin,pyqtgraph,opengl,kriging,geostatistics
category=Analysis
icon=icon.svg
experimental=False
deprecated=False
hasProcessingProvider=yes
changelog=0.68.0
    - Окно свойств слоя показывает только то, что относится
      к выбранному режиму. Таблица оболочек у точечного слоя и шаг
      стенки у поверхности сбивали с толку: правишь поле, а оно
      ничего не делает. Строка прячется вместе со своей подписью.
    - Куб отсекается поверхностями сверху и снизу. Раньше отсечка
      доходила до точек и поверхностей, но не до куба: изоповерхность
      и воксели её не читали. Теперь ячейки гасятся при чтении куба,
      до построения - оболочка, воксели и объём по блочной модели
      считаются по одному телу, а не расходятся между собой. Число
      убранных ячеек идёт в журнал.
    - У слоя появилась своя прозрачность поверх общей. Общая правит
      всю сцену разом, а этой приглушают один слой, чтобы видеть тело
      под ним. Текстуру она накрывает тоже.
    0.67.3
    - Отменено отключение записи глубины из 0.67.2: оно променяло одну
      беду на другую. Грани одной оболочки начали смешиваться
      вразнобой, и по поверхности пошли светлые полосы и провалы.
    - Вложенные оболочки решаются порядком: внутренние рисуются
      раньше наружных. Нарисованная первой закрывает собой то, что
      за ней, поэтому наружная, идя первой, съедала все внутренние.
      Идя последней, она ложится поверх них своей прозрачностью.
    - Цвет оболочки из таблицы больше не перебивается раскраской
      по каналу: человек назвал цвет, решать за него нечего.
    0.67.2
    - Исправлено: вложенные оболочки терялись, когда их несколько.
      Штатный режим полупрозрачности пишет в буфер глубины, и первая
      же оболочка закрывала собой всё, что за ней. Поодиночке каждая
      была видна, вместе - нет.
    - Оболочки рисуются своим режимом: глубина проверяется, но
      не пишется. Тогда сквозь наружную читаются внутренние, ради
      чего вложенные и строят.
    - Режим заводится один раз и только для оболочек: прочим
      полупрозрачным поверхностям запись глубины нужна, иначе они
      начнут просвечивать друг сквозь друга.
    0.67.1
    - Строку таблицы оболочек можно удалить: правая кнопка на строке.
      Без этого таблица только росла, а стёртый уровень оставлял
      за собой пустую строку.
    - Цвет выбирается мышью: двойной щелчок по ячейке открывает выбор,
      и цвет виден прямо в ячейке заливкой. Набирать код никто
      не обязан, хотя это по-прежнему можно.
    - Непрозрачность в таблице переведена в проценты, как и
      прозрачность поверхностей в свойствах сцены рядом. Доли единицы
      рядом с процентами читаются как ошибка ввода.
    0.67.0
    - Оболочки задаются таблицей: строка на уровень, столбцы уровень,
      цвет и плотность, галка показа. Два списка, связанные
      по порядку, съезжают молча: пропустил цвет, и все остальные
      встали не на свои уровни. В строке съехать нечему.
    - Таблица заменила поля «оболочек по отсечке» и «свои уровни»:
      три способа задать одно и то же это перебор.
    - Пустая ячейка берёт автоматическое: цвет по номеру оболочки,
      плотность растёт наружу. Тому, кому цвета безразличны,
      заполнять их руками не нужно. Пустая таблица это отсечка
      и одна оболочка.
    - Таблица растёт сама: заполнили последнюю строку - появилась
      следующая. Снятая галка убирает оболочку, не стирая строку.
    - Исправлено: границы отметок, поверхности отсечки и координатный
      короб не сохранялись в проект. Они добавлялись позже прочего,
      и проект открывался с прежними значениями. Проверка сверяет
      теперь весь список настроек сцены.
    0.66.6
    - Оболочка может закрывать выход тела на край куба. Маршевая
      поверхность там обрывается: тело выглядит вскрытым, а объём
      по нему не посчитать. Крышка закрывает выход плоским куском
      на самой грани.
    - Каждая ячейка грани делится на два треугольника и обрезается
      по уровню так же, как режется сама изоповерхность. Поэтому края
      сходятся вершина в вершину и щели не остаётся: на демонстрационном
      кубе краевых рёбер было семьсот четыре, стало ноль.
    - По умолчанию выключено: крышка нужна не всегда, а граней
      добавляет.
    - Умолчания настроек оболочек сведены в одно место: раньше они
      были разбросаны по вызовам чтения, и часть настроек умолчания
      не имела вовсе.
    0.66.5
    - Исправлено: свои уровни оболочек, сглаживание и отброс мелочи
      никуда не сохранялись. Поля были украшением: человек их правил,
      а до сцены значение не доходило, и работала отсечка. При нуле
      весь куб оказывается внутри, оболочки нет вовсе - отсюда
      «ничего не построено».
    - Проверка сверяет каждую настройку слоя: что сохраняется, то
      и читается обратно. Раньше поле можно было добавить и забыть
      про сохранение, и никто бы не заметил.
    - Исправлено: одна оболочка рисовалась на две трети прозрачной.
      Разнос прозрачности нужен, когда сквозь наружную читают
      внутренние; одна сквозь себя ничего не показывает и остаётся
      плотной.
    - Сообщение о пустом построении называет уровни, по которым
      строили, а не отсечку: при своих уровнях отсечка ни при чём.
    0.66.4
    - Запятая в числах читается как знак дроби, а не как разделитель.
      У нас пишут «2,5 3 3,5», и приняв запятую за разделитель,
      из двух с половиной выходило два и пять. Разделяют пробел
      и точка с запятой, запятая в конце числа прощается.
    - Правило одно и для своих уровней оболочек в сцене, и для своих
      границ интервалов в 2.04: два синтаксиса в одном модуле человек
      запоминать не обязан. Разбор общий, за этим следит проверка.
    0.66.3
    - Уровни оболочек можно задать строкой: «2 5 8» через пробел
      или запятую. Порядок и повторы не важны, одного уровня
      достаточно.
    - Свои уровни важнее отсечки и числа оболочек: раскладывать
      по долям надо тогда, когда уровни неизвестны, а если человек
      их назвал, решать за него нечего. Что построено, печатается
      в журнал.
    0.66.2
    - Уровни вложенных оболочек раскладываются по долям, а не к вершине
      куба. У содержаний хвост вверх длинный, и верхняя оболочка
      вставала там, где ячеек почти нет: на демонстрационном кубе шесть
      сотых процента вместо пяти с половиной, и в сцене вместо
      оболочки была пустота.
    - Каждая следующая оболочка охватывает вдвое меньше ячеек, чем
      предыдущая. Уровни печатаются в журнал: гадать, что построилось,
      не надо.
    - Если выше отсечки ячеек мало, оболочек выйдет меньше заказанного,
      и об этом говорится прямо, а не молча.
    0.66.1
    - Исправлено: у градуированной раскраски значение ровно на границе
      класса уходило в следующий. У QGIS интервал «больше нижней,
      меньше или равно верхней», а поиск шёл по нижним границам.
      На блочной модели значения квантованы и ложатся на границы
      часто, поэтому целые классы уезжали и цветов на глаз
      недоставало.
    - Поиск идёт по верхним границам, как у QGIS. Правило закреплено
      проверкой на граничных значениях.
    0.66.0
    - Подписи в выгрузке рисуются полосками, а не линиями. Толщину
      линий в glTF задать нельзя: её выбирает просмотрщик, и обычно
      это один пиксель, который на большой модели теряется. Полоска
      даёт настоящую толщину, в метрах.
    - Толщина берётся седьмой частью высоты знака: на площадке
      в двенадцать километров это тридцать четыре метра по плану
      и три с половиной по вертикали.
    - У каждого штриха свои вершины: слипшись, соседние полоски дали
      бы залом на стыке. Замер: подписи короба это восемьсот восемьдесят
      вершин и четыреста сорок треугольников, весь файл короба
      тридцать три килобайта.
    0.65.8
    - Подписи в выгрузке приведены в вид. Размер знака считался
      от общего охвата: на площадке в двенадцать километров
      и отметках в двести метров он выходил в двести метров
      и по вертикали накрывал короб целиком. Теперь размер берётся
      от своей оси: по плану один на обе, по вертикали от своего
      размаха, но не мельче двадцатой части.
    - Исправлено: штрихи оси Y уходили вниз на длину штриха. Они
      выводились «по следующей оси», а следующей для Y выходит Z,
      и штрихи вместе с подписями проваливались под короб.
      Плановые оси уводятся в плане, вертикальная тоже.
    - Подпись отодвинута от штриха и не налезает на короб.
    0.65.7
    - Подписи делений уходят в выгрузку GLB. В glTF текста как
      такового не бывает: либо геометрия букв, либо картинка
      на плоскости. Картинка при повороте встаёт ребром и пропадает,
      поэтому цифры рисуются отрезками, как на чертёжном шрифте.
      Они поворачиваются вместе с коробом и весят копейки.
    - Замер на площадке двенадцать на восемь километров: рёбра
      и штрихи двадцать пять отрезков, подписи ещё двести двадцать,
      весь короб шестнадцать килобайт.
    - Незнакомый знак пропускается вместе со своим местом: подпись
      лучше покажется короче, чем не покажется вовсе.
    0.65.6
    - Исправлено: выгрузка падала на проверке массива numpy
      в булевом виде. Выражение вида «массив или пусто» бросает
      исключение: у массива из многих чисел нет однозначной
      истинности. Ошибка внесена мной в 0.65.4 при починке
      предыдущей, и файл не писался три версии подряд - открывался
      прежний.
    - Проверка ищет этот приём во всех расчётных файлах, чтобы
      он не вернулся.
    - Сквозной прогон отчёта и записи проверен на тех же типах,
      что в настоящей выгрузке: тело с гранями и короб с линиями.
    0.65.5
    - Короб уходит в выгрузку и тогда, когда его не показывают
      на экране. Это разные решения: в файле без короба нет масштаба,
      а на экране он мешает смотреть, и связывать их одной кнопкой
      неверно.
    - Итог выгрузки виден в окне, а не только в журнале: сколько тел,
      есть ли короб, применено ли преувеличение, размер файла. Иначе
      неудачу от удачи не отличить, и открывается прежний файл.
    0.65.4
    - Исправлено: выгрузка падала целиком, если в неё попадал
      координатный короб. У короба нет граней, только линии,
      а отчёт о выгрузке обращался к граням напрямую. Файл не
      писался вовсе, и об этом говорила лишь строка «Выгрузка
      не удалась». Ошибка внесена вместе с коробом в выгрузке.
    - Отчёт печатает и грани, и линии, а отсутствие тех или других
      не роняет работу.
    0.65.3
    - Координатный короб уходит в выгрузку GLB: рёбра, штрихи и сетка
      линиями. Без них в файле нет масштаба, и модель читается
      на глазок.
    - Запись GLB научилась линиям, а не только треугольникам: рёбра
      короба писать треугольниками незачем.
    - Подписи делений в файл не идут: в GLB текст это геометрия букв,
      и делать её ради чисел незачем. Рёбра, штрихи и сетка масштаб
      дают и без них.
    - Короб не участвует в подсчёте середины для преувеличения:
      он уже в настоящих отметках, как и прочие части.
    0.65.2
    - Исправлено: в выгрузку GLB поверхность уходила ровным цветом
      слоя, даже когда на экране была раскрашена шкалой. В файле все
      поверхности выходили одинаковыми пятнами, и по ним ничего
      не разобрать.
    - Теперь в выгрузку идёт та же раскраска, что и на экране: цвета
      по вершинам из шкалы слоя либо из атрибутного растра. Ровный
      цвет остаётся только там, где шкалы нет.
    0.65.1
    - Исправлено: вертикальное преувеличение в выгрузке GLB считалось
      от середины каждой части отдельно. Растягивался только рельеф
      внутри части, а расстояния между частями оставались прежними,
      и на глаз казалось, что преувеличение не применилось вовсе.
      На двух поверхностях с разносом в пятьдесят метров и
      преувеличением десять разнос так и оставался пятьдесят вместо
      пятисот.
    - Середина берётся одна на всю выгрузку. В журнал пишется, какое
      преувеличение применено и от какой отметки.
    - Выбор при выгрузке остался: спрашивается, брать модель как
      на экране или настоящие высоты. Ответ пишется в журнал, чтобы
      потом не гадать, что вышло в файл.
    0.65.0
    - Исправлено: у кнопки координатного короба не было значка.
      Я взял вид «grid», а такого в наборе не оказалось, и кнопка
      рисовалась пустой.
    - Значок нарисован: рамка с сеткой и стрелка севера рядом.
    - Проверка сверяет виды значков у кнопок плашки с теми, что умеет
      рисовать набор. Кнопка без значка выглядит поломанной, и такое
      надо ловить до выдачи, а не глазами.
    0.64.9
    - Число секторов поиска берётся от данных: ноль в поле означает
      «замерить и решить». У скважин деление нужно, иначе все соседи
      узла окажутся в одном стволе. У проб в плане стволов нет, делить
      нечего, а граница сектора идёт лучом от узла, и на ней набор
      соседей меняется скачком: отсюда звёзды в поле.
    - Умолчание в восемь секторов было сделано под скважины и не
      разведено с плановыми данными. Это недоделка, а не ошибка счёта:
      инструмент замеряет сеть опробования и должен был сам понимать,
      есть стволы или нет.
    - Правило простое: замеров в одной точке плана один-два - деления
      нет, больше - восемь секторов. Что подставлено, печатается
      в журнал. Правило работает в 2.02, 2.05 и 2.06.
    0.64.8
    - Свойства сцены разбиты на три части: вид, обрезка, координатный
      короб. Тринадцать строк подряд читались как свалка, и нужное
      приходилось искать перебором. В каждой части не больше пяти
      строк, за этим следит проверка.
    - Две поверхности отсечки встали в одну строку, как и границы
      отметок: они всегда правятся вместе.
    0.64.7
    - Координатная сетка, управляемая свойствами сцены. Две новые
      строки: на каких плоскостях рисовать и с каким шагом. Пол даёт
      масштаб в плане, стены - по отметкам, что для разреза важнее.
    - Ноль в шаге означает круглый шаг от размаха сцены, а не пустую
      сетку. Слишком мелкий шаг укрупняется сам: сетка гуще самой
      сцены читать не помогает, а рисуется долго. Потолок четыре
      тысячи линий.
    - Кнопка на плашке по-прежнему включает короб целиком, а чем его
      наполнить, решают свойства: править это на плашке негде
      и незачем.
    0.64.6
    - Стрелка севера рядом с координатным коробом, с подписью.
      На повёрнутой сцене стороны света теряются мгновенно, а по одной
      подписи их не восстановить.
    - Стрелка смотрит по возрастанию Y: в проекции карты это и есть
      север. Стоит она за коробом сбоку - поперёк тела мешала бы
      читать форму. Размер соразмерен сцене, чтобы она была видна
      и на километре, и на десяти.
    0.64.5
    - Координатный короб: кнопка на плашке рисует рёбра охвата,
      штрихи и подписи по осям. Сцена без делений не даёт размера:
      тело выглядит одинаково и на сто метров, и на двадцать
      километров. По вертикали подписываются отметки, что для разреза
      важнее всего.
    - Деления идут по круглым числам: шаг берётся единицей, двойкой
      или пятёркой на степень десяти. Подпись 250 читается сразу,
      а 247.3 надо разбирать.
    - Подписей не больше шестидесяти: остальные не ставятся, иначе они
      забьют сцену. Об этом говорится в журнале.
    0.64.4
    - Чистка изоповерхности: сглаживание и отброс мелочи. Маршевая
      поверхность идёт ступенями по ячейкам куба, и мелкие обрывки
      на ней шумят. Два новых поля в свойствах слоя: сколько проходов
      сглаживания и какие куски отбрасывать.
    - Мелочь отбрасывается до сглаживания, иначе обрывки успевают
      затянуть к себе соседей.
    - Края при сглаживании не двигаются: крышка на срезе строится
      по краевым рёбрам, и стоит их сдвинуть, как она перестанет
      сходиться с телом.
    - Если порог убирает всё, поверхность остаётся как была: пустая
      сцена это не чистка, а потеря. Число отброшенных кусков идёт
      в журнал.
    - Сглаживание слегка ужимает тело, поэтому для подсчёта объёма
      брать надо несглаженное. Об этом сказано в подсказке.
    0.64.3
    - Инструмент 2.04 берёт свои границы интервалов: строка вида
      0, 5, 10, 15 вместо равных долей. Порядок и повторы не важны,
      ячейка выше последней границы остаётся в последнем интервале.
      Свои границы важнее числа интервалов: подменять заданную руками
      разбивку равными долями значит решать за человека.
    - Интервалам можно дать названия: низкое, среднее, высокое. Они
      пишутся в поле name слоя. Недостающие остаются пустыми, лишние
      отбрасываются: подставить название не тому интервалу хуже, чем
      оставить его без названия.
    - Инструмент 2.03 отсекает точки поверхностями сверху и снизу:
      всё выше дневного рельефа или вне пласта в модель не идёт.
      Число убранных точек пишется в журнал.
    0.64.2
    - Отсечка поверхностями в сцене. В свойствах сцены появились две
      строки: поверхность сверху и поверхность снизу, любой растр
      проекта. Остаётся то, что между ними. Одной отметкой этого
      не заменить: кровля и подошва меняются по площади, а отметка
      плоская.
    - Отсекать можно и одной поверхностью: только сверху - убрать всё
      выше дневного рельефа, только снизу - всё ниже подошвы.
    - Точка, под которой поверхности нет, не остаётся: пропустить её
      значит показать данные там, где отсечка не работала, а на глаз
      одно от другого не отличить.
    - Растр отсечки читается раз на сборку сцены, а не на каждый слой.
    0.64.1
    - Полуширина коридора и границы отметок переехали с плашки
      инструментов в свойства сцены, к остальной обрезке. На плашке
      они занимали место у кнопок, которыми пользуются постоянно,
      а правят их редко.
    - Снятие обрезки по отметке стало кнопкой «Снять» в той же строке.
      Общая кнопка очистки на плашке по-прежнему снимает и её.
    0.64.0
    - Найдена причина дырок, и она моя. В 0.63.14 я стал оставлять
      отвесные грани целиком, если хоть одна вершина внутри области:
      это спасало от потери стенок, но стенка торчала за контур,
      соседняя горизонтальная была обрезана по нему, и между ними
      оставалась щель. Числа показали прямо: после резки шесть тысяч
      краевых рёбер, из них на контуре среза полторы.
    - Отвесная грань теперь режется точно. В плане она вырождается
      в отрезок, и резать её как полигон нечем, зато вдоль отрезка
      она режется без потерь: вершины переводятся в пару «доля вдоль
      отрезка - отметка», грань обрезается по доле и возвращается
      обратно в пространство.
    - Если резать нечем, стенка по-прежнему остаётся целиком: это
      лучше, чем потерять её вовсе.
    0.63.29
    - В журнал добавлено главное число: сколько тел не замкнуто ещё
      до резки и сколько у них краевых рёбер. Крышку такому телу
      не построить никаким способом, и без этого числа беду принимали
      за отказ крышки.
    - Обход колец переживает Т-образные стыки: у узла с тремя
      соседями берётся ещё не пройденный. Кольцо замкнётся не всегда,
      но там, где замкнётся, крышка встанет.
    0.63.28
    - Найдена причина дырок. У всех восьми тел крышка выходила
      с одним и тем же: у области обрезки нет границы. Штатный вызов
      границы у полигона в этой сборке QGIS возвращает пусто. Крышку
      строить не на чем, а тем же способом режутся грани поперёк
      границы - без него они выбрасываются целиком, и в теле
      появляются дырки.
    - Граница области обрезки теперь собирается из колец полигона,
      а штатный вызов только пробуется первым.
    - Негодная по геометрии область исправляется перед работой:
      пересечение с негодной даёт пусто, и грани поперёк границы
      пропадают целиком. Об исправлении говорится в журнале.
    0.63.27
    - Причины раннего выхода крышки считаются по каждому телу,
      а не хранятся одной на весь прогон. Прежняя перетиралась
      последним телом, и по ней нельзя было судить об остальных:
      строка называла причину для одного, а молчали все.
    - Добавлено число вызовов крышки и сколько из них пришло
      с гранями. Если вызовов много, а с гранями ноль, значит тела
      до крышки не доходят вовсе, и искать надо выше.
    0.63.26
    - Крышка собирается обходом колец, а полигонизация оставлена
      запасным путём. Обход я заменил на полигонизацию тогда, когда
      оболочка была рваной и кольца не замыкались. Теперь тело
      замкнуто, и обход для него точен: он идёт по рёбрам, а не решает
      за нас, где площадь.
    - Обход берёт кольца, поданные вразнобой и в разные стороны,
      несколько колец сразу, и не достраивает незамкнутые куски:
      рисовать площадь, которой нет, хуже, чем оставить дыру
      и сказать об этом.
    0.63.25
    - Номер сборки виден в заголовке окна просмотра. Без него нельзя
      отличить, какая версия стоит, и разбор журнала начинается
      с гадания.
    - Строка о крышке печатается всегда, а не только когда рёбра
      нашлись. Если крышка вышла из работы раньше, называется
      причина: область обрезки не построилась, после резки граней
      не осталось, у области нет границы, краевых рёбер нет.
      Молчание нельзя было отличить от старой сборки: и там и там
      строки просто нет.
    0.63.24
    - Сквозная проверка разреза на числах, без QGIS: тело вокселей
      строится, склеивается, режется, склеивается снова, и все краевые
      рёбра обязаны лежать в зоне среза. Хоть одно в глубине тела -
      значит резка теряет грани.
    - Проверка проходит: резка тело не рвёт. Значит дырки не в ней,
      а в крышке, и указать место должны четыре числа отчёта крышки.
    0.63.23
    - Точки отбираются разом, а не по одной. На каждую шли два вызова
      отбора, и каждый строил массивы ради одного числа. Замер:
      сто девяносто тысяч точек разом это пятнадцать тысячных секунды
      против пяти целых семи, то есть в триста семьдесят раз быстрее.
    - Градуированный и категорийный стиль читаются разом. Границы
      диапазонов известны заранее, и цвет находится по значению поля
      поиском по границам, одним проходом. Раньше символ спрашивался
      у каждого объекта: на полумиллионе это полмиллиона вызовов
      QGIS.
    - Объекты для стиля читаются без геометрии и только по тому полю,
      по которому идёт раскраска.
    0.63.22
    - Крышка отчитывается в журнал четырьмя числами: сколько краевых
      рёбер нашлось, сколько из них легло на контур среза, сколько
      полигонов собралось и сколько не разбилось. По картинке не
      понять, чего не хватило, а эти четыре числа различают все
      четыре случая.
    0.63.21
    - Исправлено: отбор по отметке не работал сам по себе. Резка
      граней вызывалась, только когда задан контур или коридор,
      и диапазон отметок без них не срабатывал вовсе: тело оставалось
      целым, а верхняя и нижняя плоскости как будто не резали.
    - Перепутанные границы теперь называются: z больше или равно
      минус пятидесяти вместе с z меньше или равно минус ста
      невыполнимы, и сцена выходит пустой. Молчать об этом значит
      отправить человека искать причину в данных.
    0.63.20
    - Бюджет вершин считается по построенному телу, а не по исходной
      геометрии. В слое каждый четырёхугольник несёт свои вершины,
      а в сцене после склейки их вдвое меньше: считая по исходным,
      одно тело съедало весь предел, занимая на деле половину.
      Отсюда «объектов 10, показан 1».
    - Предел проверяется после сборки тела, и в сообщении стоит то
      число, которое и правда занято.
    0.63.19
    - Найдена настоящая причина открытого среза, и она в 2.04.
      Инструмент пишет объект на интервал окраски, а грань между
      двумя занятыми ячейками отбрасывалась независимо от их
      интервала. На стыке интервалов её не было ни у одного куска:
      каждое тело выходило дырявым. Вместе они выглядели целыми,
      и беда вылезала только при разрезе.
    - Теперь грань на стыке интервалов остаётся у обоих тел. Замер
      на демонстрационном теле: у всех восьми интервалов краевых
      рёбер ноль, то есть каждое тело замкнуто само по себе.
      Граней стало вдвое больше, это цена замкнутости.
    - Совет «снимите слияние» был неполным: без этой правки куски
      оставались дырявыми и без слияния.
    - Поля слоёв заводятся помощником: в новых сборках QGIS прежний
      конструктор объявлен устаревшим и сыпал предупреждениями
      в журнал на каждом запуске.
    0.63.18
    - Разобрана до конца история с открытым срезом. Замерено: у тела
      вокселей без слияния краевых рёбер ноль, оболочка замкнута,
      и после резки кольца среза замыкаются. У слитого граница
      разорвана Т-образными стыками ещё до всякой резки: шесть тысяч
      краевых рёбер, восемьсот узлов, где кольцо рвётся. Крышку
      на таком теле не построить никаким способом - чинить надо выше,
      при сборке тела.
    - Сообщение теперь говорит это числом и по делу: сколько тел,
      сколько краевых рёбер, и что собрать тело в 2.04 со снятым
      слиянием. Подсказка к флагу слияния в 2.04 предупреждает
      об этом заранее.
    - Тело склеивается ещё раз после резки: резчик добавляет куски
      отдельными блоками со своими вершинами, и швы между ними снова
      выглядели краевыми рёбрами.
    - Свойство закреплено числовыми проверками: слияние рвёт границу
      на порядок сильнее самой резки.
    0.63.17
    - Найден корень истории с открытым срезом. Меш тела приходил
      несклеенным: у каждого треугольника свои вершины, и по номерам
      каждое ребро выглядело краевым. Оболочка никогда не признавалась
      замкнутой, и крышка не строилась ни разу ни у кого - ни у тела
      вокселей, ни у полиэдров.
    - Тело склеивается до разбора рёбер. На теле вокселей без слияния
      краевых рёбер становится ноль, то есть оболочка замкнута
      по-настоящему. Со слиянием остаются Т-образные стыки, это
      заложенная в 2.04 плата за лёгкость.
    - Заодно вершин втрое меньше: пятьдесят две тысячи против
      тринадцати на демонстрационном теле.
    - Проверка «лежит ли вершина на контуре» получила грубый отсев
      по охвату: она идёт геометрией QGIS и на тысячах краевых рёбер
      стоила десятки секунд.
    0.63.16
    - Крышка на срезе собирается заново. Раньше рёбра среза обходились
      кольцами, и на слитых гранях обход рвался: длинный прямоугольник
      упирается в два коротких, ребро низа в месте стыка не разбито,
      узел стенки повисает со степенью один, и кольцо через него
      не проходит. Отсюда девять тел с открытым срезом.
    - Теперь рёбра переводятся в плоскость «путь вдоль контура -
      отметка», сшиваются по узлам и собираются в полигоны сразу.
      Порядок обхода такому способу не нужен вовсе, и Т-образные
      стыки ему безразличны.
    - Обоснование замены закреплено числами: проверка строит ту самую
      сеть с Т-образным стыком и показывает висящий узел.
    0.63.15
    - Крышка на срезе пробуется и у незамкнутой оболочки. Раньше она
      ставилась только замкнутым, а тело вокселей со слиянием граней
      не замкнуто по построению: срез оставался открытым, было видно
      нутро, и тело выглядело россыпью плит. Хуже от попытки
      не станет: не вышло - остаётся как было.
    - Если крышка так и не встала, об этом говорится в журнале
      и называется причина: оболочка не замкнута, у тела вокселей
      надо снять в 2.04 слияние соседних граней.
    0.63.14
    - Исправлено: при обрезке тела вокселями оставался один низ.
      Стенки ячеек отвесные, и в плане такой треугольник вырождается
      в отрезок нулевой площади. Он уходил в резку по контуру,
      пересечение давало пусто, и все стенки пропадали целиком.
      У тела оставались только горизонтальные грани.
    - Вырожденные в плане грани теперь решаются по вершинам:
      остаются, если хоть одна внутри. Перелёт не больше размера
      ячейки, потеря стенок была куда заметнее.
    - Проверка численная: стенка ячейки поперёк границы коридора
      должна уцелеть. Откат проверен, сторож его ловит.
    0.63.13
    - В отчёт обрезки добавлено расстояние от линии до данных:
      от ближайшей грани до дальней. Без него «срезало почти всё»
      не отличить от «линия проведена мимо»: числа одинаковые,
      а причины разные. Если ближайшая грань дальше полуширины,
      об этом говорится прямо.
    0.63.12
    - Обрезка отчитывается в журнал: сколько граней осталось из
      скольких, каким источником, в каком режиме, с какой полушириной
      и с какими границами отметок. Когда от сцены остаётся горстка
      треугольников, по картинке не понять, кто их срезал, а одно
      число без другого ничего не говорит.
    0.63.11
    - Спрямление появилось и у кригинга 2.06. Оно идёт до замера
      вариограммы: модель должна быть снята в тех же координатах,
      в которых пойдёт расчёт, иначе она не от этих данных.
    - У 2.02 анизотропию можно не задавать: ноль замеряет вариограмму
      по данным и берёт отношение вертикальной длины связи к плановой.
      Замер идёт после спрямления, по тем же координатам.
    - Замер на демонстрационном пласте со складкой, исключение
      по скважине: в абсолютных отметках обратные расстояния 0.936,
      кригинг 0.896; в спрямлённых 0.459 и 0.516. Спрямление даёт
      вдвое, и на нём обратные расстояния обходят кригинг: сеть
      в сорок девять скважин для кригинга ещё редкая.
    0.63.10
    - Спрямление: у инструмента 2.02 появилась опорная поверхность.
      Вертикаль отсчитывается от кровли или подошвы, и интерполяция
      идёт вдоль напластования, а не поперёк. В абсолютных отметках
      у пласта со складкой соседняя по вертикали проба лежит в другой
      пачке, и никакой анизотропией это не лечится: она правит
      масштаб, а не форму.
    - Замер на демонстрационном пласте со складкой, сорок девять
      скважин, исключение по скважине: в абсолютных отметках ошибка
      0.935, в спрямлённых 0.468 при той же анизотропии. Вдвое.
    - Второй поверхностью задаётся доля мощности: ноль на кровле,
      единица на подошве. Так сопоставляются пачки разной мощности,
      и раздув не размазывает связь.
    - Пробы и узлы сетки спрямляются одинаково, а сама сетка остаётся
      в настоящих отметках: куб читается всем прочим без правок.
      Проба и узел вне опорной поверхности остаются пропуском,
      число пропущенных пишется в журнал.
    0.63.9
    - Чтение стиля слоя ускорено. У слоя с одним символом цвет теперь
      не спрашивается у каждого объекта: на блочной модели
      в полмиллиона точек это было полмиллиона вызовов ради одного
      и того же ответа.
    - Для остальных стилей объекты читаются без геометрии и только
      по тем полям, которые читает сам стиль. Геометрия для цвета
      не нужна, а на полумиллионе объектов её чтение и есть основная
      цена.
    - Единый стиль отвечает на любой номер объекта, поэтому места,
      которые читают стиль, этот случай не различают: их четыре,
      и забыть одно было бы проще простого.
    0.63.8
    - Исправлено: сцена из одних тел падала теперь на режиме
      отрисовки. Та же ошибка, что и с прозрачностью в прошлой
      сборке: имя заводилось внутри обхода поверхностей, а тела берут
      его ниже. В прошлый раз я починил одно имя вместо целого
      класса.
    - Проверка переписана на весь класс: разбором кода ищется любое
      имя, которое читают ниже обхода поверхностей, а заводят только
      внутри него. Прежняя проверка называла имена по одному
      и вдобавок брала не тот цикл: обход дерева идёт не в порядке
      строк.
    - Откат проверен: возврат имени внутрь цикла проверку роняет.
    0.63.7
    - Исправлено: сцена из одних тел не строилась, в журнале была
      ошибка про прозрачность. Она заводилась внутри обхода
      поверхностей, а тела берут её ниже: когда поверхностей в сцене
      нет вовсе, обход не выполняется, и имени не существует.
      Ошибка внесена вместе с прозрачностью оболочек по отсечке.
    - Исправлено: кнопка снятия обрезки по отметке висела в левом
      верхнем углу окна поверх всего. Помощник только создаёт кнопку
      с родителем-диалогом, добавлять её в панель надо отдельно,
      и я этого не сделал.
    - Обе ошибки закреплены проверками: прозрачность заводится
      до обхода поверхностей, и ни одна кнопка панели не создаётся
      без добавления в раскладку.
    0.63.6
    - Исправлено: обрезку по отметке нельзя было снять. «Без границы»
      это минимум диапазона, минус десять миллионов, и спустить туда
      со ста метров можно было только набрав это число руками.
      Рядом с полями появилась кнопка «Снять обрезку по отметке»,
      и то же делает общая кнопка очистки.
    0.63.5
    - Кригинг делит узлы на порции по числу ячеек, а не по постоянному
      числу узлов. Отбор соседей держит несколько матриц размером
      порция на число проб, и при сорока тысячах проб выходило около
      гигабайта временных: в фоновом потоке Windows это кончалось
      не ошибкой памяти, а падением по обращению к чужой памяти.
      Теперь потолок два миллиона ячеек, и память не растёт с числом
      проб: шестьдесят четыре мегабайта хоть на сорока тысячах,
      хоть на двухстах.
    - Составляющие азимута в отборе по секторам освобождаются до
      перебора секторов: держать их рядом с копиями значило удваивать
      память на пустом месте.
    - Исправлено: ширина набора соседей считалась по первой порции,
      и при расхождении массивы пересоздавались, стирая уже
      посчитанное. Ширина теперь известна заранее.
    - Инструмент 2.06 печатает число проб и предупреждает, когда их
      больше двадцати тысяч.
    0.63.4
    - Инструмент 2.01 печатает расшифровку своих полей по окончании:
      что такое hole, from_m, to_m, grade, truth и zone, и какое поле
      брать для интерполяции. По именам это не видно, а 2.02 подставляет
      первое числовое поле, то есть номер скважины, и куб выходит
      по номерам.
    - Подсказки к полю значения в 2.02, 2.05 и 2.06 называют поле
      демонстрационных данных прямо: это grade, а не hole.
    - В руководствах поля 2.01 сведены в таблицу, добавлено, зачем
      нужны truth и hole. В таблицу типичных ситуаций добавлена строка
      про куб по номерам скважин.
    0.63.3
    - Классы окна вынесены из функции в отдельный модуль
      viewer_dialog.py. Раньше оба класса жили внутри _build_dialog,
      чтобы отложить импорт Qt: модуль читается и там, где QGIS ещё
      не поднят. Приём остался, но перенесён на уровень выше -
      откладывается импорт модуля, а не определение класса.
    - Точка входа viewer3d.py ужалась с 5373 строк до 681. Окно
      разделено на три файла: точка входа, сам диалог и расчётная
      часть.
    - Две проверки закрепляют разделение: классы живут в своём модуле
      и не остались в функции, а точка входа не тянет Qt при чтении.
    0.63.2
    - Расчётная часть окна вынесена в viewer_core.py: тридцать четыре
      функции и пятнадцать констант, всё, что считается без Qt и QGIS.
      Окно ужалось с 6139 строк до 5373.
    - Снаружи ничего не изменилось: viewer3d переэкспортирует все
      её имена, и поведение прежнее до мелочи.
    - Шесть наборов проверок перестали вырезать куски исходника
      текстом и просто импортируют нужное. Вырезание по имени соседней
      функции ломалось каждый раз, когда рядом появлялась новая,
      и за сессию сработало трижды.
    - Две проверки следят за разделением: ядро не тянет QGIS и Qt,
      окно переэкспортирует все его имена.
    0.63.1
    - Новый режим слоя «Объёмная заливка». Куб показывается насквозь:
      цвет по значению, непрозрачность растёт вместе с ним. Это то
      свечение вокруг тела, ради которого всё и затевалось.
    - Ниже отсечки заливки нет вовсе. Без этого виден весь ящик
      целиком, и в тумане не разглядеть ничего: показывать надо то,
      что выше неё. Отсечка берётся та же, что у изоповерхности.
    - Плотность правится строкой в свойствах слоя. Пропуски в данных
      прозрачны: пустота это не ноль. Куб из одного значения
      заливается ровно, а не пропадает.
    - Заливка не заменяет оболочку, а дополняет её: оболочка отвечает,
      где граница тела, заливка - как значение меняется вокруг.
    - Углы куба идут в общий охват сцены: своих вершин у заливки нет,
      и без этого сцена из одной заливки центровалась бы по пустому
      множеству.
    - Потолок сорок миллионов ячеек. Замер на демонстрационном кубе:
      сто на сто на шестьдесят это две с половиной десятых секунды
      и два с половиной мегабайта, видимых ячеек двенадцать процентов.
    0.63.0
    - Новый режим слоя «Стенка по линии». Вертикальный срез куба вдоль
      ломаной с раскраской по значению. Оболочка показывает границу
      тела, воксели занятые ячейки, а стенка показывает само поле
      значений внутри, там где её провели.
    - Линия берётся из списка обрезки: рисовать её отдельным способом
      незачем, она там уже есть. Шаг узлов задаётся строкой в свойствах
      слоя, ноль берёт шаг грида.
    - Значения выбираются трилинейно. За краями куба возвращается
      пропуск, а не край, и треугольник с пропуском в узле не строится:
      иначе у стенки появился бы кусок из ничего, а на глаз он выглядел
      бы данными.
    - Ломаная с изломом обходится общим шагом, а не по отрезкам:
      на изломе стенка не рвётся.
    - Замер на демонстрационном кубе сто на сто на шестьдесят, ломаная
      из трёх узлов: при шаге десять метров семь тысяч узлов
      и четырнадцать тысяч треугольников, треть мегабайта.
    0.62.0
    - Правило нумерации: средний номер меняется в выпуске,
      рабочие сборки между выпусками меняют третий. Раньше
      средний поднимался на каждой сборке, и в репозитории
      номера шли с пропусками.
    0.61.0
    - Инструмент 2.06 «Кригинг в объёме». Два выхода: куб значений
      и куб дисперсии оценки. Вариограмма замеряется по самим данным,
      длина связи из планового замера, самородок из вертикального,
      анизотропия как отношение длин. Ручной ввод трёх чисел оставлен
      в дополнительных параметрах.
    - В журнал идут обе вариограммы, собранная модель, шаг сети
      и диапазон дисперсии. Если шаг сети больше половины длины связи,
      инструмент предупреждает: на такой сети кригинг обычно
      не точнее обратных расстояний, а дисперсия остаётся полезной.
    - Если оценка вышла за размах проб, инструмент это называет:
      у кригинга веса бывают отрицательными, и на содержаниях это даёт
      значения ниже нуля. Гауссова модель склонна к этому сильнее
      прочих.
    - Прогон на демонстрационных данных: 1844 пробы, сетка 49 на 49
      на 96, двести тридцать тысяч узлов, тридцать восемь секунд.
    0.60.0
    - Обычный кригинг в объёме, ядро. Веса берутся из вариограммы,
      поэтому метод знает, на каком расстоянии связь пропадает
      и сколько разброса приходится на ошибку опробования. Две пробы
      рядом друг с другом несут почти одно и то же, и кригинг
      не даёт им двойного голоса. Инструмента пока нет.
    - Дисперсия оценки вторым выходом: в самой пробе ноль, дальше
      от данных растёт. Это карта доверия, которой у обратных
      расстояний нет вовсе.
    - Сборка рабочей модели из двух замеров. Самородок берётся
      из вертикального: в плане пар ближе шага сети нет вовсе,
      и самородок из планового замера это продолжение прямой к нулю
      через пустоту. Анизотропия это отношение длин связи, а не
      догадка.
    - Замерена граница применимости. На густой сети кригинг выигрывает
      у обратных расстояний до восьми процентов, на редкой проигрывает
      до девяти. Перелом там, где шаг сети около половины длины связи.
      Обе стороны закреплены проверками, чтобы проигрыш на редкой сети
      не выдавали за поломку.
    0.59.0
    - Проверка 2.05 умеет исключать скважину целиком: новое поле
      «Поле скважины». Без него убиралась одна проба, соседи брались
      из того же ствола в трёх метрах, и мерялась связность по стволу,
      а не умение попасть между скважинами. На демонстрационных данных
      разница шестикратная: ошибка по пробам 0.17, по скважинам 1.10.
    - Отсюда следует, что все числа сходимости, которые я приводил
      раньше, были занижены: они получены проверкой по одной пробе.
    - Проверка по одной пробе к тому же почти не видит анизотропию:
      отбор ближайших от неё не зависит, пока ближайшая точка своя же
      по стволу. По скважинам замеренная по вариограмме анизотропия
      уменьшает ошибку, по пробам не меняет ничего.
    - Справка 2.05 расписана по разделам: зачем, что исключать, что
      значат числа в журнале, что подбирать, про радиус и про слой.
    - Если часть проб отброшена при разборе отметок, номера скважин
      перестают совпадать с пробами. Инструмент это замечает
      и отказывается от группировки, а не проверяет не то.
    0.58.0
    - Первый шаг к кригингу: вариограмма. Замер по парам проб и подбор
      модели, сферической, показательной или гауссовой. Инструмента
      пока нет, наружу ничего не выведено.
    - Замер делится по направлению: все пары, только в плане, только
      по вертикали. У пласта содержание меняется поперёк залежи быстро,
      а вдоль неё медленно, и одной вариограммой эти два строения
      не описать: общий замер усредняет их в одно и не описывает
      ни того, ни другого. На демонстрационных скважинах длина связи
      в плане выходит 273 метра, по вертикали 40.
    - Число пар растёт как квадрат числа проб, поэтому выше двух
      миллионов берётся случайная выборка с заданным зерном: замер
      не меняется от запуска к запуску.
    0.57.0
    - Площадка в 2.01 задаётся одним охватом. Раньше на один и тот же
      прямоугольник шло пять полей: охват, X угла, Y угла, ширина
      и высота, причём четыре последних читались, только когда охват
      пуст. Полей стало четырнадцать вместо восемнадцати,
      в основном списке девять.
    - Пустой охват даёт километр от начала координат, и об этом
      пишется в журнал. Требовать охват до первого запуска
      у демонстрационного инструмента незачем.
    0.56.0
    - Инструмент 1.07 разделён. Карта для текстуры вынесена в новый
      1.08, а в 1.07 осталось восемь полей вместо тринадцати, и все
      они работают при любом выборе примера. Раньше при выборе карты
      читались четыре поля картинки, а мощность, разбиение и число
      пластов не читались вовсе: по списку было не понять, какие поля
      про твой случай.
    - Проверка следит за составом обоих: восемь полей у 1.07,
      шесть у 1.08, поля карты в 1.07 не встречаются.
    0.55.0
    - Новый инструмент 2.05 «Проверка интерполяции». Убирает каждую
      пробу по очереди, считает значение в её точке по остальным
      и сравнивает с настоящим. Это единственный способ узнать, можно
      ли верить кубу: сравнивать построенное не с чем, а на глаз
      одинаково убедительно выглядят и хорошая модель, и вымысел.
    - В журнал идут средняя ошибка, среднеквадратичная, смещение
      и доля ошибки от размаха данных. Смещение показывает,
      уводит ли модель в одну сторону: разброс и односторонний увод
      лечатся по-разному.
    - Слой невязок с полями value, model, resid и aresid: видно
      не только величину промаха, но и где он случился.
    - Разбор точечных проб вынесен общим для 2.02 и 2.05. Оба берут
      один и тот же слой одинаково, и разойтись им теперь нельзя.
    0.54.0
    - Подсказки к полям доведены до всех инструментов: девяносто три
      поля, девяносто три подсказки. Ни одно поле не осталось
      без объяснения, за этим следит проверка.
    0.53.0
    - У каждого поля инструментов группы 2 появилась своя подсказка,
      сорок семь штук. Общая справка лежит сбоку и читается один раз,
      а решать «что сюда писать» приходится у каждого поля. Подсказка
      отвечает на этот вопрос и говорит, чем плох другой выбор.
    - Проверка следит, что без подсказки не осталось ни одного поля
      этих инструментов, и что подсказка не пересказывает имя поля.
    - Проверка двуязычия научилась видеть подсказки. Они уходят
      пользователю через tr, но лежат в словаре, а не в вызове,
      и разбор их не находил: сорок семь строк остались бы без
      английского незаметно.
    0.52.0
    - Инструмент 2.02 упрощён. В основном списке осталось десять строк
      и все они про исходные данные. Анизотропия, радиус, степень,
      наименьшее число точек и сектора убраны в дополнительные:
      это настройка метода, к данным она отношения не имеет
      и в основном списке только мешала выбирать.
    - Шаг по горизонтали, шаг по вертикали и наибольшее число точек
      берутся от данных, если оставить ноль. Шаг в плане это пятая
      часть расстояния между точками плана, шаг по вертикали половина
      шага опробования, соседей на одного больше, чем замеров
      в одной точке плана, но не меньше четырёх и не больше
      шестнадцати. Что подставлено, печатается в журнал.
    - Постоянные умолчания не подходили никому: на почвенных пробах
      через триста метров шаг в двадцать пять метров мельче самих
      данных, а на площадке в двадцать семь километров те же двадцать
      пять метров давали сорок пять миллионов узлов. Оба раза это был
      не выбор человека, а умолчание.
    0.51.0
    - Оболочек по отсечке теперь можно строить несколько. Уровни
      раскладываются от заданной отсечки до вершины куба, цвет каждой
      берётся из шкалы, прозрачность растёт к наружным: внутренние
      видно сквозь них.
    - Марш идёт по пограничным ячейкам, а не по всему кубу. Ячейки
      целиком внутри и целиком снаружи граней не дают, а их
      подавляющее большинство, и перебор четырнадцати случаев по всему
      кубу стоил больше самой врезки.
    - Вершины склеиваются. Марш выдавал три вершины на грань без
      единого общего ребра. Ключ склейки упакован в одно целое,
      и сортировка идёт по нему, а не по тройке: на шестистах тысячах
      вершин это в четыре с половиной раза быстрее.
    - Координаты узлов больше не разворачиваются на весь куб восемью
      массивами точек: они восстанавливаются по номеру ячейки и биту
      вершины. На кубе сто на сто на шестьдесят это восемнадцать
      мегабайт против ста сорока семи.
    - Итог на демонстрационном кубе сто на сто на шестьдесят, пять
      уровней: одна и три десятых секунды против пятнадцати с половиной,
      триста тысяч вершин против миллиона восьмисот, одиннадцать
      мегабайт против пятидесяти.
    0.50.0
    - Обрезка по отметке. Контур и коридор режут только в плане,
      к высоте они отношения не имеют, и вертикальной обрезки
      в модуле не было вовсе. Теперь на плашке инструментов стоят два
      поля, наименьшая и наибольшая отметка, наименьшее значение
      означает «без границы».
    - Отбор идёт у тел и поясов, линий, точек, растровых поверхностей
      и вокселей. Границы включаются: отметка ровно на границе
      остаётся, иначе у куба пропадал бы крайний уровень.
    - Перепутанные местами границы дают пусто, а не меняются молча:
      опечатку в поле лучше увидеть сразу, чем искать причину пустой
      сцены в данных.
    0.49.1
    - Исправлено: после готовой линии или контура обрезка выглядела
      нерабочей. Выбор нарисованного в списке обрезки помечает сцену
      устаревшей и пишет в строку состояния, что нажать «Обновить
      сцену», а следом сообщение о готовой линии эту строку затирало.
      Линия готова, а в сцене ничего не меняется, и подсказки нет.
      Теперь сообщения о готовой линии, замкнутом контуре и снятой
      точке опроса несут подсказку с собой.
    0.49.0
    - Инструмент 2.02 предупреждает о неподъёмной сетке до начала
      счёта: называет число узлов и говорит, что счёт займёт минуты
      и сотни мегабайт. Порог двадцать миллионов узлов.
    - Отдельно предупреждает, когда шаг сетки много мельче сети
      опробования: между соседними точками плана нет ни одного
      замера, и лишние узлы повторяют одно и то же. Порог пятьдесят
      ячеек между соседними точками плана.
    0.48.0
    - Инструмент 2.02 замеряет сеть опробования и пишет в журнал: шаг
      по вертикали, шаг в плане, замеров в одной точке плана.
    - Если наибольшее число точек больше числа замеров в одной точке
      плана, инструмент предупреждает: в среднее попадут все уровни
      сразу и различие по глубине сгладится. На пробах по трём
      уровням умолчание в шестнадцать точек делает поле ровным,
      и это не очевидно из параметров.
    - Подсказать анизотропию по данным нельзя, и попытка убрана:
      у скважин и у проб по уровням отношение шагов почти одинаковое,
      а нужные значения различаются в тысячу раз. Инструмент печатает
      измеренное и поясняет, что делает анизотропия, а решение
      остаётся за геологом.
    0.47.0
    - У инструмента 2.02 появился выбор источника отметки: высота
      геометрии, поле отметки, глубина от поверхности.
    - Исправлено: у плоского слоя 2.02 молча ставил всем точкам ноль.
      Все пробы ложились в одну плоскость, и куб выходил
      бессмысленным без единого предупреждения. Теперь источник
      задаётся явно, а если все точки всё-таки оказались на одной
      отметке, инструмент отказывается со внятной причиной.
    - Глубина отсчитывается вниз от выбранной поверхности. Это случай
      почвенных и подобных проб: там записана глубина, а не отметка,
      и без поверхности перевести одно в другое нельзя. Пробы в одной
      точке плана расходятся по отметке и перестают схлопываться
      в одну точку.
    - Точка, для которой отметку получить не удалось, в расчёт
      не идёт, число таких пишется в журнал.
    0.46.0
    - Исправлено: обратные расстояния в объёме давали то же, что
      ближайший сосед. Причина не в формуле, а в геометрии: при
      анизотропии проба в стволе оказывается в сотни раз ближе
      соседней скважины, и все ближайшие точки узла берутся из одной
      скважины. Веса считались по одному значению, и вместо
      сглаженного поля выходили ячейки Вороного.
    - Соседи теперь набираются по секторам: окружность вокруг узла
      делится на равные части, из каждой берётся своя доля ближайших
      точек. На разведочной сети совпадение с ближайшим соседом упало
      со ста процентов до двенадцати, а ошибка с исключением по одной
      на демонстрационных данных снизилась с 0.282 до 0.174.
    - Число секторов задаётся строкой «Секторов поиска»
      в дополнительных параметрах 2.02, по умолчанию восемь. Один
      сектор возвращает прежний отбор просто по расстоянию.
    - Отбор соседей вынесен отдельной функцией и проверяется прямо:
      по ней видно, из скольких скважин набраны соседи.
    0.45.1
    - Исправлены тридцать две плоские записи перечислений в новых
      инструментах: QgsWkbTypes, тип числового параметра, тип источника
      и тип поля. В новых сборках QGIS такая запись даёт ошибку.
      В остальном модуле конвенция была соблюдена, недосмотр только
      в добавленном коде.
    - Проверка на плоские перечисления добавлена в набор по группе
      инструментов, откат она ловит.
    0.45.0
    - Вид маркера точки выбирается: круг, квадрат, ромб, треугольник,
      крест. Круг остаётся экранным значком: размер в пикселях,
      при приближении не растёт, стоит почти ничего. Остальные виды
      лежат в плане на отметке точки, размер в метрах. Такой значок
      закрывается поверхностью и уходит под кровлю, чего экранный
      не умеет, а стоит два-четыре треугольника на точку: слой
      в восемь с половиной тысяч точек это семнадцать тысяч
      треугольников и полтора мегабайта.
    - Строка размера следует за видом: у круга пиксели, у плоского
      значка метры. Единица у них разная, и видна та, что работает.
    - Число подписей задаётся строкой «Подписей не более», прежде
      было наглухо четыреста. Ноль означает «без подписей».
    - Строка числа подписей видна только когда выбрано поле подписи.
    0.44.2
    - Исправлено: сборка сцены падала с «too many values to unpack»,
      как только у точечного слоя появлялись размер и подпись. Охват
      сцены разбирал запись точки жёсткой распаковкой на пять полей,
      а полей стало семь. Теперь координаты берутся срезом, и новое
      поле записи сборку больше не ломает. Запись линии читается
      так же.
    0.44.1
    - Исправлено: окно свойств открывалось пустым, с одним разделом
      «Разрез» и без заголовка. Подбор строк вызывался из показа
      свойств, а значения в виджетах к этому моменту могли
      принадлежать прежнему слою. Строки подбираются в конце загрузки
      свойств, когда виджеты уже заполнены, там этот вызов и был
      с самого начала.
    - Подмена источника высоты у слоя без Z срабатывает только
      во время загрузки свойств. Вне её она записывала настройку
      чужому слою и тянула пересборку сцены.
    - Заголовок окна свойств ставится первым, до остальной сборки.
    0.44.0
    - Обычный точечный слой подписывается: новая строка «Поле подписи
      точек» в свойствах. Подписи с ореолом, как у скважин.
    - Подписи прореживаются: если рядом уже есть подписанная точка,
      текст не ставится, иначе на слое в тысячи точек не читается
      ни одна. Потолок четыреста подписей на сцену, каждая подпись
      это отдельный элемент отрисовки. Сколько показано из скольких,
      пишется в журнал.
    0.43.0
    - Размер точки берётся из стиля слоя, включая размер по данным.
      Размер маркера на карте задан в миллиметрах печати, поэтому
      пересчитывается от обычных двух миллиметров. Своё число
      задаётся строкой «Размер точки, px», ноль означает «из стиля».
    - Подписи получили ореол. Одноцветный текст пропадал на пёстрой
      сцене: тёмный на тёмном, светлый на светлом. Теперь под текст
      кладётся обводка контрастного цвета, как на топографических
      картах, и подпись стоит с отступом от точки, а не поверх неё.
    - Подписи рисуются полупрозрачно, а не аддитивным смешением:
      на светлом фоне сцены аддитивное выцветало в белое.
    0.42.0
    - Свой цвет у векторного слоя убран. Он дублировал оформление
      слоя и стирал раскраску по отметке, а задаётся оно всё равно
      в самом слое. Цвет объекта берётся из стиля, запасной остаётся
      на случай, когда стиль цвета не дал.
    - Свойства векторного слоя подбираются под слой. Строка, которая
      к нему не относится, убирается, а не гасится: погашенная всё
      равно занимает место и заставляет гадать, отчего она серая.
      У точечного слоя нет строк призмы, у линий и полигонов нет
      строки типа точек, поля отметки и поверхности видны каждое
      при своём источнике высоты, поля скважин только в режиме
      скважин, разрез только у линейных слоёв.
    - Строка прячется вместе с подписью: одно поле спрятать мало.
    0.41.0
    - Исправлено: у слоя без своей высоты Z отметка с поверхности
      теряла все объекты. Вершина без отметки отсеивается ещё
      при разборе геометрии, до укладки дело не доходило. Точки
      и любые плоские слои теперь ложатся на поверхность.
    - У края данных отметка добирается ближайшей ячейкой. Билинейной
      выборке нужны четыре соседа, и на границе она молчит даже там,
      где ячейка есть: отсюда лишние разрывы линий.
    - Новый параметр слоя «Смещение по вертикали, м». Работает поверх
      любого источника высоты, включая укладку на поверхность.
      Небольшой подъём убирает спор за глубину, когда линия лежит
      ровно на поверхности.
    0.40.0
    - Новый источник высоты у векторного слоя: «Отметка
      с поверхности». Растровый слой выбирается строкой ниже,
      и отметка читается в каждой вершине, поэтому объект ложится
      на рельеф, а не встаёт на общую отметку.
    - Там, где у поверхности нет данных, объект обрезается. Точка
      выбрасывается, ломаная рвётся на куски, а треугольник тела
      с пропуском в любой вершине не строится вовсе. Ноль это
      отметка, а не отсутствие отметки, и сажать на него нельзя.
    - Работает у точек, линий, контуров и тел. Слой без выбранной
      поверхности отказывается с внятной строкой, а не молчит.
    0.39.0
    - Список слоёв в окне строится в порядке дерева карты, сверху
      вниз. Раньше он брался из словаря слоёв, у которого порядка
      нет вовсе, и список выходил случайным.
    - Верхний слой карты рисуется поверх нижнего. Совпадающая
      геометрия иначе спорит за глубину: изолинии то видны,
      то тонут в поверхности, на которой лежат. Подъём считается
      от места в списке и на глаз не заметен.
    - Список сцены следует за деревом карты сам: добавили слой,
      убрали, переставили - список обновляется, а кнопка обновления
      подсвечивается. Сцена при этом не пересобирается.
    - Точку опроса можно убрать. Клик по пустому месту снимает её,
      Esc вне режима рисования тоже, и кнопка очистки теперь снимает
      обрезку, наброски и точку разом.
    0.38.0
    - Сцена приведена к системе координат проекта, как холст карты.
      Раньше преобразования не было вовсе: слой попадал в сцену
      в своих координатах, слой в другой системе уезжал в сторону,
      а смена системы координат слоя ничего не меняла, потому что
      записанные координаты она и не двигает.
    - Переводятся тела, линии, точки, скважины, контур обрезки
      и сетка растровой поверхности. Отметка не трогается,
      она и так в метрах.
    - Значения растра читаются в его собственной системе: окраска
      по каналу, внешний атрибутный растр, шкала слоя, опрос
      по клику и поиск поверхности лучом. Иначе всё это брало бы
      значения мимо данных.
    - Обрезка растра считается по его сетке, поэтому контур
      переводится обратно в систему слоя.
    - В строке состояния печатается, сколько слоёв перепроецировано.
    0.37.0
    - Поверхность красится шкалой самого слоя. Читается то же
      оформление, что рисует карту: непрерывная шкала, ступенчатая,
      точная и палитра классов. Раньше растр без заданного канала
      окраски уходил в сцену ровным цветом из палитры, и синь-зелень-
      краснота с холста пропадала.
    - Порядок источников цвета: текстура карты, заданный канал
      окраски, внешний атрибутный растр, шкала слоя, палитра.
      Выбранное руками главнее оформления.
    - Своя шкала слоя главнее общей шкалы сцены. Общая растягивается
      сразу на все слои, и расцветка ушла бы от карты ровно там,
      где её просили повторить.
    - Значения вне шкалы прижимаются к её концам, пропуски уходят
      серым.
    0.36.0
    - Точки в сцене рисовались аддитивным смешением, как оно задано
      по умолчанию в pyqtgraph. Фон сцены почти белый, и точки
      выцветали в него целиком. Теперь непрозрачно, как всё остальное.
    - Точки берут цвет из стиля слоя, как линии и тела.
    - Класс, снятый в легенде слоя, больше не попадает в сцену: ни
      телом, ни линией, ни точкой. Нечитаемый стиль при этом ничего
      не прячет, эти два случая различаются.
    - В журнал по стилю слоя пишется, сколько объектов скрыто классами.
    0.35.0
    - Линии в сцене красятся по стилю слоя, как это давно делают тела.
      Изолинии почти всегда раскрашены по отметке, а в сцену шёл один
      цвет на весь слой: вместо шкалы глубин выходила ровная бурая
      паутина. Полигоны в режиме контура красятся так же.
    - Заданный в свойствах слоя цвет по-прежнему главнее стиля,
      и тогда стиль не читается вовсе.
    0.34.0
    - Разбор тел с переменной отметкой пошёл через кэш. Кэш
      триангуляции был, но этот путь мимо него шёл: слой из 237 тел
      разбирался заново на каждое нажатие кнопки обновления.
      Теперь повторная сборка берёт готовое, а в строке состояния
      видно, сколько разбивок пришло из кэша.
    - У разбора по кольцам свой ключ кэша. Плоская разбивка и разбивка
      по кольцам для одного объекта дают разное, и подменять одну
      другой нельзя: в плане вертикальная стенка вырождается в линию.
    0.33.0
    - Тела показывались не полностью не из-за памяти, а из-за бюджета
      вершин. Бюджет делился между всеми отмеченными векторными
      слоями, хотя линии и точки из него не берут ничего: отмеченный
      слой изолиний забирал половину, и слой тел обрезался. Теперь
      бюджет делится только между слоями, которые идут телами.
    - Сообщение об урезании называет числа: сколько вершин набрано
      и каков предел. Прежнее «показаны первые 237» читалось как
      нехватка памяти, а крутить было нечего.
    - Предел вершин на сцену вынесен в свойства сцены и хранится
      в проекте. Умолчание прежнее, шестьсот тысяч.
    0.32.0
    - Сцена считается по кнопке «Обновить сцену». Отметки видимости
      и ползунки теперь только записывают, что показывать. Раньше
      каждый щелчок в списке тянул полную пересборку, и на тяжёлом
      кубе это выглядело зависанием.
    - Кнопка обновления стоит первой на плашке инструментов
      и отделена разделителем от остальных.
    - Пока показанная сцена отстаёт от настроек, кнопка подсвечена,
      а в строке состояния написано, что нажать.
    - Галка «Обновлять автоматически» осталась, но по умолчанию снята.
      При её включении сцена подтягивается сразу.
    0.31.1
    - Умолчания 2.01 были тяжёлые: 36 скважин с пробой 2 м давали
      3389 проб, и на них интерполяция считалась долго. Стало
      25 скважин с пробой 3 м, это 1547 проб. Тело по-прежнему
      воспроизводится, цепочка по умолчанию идёт около двух секунд
      вместо семи.
    - При числе проб больше двух тысяч 2.01 предупреждает в журнале:
      узел в объёме взвешивается по всем пробам, и время растёт
      вместе с их числом.
    - Интерполяция в объёме считает расстояния блоками узлов через
      произведение матриц, а не по одному узлу. Ускорение около
      полутора раз, расхождение с прежним расчётом до 1e-10
      от округления.
    - Воксели оценивают размер до сборки. Счёт видимых граней идёт
      на NumPy и стоит доли секунды, а сборка при миллионах граней
      уводила окно в неотзывчивость. Выше полутора миллионов граней
      сцена не строится, а в журнал пишется число и что покрутить.
    0.31.0
    - Инструмент 2.03 «Куб в блочную модель». Точка-центроид
      на занятую ячейку, поля bid, lev, row, col, x, y, z, dx, dy, dz,
      vol, val, cls, при заданной плотности dens и ore_t. Дальше
      работает обычный векторный аппарат QGIS.
    - Инструмент 2.04 «Тело куба вокселями». Слой MULTIPOLYGON Z,
      объект на интервал окраски. То же, что видно в сцене, но слоем.
    - Найден и закрыт защип по ребру: две ячейки, соприкасающиеся
      одной диагональю, дают ребро на четырёх гранях, и проверка
      замкнутости такое тело отвергает. Инструмент 2.04 считает
      защипы и по умолчанию убирает их заполнением угла. Проверено
      сквозь GeoPackage внешней проверкой оболочек.
    - Выключатель слияния граней выведен в свойства слоя окна
      просмотра. Со слиянием сцена в разы легче, без слияния
      оболочка замкнута.
    0.30.0
    - Новый режим слоя «Воксели по кубу». Ячейка показывается коробкой,
      цвет по интервалу содержания. Куб перестал быть просто набором
      каналов: у него появилась форма, которую видно.
    - Строятся только видимые грани. Грань между двумя занятыми
      соседями не видна никогда, поэтому её отбрасывают. На кубе
      двести на двести на сто это сто двадцать шесть тысяч граней
      вместо двадцати четырёх миллионов.
    - Соседние грани одного интервала сливаются в прямоугольник.
      Демонстрационный пласт на четырёх миллионах ячеек даёт
      тридцать четыре тысячи прямоугольников и две с половиной
      мегабайты сцены, сборка около секунды.
    - Обрезка контуром и коридором работает и для вокселей. Там это
      отбор ячеек, поэтому крышку строить не нужно и срез выходит
      плоским сам по себе.
    - Число интервалов окраски задаётся в свойствах слоя. Чем меньше
      интервалов, тем крупнее прямоугольники и легче сцена.
    - Слияние можно выключить: тогда каждая видимая грань идёт
      отдельно и каждое ребро принадлежит ровно двум граням. Это форма
      для подсчёта объёма, а слитая - для показа.
    - Инструмент 2.01: прямоугольник площадки задаётся координатами
      левого нижнего угла, шириной и высотой. Охват, если он задан,
      по-прежнему главнее.
    0.29.0
    - Инструмент 2.01 переписан. Тип залежи выбирается: пласт
      со складкой и падением, линза, крутая жила. Пласт нужен, чтобы
      было видно, как горизонтальные уровни куба режут залежь поперёк.
    - Опробование идёт интервалами: поля from_m и to_m вместо одной
      глубины, длина пробы задаётся в метрах. Добавлено поле zone,
      единица внутри тела.
    - Сеть скважин со сбивкой, устья по рельефу, глубина разная, часть
      скважин недобурена. Правильная сетка одинаковой глубины давала
      интерполяции слишком лёгкую задачу.
    - Содержание с плоской вершиной и быстрым спадом. Граница тела там,
      где содержание падает до половины ядра над фоном, отсечка
      печатается в журнал. Внутри тела содержание меняется по площади,
      поэтому методы расходятся между собой.
    - Шум логнормальный: отрицательных содержаний не возникает
      и обрезка по нулю больше не смещает выборку.
    - Исправлено: размер площадки в модели содержаний подменялся
      номером скважины, и у первой скважины содержание считалось
      делением на ноль.
    - Модель вынесена в demo3d.py и проверяется отдельно,
      семнадцать проверок.
    0.28.0
    - Группы пронумерованы: «1. Пласт и блочная модель»
      и «2. 3D-интерполяция». Номера инструментов приведены к номеру
      группы: 2.01 и 2.02 вместо 3.01 и 3.02. Прежние взялись
      из нумерации Isoliner, где эта ветка третья, а здесь группа всего
      вторая.
    - В демонстрационных точках задаётся охват площадки: можно выбрать
      окно карты или слой, а не только сторону квадрата от начала
      координат. Так демо ложится на реальный участок.
    0.27.1
    - Инструменты не открывались в QGIS 4: базовый класс Processing
      больше не даёт метод перевода, а им пользуются все инструменты.
      Метод заведён в своём базовом классе, разом для всех.
    0.27.0
    - Инструмент 3.02: интерполяция точек в объёме, ближний сосед
      и обратные расстояния. Результат многоканальный грид, канал это
      уровень, отметка первого уровня и шаг пишутся в метаданные,
      поэтому куб сразу показывается изоповерхностью и читается
      блочной моделью.
    - Анизотропия задаётся отношением вертикального масштаба
      к горизонтальному: без неё ближайшей точкой оказывается соседняя
      скважина, а не соседний замер в той же точке плана.
    - Поиск соседей идёт по ячейкам, а не перебором: на четырёх
      миллионах узлов перебор всех точек не проходит.
    - Узлы, где точек в радиусе меньше нужного, остаются пропуском.
    0.26.0
    - Новая группа «3D-интерполяция» и первый инструмент 3.01:
      демонстрационные точки в объёме. Скважины с замерами по глубине,
      плавная рудная линза и шум, содержание без шума пишется отдельным
      полем. Истина известна, поэтому на этих данных сравниваются методы
      интерполяции: ошибка считается по расхождению с моделью, а не
      на глаз. Линза по горизонтали шире, чем по вертикали, поэтому
      на ней проверяется и анизотропия.
    0.25.0
    - Куб значений показывается изоповерхностью: в свойствах растрового
      слоя появился режим «Изоповерхность по кубу» и отсечка. Каналы
      грида считаются уровнями, отметка первого уровня и шаг берутся
      из метаданных. Оболочка замкнута, поэтому по ней считается объём,
      режется контуром и коридором и выгружается в GLB наравне
      с остальным.
    0.24.0
    - Изоповерхность по кубу значений: оболочка по отсечке из
      многоканального грида. Взят марш по тетраэдрам, а не по кубам:
      у кубов есть неоднозначные случаи, на которых соседние ячейки
      расходятся и оставляют дыру, а нам нужна замкнутая оболочка.
      Грани разворачиваются наружу по данным, поэтому по такому телу
      считается объём. Пропуски остаются снаружи.
    0.23.0
    - При выгрузке в GLB спрашивается, применить ли вертикальное
      преувеличение. Настоящие высоты верны для расчёта, но пласт
      в километры по площади и десятки метров по мощности сплющивается
      в блин, и для показа нужна модель как на экране.
    0.22.2
    - В журнал пишется состав выгрузки: какие части собраны и сколько
      в них вершин и граней. По этой строке видно, доходит ли слой
      до файла вообще.
    0.22.1
    - В выгрузку GLB попадают и поверхности с текстурой: прежде они
      пропускались, и в файле оставались только слои, рисуемые цветом.
      Сама текстура пока не уходит, поверхность выгружается ровным
      цветом: для картинки нужны координаты текстуры у каждой вершины
      и сама картинка внутри файла.
    0.22.0
    - Выгрузка сцены в файл GLB. Формат выбран из-за читателей: его
      открывают браузерные просмотрщики, Blender и Windows, поэтому
      модель можно просто отправить письмом. Выгружается ровно то, что
      видно, включая обрезку, с цветами в вершинах. Координаты пишутся
      настоящие, без центрирования сцены и без вертикального
      преувеличения: преувеличение это способ смотреть, а не свойство
      модели.
    0.21.1
    - Убраны прежние подходы к срезу: отбор граней по центру и лента
      между отметками. Работает разрезка граней по контуру с крышкой
      по кольцам среза, две реализации одного и того же держать рядом
      незачем.
    0.21.0
    - Замкнутые оболочки режутся контуром и срез закрывается крышкой.
      Рёбра отверстия собираются в кольца, кольцо перекладывается
      в координаты «путь вдоль контура на отметку», где оно плоское,
      там разбивается и возвращается обратно. Открытым поясам крышка
      не строится: замкнутость определяется по рёбрам.
    0.20.1
    - Грани, пересечённые контуром обрезки, режутся по нему, а не
      отбираются по своему центру. У пояса встречаются треугольники
      крупнее коридора: по центру они торчали за краем. Новым вершинам
      высота берётся из плоскости исходной грани.
    0.20.0
    - Пояса режутся по треугольникам, а не выбрасываются целиком
      по центру объекта. Это открытые поверхности, крышка на срезе им
      не нужна, поэтому край идёт по контуру обрезки. Прежде пояс либо
      оставался весь, либо исчезал весь.
    0.19.4
    - В журнал пишется, какие цвета прочитаны из стиля слоя: по этой
      строке видно, читается ли стиль вообще, или дело в отрисовке.
    0.19.3
    - Тела из векторных слоёв рисуются без затенения. Цвет берётся
      из стиля слоя, а затенение его умножало и уводило оранжевый
      в бурый. Пояса плоские, светотень им ничего не добавляет,
      а совпадение с картой важнее.
    0.19.2
    - Грани тел разворачиваются нормалью вверх. Прежняя попытка
      дублировать грань обратной копией оказалась неверной: копия
      ложится ровно на оригинал, две грани спорят за глубину, отчего
      появляются полосы, а цвет уходит в чёрный.
    - Цвет объекта берётся из стиля слоя QGIS, если свой цвет не задан:
      как слой покрашен на карте, так он выглядит и в объёме. Своей
      легенды не заводим, раскраска уже сохраняется вместе с проектом.
    0.19.0
    - Объект с переменной высотой разбирается по кольцам, каждое в своей
      плоскости. Разбивка в плане не годится для вертикальных стенок:
      там кольцо вырождается в линию, и грань превращалась в мусор.
      Нормаль кольца берётся по формуле Ньюэлла, то есть по всему
      кольцу, а не по первым трём точкам.
    0.18.3
    - Обрезка объёмных тел отключена: отбор треугольников по центру
      с крышкой по линии реза давал рваную оболочку на юбках. Такие тела
      снова показываются или скрываются целиком, как в 0.17. Срез по ним
      требует разрезки треугольников плоскостью, это отдельная работа.
      Обрезка призм, поверхностей, линий и точек работает как прежде.
    0.18.2
    - Обрезанное тело разбивается так же, как необрезанное: в новой ветке
      полигон снова уходил на веерную разбивку, и на плоском контуре она
      тянула лучи через всю фигуру.
    - Отбор треугольников считается разом по массиву, а не по одной
      точке: на слое из десятков тысяч треугольников сборка занимала
      почти сорок секунд.
    0.18.1
    - Тела с объёмной геометрией (юбки, полиэдры) режутся контуром,
      и срез закрывается крышкой: в каждой точке линии реза берётся
      интервал, который тело занимает по вертикали, и строится лента.
      Прежде на месте среза была дыра, сквозь которую видна изнанка
      оболочки.
    0.18.0
    - Призмы режутся контуром по-настоящему: контур объекта пересекается
      с областью обрезки, и призма строится по новому контуру заново
      вместе с крышками. Срез получается закрытым, а не дырой в оболочке,
      и виден как разрез. Прежде объект выбрасывался целиком по своему
      центру.
    0.17.0
    - Вытягивание объектов от поверхности: низ призмы берётся с выбранного
      растра, верх это низ плюс высота из поля. Подошва дома садится
      на рельеф, а не на общую отметку. Прежний вариант «от поля до поля»
      остался.
    - Настройки сцены сохраняются в проект QGIS и восстанавливаются при
      открытии окна: отмеченные слои, свойства каждого, преувеличение,
      разнос, прозрачность, разрешение текстуры, обрезка вместе
      с нарисованными контуром и линией. Отдельного файла нет намеренно:
      настройки описывают те же слои и должны ехать вместе с проектом.
    0.16.3
    - Разметка кладётся на один уровень над сценой. Отметка вершины
      берётся с поверхности только ради попадания луча, для обрезки
      важно плановое положение, а разброс высот при вертикальном
      преувеличении читался как ошибка.
    0.16.2
    - Окно снова не открывалось: обработчик показа разметки трогал сцену,
      которой ещё нет. Сцена объявлена заранее, обработчики проверяют,
      что она уже создана.
    - Изолинии и прочие векторы теперь режутся с первой же сборки: контур
      обрезки сбрасывался после их разбора, и они резались по прошлому
      состоянию.
    - Размечать можно и в сцене без растровых поверхностей: вершина
      берётся с уровня середины сцены. Раньше на слое одних изолиний
      нарисовать линию обрезки было нечем.
    0.16.1
    - Окно не открывалось: кнопка показа разметки включается при сборке
      окна и вызывала перерисовку раньше, чем появлялось состояние сцены.
      Всё состояние теперь заводится до создания виджетов, а тест это
      стережёт.
    0.16.0
    - Обрезка режет и векторные слои, а не только растры. Линии рвутся
      там, где выходят за кусок, точки и скважины отбираются по своему
      положению, тела по центру объекта. Раньше изолинии и разломы
      торчали за краем обрезанной модели.
    - Контур обрезки считается один раз за сборку, а не на каждую
      вершину.
    0.15.1
    - Перечисления Qt берутся по имени через getattr во всех местах:
      ветвление через hasattr оставляло в коде короткое имя, и проверка
      совместимости с Qt6 на него ругалась. Вызов exec_ заменён на exec,
      взятый по имени: в Qt6 подчёркнутого варианта нет.
    0.15.0
    - Показ разметки включается и выключается кнопкой: контур и линия
      разреза нужны, пока размечаешь, и мешают, когда смотришь результат.
      Обрезка при этом продолжает работать.
    0.14.5
    - Замыкание контура больше не выворачивает обрезку наизнанку: режим
      куска мог остаться от работы с линией, а в обрезке по контуру всё,
      кроме «оставить внутри», понималось как «убрать внутри». Теперь
      контур ставит осмысленное умолчание, а вывернутым считается только
      явный вариант «убрать внутри».
    0.14.4
    - Исправлена отрисовка контура поверх модели: в опциях отрисовки
      был передан лишний ключ и функция смешивания вместе с аргументами,
      из-за чего линия не рисовалась вовсе. Набор ключей теперь повторяет
      штатный, только проверка глубины выключена.
    0.14.3
    - Нарисованный контур и линия рисуются поверх модели, не считаясь
      с глубиной: высота вершин для работы не нужна, важно плановое
      положение, а линия, спрятанная под складкой рельефа или под
      верхним пластом, мешает постоянно.
    0.14.2
    - Кнопки на панели над сценой снова отзываются на наведение
      и нажатие: стиль плашки распространялся на кнопки внутри и стирал
      у них подсветку. Нажатая кнопка режима теперь видна по заливке.
    0.14.1
    - Прежние наброски больше не висят поверх модели: они живут вне
      списка элементов сцены, и при пересборке обнулялась только ссылка,
      а сама линия оставалась в сцене.
    - Клик при рисовании попадает только по видимой части модели. Луч
      ищет пересечение по исходным гридам, поэтому вершина ставилась
      и там, где сцена уже обрезана.
    0.14.0
    - Появилась настоящая параллельная проекция и кнопка переключения
      между ней и перспективной. Вид сверху включает её сам: план
      с перспективой это не план, объекты на разной высоте смещаются
      в кадре и перестают совпадать в плане. Прежний приём со сжатием
      раствора камеры убран: он уводил камеру далеко и портил точность
      буфера глубины, отчего близкие поверхности спорили полосами.
    0.13.4
    - Убрана рябь между близкими поверхностями на виде сверху: раствор
      камеры в один градус уводил её слишком далеко, и буфер глубины
      терял точность. Теперь двенадцать градусов, перспективы почти нет,
      а глубина считается верно.
    - После обрезки сцена снова попадает в кадр: если охват изменился
      заметно, камера кадрируется заново.
    - Новая кнопка снимает обрезку и убирает наброски, возвращая сцену
      целиком.
    0.13.3
    - Вид сверху стал настоящим планом: раствор камеры сжимается почти
      до нуля, расстояние растёт так, чтобы масштаб не менялся. Раньше
      вид сверху оставался перспективным, и объекты, лежащие выше,
      уезжали в кадре к краям: нарисованная линия переставала совпадать
      с коридором, собранным из нескольких поверхностей.
    0.13.2
    - Полуширина коридора вводится прямо на панели над сценой, рядом
      с кнопкой линии, и видна только тогда, когда режут коридором.
      В свойствах сцены её никто не искал.
    0.13.1
    - В сцене рисуется не только замкнутый контур, но и линия: кнопка
      «Завершить линию» отдаёт её в обрезку коридором и сама включает
      нужный режим. Контур режет площадь, линия режет вдоль профиля.
    - Наброски показываются только пока они режут сцену: нарисованный
      контур больше не висит поверх модели, когда обрезка идёт по другому
      слою.
    0.13.0
    - Резать сцену можно и линией, не только контуром. В списке обрезки
      появились линейные слои, а в вариантах куска: слева от линии,
      справа и коридор вдоль неё с заданной полушириной. Коридор даёт
      профиль разреза вместе с данными по обе стороны, а не голую линию.
    - Сторона считается по ближайшему звену, поэтому на изломах ломаной
      она меняется там же, где меняется ближайшее звено.
    0.12.5
    - Нарисованный контур больше не расходится с моделью. Он живёт
      в координатах сцены, а центр сцены меняется вместе с данными:
      после обрезки охват уменьшался, и линия оставалась висеть
      по прежнему центру. Теперь контур перерисовывается при каждой
      сборке.
    0.12.4
    - На панель сцены вернулся вид сверху: рисовать контур по плану
      удобнее именно с него.
    0.12.3
    - Подсказка держится всё время рисования и показывает число вершин,
      а не гаснет после первого клика.
    - За курсором тянется резинка от последней вершины, поэтому видно,
      куда ляжет следующая сторона.
    - В режиме рисования правая кнопка снимает последнюю вершину: она
      отбирается у камеры только на это время.
    0.12.2
    - Вершины больше не ставятся в пустоту: поблажка на попадание
      впритирку убрана, точка берётся только при настоящем пересечении
      луча с поверхностью.
    - Снять последнюю вершину и замкнуть контур теперь можно кнопками
      рядом со значком рисования: правая кнопка и Esc в сцене заняты
      камерой и до рисовалки не доходили.
    0.12.1
    - Рисование контура стало попадать. Луч бьётся вчетверо мельче
      (4096 отсчётов вместо 512), а если пересечения нет, но луч прошёл
      впритирку к поверхности, точка берётся по ближайшему сближению
      в пределах четверти ячейки.
    - Правая кнопка снимает последнюю вершину, Esc отменяет рисование,
      Backspace тоже снимает вершину. Красный шарик опроса убирается
      при входе в режим рисования.
    0.12.0
    - Инструменты переехали на сцену маленькими значками, как на холсте
      карты: рисование контура, сохранение контура слоем, копирование
      и сохранение снимка, пересборка при снятом автообновлении. Список
      слоёв больше не тесним кнопками. Значки рисуются кодом, поэтому
      одинаково выглядят в светлой и тёмной теме.
    0.11.1
    - В режиме рисования контура отказ больше не молчит: клик мимо
      поверхности и отсутствие растровых поверхностей в сцене
      объясняются в строке состояния.
    0.11.0
    - Контур обрезки рисуется прямо по сцене. Кнопка «Рисовать контур»,
      клик по поверхности ставит вершину, двойной клик замыкает. Готовый
      контур сразу режет сцену, кнопка «Контур в слой» сохраняет его
      слоем проекта.
    0.10.0
    - Обрезка сцены по контуру. В свойствах сцены выбирается любой
      полигональный слой и что показать: кусок внутри контура или всё
      остальное. Поверхности и тела пластов режутся по границе контура,
      а не по прямоугольнику охвата, дырки контура остаются дырками.
    0.9.5
    - Кадр сцены копируется в буфер обмена кнопкой «Копировать снимок»
      или сочетанием Ctrl+C: чаще всего снимок нужен, чтобы сразу
      вставить его в письмо или в записку, а не хранить файлом.
    0.9.4
    - На время сборки сцены курсор меняется на часы, а в строке
      состояния стоит «Собираю сцену…». Полоса не годилась: сборка идёт
      в потоке интерфейса, и бегущая полоска всё равно не двигалась бы.
    - Кнопок видов больше нет, сцена крутится мышью. Внизу осталась одна
      кнопка «Сохранить снимок…». Кнопка сборки появляется только тогда,
      когда снята галка «Обновлять автоматически».
    - Из строки состояния убрана подпись о числе поверхностей.
    0.9.2
    - Исправлена рекурсия в приёмнике элементов сцены: массовая замена
      вызовов переписала и его собственное тело, поэтому сборка падала
      с maximum recursion depth exceeded. Добавлена проверка, которая
      ищет вызовы по кругу между методами окна.
    0.9.1
    - Сбой сборки сцены больше не выглядит пустым окном: причина
      выводится в строку состояния, полный след уходит в журнал
      сообщений QGIS, раздел Isoliner3D.
    0.9.0
    - Галка слоя прячет и показывает его сразу, без пересборки сцены:
      элементы уже лежат в видеопамяти, поэтому отклик мгновенный
      на сцене любой тяжести.
    - Правка свойств сама пересобирает сцену, с задержкой в четверть
      секунды после последнего изменения, чтобы кручение ползунка
      не вызывало десяток сборок подряд. В свойствах сцены есть галка
      «Обновлять автоматически» на случай тяжёлой сцены.
    - Тела, линии и точки собираются в один меш на слой, а не на всю
      сцену: иначе слой нельзя было спрятать, не пересобирая всё.
    0.8.3
    - Убраны семь конструкций except/continue, на которых сканер каталога
      QGIS отклоняет загрузку (B112). Добавлена проверка, которая ищет
      такие места и не даёт им вернуться: сканер сообщает о них только
      при отправке, поэтому ловить их надо у себя.
    0.8.2
    - Слой, свойства которого ни разу не открывали, рисуется по своим
      умолчаниям. Показ читал словарь настроек напрямую и на пустой
      записи брал контурный режим, поэтому полигоны с Z выходили
      линиями, хотя в свойствах стояло «Телом (заливка)». После
      переустановки плагина словарь пуст, отсюда линии вместо тел.
    - Полигоны в режиме призмы больше не дублируются контуром.
    0.8.1
    - Поверхность полигона с переменной Z строится триангуляцией Делоне
      с сохранением вершинных отметок. Прежде такой объект уходил на
      веерную разбивку: она рассчитана на простые грани полиэдра, а на
      поясе между изолиниями тянула лучи через фигуру и теряла
      внутренние кольца. Пояс с нижней границей на одном уровне и
      верхней на другом теперь выходит скатом, шапки вершин и днища
      впадин остаются плоскими.
    - Распознавание плоского объекта смотрит все вершины, а не первые
      4096. Обход контура идёт сначала по одной границе, поэтому пояс в
      двадцать пять тысяч вершин объявлялся плоским по своему началу и
      скат превращался в плиту.
    - Отбор объектов в сцену считает вершины, а не объекты. Слой из 1174
      поясов показывался наполовину, упираясь в потолок в пятьсот
      объектов, тогда как весит он меньше одного растра.
    - Триангуляция Делоне без ограничений (сборки без GEOS 3.11)
      отсеивает треугольники вне фигуры по центру. Раньше на вогнутом
      контуре она затягивала заливы и закрывала дыры.
    0.8.0
    - Показ полигонов призмой: контур выдавливается от поля низа до поля
      верха, получаются две крышки и вертикальные стенки. Так ступени
      рельефа, уступы карьера и подсчётные блоки с кровлей и подошвой
      становятся объёмом, а не стопкой плит.
    - Диагностика геометрии слоя: если все объекты плоские, в окно
      выводится их число, размах отметок и подсказка про призму.
    0.7.4
    - Кэш триангуляции полигонов. Разбивка повторялась на каждую сборку
      сцены, хотя геометрия не менялась: на пятистах контурах это шесть
      секунд каждый раз. Ключ считается без разбора геометрии: слой,
      объект, число вершин, охват и отметка. Потолок 128 МБ.
    0.7.3
    - Тела собираются в один меш вместо элемента на объект, цвет каждого
      хранится в вершинах. На 500 объектах это было 500 наборов буферов
      плюс нормали в двойной точности на каждый: сотни мегабайт при
      34 МБ полезных данных. Шарики на устьях скважин собраны так же.
    - Прореживание считает бюджет вершин на всю сцену, а не потолок
      на слой. Одиночная поверхность получает вдесятеро больше деталей,
      чем раньше, а тяжёлая пачка перестаёт складывать миллионы вершин.
    - В отчёт перестройки добавлена оценка занятой видеопамяти.
    0.7.2
    - Честная триангуляция подключена и к полигонам со своей высотой Z.
      Раньше она работала только при отметке из поля, а плоский контур
      с собственной Z по-прежнему разбивался веером и давал лучи через
      всю фигуру. Теперь плоский объект распознаётся по постоянной Z
      и разбивается Делоне, а настоящая поверхность с переменной Z
      идёт прежним путём: её грани простые, веер для них верен.
    0.7.1
    - После слияния списков отбор слоёв перестал фильтровать по типу:
      векторный слой уходил в чтение как растр, не открывался и попадал
      в «Пропущено», хотя рисовался телами. Отбор снова разделён.
    0.7.0
    - Вкладки убраны, список слоёв один: растры и векторы вместе, как
      в дереве QGIS, тип слоя помечен в строке. Первой строкой закреплена
      «Сцена». Фильтр действует на весь список.
    - Разрез стал свойством линейного слоя: галка «Показывать плоскостью
      разреза» и выбор чертежа в свойствах. Отдельная вкладка не нужна,
      а разрезов в сцене может быть несколько, каждый со своим чертежом.
    - Окно свойств показывает набор по типу выделенного: растру каналы
      и окраска, вектору источник высоты и цвет, линейному слою вдобавок
      разрез, «Сцене» общие настройки.
    0.6.4
    - Кольца полигона больше не склеиваются в одну ломаную. Внутри части
      геометрии кольца идут подряд, и обход всех вершин соединял конец
      внешнего кольца с началом дыры: через фигуру тянулся прямой штрих,
      а на слое контуров рельефа такие штрихи давали паутину.
    - Число линий на слой ограничено полутора тысячами, с сообщением.
    0.6.3
    - У полигонального слоя появился выбор показа: контуром или телом.
      Вложенные контуры уровней осмысленно смотреть линиями, заливка
      нужна телам пласта и полиэдрам. Слой без Z по умолчанию идёт
      контуром, слой с Z телом.
    - Предупреждения выводятся в окно, а не только в журнал: нет высоты Z,
      не выбрано поле отметки, слишком много объектов.
    - Убрана подсказка над списком векторных слоёв.
    0.6.2
    - Полигоны разбиваются триангуляцией Делоне с ограничениями. Прежняя веерная разбивка годится для выпуклых
      граней полиэдра и на вогнутом контуре с дырами давала лучи через
      всю фигуру.
    - Несовместимые параметры слоя больше не выбираются: источник высоты
      гаснет у скважин, поле отметки доступно только при высоте из поля,
      поля отметок только в режиме скважин, «Своя высота геометрии»
      недоступна слою без Z и заменяется отметкой из поля.
    0.6.1
    - Линии и точки не рисовались вовсе: высота бралась через asPolyline
      и asPoint, а они отдают точки без Z. Теперь читаются настоящие
      вершины геометрии.
    - Полигональный слой без высоты Z больше не превращает сцену в кашу:
      такой слой пропускается с записью в журнал, а число объектов
      на слой ограничено пятьюстами.
    - Пустая сцена без объяснений заменена записью в журнал: не выбрано
      поле отметки, нет Z, слишком много объектов.
    0.6.0
    - Диалог перестроен. Все настройки убраны с главного окна в свойства:
      открываются двойным кликом по строке списка и правой кнопкой, как
      в QGIS. Первой строкой списка закреплена «Сцена», её свойства это
      преувеличение, разнос по Z, прозрачность и сторона текстуры.
    - Вкладка «Тела» стала «Векторами» и переехала на второе место.
      Она принимает любые векторные слои: полигоны с Z рисуются телами,
      линии и точки берут высоту из геометрии или из числового поля.
      Изолинии с отметкой в поле ложатся в сцену на своей высоте.
    - Скважины переехали в «Векторы» и стали режимом точечного слоя,
      поэтому вкладка «Разрезы» занята только разрезами.
    - Вокруг сцены появилась тонкая рамка, как у холста карты QGIS.
      Кнопки видов дополнены наклонным ракурсом.
    0.5.4
    - Выбранная окраска больше не сбрасывается на палитру при переходе
      на другой слой. Штатный findData сравнивает данные пункта через
      QVariant и на кортежах Python молча возвращает -1, поэтому в списке
      показывалась палитра, хотя в сцене оставалась прежняя окраска.
      Тем же были задеты списки чертежа разреза, скважин и каналов.
    0.5.3
    - В инструменте 1.07 вернулся вариант «Карта (растр для текстуры)»:
      при слиянии демо-инструментов он остался в коде, но пропал из списка
      вариантов и лишился своих параметров, поэтому выбрать его было
      нельзя. Добавлен тест: каждый вариант обязан быть виден в диалоге.
    0.5.2
    - Исправлен перенос группы инструментов из Isoliner: не были захвачены
      импорт QVariant и три служебных объекта пост-процессора мешей.
      Инструмент 1.04 при запуске падал, остальные при записи полей.
      Ошибку добавлен ловить новый тест: pyflakes по всем модулям
      с требованием нуля неопределённых имён.
    0.5.1
    - Первый выпуск. 3D-просмотр выделен в отдельный плагин из набора
      Isoliner. Поверхности из растров проекта, водонепроницаемые тела
      пластов из многоканальных гридов, скважины стволами с мачтами
      и подписями, плоскость разреза, полиэдры, TIN и MultiPolygon Z,
      опрос сцены кликом, снимок PNG. pyqtgraph и PyOpenGL в комплекте,
      устанавливать ничего не нужно.
    - Наложение карты на поверхность настоящей текстурой с затенением
      по нормали: ортофото, подложка, геологическая карта со всей
      символикой. Разрешение задаётся отдельно и от плотности сетки
      не зависит. Отдельно накладывается чертёж разреза на ленту,
      несколько разрезов показываются одновременно.
    - Группа Processing «Пласт и блочная модель», семь инструментов:
      сборка грида пласта, калькулятор запасов, блочная модель, экспорт
      поверхностей в меши 2DM, домены в канал пласта, разность запасов
      и генератор демонстрационных данных.
    - Кэш прочитанных гридов и отрисованных текстур: повторная сборка
      сцены идёт из памяти. Счётчики перестройки сцены в окне
      и с разбивкой по фазам в журнале сообщений.
    - Двуязычное руководство (PDF, RU и EN) в комплекте, открывается
      по языку интерфейса кнопкой Справка.
