[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. Sixteen Processing tools in two groups: the bed and block model computes thickness, volume and reserves from a bed grid, and the interpolation in volume builds cubes by kriging and multilevel B-splines and a bed grid from the outlines drawn on sections, with the contact of neighbouring beds built as one surface. 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 в двух группах: пласт и блочная модель считают мощность, объём и запасы по гриду пласта, а объёмная интерполяция строит кубы кригингом и мультисеточными B-сплайнами и грид пластов по зарисовкам на разрезах, склеивая контакт соседних пластов в одну поверхность. Снимок PNG для отчётов. Спутник набора кригинга и изолиний Isoliner (plugins.qgis.org/plugins/grid_isolines) и чистки топологии Topoliner (plugins.qgis.org/plugins/topoliner). pyqtgraph и PyOpenGL идут в комплекте - устанавливать ничего не нужно. Спутник набора кригинга Isoliner. Разработано при поддержке ООО «Информ++» (www.informpp.ru).
version=0.84.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.84.0
    - Линза внутри пласта больше не портит его границу. Контуры одного
      пласта опрашивались каждый сам по себе, и пробы сваливались
      в одну кучу: если внутри пласта нарисован ещё один контур с тем
      же номером, в облаке кровли оказывались и настоящая кровля,
      и верх линзы. Интерполяция получала в одной точке два ответа
      и проводила поверхность между ними - кровля ныряла к подошве.
    - Теперь контуры одной плоскости разреза разбираются вместе,
      по внешней границе: кровля по самому верхнему, подошва по самому
      нижнему. На проверочной стенке пласт 2.00 - 2.30 с линзой
      2.10 - 2.20 внутри даёт кровлю 2.30 и подошву 2.00 на всём
      протяжении; раньше выходило 2.20 и 2.10.
    - Контуры РАЗНЫХ разрезов не объединяются никогда. Расхождение
      в одной точке плана между двумя разрезами это данные, и его надо
      показывать, а не прятать взятием крайнего.
    - Пласт, выходящий на одной стенке в двух местах, остаётся двумя
      кусками: внешняя граница берётся только там, где контуры
      перекрываются в плане.
    - Сцена предупреждает, если у тела объём в поле volume больше его
      собственного габарита. Так выглядят слои, выгруженные сборкой
      до 0.74.1, где счёт объёма терял значащие цифры в настоящих
      координатах: на присланном слое из 93 тел таких оказалось 37,
      у худшего объём превышал габарит в пятьдесят тысяч раз. Молча
      пересчитывать чужой слой хуже, чем сказать, что верить его
      числам нельзя.
    0.83.0
    - Расхождение на разрезах теперь называет и МЕСТО: координаты
      точки, где оно наибольшее. С одним числом человеку идти некуда,
      а с адресом он открывает своё место в слое и видит съехавшую
      вершину. Печатается и для контакта соседних пластов, и для
      пересечений разрезов между собой.
    - На присланном шурфе это сразу показало причину: расхождение
      контакта пластов 1 и 2 в 0.245 м сидит в одной вершине контура,
      уехавшей вниз на полметра.
    0.82.0
    - Градиентный фон включён по умолчанию и ставится заново
      на каждой пересборке сцены. Он живёт в самом виде, а не в сцене,
      и терялся на любом пути, который вид пересоздавал: сцена
      собиралась, градиент пропадал, и приходилось снимать и ставить
      флажок.
    - 2.08 больше не молчит, когда контакт соседних пластов найти
      не удалось. Раньше сообщение шло только про найденный контакт,
      а «не нашлось вовсе» выглядело как «склейка не сработала».
      Причина у этого одна и человеку не очевидная: контуры соседних
      пластов нарисованы в разных местах плана, дальше шага
      опробования, и общих проб у них нет.
    0.81.0
    - Сцена из тел больше не выходит тёмной. Штатный шейдер pyqtgraph
      светит одним источником и обрезает освещённость нулём, а фон
      у него пятая доля цвета: всё, что от источника отвёрнуто,
      выглядит почти чёрным. У тела пласта таких граней половина -
      боковые стенки и подошва.
    - Источников теперь три: основной рисует форму, второй светит
      с другой стороны вполсилы, третий снизу не даёт провалиться
      низу. Освещённость берётся по модулю косинуса: у замкнутого
      тела грань, повёрнутая от источника, всё равно видна.
      На случайных нормалях средняя яркость выросла с 0.40 до 0.71,
      наименьшая с 0.20 до 0.44, и при этом свет не стал плоской
      заливкой - размах яркости больше трети.
    - Отмывка поверхностей, раскрашенных шкалой, оставлена
      однолучевой. Тремя источниками она выходит площе: размах
      яркости сжимается с 0.45 - 1.00 до 0.50 - 0.86, и рельеф
      внутри одного оттенка читается хуже. Тёмными были тела,
      а не шкала.
    0.80.0
    - 2.08 склеивает контакты пластов. Подошва верхнего и кровля
      нижнего это одна граница, если геолог провёл их одной линией.
      Построенные порознь, они между разрезами расходятся, и в модели
      встаёт щель или нахлёст, которых на разрезе нет. Теперь такая
      граница строится ОДИН раз по обоим наборам точек и кладётся
      в обе полосы, поэтому щель обращается в ноль по построению,
      а не по удаче.
    - Допуск склейки задаётся в «Дополнительно», по умолчанию сантиметр.
      Ноль отключает склейку. Расхождение контакта на разрезах
      печатается всегда, склеен он или нет: по этому числу и видно,
      одна там линия или две разные.
    - Пласты упорядочены по залеганию, сверху вниз, а не по имени поля.
      Номера бывают текстом, и тогда «10» встаёт между «1» и «2»,
      а контакт ищется между соседями по разрезу, не по алфавиту.
    - Замер на модели: два пласта с общей границей, нижний контур
      короче по простиранию. Порознь границы разошлись на 6 мм,
      склеенные совпадают точно. Числа маленькие, но при вертикальном
      преувеличении в сцене они и видны как щель.
    0.79.0
    - Кнопка «Оболочки в слой проекта» принимает и тело пласта, не
      только изоповерхность куба. Раньше она отвечала «Слой не
      в режиме изоповерхности», и вытащить тело пласта в QGIS было
      нечем: 1.04 даёт кровлю и подошву порознь, а выгрузка сцены -
      файл, а не слой.
    - Выгрузка строит своё тело, а не берёт показанное. У показанного
      вертикаль растянута преувеличением, разнесена по Z и прорежена
      под бюджет вершин: объём такого тела неверен ровно во столько
      раз, во сколько растянута вертикаль. Здесь отметки настоящие
      и сетка полная.
    - Обрезка берётся та же, что настроена в сцене: человек её уже
      задал и видит результат.
    - На каждый пласт своё тело, объём считается тут же, поля те же,
      что у оболочек куба: body, level (канал кровли), volume, closed,
      holes, pinch, zmin, zmax.
    - Объём меша идёт по центрам ячеек, поэтому на полячейки с каждой
      стороны меньше, чем считает 1.02 по ячейкам целиком. На мелкой
      сетке разница около процента, на грубой заметна, и знать о ней
      надо.
    0.78.0
    - У 2.08 появилась векторная маска области. Грид строился на весь
      охват контуров, и за пределами разрезов тело жило там, где
      данных нет вовсе. Маской задаётся, докуда поверхностям верить:
      контур выработки, шурфа, подсчётного блока. За её пределами
      грида нет, в журнал идёт доля оставшихся ячеек.
    - Есть запас наружу от маски: пласт обычно продолжается за контур
      выработки, и обрезка ровно по нему срезала бы то, что в данных
      есть.
    - Система координат маски своя. Пересчёт делается сам, а если
      маска не накрыла ни одной ячейки, расчёт останавливается
      и называет обе обычные причины: разные системы координат либо
      маска в стороне от участка. Молча пустой грид тут хуже отказа.
    0.77.0
    - Строки расчёта дублируются в журнал плагина. Раньше журнал знал
      только имя инструмента и время: снимок показывал, что расчёт
      прошёл за полсекунды, и ни одного числа, по которому видно,
      что именно он посчитал. Всё остальное - прогресс, отмена -
      остаётся делом самого Processing.
    - Кубовые режимы сцены отказываются работать с гридом пласта
      и говорят, почему. Каналы куба это уровни по Z, и разметку по Z
      пишут все инструменты куба. У грида пласта её нет: каналы там
      кровля и подошва, а значения - абсолютные отметки. Считая их
      уровнями от нуля с шагом единица, сцена рисовала параллелепипед
      у нулевой отметки, ниже всех объектов, и по нему делали вывод
      о модели.
    - Многоканальный растр без разметки по Z, но и не похожий
      на пласт, строится как прежде, только теперь с предупреждением,
      что по высоте он встанет не на своё место.
    0.76.1
    - Снятие тренда включено и в 2.07 MBA в объёме: дефект там тот же,
      просто виден слабее. На содержаниях около двадцати процентов
      с пропуском в середине истинное значение 21.99, выходило 20.26,
      стало 21.63. Ошибка была сопоставима со всем разбросом данных.
    0.76.0
    - Исправлены горбы и ямы на кровле и подошве в 2.08. Коэффициент
      решётки MBA считается формулой, линейной по значению, поэтому
      ошибка росла вместе с самой отметкой, а не с её разбросом.
      На шурфе с контурами по четырём стенкам, кровля около -250 м
      с разбросом восемьдесят сантиметров, поверхность уходила
      на 14.5 м. Число уровней этого не меняло: с третьего уровня
      ошибка не менялась вовсе, а на первом была 57 м.
    - Перед подгонкой снимается плоский тренд, а после возвращается
      в коэффициенты нулевого уровня. Плоскость решётка воспроизводит
      точно, поэтому оценка, грид и куб остаются в абсолютных
      отметках, и вызывающей стороне помнить о поправке не надо.
      На том же шурфе отклонение от истинной кровли стало 0.000 м,
      мощность по площади 3.00 .. 3.00 при 3.00 на разрезах.
    - Снятие тренда включается параметром и включено пока только
      в 2.08: где на прежнем поведении что-то построено, оно
      не меняется молча.
    - Расхождение отметок на пересечениях разрезов попадает в журнал.
      Считалось оно знаковой проверкой, годной для поля «внутри плюс,
      снаружи минус»: у отметок кровли знак у всех один, и расхождения
      не находилось никогда. Результат к тому же никуда не выводился.
    - Теперь считается размах отметок там, где сошлись РАЗНЫЕ контуры,
      отдельно по кровле и по подошве, с предупреждением, если
      расхождение больше наименьшей мощности пласта. Пробы сводятся
      по шагу опробования, а не по ячейке грида, и четырьмя сетками
      со сдвигом: одной сеткой все четыре угла шурфа терялись, а там
      зарисовки соседних стенок как раз и обязаны сойтись.
    0.75.1
    - Исправлено: модель уезжала в чужие координаты. Система координат
      у слоя и у проекта бывает МЕСТНОЙ, без привязки к земле -
      у раскопа, карьера, шахтного поля. QGIS всё равно вёл пересчёт
      между ними через WGS 84, и полтора миллиона превращались
      в минус миллион. Между местными системами пересчёт больше
      не делается, и сцена говорит об этом.
    - Исправлен разбор контуров на кровлю и подошву. Я делил кольцо
      пополам, считая первую половину кровлей: так устроен только
      забор, где верх идёт вперёд, а низ назад. У нарисованного
      от руки контура порядок вершин произволен, и мощность выходила
      нулевой там, где пласт есть.
    - Теперь кровля и подошва берутся как верх и низ контура
      в каждой точке вдоль линии. На присланном раскопе нулевых
      мощностей не осталось, точек стало 240 вместо 46, пласты вышли
      от одного до пятидесяти трёх сантиметров.
    0.75.0
    - Забор в сцене сделан заново и по делу: вертикальный разрез
      сквозь всю пачку пластов по заданной линии, с кровлей
      и подошвой каждого. Строится ровно по линии, без толщины -
      чертёж разреза, поставленный в сцену.
    - Прежний переключатель менял режим слоя на стенку: полотнище,
      натянутое на ОДНУ поверхность. Это было не то, о чём просили,
      и он убран.
    - Ломаная линия даёт ломаное полотнище. Где пласта нет, там нет
      и разреза: пропуск не выдумывается.
    - Обрезка полигональным слоем работала, но молча ничего не резала,
      если оставить «Коридор вдоль линии»: коридор строится только
      по линии. Теперь сцена называет несовпадение, и наоборот -
      линейный слой с внутренностью тоже.
    0.74.1
    - Исправлен подсчёт объёма в настоящих координатах. Формула
      складывает объёмы тетраэдров от начала координат, и при шести
      миллионах метров по северу каждое слагаемое выходит порядка
      десяти в четырнадцатой, а сумма должна дать миллион: значащие
      цифры съедаются взаимным вычитанием.
    - На присланном слое из 93 тел у 37 объём выходил больше их
      собственного габарита - у самого большого в тысячу триста раз.
      Суммарно было восемь миллиардов кубометров, стало шесть
      миллионов.
    - Считается от середины тела. Проверка на плите из тринадцати
      тысяч граней в настоящих координатах ловит возврат ошибки.
    - Выгрузка не записывает объём, который больше габарита тела,
      и говорит об этом: число выглядело бы настоящим и ушло бы
      в отчёт.
    0.74.0
    - Обрезка растровой маской: тело остаётся там, где значение
      не меньше порога. Полигон задаёт границу линией, а маска -
      площадью, и это удобнее, когда границу посчитал инструмент.
      Пропуск в маске считается «снаружи», точка вне охвата маски -
      тоже.
    - Заборы по линии переехали из свойств слоя в свойства сцены:
      обрезка общая, и разрез по той же линии тоже общий. Одна галка
      показывает все поверхности вертикальными полотнищами. Кубы
      и воксели остаются как есть: у них своя геометрия.
    - Названия в разделе обрезки поправлены: «Контуром или линией»,
      «Что оставить», «Сверху и снизу (растры)». Прежние скрывали
      назначение, и человек не находил того, что уже есть.
      У каждой строки появилась подсказка.
    - Проверка перевода собирала строки из перечисленных вручную
      файлов, и viewer_dialog.py в список не попал - а там половина
      строк окна. Теперь собирает из всех файлов модуля: 774 строки
      вместо прежних.
    0.73.1
    - Тело пласта строится по ВСЕМ парам каналов, а не по первой.
      Режим брал каналы 1 и 2 жёстко, и переключатели каналов на него
      не действовали вовсе: у грида из 2.08 на каждый пласт своя пара,
      а виден был только верхний.
    - Десять каналов дают пять тел одним слоем. Канал высот задаёт,
      с какой пары начать, и об этом сказано в подсказке к нему.
    - Число пар говорится в журнале: по нему видно, все ли пласты
      попали в сцену.
    0.73.0
    - Инструмент 2.08 переделан целиком: вместо куба он строит грид
      пластов - кровлю и подошву на каждый. Прежний подход задачу
      не решал, и это моя ошибка в самой постановке.
    - Почему не решал. Я строил в объёме поле, у которого ноль это
      граница. Между разрезами данных нет, коэффициент остаётся
      нулевым, а ноль там и есть граница: «нет данных» и «здесь
      граница» оказывались одним значением. Тело не выходило
      за плоскости разрезов, и получался крест по разрезам вместо
      пласта.
    - У пласта есть кровля и подошва, и каждая из них обычная
      поверхность. Их и надо интерполировать: это задача, у которой
      решение есть при любой сети разрезов.
    - Замер на присланных разрезах: пять пластов, площадь заполнена
      целиком, мощности от 2.4 до 13.7 метра - ровно в тех пределах,
      что на разрезах. Объёмы от 9.6 до 20.8 миллиона кубометров.
      Счёт - одна десятая секунды вместо двадцати трёх.
    - Все пласты ложатся в один файл: у них общая площадь и сетка,
      а грид многоканальный. Папка для отдельных кубов больше
      не нужна.
    - Такой грид сцена показывает телом пласта сразу, а 1.02 и 1.03
      считают по нему мощность, блоки и объёмы - без единой новой
      строки после инструмента.
    0.72.3
    - Записанные кубы открываются слоями сами. Папка в проект ничего
      не кладёт, а открывать по пять файлов руками - работа
      на пустом месте.
    - Инструмент перенумерован из 2.09 в 2.08. Номер освободился,
      когда прежний 2.08 убрали в кнопку сцены, а дыра в нумерации
      читается как «инструмент был и пропал».
    - Проверка следит, чтобы номера шли подряд: дыра её остановит.
    0.72.2
    - У 2.09 один выход вместо двух: папка, куда ложатся кубы
      по файлу на пласт. Прежде рядом с ней объявлялся ещё и куб
      одним файлом, и QGIS в конце ругался, что тот не создан.
    - Один файл на все пласты не годится по существу: сцена читает
      куб целиком и пласты в нём не различит. Держать такой выход
      «на всякий случай» значило дать выбрать заведомо негодное.
    0.72.1
    - Оценка на сетке ускорена в сорок пять раз. Она строила точки
      и считала их вразнобой, собирая на каждую по шестьдесят четыре
      соседа. На правильной сетке веса разделяются по осям, и решётку
      можно сворачивать по одной оси за раз.
    - Замер на присланных разрезах: куб 209x210x73 считается
      0.4 секунды вместо 17.8. Пласт целиком - 4.2 секунды вместо
      21.7, пять пластов - 21 секунда вместо 109.
    - Ответ тот же до последнего знака, и это закреплено проверкой:
      счёт по сетке сверяется со счётом по отдельным точкам.
    - Ускорение досталось и плоскому случаю: поверхность тысяча
      на тысячу считается за 0.13 секунды. Им пользуются 2.07 и 2.09.
    0.72.0
    - Найдено и исправлено по присланным разрезам: 2.09 не давал тела
      вовсе. Забор нарезан на куски по звеньям линии, а я считал знак
      по каждому куску отдельно и ставил минусы вокруг него. Минусы
      одного куска ложились туда, где соседний кусок того же пласта
      даёт плюс.
    - На падающем пласте это губительно: пласт тонкий, шесть метров,
      а падает на семьдесят пять по площади. Плюсов в слое решётки
      оставалось три процента, ноль в кубе не встречался, и в журнале
      это выглядело как «куб доходит до -0.000».
    - Теперь пласт опробуется целиком: точка внутри, если она внутри
      любого куска, а расстояние берётся до ближайшего. На присланных
      данных точек внутри стало 17123 вместо 2137, и куб пошёл
      от -41 до +3.4 - тело есть.
    - Заодно исправлено продолжение линии за её начало: направление
      бралось задом наперёд, и точки за началом ложились внутрь.
      В одном месте оказывались две точки с разными знаками.
    0.71.8
    - В журнал 2.09 добавлено число точек, попавших внутрь контуров.
      Оно разделяет две разные беды: если внутри ноль, опробование
      не нашло внутренности и дело в геометрии контуров; если внутри
      много, а ноль в кубе не встретился, дело в решётке или
      в перевесе минусов.
    - Прежнее предупреждение винило решётку всегда, и это сбивало
      с толку.
    0.71.7
    - Пласты больше не надо строить по одному. У 2.09 появилась папка
      для кубов по пластам: на каждый ложится свой файл, и все они
      считаются за один прогон.
    - Ограничение было моё, а не по существу: куб это один файл,
      и я свалил все пласты в него стопками каналов. Сцена читает куб
      целиком и пласты в нём не различала.
    - Пластов несколько, а папка не задана - инструмент говорит это
      сразу и перечисляет пласты, а не считает впустую и не выдаёт
      куб, из которого ничего не построить.
    0.71.6
    - Исправлено главное: у тонких пластов ноль в кубе не встречался
      вовсе. Сетка опробования шла по вертикали тем же шагом, что
      и по горизонтали, а пласт тоньше этого шага: ни одна точка
      не попадала внутрь контура, все ложились ровно на границу.
      В журнале это выглядело как «куб доходит до -0.000».
      Теперь шаг по вертикали берётся от мощности самого контура,
      и мелкий он только у пласта - растянув его на весь запас,
      получишь десятки тысяч точек там, где и так всё минус.
    - Исправлено: забор по ЛОМАНОЙ линии разреза разворачивался
      проекцией на прямую и складывался сам на себя. Внутри контура
      оставались две точки из восьмисот. Теперь разворот идёт по пути
      вдоль линии, и сетка опробования кладётся вдоль неё же,
      а не на прямую плоскость.
    - Значение теперь расстояние до контура со знаком, а не плюс
      и минус. При одинаковом весе минусов вокруг тонкого пласта
      много больше, и они тянут поле вниз; расстояние ставит ноль
      на границу по геометрии, а не по числу точек.
    - Предупреждение о нескольких пластах стало полезным: говорит,
      сколько их, сколько от них каналов и как построить по одному.
    0.71.5
    - Решётка в 2.09 выбирается по данным, а не берётся жёсткой
      8x8x2. Самая мелкая ячейка ставится около шага опробования:
      крупнее - плюс усредняется в минус, и тела не выходит вовсе.
    - Куб говорит свой размах в журнал, и если ноль в нём
      не встретился, инструмент прямо предупреждает: тела не будет.
      Прежде человек искал причину в сцене, где показывать было
      просто нечего.
    - Размер решётки и её ячейка тоже печатаются: по ним и видно,
      крупна ли она для пласта.
    - Память решётки проверяется до выделения, как в 2.07. Прежде
      число уровней восемь давало решётку 1024x1024x256 и убивало
      расчёт без объяснений.
    0.71.4
    - Исправлено падение QGIS на большом наборе точек. Каждая точка
      разворачивается в шестьдесят четыре узла носителя, и на них
      заводится несколько массивов: полмиллиона точек это гигабайт,
      миллион - два. QGIS падал раньше, чем NumPy успевал сказать
      «нет памяти».
    - Подгонка и оценка считаются порциями. Память перестала зависеть
      от числа точек: четыреста тысяч - 245 МБ, полтора миллиона -
      253 МБ. Прежде полтора миллиона потребовали бы около трёх
      гигабайт. Ответ тот же, и это закреплено проверкой.
    - Заодно втрое быстрее: порция помещается в кэш, и большие
      массивы не гоняются в память и обратно. На четырёхстах тысячах
      точек 5 секунд против 17.
    - Оценка держала больше памяти, чем сама подгонка: невязка
      по уровням считается по всем точкам сразу. Порциями теперь
      и она.
    - Число точек опробования говорится в журнале до счёта: на нём
      и решают, менять ли шаг.
    0.71.3
    - В подсказках и руководстве расписано, откуда 2.09 берёт
      координаты: из самой геометрии контуров, по вершинам, у которых
      есть X, Y и Z. Линии разрезов задавать отдельно не надо, они уже
      в данных.
    - Сказано прямо, что плоский чертёжный разрез не годится: у него
      X и Y это координаты на листе, а не на местности. Тип геометрии
      должен быть PolygonZ или MultiPolygonZ.
    - Расписано, как определяется граница тела. Знак это признак
      «тело или не тело», а граница проходит там, где поле сменило
      знак, - не по контуру. На самом разрезе это почти одно и то же,
      между разрезами - догадка интерполяции, а не данные.
    - Сказано и про край участка: тело там закрывает кольцо минусов,
      то есть запас наружу от контура. Без него поле осталось бы
      положительным до края куба.
    0.71.2
    - Исправлено: 2.09 падал на NumPy 2. У массивов там убрали метод
      ptp, а я им пользовался. На старой NumPy такой код работает
      и молчит, а у человека с новой падает посреди расчёта.
    - Проверка ищет по всему модулю вызовы, снятые в NumPy 2: методы
      ptp, itemset, newbyteorder и имена вроде np.float_ и np.alltrue.
      Прочие места пользовались верной записью, но полагаться на это
      нельзя.
    - 2.09 отказывается от слоя оболочек и говорит почему: двести
      тысяч треугольных полигонов это грани готового тела, а не
      зарисовки пластов на разрезах. Прежде он взялся бы считать
      и считал бы час впустую.
    0.71.1
    - У каждого пункта меню свой значок. Все три брали один и тот же,
      и в меню они были неразличимы: человек жмёт наугад.
    - «О плагине» получил круг со знаком «i», «Справка» - страницу
      с загнутым углом. Отличаются формой, а не только цветом:
      в меню значки мелкие, и цвет один читается плохо.
    - Проверка не пропустит повторный значок: она сверяет, какие
      значки розданы пунктам, и требует, чтобы все были разными.
    0.71.0
    - Новый инструмент 2.09 «Куб по разрезам»: тело по контурам
      пластов, нарисованным на разрезах. Плоскость каждого разреза
      опробуется знаком - внутри контура плюс, снаружи минус, - и
      нулевой уровень куба оказывается границей тела по построению.
    - Класть значение только на границу контура нельзя: вокруг пусто,
      и нулевой уровень уходит куда угодно. На проверочном эллипсоиде
      такая подмена дала объём вчетверо с лишним больше настоящего,
      против двух процентов ошибки при опробовании знаком.
    - Точность решает частота разрезов: восемь разрезов дали ошибку
      объёма два процента, четыре - двадцать один, три - тридцать
      девять, и тело вдобавок ложно развалилось надвое. Это сказано
      и в подсказке инструмента, и в руководстве.
    - Расхождения разрезов на пересечениях считаются и печатаются
      в журнал: там граница проведена по-разному, и усреднив её молча,
      получишь модель, которая выглядит правдоподобно и неверна.
    - Каждый номер пласта считается отдельно и ложится своей стопкой
      каналов. Смешав пласты в один, получишь границу между ними там,
      где её нет.
    - Плоский чертёжный разрез не годится: у него настоящих отметок
      нет, и такие контуры пропускаются с предупреждением.
    0.70.2
    - Из руководства убраны два числа, которых я не считал: «ошибка
      по пробе вчетверо меньше настоящей» и «если втрое больше».
      Оба взяты для веса, а читатель принял бы их за измеренные.
    - Вместо них замер на демонстрационной залежи: при сети скважин
      100, 200 и 400 метров отношение ошибок выходит 0.9, 1.6 и 2.6.
      Выдуманное было завышено втрое.
    - Из замера видно и то, чего я не знал: ошибка по пробе почти
      не зависит от сети, а по скважине растёт вместе с расстоянием
      между стволами. Сказано, что числа для демонстрационных данных,
      и смотреть надо на отношение.
    0.70.1
    - В руководство добавлена глава «Типовые задачи»: шесть цепочек
      работы от данных до результата, с номерами инструментов и с тем,
      где кончается Isoliner и начинается Isoliner3D.
    - У каждой цепочки сказано не только что делать, но и что
      проверить: невязка по уровням, поле holes у тел, разница ошибок
      при исключении пробы и скважины.
    0.70.0
    - Исправлено: журнал не заводился вовсе, и кнопка «Журнал»
      отвечала, что его нет. Путь подставляется снаружи, при загрузке
      плагина, а этого никто не делал: функцию, которая это делает,
      я снял в 0.66.0 как «код без единого вызова». Вызова не было
      потому, что цепочку не довели до конца, а не потому, что она
      лишняя.
    - Журнал заводится при загрузке рядом с профилем QGIS, файлом
      isoliner3d.log, и первым делом: всё дальнейшее должно в него
      попасть. Некуда писать - пустой путь, а не падение.
    - Проверка держит цепочку целиком: путь, запись, кнопка. Обрыв
      в любом звене её останавливает.
    0.69.18
    - Пункт «О плагине» вынесен и на панель, а не только в меню:
      в меню его ищут, а на панели он под рукой.
    - Из папки руководства убраны семь старых снимков, на которые
      никто не ссылается. Старая картинка вводит в заблуждение сильнее,
      чем её отсутствие: окно давно другое, а снимок показывает
      прежнее. Папка похудела с трёх мегабайт до девятисот килобайт.
    - Проверка не пропустит ни картинку без ссылки на неё, ни пункт
      «О плагине» без кнопки на панели.
    0.69.17
    - Пункт меню «О плагине»: значок, версия, ссылки на сайт
      разработчика, исходный код и сообщение об ошибке, кнопки истории
      изменений, руководства и журнала. Устроен как у Isoliner.
    - Версия и история читаются из metadata.txt. Отдельный файл истории
      не заводится: канонический список уже там, а второй завёл бы
      расхождение между ними.
    - Qt тянется внутри функций: модуль читается и там, где QGIS
      не поднят, и потому проверяется без него.
    - В руководство добавлена глава о лицензии и разработчике: GPL
      версии 2 или новее, отсутствие гарантий, ответственность
      за применение результатов, вложенные библиотеки и их лицензии.
    0.69.16
    - Руководство переработано целиком. Было двадцать семь страниц,
      писанных по мере правок и оттого вразнобой: главы про окно
      вперемешку с инструментами, восемь картинок, все устаревшие.
      Стало шестнадцать страниц и одна картинка.
    - У каждого инструмента таблица полей: что задаёт каждое.
      Пятнадцать инструментов, сто сорок два поля.
    - Таблицы собираются из самого кода разбором algorithms.py:
      подписи полей и пояснения берутся оттуда, где они объявлены.
      Руководство, писанное отдельно, расходится с кодом на первой же
      правке - поле переименовали, а в тексте старое имя.
    - Проверка сверяет руководство с кодом: подпись поля, которой
      в нём нет, останавливает сборку.
    - Английское руководство собрано тем же способом, из таблицы
      переводов: непереведённых мест не осталось.
    0.69.15
    - Окно сцены возвращается вперёд после долгой работы, если оно
      было впереди до неё. Ради курсора ожидания мы даём Qt обработать
      события, и на этом оконный управляющий может переложить окна:
      наше уходит за главное, и первое «Обновить» прятало сцену.
    - Возвращаем с разбором: если человек нарочно ушёл в другое окно,
      вырывать у него ввод грубо. Поднимаем, только когда мы были
      впереди и оказались позади.
    0.69.14
    - Окно сцены показывается до чтения слоёв, а не после. На большом
      проекте чтение занимает секунды, и всё это время окно уже
      создано, но не показано: человек жмёт кнопку и не видит ничего,
      а к моменту показа окно оказывается позади главного. Открыть
      его удавалось только свернув и развернув QGIS.
    - После поднятия окну передаётся ввод: одного поднятия части
      оконных управляющих мало.
    - При первом открытии за сеанс окну дают прорисоваться прежде
      долгой работы, иначе оно висит пустым прямоугольником.
    0.69.13
    - Сглаживание краёв задаётся самому виджету сцены, а не всему
      приложению. Общий формат отрисовки применяется к уже созданным
      окнам не сразу, и такое правится только пересозданием окна.
      Это одна из причин, по которой сцена могла открываться пустой
      до сворачивания и разворачивания QGIS.
    0.69.12
    - Выгрузка сцены в файл одной кнопкой вместо двух: формат
      выбирается расширением - GLB, STL или OBJ. Действие одно,
      форматов три, и разводить их по кнопкам значит заставлять
      человека помнить, какая для чего.
    - Кнопка стоит после выгрузки оболочек в слой проекта: сперва
      данные в проект, потом сцена в файл.
    - Вопрос о вертикальном преувеличении остался только у GLB.
      В CAD нужны настоящие отметки, и спрашивать там нечего.
    0.69.11
    - Вращение сцены кнопкой на плашке: камера сама обходит модель,
      ещё раз - останавливается. Крутится камера, а сцена
      не пересобирается: пересборка занимает секунду с лишним,
      и анимация из пересборок вышла бы слайд-шоу с рывками.
    - Съёмка оборота кадрами PNG: тридцать шесть кадров по десять
      градусов в выбранную папку. Складывать их в видео модуль
      не берётся - для этого есть готовые средства, а тащить их
      в плагин ради одной кнопки незачем.
    - Кадры нумеруются с ведущими нулями: иначе склейка поставит
      десятый между первым и вторым.
    - Вращение останавливается при закрытии окна: таймер, оставшийся
      жить, дёргал бы мёртвый виджет.
    - Снимок в README заменён на новый, с отмывкой и разрезами.
      В руководство добавлена глава про оформление сцены с этим же
      снимком.
    0.69.10
    - Исправлено: градиентный фон не работал, а давал чёрный. Я делал
      его подложкой Qt под областью показа, но область OpenGL
      закрашивает подложку, и прозрачный фон выходит чёрным.
    - Градиент рисуется внутри самого вида - там, где он и так
      заливает фон одним цветом. Элементом сцены его тоже не сделать:
      пришлось бы держать обращённым к камере.
    - Сверху холоднее, снизу светлее: так небо и земля, и модель
      на таком фоне читается лучше плоской заливки.
    0.69.9
    - Новый раздел свойств сцены «Оформление» с тремя настройками.
    - Отмывка по наклону поверхности. Это не украшение: поверхность,
      раскрашенная шкалой, рисовалась одним цветом вершин без света
      вовсе, и рельеф внутри одного оттенка пропадал целиком. Цвет
      умножается на освещённость, сама шкала не трогается - светлее
      и темнее становится один и тот же цвет. Ноль возвращает как
      было.
    - У вырожденной грани нормали нет, и такая вершина не темнится:
      иначе на месте изъяна появилось бы чёрное пятно.
    - Градиентный фон, по умолчанию выключен. Рисуется средствами Qt
      под областью показа: элемент сцены пришлось бы держать всегда
      обращённым к камере, а это возня без пользы.
    - Сглаживание краёв линий и подписей, по умолчанию включено.
      Задаётся при создании окна и действует со следующего открытия:
      режим рисования выбирается один раз и потом не меняется.
    - Все три сохраняются в проект.
    0.69.8
    - У векторного слоя появилось поле прозрачности. Код тел его читал
      с прошлой сборки, а задать было негде: настройка, всегда равная
      нулю. Упёрлось бы это в первом же случае, когда нужно
      посмотреть тело сквозь тело - два пласта один под другим,
      воронку сквозь вмещающее.
    - Сохраняется в проект и читается обратно, как прочие настройки
      слоя.
    0.69.7
    - Общая прозрачность больше не относится к телам. Настройка
      зовётся «прозрачностью поверхностей», а применялась ко всему:
      разрез просвечивал оттого, что просвечивает поверхность
      над ним. Тела брали прозрачность и режим рисования, оставшиеся
      от обхода поверхностей, а своих настроек не читали вовсе.
    - У тела своя прозрачность, в свойствах его слоя, и свой режим
      рисования по ней же. Хотите просвечивающий разрез - задайте
      прозрачность ему самому.
    0.69.6
    - Прозрачность уходит в выгрузку GLB такой же, как на экране.
      Прежде она принудительно ставилась полной: я считал, что
      полупрозрачная модель в чужом просмотрщике выглядит поломкой.
      Оказалось наоборот - сцену настраивают глазом, и разглядывать
      выгрузку человек будет так же.
    - Одной прозрачности в цвете вершин мало: пока материал объявлен
      непрозрачным, просмотрщик её не смотрит. В файле теперь два
      материала, и смешивающий заводится только при настоящей
      прозрачности - лишний материал сбивает с толку того,
      кто открывает файл.
    0.69.5
    - Исправлено: тела и текстурные поверхности уходили в выгрузку GLB
      в координатах СЦЕНЫ - уже сдвинутые к середине и растянутые
      преувеличением. Прочие части шли в настоящих, и разрезы
      оказывались не на месте и в другом масштабе. Замер: смещение
      равно расстоянию от начала координат до середины площадки,
      размах отметок отличается ровно на множитель преувеличения,
      то есть оно накладывалось дважды.
    - В выгрузку идут настоящие координаты у всех частей. Тела копят
      и те и другие: сцене нужны сдвинутые, выгрузке настоящие.
    - Проверка разбирает все вызовы выгрузки и не пропускает те, что
      отдают координаты сцены. Так же было бы поймано и то,
      что нашлось сейчас.
    0.69.4
    - Исправлено: в выгрузке GLB тела улетали прочь от координатного
      короба. Середина для преувеличения считалась по всем частям
      с гранями, а подписи короба это полоски, то есть тоже грани.
      Лежат они по краю охвата и тянули середину на себя. Замер:
      на телах в диапазоне двухсот метров середина смещалась
      на пятьдесят пять, и тела уходили на пятьсот единиц.
    - Короб и подписи помечены украшением вида и не участвуют
      ни в подсчёте середины, ни в выгрузке для CAD: там нужны тела.
      Прежде подписи отличались от тел по имени, а это ломается
      от первого же переименования.
    0.69.3
    - Исправлено: под полупрозрачной поверхностью не было видно
      ничего, сколько прозрачности ей ни задай. Полупрозрачная
      поверхность пишет в буфер глубины, и нарисованная раньше
      разреза, она отбрасывала его ещё до смешивания цветов.
    - Очередь рисования задаётся режимом прозрачности: непрозрачное
      идёт первым и заполняет глубину, прозрачное ложится поверх.
      Отключать запись глубины нельзя - грани одной поверхности
      начнут смешиваться вразнобой, и по ней пойдут светлые полосы.
    0.69.2
    - Исправлено: слой уезжал по высоте от растра, по которому
      построен. Подъём слоя по порядку в списке - он нужен, чтобы
      совпадающая геометрия не спорила за глубину - считался долей
      охвата в плане. На площадке в двенадцать километров это давало
      до пяти метров, а мощность пласта измеряется метрами.
    - Подъём меряется размахом отметок: на той же площадке двадцать
      сантиметров у верхнего слоя вместо четырёх метров восьмидесяти.
      Проверено, что подъём не превышает пятисотой доли размаха
      отметок при любом их диапазоне.
    - Шкала Z в сцене и раньше была одна на все слои: общий ноль
      считается по всем видимым слоям сразу, множитель один. Ни
      нормировки на слой, ни отдельного множителя для растров нет,
      и проверка это закрепляет.
    0.69.1
    - Цвет объекта читается из поля «color», если оно есть в слое,
      и только потом из символики. Инструменты Isoliner пишут туда
      цвет пласта по справочнику, тем же, что и на чертеже:
      пересчитывать его символикой значит расходиться с планом.
    - Годятся запись «#RRGGBB», короткая «#RGB» и название цвета.
      Восьмизначная запись сводится к цвету: прозрачность задаёт слой.
    - Объект с испорченным значением не роняет сцену и не красится
      наугад - берёт цвет по общему правилу. Сколько значений
      разобралось, а сколько нет, пишется в журнал.
    - Поле читается без геометрии и без лишних столбцов: на большом
      слое чтение геометрии и есть основная цена, а цвету она не
      нужна.
    0.69.0
    - Найдена причина незамкнутого тела, по присланному слою.
      После склейки вершин часть треугольников вырождается в линию:
      два номера совпадают. Такая грань считает своё ребро дважды,
      и счёт врёт. На теле в сорок две тысячи граней тридцать четыре
      вырожденных выдумали двадцать пять защипов и спрятали дыру
      из трёх рёбер, показав одно. Дыру из одного ребра зашить
      нельзя - это не кольцо и не путь, - поэтому четыре сборки
      подряд ничего не менялось.
    - Схлопнувшиеся грани убираются до счёта рёбер, до зашивания
      и до подсчёта объёма. Площади у них нет, объёму они не нужны.
    - Проверено на присланном теле: дыр три, зашита одна, стало ноль.
      Объём 598 179 856 кубометров.
    0.68.16
    - Исправлено: зашивание дыр обходило край с любой вершины,
      и начав с середины, уходило в одну сторону. Вторая половина
      края оставалась необойдённой, и дыра не зашивалась вовсе.
      Порядок вершин в словаре произволен, так что срабатывало
      через раз.
    - Обход начинается с концов края. Проверка идёт и на пути,
      и на кольце: обход обязан справиться с обоими.
    0.68.15
    - Мелкие дыры оболочки зашиваются веером по краю. На теле в сорок
      тысяч граней оставалась пара рваных рёбер - вырожденная ячейка
      на стыке крышки с поверхностью. Искать причину по одному такому
      случаю дороже, чем зашить остаток.
    - Большая прореха не трогается: затянув пол-оболочки плоской
      заплатой, получишь объём, который выглядит настоящим и неверен.
      Порог в шестьдесят четыре ребра по краю и есть граница между
      изъяном и настоящей прорехой.
    - Число зашитых дыр говорится в итоге выгрузки.
    0.68.14
    - Дыра и защип теперь различаются. Правило «у каждого ребра ровно
      две грани» валило в одну кучу два разных случая: настоящую дыру,
      по которой объём бессмыслен, и касание тела самого себя, где
      дыр нет и объём точен. Мелкие тела на пару сотен граней
      объявлялись незамкнутыми именно из-за защипов.
    - В слое два новых поля: holes - число рваных рёбер, pinch -
      число касаний. Объём считается, когда дыр нет, защипы ему
      не мешают.
    - Дефекты считаются по склеенным вершинам: у несклеенного меша
      совпадающие точки это разные номера, и ни дыры, ни защипа
      не видно.
    0.68.13
    - Исправлено: слой оболочек перестал создаваться. Разбор на тела
      возвращал кортеж разной длины - пару без метки и тройку
      с меткой, - а выгрузка ждала тройку. Такое ловится только
      падением на месте вызова.
    - Длина кортежа теперь одна всегда: без метки третьим идёт
      пустое значение. Проверка это закрепляет.
    0.68.12
    - Исправлено: тело оставалось незамкнутым, если куб отсечён
      поверхностью. Правка прошлой сборки гасила пропуски только
      перед крышкой, а сама оболочка строилась по сырому кубу
      и оставалась рваной по границе пропусков. Замер: восемьдесят
      четыре краевых ребра против нуля.
    - Пропуски гасятся до построения оболочки. Крышка ставится сразу
      за ней, до чистки: сглаживание и отброс мелочи работают уже
      по цельному телу.
    - Проверка следит за порядком: пропуски раньше построения,
      крышка раньше чистки.
    0.68.11
    - Выгрузка оболочек из сцены сразу разбирает их на связные тела
      и считает объём каждого. Разбирать потом отдельным инструментом
      значило делать в два действия то, что нужно в одно.
    - Инструмент 2.08 убран: его работу делает кнопка в сцене.
    - В слое тело на объект: номер, уровень, цвет, число граней,
      замкнутость, объём и диапазон отметок. У незамкнутого тела объём
      не считается, и число таких говорится прямо.
    0.68.10
    - Исправлено: оболочка оставалась незамкнутой, если куб отсечён
      поверхностью. Крышка ставится на гранях куба, а срез по рельефу
      идёт внутри него, и такой срез она не закрывала. Замер:
      сто четырнадцать краевых рёбер.
    - Пропуски куба теперь считаются «ниже отсечки»: пропуск по смыслу
      и есть «не тело». Замыкание по их границе выходит само собой,
      той же маршевой поверхностью, без особого случая. Краевых рёбер
      стало ноль.
    - Исправлено: значки «нарисовать контур» и «линия разреза»
      рисовались одним набором фигур - ломаная с точками, - и
      на восемнадцати пикселях выходила одна картинка. Линия разреза
      теперь прямая с засечками.
    - Проверка сверяет значки не только по наличию, но и попарно:
      два значка не могут рисоваться одними фигурами по одним точкам.
    0.68.9
    - Исправлено: 2.08 отклонял слой оболочек на входе, не начав
      работу. Набор смежных треугольников не бывает годным
      мультиполигоном по правилам OGC: у частей не должно быть общих
      внутренностей, а у оболочки соседние грани касаются рёбрами.
      Оболочка это меш, а не мультиполигон, и проверять её этим
      правилом нечего.
    - Проверка ищет такие входы во всех инструментах: полигональный
      вход плюс разбор колец значит чтение меша, и годность там
      проверять не надо.
    0.68.8
    - Новый инструмент 2.08 «Оболочки в тела и объём». Разбиение
      составной геометрии средствами QGIS даёт отдельные треугольники:
      связность там не считается, и тел не выходит. Здесь вершины
      склеиваются, меш разбирается на связные куски, и каждый кусок
      становится своим объектом.
    - Объём считается точной формулой по замкнутой оболочке.
      Замер на демонстрационном теле: 21.1 миллиона кубометров против
      22.2 по сумме целых ячеек - разница пять процентов, и это ровно
      те краевые ячейки, которые грубый счёт округляет вверх.
    - Обход граней согласуется перед счётом: формула складывает
      подписанные объёмы, и грань, обойдённая в другую сторону,
      вычитается вместо сложения. У маршевой поверхности с крышками
      обход вразнобой, и без согласования объём выходил втрое меньше
      настоящего.
    - У незамкнутого тела объём не считается вовсе: число вышло бы,
      а смысла в нём нет, и в отчёте оно стояло бы наравне
      с настоящими. Число таких тел идёт в журнал.
    - Плотностью можно сразу получить массу.
    0.68.7
    - Исправлено: инструмент 2.07 падал на первом же уровне. Отчёт
      по уровням возвращает словари, а я подставлял их в журнал как
      строки. Ошибка моя: подпись чужого ядра я не проверил.
    - Отчёт разбирается и печатается по делу: решётка уровня,
      наибольшая невязка и средняя квадратичная. По ним видно, когда
      дробить пора прекратить - если уровень почти не уменьшил
      невязку, дальше он ловит шум замеров.
    - Проверка сверяет все вызовы ядра из инструмента с настоящими
      подписями ядра: имя, которого в ядре нет, дальше не пройдёт.
    0.68.6
    - У инструмента 2.07 появились края значений: наименьшее
      и наибольшее. Метод приближает и за диапазон выходит,
      а содержание не бывает ниже нуля.
    - Обрезка тупая: что вышло за край, встаёт на край, и на месте
      выброса получается плато - форма там теряется. Зато поправка
      предсказуема, и в журнал идёт число прижатых узлов: по нему
      видно, годится ли модель. Замер на логнормальных содержаниях:
      при пяти уровнях прижато 1.2 процента узлов.
    - Перепутанные края работу останавливают, а не проходят молча.
    - Пропуски остаются пропусками.
    0.68.5
    - Новый инструмент 2.07 «MBA в объёме»: куб значений
      мультисеточными B-сплайнами. Грубая решётка приближает данные,
      остаток приближается решёткой вдвое мельче, и так уровень
      за уровнем. Система уравнений не решается вовсе, поэтому работа
      линейна по числу точек: триста тысяч замеров - семнадцать
      секунд.
    - Ядро перенесено из Isoliner дословно, вместе с шестнадцатью
      проверками. Размерности оно не знает и в объёме работает как
      есть.
    - Оценка на воксельную сетку написана отдельной функцией в ядре:
      точки идут как (x, y, z), а куб адресуется как (уровень, строка,
      столбец), и порядок осей тут легко перепутать. На симметричной
      сетке такая ошибка не видна, поэтому сверка идёт с прямой
      оценкой на НЕкубической сетке.
    - Память решёток считается до выделения: последний уровень растёт
      кубом, и 256 по каждой оси это уже четверть гигабайта. Больше
      двух гигабайт инструмент не берёт и говорит об этом.
    - Решётка не обязана быть кубической: по плану километры,
      по мощности метры. Умолчание 8x8x2 и есть анизотропия
      с экономией памяти разом.
    - В журнале прямо сказано, что метод приближает, а не оценивает:
      ошибки оценки и весов он не даёт, и для оценки нужен кригинг
      в объёме.
    0.68.4
    - Исправлено: оболочки по кубу не резались ни контуром, ни
      коридором, ни отметкой. Поверхности режутся маской по растру,
      тела резчиком граней, а оболочки не попадали ни туда, ни сюда
      и оставались целыми.
    - Теперь оболочка режется как тело, и срез закрывается крышкой:
      видно сечение, а не изнанку.
    0.68.3
    - Выгрузка сцены в STL и OBJ для CAD, кнопкой на плашке. Формат
      выбирается расширением при сохранении. GLB несёт цвет
      и прозрачность и годится для просмотра, а в CAD нужна замкнутая
      оболочка, из которой делают тело.
    - STL двоичный, частей в формате нет: несколько оболочек сливаются
      в одну. OBJ текстовый, части остаются группами со своими
      именами, зато файл больше. Замер на оболочке в тридцать четыре
      тысячи граней: STL 1.64 МБ, OBJ 1.30 МБ.
    - Короб, сетка и подписи в CAD не идут: там нужны тела,
      а не украшение вида.
    - Про преувеличение здесь не спрашивается: в CAD нужны настоящие
      отметки. Зато говорится, сколько тел вышло замкнутыми:
      незамкнутое CAD покажет, но телом не сделает.
    0.68.2
    - Оболочки выгружаются в слой проекта кнопкой на плашке. Берётся
      то, что настроено и видно: уровни, крышка на краю, сглаживание
      и отброс мелочи из свойств слоя. Набирать их заново человек
      не обязан, он уже подобрал их глазом.
    - Пишутся полигонами с Z, объект на уровень. Такой слой сцена
      читает обратно как тело: его можно резать контуром с крышкой
      на срезе, выгружать в GLB и считать по нему объём. Меш и тинка
      не годятся: они хранят одну отметку на узел и вертикальных
      стенок не выразят.
    - В полях уровень, цвет, число граней и признак замкнутости. Слой
      временный: чтобы он пережил проект, сохраните его в файл.
    - Отметки настоящие: вертикальное преувеличение это способ
      смотреть, а не свойство модели.
    0.68.1
    - Отбор по режиму доведён до конца: каналы высот, окраски
      и атрибута прячутся в режимах куба. Замер по коду: ни
      изоповерхность, ни воксели, ни стенка, ни туман их не читают -
      отметки берутся из шага между каналами, цвет из таблицы
      оболочек либо из интервалов окраски.
    - В прошлой сборке отбор накрыл только строки оболочек, вокселей,
      стенки и заливки, а три канала остались висеть мёртвыми.
    - Строка окраски обёрнута виджетом: прятать по режиму можно
      только виджет, у раскладки такого нет.
    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) в комплекте, открывается
      по языку интерфейса кнопкой Справка.
