Skip to main content

blockwright-capture

Этап 1 Blockwright — захват и конвертация. Используй, когда нужно превратить ge-export из Google Earth в .obj, обрезать клип по участку, посчитать clip-box, привести стороннюю 3D-модель к метрам и Y-вверх, отрендерить ортографические виды в Blender, или когда падает ge_convert.py / render_orthos.py.

Source facts

Repository
MelonHell/VibeBuilding
Last source activity
August 17, 2026 at 16:54
Detected SKILL.md language
Russian
Stars
1
Forks
1

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
blockwright-capture
description
Этап 1 Blockwright — захват и конвертация. Используй, когда нужно превратить ge-export из Google Earth в .obj, обрезать клип по участку, посчитать clip-box, привести стороннюю 3D-модель к метрам и Y-вверх, отрендерить ортографические виды в Blender, или когда падает ge_convert.py / render_orthos.py.
# Этап 1 — захват и конвертация Этап нужен, только если вход — Google Earth или модель в чужом формате. Проект на карте, на чертежах или на одном описании начинается с этапа 2. На входе: экспорт Google Earth как пакет сценария Microsoft Flight Simulator — сотни glTF-тайлов, текстуры в подкаталоге, на который сами glTF не ссылаются, и расстановка в отдельном XML в географических координатах. На выходе: один OBJ с работающими материалами, `meta.json` в метрах, и десять ортографических рендеров. ## Конвертировать дважды ```sh # 1. весь захват — чтобы увидеть окружение и снять clip-box с орто-видов python tools/ge_convert.py buildings/<name>/input/ge-export \ -o buildings/<name>/out/mesh blender -b -P tools/render_orthos.py -- \ buildings/<name>/out/mesh/merged.obj \ -o buildings/<name>/out/mesh/orthos # 2. тот же захват, обрезанный по участку — не по контуру здания python tools/ge_convert.py buildings/<name>/input/ge-export \ -o buildings/<name>/out/mesh-clip \ --clip-east <a> <b> --clip-north <c> <d> --clip-up <ceiling> blender -b -P tools/render_orthos.py -- \ buildings/<name>/out/mesh-clip/merged.obj \ -o buildings/<name>/out/mesh-clip/orthos ``` Границы клипа снимаются с вида сверху из шага 1 и записываются в `out/mesh-clip/meta.json`. Клип нужен не для красоты: после него каждый пробник работает быстрее и ни одному из них не приходится отфильтровывать соседей. Клип следует за участком, не за зданием. Нижняя граница по Y не режется никогда: `--clip-up` принимает только потолок. Клип, который начинается выше земли, молча снимает с эталона всё низкое — клубный дом в четыре метра, террасы в три, палубу бассейна — и ниже по цепочке просто нечего мерить. Юбки рельефа снимаются не клипом, а `MESH_FLOOR` в пробнике: измерение их не видит, файл их держит, потеря видна. Если гейт сказал `the clip holds the site` красным — переклипай по напечатанной строке `--clip-east` / `--clip-north` и перемерь. Это те же оси, что у `ge_convert`, и та коробка, которой хватило бы на постройку и на эталон сразу; второй взгляд на орто не нужен. ## Чек-лист первой конвертации Три проверки **до всякого обмера**. Каждая делается за минуту, каждая стоила кому-то от получаса до половины сборки. **1. Куда смотрит захват.** Открой `top_tex.png` и найди улицу. Если уличный фасад оказался не в том орто — экспорт лежит развёрнутым, лечится `--heading 180` на конвертации. Гейт разворот проглотит (`Registration.orient` перебирает четыре укладки), а ревью — нет: оно рендерит эталон через собственную раму меша, и ракурсы разъедутся. **Компас захвата не свидетель.** `meta.json` пишет «assumed frame for a heading=0 export», и это честно. Сторона улицы, сторона моря и вход читаются с карты или с брифа, никогда с осей захвата. **2. Где земля.** `Mesh.datum()` печатает квантиль, самую плотную полосу высот и расхождение между ними; `derive` останавливается, если они разошлись больше чем на метр. Юбки полигонов под грунтом датум отравляют. Нижнюю границу клипа не режь — это молча снимет низкие постройки. Юбку из измерения убирает `MESH_FLOOR`; если под грунтом правда есть цоколь, поднимай `DATUM_AGREEMENT` и скажи почему. **3. Есть ли тайлинг.** Гистограмма высот вершин по фасаду: если пики стоят ровно через 4.5 м с огромными счётчиками — это шов экспортёра, а не этажи. Пайплайн теперь отказывается называть 4.5 м высотой этажа, но знать об этом стоит заранее. ## Клип по участку, а не по зданию Клип, обрезанный вокруг контура, правилен для регистрации башни и неправилен для участка: двор, бассейн, парковка, палуба, клубный дом выпадают из эталона и больше никем не меряются. Один клип — широкий, по участку. Деревья и юбку рельефа из измерения убирает `MESH_FLOOR`, не граница. Одно здание вывело из фразы «благоустройство мешем не проверяется» вывод «нечем и строить» и поставило прямоугольник; переделка стоила двух часов. **Расширив клип, подними `REGISTER_FLOOR` и `MESH_FLOOR` в `probes/derive.py`.** Это вторая половина того же решения, и без неё широкий клип ломает обмер. `Mesh.frame` вписывает раму по всем вершинам выше `MESH_FLOOR`, регистрация подгоняется по всем вершинам выше `REGISTER_FLOOR` — а план, с которым она их сравнивает, это только нарисованное здание. Под клипом по зданию два этажа значили «оставить за бортом дорогу, машины и изгородь». Под клипом по участку они значат ещё и **«вот эта из масс на участке — то здание, которое нарисовал план»**: виллы в четырнадцать метров, пальмы в двадцать и сосед за межой все выше двух этажей. Не поднял — получишь одно из двух: либо обе стороны раздуваются вместе и аффинное преобразование тихо неверно для всех, кто читает `derived.json`, либо `derive` останавливается на `plan overlap` или на `registration` и говорит про клип, который ни при чём. Оба отказа теперь называют этот выход третьим. Поднимают выше вспомогательных объёмов и **ниже самой низкой части нарисованного здания**. Пол ограничивает подгонку, а не чтение: `skyline` идёт по всем вершинам, поэтому четырёхметровый клубный дом под полом всё равно измерен и всё равно приезжает на план сборкой. ## Оси **X на восток, Y вверх, Z на юг** — та же хиральность, что у Minecraft, поэтому точка меша ложится прямо в раму, построенную по карте. Ничего нигде не переворачивается. ## Орто-рендеры `tools/render_orthos.py` рисует пять ортографических видов, каждый дважды: - **текстурированный** — читается материал, ритм окон, цвет; - **плоский с cavity** — читается объём, который зашумлённая фото-текстура прячет. Скрипт пишет точное число метров на пиксель для каждого вида, поэтому расстояние, померенное в рендере, переводится в метры без гадания. Ему же передают `--shot` для перспективных кадров — так этап 5 рендерит меш из тех же камер, что и постройку. ## Blender Нужен в PATH. На Windows обычно не там; `review.py` перебирает стандартные пути установки и, если не нашёл, печатает команду, чтобы человек запустил сам. Если Blender недоступен, орто-рендеры пропускаются — постройка от этого не страдает, страдают только листы сравнения, и скрипт об этом говорит. ## Векторный план Если контур есть в векторе — GeoJSON из OSM или GIS, SVG из чертёжной программы — клади `input/plan.geojson` и этап с палитрой пропускай целиком. Полигон это уже контур: ни порогов, ни сглаженной каймы, ни лестницы из клеток. У SVG нет единиц, поэтому `VECTOR_SCALE` заявляется так же, как `MODEL_SCALE` у OBJ. ## Плоская карта: сначала палитра Библиотека читает карту по оттенкам серого, и по умолчанию стоит палитра одной конкретной карты. Прежде чем удивляться «no building found», прогони ```sh python -m tools.map_probe buildings/<имя>/input/layout.png ``` — он печатает гистограмму серых и предлагает `MAP_PALETTE` для `probes/derive.py`. ## Сторонняя 3D-модель Пайплайн читает OBJ. Модель в GLB, FBX, SKP или чём угодно ещё конвертируется в OBJ Blender'ом и кладётся в `input/model.obj`. Две вещи, которые файл о себе не говорит и которые придётся заявить в `probes/derive.py`: - **`MODEL_UP`** — `"y"` или `"z"`. Половина экспортёров пишет Z-вверх. Ошибка видна сразу: здание лежит на боку. - **`MODEL_SCALE`** — множитель до метров. Если габарит выходит абсурдным, `model.read` останавливается и требует масштаб, вместо того чтобы домножить на подходящее число: один угаданный коэффициент проходит через каждый размер, и поймать его потом нечем. Никакой чистки модели не нужно — `model.read` сам отбрасывает всё ниже двух метров над землёй и заливает внутренние дыры. ## Что кладут в `input/` ``` input/ brief.md словесное описание — иногда этого одного хватает plan.geojson контур вектором (или plan.svg) layout.png кроп плоской карты, 1 пиксель = 1 метр drawings/ чертежи с масштабом sketches/ эскизы и чертежи без масштаба model.obj полноценная 3D-модель: метры, Y вверх ge-export/ пакет сценария из Google Earth photos/ все фотографии, какие есть ``` Ничего из этого не обязательно, и чем больше положено, тем больше проверено. Что каждый вход решает — в `docs/sources.md`. Фотографий нужны все, а не отобранные три. Они не сопоставляются ни с одним ракурсом и не должны — значит, нет причины предпочитать одну другой, а вместе они покрывают двор, улицу и уровень земли, где захват хуже всего.
View on GitHub