@TrickyFoxy, сначала по вашему сообщению выше. Увидел, спасибо за конкретику со скриншотом. NULL в значениях тегов и двоеточия, ставшие подчёркиваниями, проверю на боевом сервисе и отвечу отдельным постом с замерами, а не на глазок. Вторая половина претензии выглядит справедливой сразу: если ключи переименовываются, слово «losslessly» на нашей странице своё обещание не держит — это надо либо чинить, либо убирать со страницы.
Дальше — то, с чем я изначально шёл в тему.
Небольшой апдейт по 3D — и заодно ответ на замечание из этой темы, что у нас
«просто экструзия полигонов». Замечание было по делу, поэтому отвечаю не
словами, а тем, что удалось померить.
Что там на самом деле кроме экструзии. Основа — да, экструзия контура по
высоте из height / building:levels. Но поверх неё читаются building:part
(S3DB): части здания собираются в отдельные тела, а min_height и
building:min_level дают ярусам их нижнюю отметку — башня со стилобатом
получается ярусами, а не одним параллелепипедом. Крыши строятся по roof:shape
для gabled, hipped, half-hipped, gambrel, skillion, pyramidal, dome, round, onion
и mansard; всё остальное честно остаётся плоским. На bbox Кремля это 2 592 крыши
из 2 595 размеченных — не строятся many (2 штуки) и saltbox (1). Это
по-прежнему не полноценное моделирование, но и не только выдавливание.
Чтобы не быть голословным — один и тот же bbox Кремля
(37.606,55.747,37.625,55.757), один и тот же ракурс, слева наш экспорт времён
того замечания, справа сегодняшний:
КАРТИНКА 1 сюда 
И то же самое крупным планом — шатры башен, купола и луковицы, стена объёмом,
деревья, а заодно фонари, скамьи и ограды, которых в исходной претензии не было
вовсе:
КАРТИНКА 2 сюда 
Сцена целиком: 5 687 объёмных тел, 167 091 грань, 890 деревьев, 4 500 объектов
подложки (дороги, тротуары, трава, вода). Цвета — из building:colour и
roof:colour, 68 разных значений на этот bbox.
Что чинили сейчас. У 3D-выгрузки была неприятная особенность: соседние
здания в OSM часто делят общую стену, и их контуры имеют общее ребро с
буквально совпадающими координатами. После склейки сцены такое ребро получает
четыре грани вместо двух, модель перестаёт быть watertight, и слайсер ругается —
для печати это брак.
Механизм разведения совпадающих границ у нас был с начала августа, но при
разборе выяснилось, что он ломался в трёх местах сразу.
Во-первых, он вызывался ровно из одного места и видел только тела
building:part — обычные контуры зданий не разводил вовсе. Теперь контуры и
части попадают в один граф соприкосновений.
Во-вторых, механизм целиком отключался, если тел в сцене становилось больше
20 000 — то есть ровно на тех заказах, где плотная застройка и общие стены
встречаются чаще всего. Потолок был выставлен «на глаз», поэтому мы его не
угадывали заново, а померили: пик памяти на 250 000 тел — 453 МБ, время
построения графа — 7,3 с. Потолок поднят до этой цифры по замеру, а не по
ощущению.
В-третьих, величина развода была задана в метрах исходника — доли миллиметра,
константой. Звучит безобидно, пока не вспомнишь, что координаты в файле лежат
во float32, и шаг сетки float32 растёт вместе с размером сцены. На заказе
2 × 2 км константа в 0,5 мм — это восемь шагов сетки, запас есть. На заказе
10 км — уже один шаг, то есть развода фактически нет: вершины садятся обратно
друг на друга при первом же округлении. Теперь база и шаг считаются от размера
кадра заказа (в шагах сетки float32), а прежние миллиметры остались полом. На
городских заказах до ~2 км не изменилось ни байта — проверено побайтово.
Чем это подтверждено. Пять городских сцен, одни и те же bbox, формат STL,
заказы через боевой сервис до и после правки. Считались рёбра с числом граней,
отличным от двух, при побитовой склейке вершин по float32 — ровно то, что видит
читатель файла:
| сцена |
было |
стало |
| Московский Кремль |
0 |
0 |
| Казань, центр |
0 |
0 |
| Суздаль |
0 |
0 |
| Прага, Мала Страна |
1 |
0 |
| Гейдельберг, старый город |
9 |
0 |
Число треугольников при этом не изменилось нигде — разъезжаются только вершины,
которые раньше совпадали.
Отдельно — самый крупный заказ, который мы прогнали: Гейдельберг целиком,
10 × 5,5 км, 20 988 зданий. Именно на нём было видно обе поломки сразу, и
именно он давал 344 дефектных ребра. После правки — 0, при том же числе
треугольников (374 596) и без роста времени заказа (34,6 с до, 32,8 с после,
тот же класс воркера). Это, насколько мы смогли проверить, потолок не сцены, а
нашего терпения: больше пока не заказывали.
Где это НЕ работает — честно. Два известных ограничения:
- Вырожденная геометрия в самих данных (самопересечения, нулевые площади)
остаётся законным остатком — её мы не «чиним» молча.
- Таблица выше — про STL: печатная модель, побитовая склейка. В OBJ-выгрузке
той же сцены Кремля остаются 27 незакрытых тел из 5 687 (0,47 %) — это
16 малых форм (ленты оград и стен на изломах) и 11 крышных надстроек по
24–30 граней. Другой класс дефекта, к общим стенам отношения не имеет;
месяц назад их было 50 из 4 424.
О чём прошу. Если кто-то гоняет наши STL/OBJ/glTF через слайсер или
MeshLab — интересны сцены, где watertight всё ещё ломается. Особенно города с
плотной исторической застройкой и с активно размеченным S3DB: именно там
вылезают случаи, которых нет в наших пяти сценах. Bbox и формат — этого хватит,
чтобы воспроизвести.