把单栋房屋做得更像 lodge


这次继续改进 Minecraft 自动建房工具,把精力放在一栋房子的屋顶、窗户、阳台、家具和庭院。拼装规则继续沿用,重点看房子实际变好了多少,以及还有哪些地方不够好。

第三轮 · 同一会话续跑 · 第一轮 · 第二轮 · 自己生成 · 看外观和内部

200 / 200最终自动测试通过
109 / 120实际试建成功,另 11 次拒绝
18 / 2424 栋新房屋里测得 18 种结构
0修改的共用内核文件

01 · 这轮做成了什么

我们让模型继续改进一套叫 Hearth 的 Python 建房工具。它的用法是:用户用简短代码安排房间和零件,工具负责放方块、检查支撑和道路,并自动记录每块玻璃属于哪扇窗、哪栋房子。第一轮搭好这套工具,第二轮加了桥、围墙和新的建筑群,第三轮回到单栋建筑本身的质量。

这次完整沿用第一轮任务,只在末尾追加新的重点。要求模型对照八张 lodge(木石风格住宅)参考图打磨建筑,同时保持可重复使用的零件和拼接规则。如果认为原架构有严重问题,就报告问题和更合理的方案并停下。模型先做了审查,判断屋顶单调、家具稀疏属于零件和布置规则不足,没有发现必须推翻架构的严重阻碍,所以继续实现。这个判断是模型的开发判断,不是对任意未来用途的架构证明。查看开工前的审查。

实际新增了分段坡屋顶、真正安装到屋顶上的老虎窗、较深的木框立面、可通行的阳台、带支撑的烟囱、家具组合和入口庭院。 三种新房屋程序仍会随随机编号改变房间、楼层和屋顶安排。

但还没达到参考图的美观程度。房间网格较规整,背面墙体偏空,老虎窗比例有重复,庭院留白较大。阁楼只是屋顶里的空腔,不算可居住房间;烟囱也没有模拟真实供暖。新增细节是进展,不能把测试全通过当成审美目标已经完成。

测试全通过,为什么还有建筑没造出来?

分清哪件事 最终结果 该怎样理解
自动测试 200 项通过,0 项失败 正常方案能建,故意弄坏的方案会被拦住。正确拒绝错误输入也能让测试通过
最终实际试建 120 次尝试,109 次建成、11 次拒绝 104 次普通场景全部建成;16 次困难地形里 5 次建成,11 次因地面高差超过限制而拒绝
开发中的真实错误 早期 64 次换地形试建,只有 31 次成功 另外 33 次涉及烟囱下方缺少真实支撑,确实是程序错误,后来修复;不是最终的 11 次正常拒绝

自动测试主要检查 library 的规则和组合行为,也会运行已有的高层程序;它不保证任意用户代码都正确。试建则是用具体场地和建造要求,看能否拿到建筑。库按规则拒绝可以是正确行为,但对用户来说,那一次仍然没完成建造目标。 不能用测试成绩掩盖覆盖范围不足。

02 · 第二轮到第三轮的变化

第二轮重点是“能不能加新种类的零件”;第三轮重点是“同一栋房子能不能更完整、更有层次”。第三轮保留第二轮的能力,没有把桥、围墙和大厅代码删掉。

看什么 第二轮 第三轮 变化的实际含义
工具版本 1.2.0 1.3.0 沿用现有代码继续改进
最终自动测试 179 项通过 200 项通过 新增 21 项,旧 179 项保留;不是发现了 21 个新错误
共用内核 第二轮改过一个文件 六个内核文件均与第二轮相同 本轮的建筑改善没有要求再改权限、归属和撤销的公共机制
第二轮扩展 桥、围墙、多边形大厅等 11 个扩展模块内容不变 旧功能仍能使用;它调用的原房屋部件有改善,组合结果可能随之变化
屋顶 原房屋多为普通尖顶,另有新大厅坡屋顶 增加可以反复按 1 格、2 格上升的坡面组合,并有完整的老虎窗 从统一斜坡发展出更有层次的轮廓;仍不支持任意屋顶交接
窗户与外墙 有墙上的窗和基础木框 立面增加深度;低屋顶旁的窗会避让或改为平窗 改的是共用相邻部件规则,不是对某个编号手修
门廊与阳台 有门廊 增加 3–5 格深的门廊和可从楼上进入的阳台 增加护栏、门和路线的实际检查
家具 原房间家具及第二轮大厅家具区 原房屋增加家具组合、桌面物件和使用位置 房间内部更完整;并未证明每种物品在游戏里都能正常交互
烟囱 原房屋没有这套新组件 增加外部烟囱和小型承托层 早期暴露真实支撑缺陷,后来修复并补测试
屋前环境 原绿化与广场等组合 增加入口庭院、抬高花床、灯、树及小路 庭院沿用已有公开接口,支撑和入口不能被装饰破坏
新的高层调用例子 中心建筑群、环形群等 阳台住宅、多翼大厅、三层高屋 它们是简短的使用例子,不是库里限定只能选的三种家族
默认生成命令 五栋房屋,125,475 个方块、782 个部件 五栋房屋,128,021 个方块、908 个部件 入口代码不变,但共用建造规则改变,所以内容确实变了。增加 2,546 个方块和 126 个部件;计数含地面与小零件
保存方式 建筑文件加部件关系文件 沿用原格式和保存程序 自动归属、查询和保存后恢复仍保留
美观程度 有限示例,未建立审美评分 增加外观与内饰细节,仍低于 lodge 参考 没有同条件评分或盲评,不能宣称美观提高某个百分比

统计第二轮第三轮
Python 文件数6378
Python 行数(含空行注释)61077430
原文件变化基线8 修改 / 0 删除
新增 Python 文件—15

源码统计包括工具、示例和测试,不包括参考程序、网页和数据。原来的测试文件和启动文件是否改动,是直接比较两个归档文件内容得出的。完整文件统计与校验值。

具体增加和修改了哪些 Python 文件

变化文件
新增examples/building_holdout.py
新增examples/building_quality.py
新增examples/building_views.py
新增examples/lodge.py
新增examples/lodge_inspection.py
新增hearth/adapters/bearing.py
新增hearth/components/furnishing.py
新增hearth/components/grounds.py
新增hearth/components/joinery.py
新增hearth/components/masonry.py
新增hearth/components/roofcraft.py
新增hearth/lodges.py
新增hearth/quality_assessment.py
新增hearth/validators.py
新增test/test_building_quality.py
修改hearth/__init__.py
修改hearth/adapters/site.py
修改hearth/components/building.py
修改hearth/components/interior.py
修改hearth/components/landscape.py
修改hearth/components/primitives.py
修改hearth/components/roofs.py
修改hearth/programs.py

两轮的试建对象不同:第二轮测新桥、围墙、大厅和建筑群,第三轮测新房屋和接地。第二轮困难地形 15/24 建成,第三轮 5/16 建成,不能直接把这个差异当成生成能力退步或进步。第三轮的默认输出也改变了,不能继续套用前两轮“默认结果完全相同”的结论。

03 · 自己动手生成建筑

不需要会写代码:先点“运行并生成”,再用鼠标拖动建筑、滚轮缩放。点“换随机编号生成”看同类建筑的新样子;点“换一种场景生成”轮流尝试不同例子,房屋布局等设置也会跟着变化。生成后可以点“打开屋顶看里面”,或点一块玻璃查看它属于哪扇窗、哪栋房子。

这是真正在你的浏览器中运行 Python 建筑程序,每次点击不会再去询问模型。第一次需要下载运行工具,可能要稍等;多栋房屋通常比单栋慢,可以随时停止。程序会检查建筑,并把保存的文件重新打开,核对内容是否一致。

下载本轮默认五栋房屋

默认展示本轮的阳台住宅。要手动改变房间、屋顶等设置,请选择“自己调整房间、屋顶和阳台”,再点“使用这个例子”;其他例子只读取菜单下方写明的设置。控件值不会自动改写任意 Python 代码。

这些控件对应哪些 Python 变量(写代码时查看)

相同版本、代码、参数和随机编号会重复生成同一结果。换编号也可能撞上同一种设计;如果把所有选择都写死,换编号不一定改变建筑。“换随机编号”保留当前代码;“换一种场景”会载入公开的轮换程序,连续 14 次尝试三种新房屋、水边适配、村落、中庭、原来的住宅/工坊/公共用房,以及第二轮的建筑群、大厅、桥和围墙。每次也随机结构参数,不只是换颜色。这覆盖列出的现有例子,不代表穷尽整套库的可能组合。遇到拒绝会显示原因,不会偷偷重抽。

轮换程序的完整 Python 代码
# Report examples using public library interfaces. programs = ('home', 'hall', 'high', 'adaptation', 'settlement', 'courtyard', 'commons', 'atelier', 'dwelling', 'campus', 'perimeter', 'sample_hall', 'sample_connector', 'sample_boundary') program = programs[SEED % len(programs)] if program == 'home': from hearth.lodges import hillside_home, lodge_scene scene = lodge_scene(hillside_home(SEED), seed=SEED, environment_seed=int(ENV_SEED)) elif program == 'hall': from hearth.lodges import gabled_hall, lodge_scene scene = lodge_scene(gabled_hall(SEED), seed=SEED, environment_seed=int(ENV_SEED)) elif program == 'high': from hearth.lodges import high_house, lodge_scene scene = lodge_scene(high_house(SEED), seed=SEED, environment_seed=int(ENV_SEED)) elif program == 'adaptation': from hearth import Scene from hearth.environment import Terrain from hearth.assessment import adaptation_expression from hearth.components.building import adapted from hearth.lodges import hillside_home from hearth.quality_assessment import DOMAIN field, water = adaptation_expression(int(ENV_SEED)) environment = Scene(int(ENV_SEED), domain=DOMAIN) environment.place('land', Terrain(DOMAIN, field, water)) environment.finalize() scene = environment.fork(seed=SEED) scene.compose_choice(adapted('building', hillside_home(SEED), '/land')) scene.finalize() elif program == 'settlement': from hearth.programs import settlement_scene # Same public entry point used by the delivered generate.py. # This program consumes SEED and COUNT. Other controls are unused. scene = settlement_scene(seed=SEED, count=COUNT) elif program == 'courtyard': from examples.courtyard import build scene = build(SEED) elif program == 'commons': from hearth.programs import building_scene, commons scene = building_scene(commons(SEED), seed=SEED) elif program == 'atelier': from hearth.programs import building_scene, atelier scene = building_scene(atelier(SEED), seed=SEED) elif program == 'dwelling': from hearth.programs import building_scene, dwelling scene = building_scene(dwelling(SEED), seed=SEED) elif program == 'campus': from hearth_extensions.programs import extension_scene, branching_campus scene = extension_scene(branching_campus, seed=SEED, environment_seed=int(ENV_SEED)) elif program == 'perimeter': from hearth_extensions.programs import extension_scene, perimeter_cluster scene = extension_scene(perimeter_cluster, seed=SEED, environment_seed=int(ENV_SEED)) elif program == 'sample_hall': from hearth_extensions.assessment import hall_scene scene = hall_scene(SEED, int(ENV_SEED)) elif program == 'sample_connector': from hearth_extensions.assessment import freeze_probe, connector_scene scene = connector_scene(freeze_probe(int(ENV_SEED)), SEED) elif program == 'sample_boundary': from hearth import Scene from hearth.environment import Terrain from hearth_extensions.assessment import PROBE_DOMAIN, probe_expression, boundary_scene field, _ = probe_expression(int(ENV_SEED)) environment = Scene(int(ENV_SEED), domain=PROBE_DOMAIN) environment.place('land', Terrain(PROBE_DOMAIN, field)) environment.finalize() scene = boundary_scene(environment, SEED) print('Explored program:', program)

准备就绪。点击运行,开始真正的 Python 生成。

本轮阳台住宅预览

这是之前生成的示意图。运行后会换成你这一次生成的建筑。

切开查看会暂时隐藏切线外侧的方块,下载的仍是完整建筑。单击方块查看归属,按住鼠标拖动则旋转。选中整扇窗或整栋房子时,也会包含它里面的小部件和共用支撑。

这块方块属于哪里?

下面会按“小部件 → 大部件”的顺序显示归属。点其中一个名称,再勾选“只看选中的部件”,可以单独查看它。X、Y、Z 是方块位置,其中 Y 表示高度。

方块归属的详细数据(开发者用)
尚未生成
建造结果的详细数据(开发者用)
尚未生成
运行日志和错误详情
尚未运行

下载包里有 Minecraft 建筑文件、记录“方块属于哪个部件”的文件,以及重新生成它所需的 Python 代码和设置。请一起保留:只有建筑文件,无法查询这份部件关系记录。

05 · 架构保住了什么

本轮没有发现触发停工条件的严重架构问题。重要证据不是一句“设计很好”,而是新增零件实际沿用了旧接口:外层程序可以发现屋顶提供的安装位置,装上老虎窗;也能把新屋顶换成另一份实现,而不用改房间布置程序。相关测试同时检查没有越权改屋顶、失败后没有留下半次修改。

哪一层 负责什么 本轮发生了什么
共用内核 权限、撤销、部件归属、依赖关系、检查时机 六个文件内容不变;新部件继续使用这些机制
地形与几何等基础工具 坐标、地形查询、方块状态、随机选择和保存 基础服务保持;接地适配代码增加承托层,入口测量也作了调整
部件和建造规则 屋顶、窗、房间、门廊、烟囱、家具怎样造 主要改动在这里;增加安装接口、支撑要求和实际方块检查
高层组合程序 表达房间、楼层、侧翼和连接的意图 新增三个简短房屋例子,调用相同的零件;不自己逐块补洞或写归属标签

“层级”有两种意思:上表是代码职责;“玻璃 → 窗 → 老虎窗 → 屋顶 → 房子”是大小部件的包含或安装关系。大的组合也能成为可重用部件。生成时归属由底层机制自动记录,不需要用户给每块玻璃手写这条链。

看一段能手动控制房间与屋顶的调用代码

from hearth.components.building import Blueprint, RoomSpec from hearth.components.roofcraft import RoofDesign from hearth.lodges import lodge_scene rooms = [RoomSpec(0, 0, level, purpose) for level, purpose in enumerate(('living', 'library', 'bedroom')[:FLOORS])] if WING: rooms.append(RoomSpec(1, 0, 0, 'kitchen')) plan = Blueprint(tuple(rooms), bay=BAY, porch=True, roof_design=RoofDesign(tuple(int(v) for v in RISE.split(',')), DORMER_SPACING), porch_depth=PORCH_DEPTH, balcony=BALCONY, chimney=CHIMNEY) scene = lodge_scene(plan, seed=SEED, environment_seed=int(ENV_SEED), garden=GARDEN)

新的屋顶策略是 Python 对象,需要提供屋顶高度和部件构造方法;并不是保存一个文件就能自动保存任意可执行插件。保存文件能恢复已生成的结构记录,若要按新的策略重建,仍要提供对应实现。本轮接口说明。

06 · 200 项测试具体测什么

最终自动测试 200 项全通过,0 项失败。 原来的 179 项保留,增加一个文件中的 11 个测试函数;换尺寸、方向、用途等参数展开后,新增加 21 项。它们主要检查库,也包含六次高层房屋调用。不是“新增 21 项,就发现了 21 个错误”。

新测试做什么 展开后项数 怎样算通过 主要涉及哪层
换房间尺寸、屋顶上升方式和门廊深度 3 9、11、13 格的配置都能建成,有老虎窗和阳台,房间意图保持 部件与组合规则
整栋房屋转四个方向 4 护栏连接方向正确;相同玻璃仍属于不同窗;老虎窗归属、物品和方块集合保存后相同 部件、旋转、内核归属与保存
故意破坏屋顶、玻璃、栏杆、烟囱或灯 1 检查器发现屋面缺口、围护缺失、护栏缺失、支撑不足或照明不足 部件验证规则;一项内包含多种破坏
破坏阳台门、堵住家具使用位置 1 能发现门和通路问题,拒绝挡路的新增部件 部件规则与内核撤销
老虎窗放错朝向、越界开洞,再正常安装 1 错误安装被拒绝且没有残留;另一个程序按公开位置安装成功,查询能追到屋顶 部件接口与内核权限
重新生成没有老虎窗的房屋 1 旧窗部件、归属和关联记录被清理干净 内核重建与新部件组合
换成另一种屋顶实现 1 父程序与房间布置不改,也能换回另一份屋顶实现 公共接口与高层调用
三种新房屋各跑两个随机编号 6 完整建造通过检查,至少有一个老虎窗、三棵树 高层生成程序与整套库
重复生成,再加无关的远处方块 1 重复内容相同,无关新增不改变房屋结构和已有方块集合 随机机制与结构记录
烟囱放在支柱地基上 1 小型承托层真实存在、跨度符合限制;拆掉支撑能被发现 接地适配与支撑规则
没有支撑时强行放承托层 1 拒绝建造,场景及记录保持原样 接地适配与内核撤销

这里的坏情况是测试主动制造的。比如先造好烟囱,再删掉一个承重方块,要求检查器报错;正确报错才是测试通过,不能把它当成最终交付的烟囱原本就坏了。全部新增测试源码。

原有测试具体内容见第一轮和第二轮。这些测试没有运行完整 Minecraft 游戏物理,也没有给建筑美观打分。

报告另外做了什么检查

本报告实际执行了 31 次成功的浏览器生成,51 项交互检查;页面异常 0 个。31 组结果与原 Python 环境逐一核对;实际下载包也重新读取,比较方块及完整部件记录。核对结果:全部通过。

浏览器记录 · 原环境与下载包核对

发布后另在公网执行三次生成,检查原建筑重现、玻璃归属、室内与楼梯切面、旧大厅和下载,均通过。公网检查记录。

具体操作包括:四个原建筑重现、室内和楼梯切面、点玻璃查归属、改变房间与屋顶设置、重复生成、执行手改代码、14 个例子轮换、很长的随机编号、错误提示、停止后重启,以及手机宽度显示。下载包再交给原 Python 环境打开,比较方块和完整部件记录。

网页检查脚本自身的修正

最初的检查脚本有三个错误预期:把建筑部件的类型名写错、认为换随机编号一定会改变已固定全部选项的设计、认为中庭示例一定包含多栋独立建筑。核对原程序后更正预期并复测,保留最初检查记录。同时修正网页把第二轮独立大厅显示成“零个房间”的计数。这些属于报告与检查脚本,未修改模型生成的库代码。

实验统一验收共五项,检查默认命令、重复生成、其他编号及程序附带测试:

统一验收结果秒
default通过13.084
seed-0-a通过13.13
seed-0-b通过13.139
seed-1通过7.974
tests通过158.388

报告独立重跑全部 200 项测试的日志

........................................................................ [ 36%] ........................................................................ [ 72%] ........................................................ [100%] 200 passed in 159.38s (0:02:39)

独立重跑使用原实验镜像和源代码副本,没有网络或凭证。第一次复制继承了归档的只读目录权限,测试不能写临时文件,因此停止该次检查;只给副本恢复写权限后重新执行。原始归档和测试代码都没有因此改动。模型本轮没有测试 Pyodide,网页验证是制作这份报告时另做的,不能挪用前两轮的浏览器成绩。

07 · 试建成功与拒绝要分开看

这是建造结果,不是自动测试成绩。 普通场景 104 次全部建成,困难场景 16 次中有 5 次建成、11 次被拒绝,总计 109/120 建成。

试建哪一组 建成 / 尝试 拒绝 说明
三种新房屋各 8 个编号 24 / 24 0 住宅、大厅、高屋各一组
16 个场地放 4 种房屋要求 64 / 64 0 这是修复烟囱之后重跑的原试建组,不是全新的独立证明
修复后另外准备的新场地组合 16 / 16 0 8 个新地形编号和新的地形组合,各放 2 种房屋要求
困难地形 5 / 16 11 最终这 11 次均因地面高差超过现有 5 格限制而拒绝
每组实际试建成功与拒绝的次数,不是自动测试的通过率。
三种新房屋各试建 8 次,分别测得 4、7、7 种不同结构。

换编号,结构真的会变化吗?

24 栋新房屋中测得 18 种结构:阳台住宅 4 种、多翼大厅 7 种、高屋 7 种。比较考虑房间、入口、楼梯、屋顶形状、老虎窗、门廊和烟囱等结构信息,排除仅换材料与庭院的变化。这是有限样本的观察,不是所有可能房屋的总数,也没有估算那个可能很大的组合数量。

原 64 次地形配对测得 45 种接地变化;新增 16 次测得 12 种。地基和支柱的变化单独统计,不能说“支柱高了两格,就多了一种房屋”。与第二轮不同类型的结构统计不能直接换算多样性提升百分比。

程序会比较阶梯地基和支柱等备选做法。“一次试建”不等于“只考虑一个地基方案”:普通场景共检查 208 个备选方案,其中 148 个可用;困难场景 32 个方案中 6 个可用,最后得到 5 次成功建造。每个输入只执行一次,没有失败后偷偷换编号直到成功。

逐条查看 120 次试建,含拒绝原因
试建编号建造结果建筑编号地形编号方块数部件数原始记录
home-0建造成功0013280160
查看数据
{ "label": "home-0", "inputs": { "client": "home", "structure_seed": 0, "environment_seed": 0 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "604cc83bc3745ff09f508e6e26e874f6b7c88a29ffdfc75947d0aeb71d0c7e5b", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 95, "excavation": 0, "sitework_occupied_cells": 140, "replaced_cells": 33, "new_sitework_cells": 107, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "a1068cb5e91bf85f05b3e5a840c10beb409f4669235a254473c49c4f7cd6f916", "bearing_fill": 1 }, "blocks": 13280, "nodes": 160, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.85 ], [ 1, 1.17 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-quality/final/home-0.litematic", "audit": { "queries": 142, "inventories": 16, "nodes": 160, "digest": "604cc83bc3745ff09f508e6e26e874f6b7c88a29ffdfc75947d0aeb71d0c7e5b" }, "seconds": 2.308 }
home-1建造成功1114321160
查看数据
{ "label": "home-1", "inputs": { "client": "home", "structure_seed": 1, "environment_seed": 1 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "dbd3cc548e846aeafb8ff64835469fd747e6724e977562e1b6b4b885dfcd779d", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 83, "excavation": 0, "sitework_occupied_cells": 119, "replaced_cells": 30, "new_sitework_cells": 89, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "1cc7153d51c75b87ff27cf9ab1a0fee847fd057606bbf4c4d81a8dd018e6fb68", "bearing_fill": 3 }, "blocks": 14321, "nodes": 160, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.01 ], [ 0, 1.1 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-quality/final/home-1.litematic", "audit": { "queries": 138, "inventories": 16, "nodes": 160, "digest": "dbd3cc548e846aeafb8ff64835469fd747e6724e977562e1b6b4b885dfcd779d" }, "seconds": 2.1273 }
home-2建造成功2214080152
查看数据
{ "label": "home-2", "inputs": { "client": "home", "structure_seed": 2, "environment_seed": 2 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "dd059c67d3344042cad1eab188856c9436f93280ca71cc60b3d32cbedb787c1e", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 108, "excavation": 0, "sitework_occupied_cells": 147, "replaced_cells": 30, "new_sitework_cells": 117, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "d995de1fe84840233e3ef9f80a05697c7dd7ca84bc7333cb8fafb53b16580792", "bearing_fill": 3 }, "blocks": 14080, "nodes": 152, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.2 ], [ 0, 1.32 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.4199 }
home-3建造成功3312373151
查看数据
{ "label": "home-3", "inputs": { "client": "home", "structure_seed": 3, "environment_seed": 3 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "7f3c45370e5439c9ae5dc1e535a72d4d30622eb744fd706b40471c917a997376", "principal_signature": "34d555401eb4f61ec6990aee8c4495c9ebf9c04e1ba085d91f6e97fa65c12a2b", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 11 ], { "height": 25, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 10, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 21, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 1, 2 ] }, "d3a44d1d232b88e76b544eb3ab00d0fb1880e58e250bc3a4380233a2084a6069" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 1, 2 ] }, "a08b3d0ef50cdaf52fa1d32f7a5f36b4f129562e49760444451697c3d8c9ea8f" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 67, "excavation": 0, "sitework_occupied_cells": 114, "replaced_cells": 30, "new_sitework_cells": 84, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "514b816a5239b2d8f925eebd0ef8689336d8d9bcf4954795c81361ec5dba62db", "bearing_fill": 2 }, "blocks": 12373, "nodes": 151, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 0.64 ], [ 0, 0.78 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.943 }
home-4建造成功4414767199
查看数据
{ "label": "home-4", "inputs": { "client": "home", "structure_seed": 4, "environment_seed": 4 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "2e7ccb89e25fd3996ff9aa26e2348f1fc827254d6569b5c09a64f0a3f2d8efd8", "principal_signature": "9c9b5f212c2698efdaa81ff3ffdc77259894b0242372d7f0c1966dba92cbf61d", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 10, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 10, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 21, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "b4e204665a92f8c1e792f6c207f72e5630cc92784c22f952b738704a5a16c573" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "0357138907cf6c28e5690169bc5833d9202516d7e3335b43532573efc9f0e4a4" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "25940a51f0fbbb06b6ddcbe465216617c88f7b1e053ee37dc60d6e69c11a6b71" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.library", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 36, "excavation": 0, "sitework_occupied_cells": 70, "replaced_cells": 33, "new_sitework_cells": 37, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "fe12a458d77c8d61dca5f965a877a523edfe90125b0c53d95cf4ffe0463c320f", "bearing_fill": 2 }, "blocks": 14767, "nodes": 199, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.49 ], [ 1, 0.82 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.3121 }
home-5建造成功5514519166
查看数据
{ "label": "home-5", "inputs": { "client": "home", "structure_seed": 5, "environment_seed": 5 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "c35f030d230adb06934b6cfb5165c4662920e9dbe10cfb64cd7eda3a5a94aca3", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 94, "excavation": 0, "sitework_occupied_cells": 130, "replaced_cells": 30, "new_sitework_cells": 100, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "15a6f65b83bba55f18eb056a56bd476a56e155106cc8b2fa99f9f7536bc565fa", "bearing_fill": 1 }, "blocks": 14519, "nodes": 166, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.03 ], [ 0, 1.12 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.3386 }
home-6建造成功6612004157
查看数据
{ "label": "home-6", "inputs": { "client": "home", "structure_seed": 6, "environment_seed": 6 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "e8999ace0de861867f79562df26d016dfda83cbf36837875fd21831d882208dd", "principal_signature": "34d555401eb4f61ec6990aee8c4495c9ebf9c04e1ba085d91f6e97fa65c12a2b", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 11 ], { "height": 25, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 10, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 21, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 1, 2 ] }, "d3a44d1d232b88e76b544eb3ab00d0fb1880e58e250bc3a4380233a2084a6069" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 1, 2 ] }, "a08b3d0ef50cdaf52fa1d32f7a5f36b4f129562e49760444451697c3d8c9ea8f" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 0, "excavation": 0, "sitework_occupied_cells": 33, "replaced_cells": 33, "new_sitework_cells": 0, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "47df3ba9586b88f3f40e1e919c69663a74a70e5ff24c7627a31def353bee09dd", "bearing_fill": 0 }, "blocks": 12004, "nodes": 157, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.12 ], [ 1, 0.52 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-quality/final/home-6.litematic", "audit": { "queries": 133, "inventories": 16, "nodes": 157, "digest": "e8999ace0de861867f79562df26d016dfda83cbf36837875fd21831d882208dd" }, "seconds": 1.8147 }
home-7建造成功7714019165
查看数据
{ "label": "home-7", "inputs": { "client": "home", "structure_seed": 7, "environment_seed": 7 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "2d2bb23ab4f6cea7857bb30c017a2bd6f60aca956b6443399a321a7fa7fcefcf", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 27, "excavation": 0, "sitework_occupied_cells": 66, "replaced_cells": 33, "new_sitework_cells": 33, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "28e5adba18aefa1ed9386488d3ad955254e51cb665b8fccd0d9a3b3ccfce15ba", "bearing_fill": 0 }, "blocks": 14019, "nodes": 165, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.27 ], [ 1, 0.65 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.2651 }
hall-0建造成功0014265175
查看数据
{ "label": "hall-0", "inputs": { "client": "hall", "structure_seed": 0, "environment_seed": 0 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "5075fc55b7db0a2c94b585af6fac5d77b467155facdcefe05c27261c00dc5f8e", "principal_signature": "40e70beaa844818287be4d6eb24f2dee02589d083d68d5e57efc09985272a695", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 12, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "bf0b97006007ce2e329266d91958534b18865fca65c86162623b5fcdae38ff98" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "e2f15a21b505572af03e809a947c087653d736b9a18906458ba58d9848ea8aed" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 101, "excavation": 0, "sitework_occupied_cells": 140, "replaced_cells": 30, "new_sitework_cells": 110, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "599db4c6ac49dc568994157f713b6b25e631575add19a7a7deb5c5a4ddfcd51e", "bearing_fill": 1 }, "blocks": 14265, "nodes": 175, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.96 ], [ 1, 1.22 ] ], "chosen": 0 } ], "optional_omissions": [], "artifact": "samples/building-quality/final/hall-0.litematic", "audit": { "queries": 157, "inventories": 24, "nodes": 175, "digest": "5075fc55b7db0a2c94b585af6fac5d77b467155facdcefe05c27261c00dc5f8e" }, "seconds": 2.3607 }
hall-1建造成功1112318161
查看数据
{ "label": "hall-1", "inputs": { "client": "hall", "structure_seed": 1, "environment_seed": 1 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "24aa018711d39860e99b1a1d1fc63750ae928b663d3c609031c55d06896e9edd", "principal_signature": "3043c6a91862b8606653ab884adc563ab7d85cc87d227d070b6d8d8d8549aba1", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 18 ], { "height": 18, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 9 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 8 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 9 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 9, "rise": [ 1, 2 ] }, "37a4e0c86e281da3c55746526fe3663c6bca612a5cf0f5c4ba75715d248d0879" ], [ "roof.profile", [ 0, 7, 9 ], { "axis": "x", "span": 9, "rise": [ 1, 2 ] }, "80148bd0c32ba9257c1a3a8a11a9f43cbee231bd0418c0c0abec8f37be9e0551" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 0, 9 ], "room.living", [ "north", "east" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 0, 9 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 19, "excavation": 0, "sitework_occupied_cells": 49, "replaced_cells": 30, "new_sitework_cells": 19, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "e6582d5804795152c3f514ebd35f2b953dd923854850f928d6d724868063bddf", "bearing_fill": 1 }, "blocks": 12318, "nodes": 161, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.3 ], [ 1, 0.68 ] ], "chosen": 0 } ], "optional_omissions": [], "artifact": "samples/building-quality/final/hall-1.litematic", "audit": { "queries": 140, "inventories": 24, "nodes": 161, "digest": "24aa018711d39860e99b1a1d1fc63750ae928b663d3c609031c55d06896e9edd" }, "seconds": 1.7873 }
hall-2建造成功2215607190
查看数据
{ "label": "hall-2", "inputs": { "client": "hall", "structure_seed": 2, "environment_seed": 2 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "7ea358c48593520bc02fa0d33a5fb15aaf2496888d436c2b6a09954b71905c09", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 121, "excavation": 0, "sitework_occupied_cells": 155, "replaced_cells": 27, "new_sitework_cells": 128, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "87f7261f488834ac78be15dc3eca393b2530f185746c065d5ac5830f946ce66b", "bearing_fill": 3 }, "blocks": 15607, "nodes": 190, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.34 ], [ 0, 1.57 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.3447 }
hall-3建造成功3315651182
查看数据
{ "label": "hall-3", "inputs": { "client": "hall", "structure_seed": 3, "environment_seed": 3 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "052422470cf7e0e4ae54a8eaef2d73c1a09d53038815570951bd4d0940d9bfa2", "principal_signature": "e0a20c134e35b71b45b5867a5f27be112a8cd2cfe3b5a06ee60a45580bfc0dc0", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 8, 16 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 10, 8, 12 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 10, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 11, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 21, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "0b113567c94cfc20e22478f688874069630ba7e7734afd2f93040cb45c536d9a" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "ca99eef6fe30986647b59c8c2f659e946d63d31740520270bcfaa349f738fe78" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 113, "excavation": 0, "sitework_occupied_cells": 157, "replaced_cells": 27, "new_sitework_cells": 130, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "0540b6e1bf18564ee462558e3ec6b0b3fbf9dee014aa06756eff89abdea1a2e4", "bearing_fill": 3 }, "blocks": 15651, "nodes": 182, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.1 ], [ 0, 1.3 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.2153 }
hall-4建造成功4412348178
查看数据
{ "label": "hall-4", "inputs": { "client": "hall", "structure_seed": 4, "environment_seed": 4 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "c467a671f408c71b5ef572d6b117eb2cb46434e173d384011a7fd34f190272fb", "principal_signature": "c57e64622465ff760290e227e139a1abba9c1c4ef7cff3cecbe963402831c761", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 18 ], { "height": 18, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 9 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 8, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 8, 8, 9 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 1, 2 ] }, "06be5652bfbc33e700226a991ed67c916b46f5b38b4dbb66c48ab18826e3372b" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 1, 2 ] }, "3dd34cd16478804f8f109a63d1dd5faa437b658aef2c8b976a3be6f619867b61" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south", "east" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 0, 9 ], "room.living", [ "north", "east" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 0, 0 ], "room.workshop", [ "south", "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 0, 9 ], "room.kitchen", [ "north", "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 20, "excavation": 0, "sitework_occupied_cells": 50, "replaced_cells": 29, "new_sitework_cells": 21, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "98287dd56614591fd5265eecce59d047b1fdec74e67527933bbd5f05276cfc0c", "bearing_fill": 0 }, "blocks": 12348, "nodes": 178, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.35 ], [ 1, 0.64 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.0895 }
hall-5建造成功5512989191
查看数据
{ "label": "hall-5", "inputs": { "client": "hall", "structure_seed": 5, "environment_seed": 5 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "1516b2d28eb2511b3fadef195c00571d25cd7a7f831713974778c34c4b99412c", "principal_signature": "c57e64622465ff760290e227e139a1abba9c1c4ef7cff3cecbe963402831c761", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 18 ], { "height": 18, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 9 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 8, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 8, 8, 9 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 1, 2 ] }, "06be5652bfbc33e700226a991ed67c916b46f5b38b4dbb66c48ab18826e3372b" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 1, 2 ] }, "3dd34cd16478804f8f109a63d1dd5faa437b658aef2c8b976a3be6f619867b61" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south", "east" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 0, 9 ], "room.living", [ "north", "east" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 0, 0 ], "room.workshop", [ "south", "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 0, 9 ], "room.kitchen", [ "north", "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 21, "excavation": 0, "sitework_occupied_cells": 51, "replaced_cells": 30, "new_sitework_cells": 21, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "b04cf71b4e449c7d4859f74b64577d3e2e74a7123b57241d97b8a08acf061a91", "bearing_fill": 2 }, "blocks": 12989, "nodes": 191, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.35 ], [ 1, 0.73 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.166 }
hall-6建造成功6613258204
查看数据
{ "label": "hall-6", "inputs": { "client": "hall", "structure_seed": 6, "environment_seed": 6 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "b4a9ba6fcc40c1c5d0d6adaa6fdc886388b63c079983529f5b9c06cfaa1eb21e", "principal_signature": "074423470495098347cb86a2465b04a529f216b7ee6a1126bf435e3530162538", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 18 ], { "height": 24, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 12 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 8, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 8, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 9 ], { "axis": "z", "span": 9, "rise": [ 1, 2 ] }, "d7c9c4990a066577c7c1134b0400526796a04231047d6ce20fd48bfe90e438be" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 1, 2 ] }, "dd9b771cbbbfd3daf479b2625c8519b0816d9a6449696d4ce20a92d7b870f7e9" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 1, 2 ] }, "57d3831543dae4f19d621c4b48af63cab649ef46bfd8d7c13ca642e1117bacac" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south", "east" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 0, 9 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 6, 9 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.workshop", [ "south", "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 0, 9 ], "room.kitchen", [ "north", "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 22, "excavation": 0, "sitework_occupied_cells": 52, "replaced_cells": 30, "new_sitework_cells": 22, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "98ff63f7ed246d3350d0b4da6132e8a8a64421e6552e38fb56d6b8cae4ee09c9", "bearing_fill": 1 }, "blocks": 13258, "nodes": 204, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.33 ], [ 1, 0.69 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-1/cover", "dormers": [ [ "left", 14, "existing upper volume" ] ] } ], "artifact": "samples/building-quality/final/hall-6.litematic", "audit": { "queries": 179, "inventories": 32, "nodes": 204, "digest": "b4a9ba6fcc40c1c5d0d6adaa6fdc886388b63c079983529f5b9c06cfaa1eb21e" }, "seconds": 1.963 }
hall-7建造成功7715895203
查看数据
{ "label": "hall-7", "inputs": { "client": "hall", "structure_seed": 7, "environment_seed": 7 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "69420a0eed82e8867cbefc205b5993696822adab0713fad992d3c3b92717bed2", "principal_signature": "60e929f4b5b066c96ca35111abd162a9541648eb82a123bb9d69de58154e672e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "8e9c7c26e445b0f1b4db089dc5d7ada41eb6147a9bd849a6946458e6eebe4f99" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "d4f853a881c8d0ef6771db722649eb1b6ba443473d52cab8060a84954e076b72" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "north", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 16, "excavation": 0, "sitework_occupied_cells": 46, "replaced_cells": 30, "new_sitework_cells": 16, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "0ba3342e93c171059f2622893a2af5c5d501fc3f71134db2f227ed400d1ebeee", "bearing_fill": 0 }, "blocks": 15895, "nodes": 203, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.28 ], [ 1, 0.66 ] ], "chosen": 0 } ], "optional_omissions": [], "seconds": 1.5993 }
high-0建造成功0010091162
查看数据
{ "label": "high-0", "inputs": { "client": "high", "structure_seed": 0, "environment_seed": 0 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "202dcbd2743d5bfde5e4affefaad2bc738ff12b3ba935e6e25a0bedfb94046d0", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 52, "excavation": 0, "sitework_occupied_cells": 90, "replaced_cells": 33, "new_sitework_cells": 57, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "a8051fc01efd986390bc69db773f9f186134db17cf6b17885a6ae9d0eadf8091", "bearing_fill": 1 }, "blocks": 10091, "nodes": 162, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.51 ], [ 1, 0.79 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-quality/final/high-0.litematic", "audit": { "queries": 143, "inventories": 18, "nodes": 162, "digest": "202dcbd2743d5bfde5e4affefaad2bc738ff12b3ba935e6e25a0bedfb94046d0" }, "seconds": 1.6549 }
high-1建造成功1113208201
查看数据
{ "label": "high-1", "inputs": { "client": "high", "structure_seed": 1, "environment_seed": 1 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "cb32b1db84e7f6674e2309f3dd1b866e759bc233af2524b27807b3fe4dfec0b4", "principal_signature": "8b31d9fc1f3cc8d6cab158826fa3944a0437a3efda503207d5200023c410e6f7", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 11 ], { "height": 32, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 10, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 21, 14, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 11, "rise": [ 2, 1 ] }, "dabd215d7edac1cd125e7d085d50279a9cad1db2ac5e82cbccd509abec387d4a" ], [ "roof.profile", [ 11, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 2, 1 ] }, "8430ff95b5f3f28f966e2a97809a81a016bdba29022daf004b99357bfb87aa16" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 0, 6, 0 ], "room.library", [ "east" ], true, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 6, 0 ], "room.workshop", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 67, "excavation": 0, "sitework_occupied_cells": 103, "replaced_cells": 30, "new_sitework_cells": 73, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "ca44a5148645dc4898b6b77fe6de4f5f16e3d7a973a2ea4c07b989caf0b9cd36", "bearing_fill": 2 }, "blocks": 13208, "nodes": 201, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 0.85 ], [ 0, 1.04 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-quality/final/high-1.litematic", "audit": { "queries": 177, "inventories": 26, "nodes": 201, "digest": "cb32b1db84e7f6674e2309f3dd1b866e759bc233af2524b27807b3fe4dfec0b4" }, "seconds": 2.3067 }
high-2建造成功2212583176
查看数据
{ "label": "high-2", "inputs": { "client": "high", "structure_seed": 2, "environment_seed": 2 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "103c10e2db509c5b48449c260eec7e3538f4778d82819480e65854da11ca25c0", "principal_signature": "6fd5f107d36d268cb434e3fc96f117ae057ef933c99c81f46e35d641686639c5", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 11 ], { "height": 32, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 10, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 21, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 11, "rise": [ 2, 1 ] }, "dabd215d7edac1cd125e7d085d50279a9cad1db2ac5e82cbccd509abec387d4a" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "z", "span": 11, "rise": [ 2, 1 ] }, "8430ff95b5f3f28f966e2a97809a81a016bdba29022daf004b99357bfb87aa16" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 91, "excavation": 0, "sitework_occupied_cells": 128, "replaced_cells": 30, "new_sitework_cells": 98, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "a76b432710671b78008ca91e92e3d455d816ec35c0730339419103815d231ac9", "bearing_fill": 2 }, "blocks": 12583, "nodes": 176, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.04 ], [ 0, 1.26 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.1913 }
high-3建造成功3310834167
查看数据
{ "label": "high-3", "inputs": { "client": "high", "structure_seed": 3, "environment_seed": 3 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "91f680249d2b48822ac06ce0c1f993bb8ce366affeab79844074a09b0403c986", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 54, "excavation": 0, "sitework_occupied_cells": 96, "replaced_cells": 30, "new_sitework_cells": 66, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "6439dbe885ca23ef1e0f9d59c4c81f57dac81b5648e72d3c9de331b62fa0ed78", "bearing_fill": 2 }, "blocks": 10834, "nodes": 167, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 0.6 ], [ 0, 0.72 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.0385 }
high-4建造成功4410150161
查看数据
{ "label": "high-4", "inputs": { "client": "high", "structure_seed": 4, "environment_seed": 4 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "527eedd2584e613944639140a42ba9535c4360698ddcdf7f7642cfd710833ae0", "principal_signature": "c996f1a3124234c7c03a93f7a8c50e7477a43fee099e552bcd057d8c0a3bba40", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 10, "excavation": 0, "sitework_occupied_cells": 43, "replaced_cells": 33, "new_sitework_cells": 10, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "1a2cf64b042be7578b3d52b3e4a61f014c19526123637bd3f6948270894a8735", "bearing_fill": 0 }, "blocks": 10150, "nodes": 161, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.17 ], [ 1, 0.56 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.0803 }
high-5建造成功5510966188
查看数据
{ "label": "high-5", "inputs": { "client": "high", "structure_seed": 5, "environment_seed": 5 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "9e4009beee1d7a8a936c7c88e8b5b94c8dc6fa46dcba7f13f8348a9250349bbb", "principal_signature": "ee761a9f3137e7db3859e62b8864d9ff848f4f34bcc65c70eb7082ec1d542a0a", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 14, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 13, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "east" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 6, 0 ], "room.workshop", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 6, "excavation": 0, "sitework_occupied_cells": 39, "replaced_cells": 33, "new_sitework_cells": 6, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "1c56a60f6163350c1891e7d0657c11ca9e3b03c8358dca9c65e23b77b5de960a", "bearing_fill": 1 }, "blocks": 10966, "nodes": 188, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.2 ], [ 1, 0.58 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.14 }
high-6建造成功6612640180
查看数据
{ "label": "high-6", "inputs": { "client": "high", "structure_seed": 6, "environment_seed": 6 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "40d42b26b7346cfa6198ecad77428addf6bbbcc419cfa7031fe4d0efccc5123f", "principal_signature": "9a4fa8463af657108769cfbcbf7e8f4fa7c9c6dad084be23b3e4dd5a891fa9fb", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 11 ], { "height": 32, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 10, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 21, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 11, "rise": [ 2, 1 ] }, "dabd215d7edac1cd125e7d085d50279a9cad1db2ac5e82cbccd509abec387d4a" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "z", "span": 11, "rise": [ 2, 1 ] }, "8430ff95b5f3f28f966e2a97809a81a016bdba29022daf004b99357bfb87aa16" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 0, 6, 0 ], "room.library", [], true, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 0, "excavation": 0, "sitework_occupied_cells": 33, "replaced_cells": 33, "new_sitework_cells": 0, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "47df3ba9586b88f3f40e1e919c69663a74a70e5ff24c7627a31def353bee09dd", "bearing_fill": 0 }, "blocks": 12640, "nodes": 180, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.12 ], [ 1, 0.52 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-quality/final/high-6.litematic", "audit": { "queries": 155, "inventories": 18, "nodes": 180, "digest": "40d42b26b7346cfa6198ecad77428addf6bbbcc419cfa7031fe4d0efccc5123f" }, "seconds": 1.9384 }
high-7建造成功7710723181
查看数据
{ "label": "high-7", "inputs": { "client": "high", "structure_seed": 7, "environment_seed": 7 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "98fce76878b823abf3d810386136c7d4b62166dcb1cee68dff4103796a30ce57", "principal_signature": "3ee5f0fa7e83d0600b08b42d4727961d3833a093ed2eb90000e73fcb27495597", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 14, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 13, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north", "east" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 6, 0 ], "room.workshop", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 15, "excavation": 0, "sitework_occupied_cells": 48, "replaced_cells": 33, "new_sitework_cells": 15, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "68f816e940120a70ab0185eec04060c8cd9bb51e9a72c0ad730f3d2eac74b526", "bearing_fill": 0 }, "blocks": 10723, "nodes": 181, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.27 ], [ 1, 0.65 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9667 }
adaptation-00建造成功0034533102
查看数据
{ "label": "adaptation-00", "inputs": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, -0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 3.734703416353409 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.4 ] } ] }, 2, 7 ] }, "water": 5, "digest": "84e4d5ef660eb9573a0b335b554fd074ded4b6c5decba1743d63a458d7581f78", "held_out_composition": false, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "5929b295a34c7ce78d8bad23d348f726d2ea687763f8ac53a5b6c72c42bea60a", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 160, "excavation": 0, "sitework_occupied_cells": 166, "replaced_cells": 163, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "9f3f203c3f0e70d3683099b2ae4392d6f85b45d595b8a06946a06450ce7336c9", "bearing_fill": 3 }, "blocks": 34533, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.92 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-quality/final/adaptation-00.litematic", "audit": { "queries": 94, "inventories": 16, "nodes": 102, "digest": "5929b295a34c7ce78d8bad23d348f726d2ea687763f8ac53a5b6c72c42bea60a" }, "seconds": 2.8657 }
adaptation-01建造成功1034439102
查看数据
{ "label": "adaptation-01", "inputs": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, -0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 3.734703416353409 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.4 ] } ] }, 2, 7 ] }, "water": 5, "digest": "84e4d5ef660eb9573a0b335b554fd074ded4b6c5decba1743d63a458d7581f78", "held_out_composition": false, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "e6dfc84f96bc9894e062ca3b267e319bded22b931ef3831a6243a00f619a916c", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 160, "excavation": 0, "sitework_occupied_cells": 166, "replaced_cells": 163, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "9f3f203c3f0e70d3683099b2ae4392d6f85b45d595b8a06946a06450ce7336c9", "bearing_fill": 3 }, "blocks": 34439, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.92 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9487 }
adaptation-02建造成功2034847135
查看数据
{ "label": "adaptation-02", "inputs": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, -0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 3.734703416353409 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.4 ] } ] }, 2, 7 ] }, "water": 5, "digest": "84e4d5ef660eb9573a0b335b554fd074ded4b6c5decba1743d63a458d7581f78", "held_out_composition": false, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "a6a16065f13baf96cd08b1d5197f030fb8577140558b84ae3054d58d06ef345d", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 202, "excavation": 0, "sitework_occupied_cells": 208, "replaced_cells": 205, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "fb889a40efd56f5b9c62fcd6a6b487a53c92e3e4d6cc0f484ba699eec202cdfb", "bearing_fill": 3 }, "blocks": 34847, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 6.18 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9396 }
adaptation-03建造成功3033681112
查看数据
{ "label": "adaptation-03", "inputs": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, -0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 3.734703416353409 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.4 ] } ] }, 2, 7 ] }, "water": 5, "digest": "84e4d5ef660eb9573a0b335b554fd074ded4b6c5decba1743d63a458d7581f78", "held_out_composition": false, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "96ce68acae219a7365469a2348218dceb03f78e517d957790fad20ccaf3e043b", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 71, "excavation": 0, "sitework_occupied_cells": 77, "replaced_cells": 74, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "f2e0f1c8993f8638dbf03b92cfef2b9a78336b814eaa3f1d5071af11f0e6ad38", "bearing_fill": 2 }, "blocks": 33681, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 2.25 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.5914 }
adaptation-04建造成功0130305102
查看数据
{ "label": "adaptation-04", "inputs": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.8, 0.13, 0.11, 5.044220228402418 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.7 ] } ] }, 2, 7 ] }, "water": null, "digest": "06de23238b6ccf3a76afec91a322bd15ad2c4b2b7c356183ee8bacde06115865", "held_out_composition": false, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "6c14b71ad69d6e60e0f13a6430c9659dabb7a35ed926650a9a732a371e2f753b", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 91, "excavation": 0, "sitework_occupied_cells": 103, "replaced_cells": 3, "new_sitework_cells": 100, "strategies": [ "piers" ], "signature": "e33259d98b792b6b19e8f39e470f53bd26b683ded299218bb41fb5d3c3644581", "bearing_fill": 3 }, "blocks": 30305, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.09 ], [ 0, 1.23 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.2141 }
adaptation-05建造成功1130211102
查看数据
{ "label": "adaptation-05", "inputs": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.8, 0.13, 0.11, 5.044220228402418 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.7 ] } ] }, 2, 7 ] }, "water": null, "digest": "06de23238b6ccf3a76afec91a322bd15ad2c4b2b7c356183ee8bacde06115865", "held_out_composition": false, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "6e59ce709b4e51cd99f4b534622869c2835236335bc9af14a57d214a469fcef7", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 91, "excavation": 0, "sitework_occupied_cells": 103, "replaced_cells": 3, "new_sitework_cells": 100, "strategies": [ "piers" ], "signature": "e33259d98b792b6b19e8f39e470f53bd26b683ded299218bb41fb5d3c3644581", "bearing_fill": 3 }, "blocks": 30211, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.09 ], [ 0, 1.23 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.0987 }
adaptation-06建造成功2130642135
查看数据
{ "label": "adaptation-06", "inputs": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.8, 0.13, 0.11, 5.044220228402418 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.7 ] } ] }, 2, 7 ] }, "water": null, "digest": "06de23238b6ccf3a76afec91a322bd15ad2c4b2b7c356183ee8bacde06115865", "held_out_composition": false, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "08a43b6ad35e3ffc5d01fd77e7ffc9cc20c6e1f1f71248009a5b8f9e9da252de", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 114, "excavation": 0, "sitework_occupied_cells": 126, "replaced_cells": 3, "new_sitework_cells": 123, "strategies": [ "piers" ], "signature": "3a87d4d5b3a048943a78f3aecef13528a3339fb39461af806910cb910ab868ec", "bearing_fill": 3 }, "blocks": 30642, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.32 ], [ 0, 1.52 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.2015 }
adaptation-07建造成功3129418112
查看数据
{ "label": "adaptation-07", "inputs": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.8, 0.13, 0.11, 5.044220228402418 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.7 ] } ] }, 2, 7 ] }, "water": null, "digest": "06de23238b6ccf3a76afec91a322bd15ad2c4b2b7c356183ee8bacde06115865", "held_out_composition": false, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "a7d1772f82e427547d0a6676bd5b6262494780ab5b6d05b979450bde78f84a30", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 56, "excavation": 0, "sitework_occupied_cells": 68, "replaced_cells": 3, "new_sitework_cells": 65, "strategies": [ "piers" ], "signature": "9ee500055ac0acbab069a8a150677790a570b5abfa67f50e693124d9482a80a7", "bearing_fill": 2 }, "blocks": 29418, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 0.74 ], [ 0, 0.94 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.7336 }
adaptation-08建造成功0237682102
查看数据
{ "label": "adaptation-08", "inputs": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.045, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 4.998757701772476 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.4 ] } ] }, 2, 7 ] }, "water": 6, "digest": "f3ff6572715b99e6ac24b42963c7f0b7ce38c7a885dac8614550de6de1a36682", "held_out_composition": false, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "330e5bd8b9f6ff5efc4fc2ea9749d76f96d93df781ba3ec8b9e035bd539d1bd3", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 129, "excavation": 0, "sitework_occupied_cells": 138, "replaced_cells": 135, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "2f2ecde66dbb2f344ecbf341b10bf398bb28fa25d6d7814eab4d45bbf15a2cf7", "bearing_fill": 3 }, "blocks": 37682, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.08 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-quality/final/adaptation-08.litematic", "audit": { "queries": 94, "inventories": 16, "nodes": 102, "digest": "330e5bd8b9f6ff5efc4fc2ea9749d76f96d93df781ba3ec8b9e035bd539d1bd3" }, "seconds": 2.8353 }
adaptation-09建造成功1237588102
查看数据
{ "label": "adaptation-09", "inputs": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.045, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 4.998757701772476 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.4 ] } ] }, 2, 7 ] }, "water": 6, "digest": "f3ff6572715b99e6ac24b42963c7f0b7ce38c7a885dac8614550de6de1a36682", "held_out_composition": false, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "495f8b718a0b9b52f6a115c365203fa032d6ca813e8a1411c1a1c748f75658a2", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 129, "excavation": 0, "sitework_occupied_cells": 138, "replaced_cells": 135, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "2f2ecde66dbb2f344ecbf341b10bf398bb28fa25d6d7814eab4d45bbf15a2cf7", "bearing_fill": 3 }, "blocks": 37588, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.08 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8655 }
adaptation-10建造成功2237996135
查看数据
{ "label": "adaptation-10", "inputs": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.045, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 4.998757701772476 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.4 ] } ] }, 2, 7 ] }, "water": 6, "digest": "f3ff6572715b99e6ac24b42963c7f0b7ce38c7a885dac8614550de6de1a36682", "held_out_composition": false, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "2d7031d74ff9804959073ef6896c06b88da0607ec65c36fb1b9714612ba5bb29", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 145, "excavation": 0, "sitework_occupied_cells": 154, "replaced_cells": 151, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "b051894534fbd092ed94de1bf5d0d6d6775c30e8244729323eb7846b7e101d13", "bearing_fill": 3 }, "blocks": 37996, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.56 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9434 }
adaptation-11建造成功3236830112
查看数据
{ "label": "adaptation-11", "inputs": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.045, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 4.998757701772476 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.4 ] } ] }, 2, 7 ] }, "water": 6, "digest": "f3ff6572715b99e6ac24b42963c7f0b7ce38c7a885dac8614550de6de1a36682", "held_out_composition": false, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "c96a15b8dd60eb35bc3bbc1eebe1023b7918dfa09952fd41b425c399ca20d3a5", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 86, "excavation": 0, "sitework_occupied_cells": 95, "replaced_cells": 92, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "b22f29cea133dd0e8bd2f35fda8a4883f73f7a62d9b7e31402626935fdbcb379", "bearing_fill": 2 }, "blocks": 36830, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 2.79 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.6092 }
adaptation-12建造成功0331422102
查看数据
{ "label": "adaptation-12", "inputs": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 0.814364809860294 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": null, "digest": "96e0db82efdbdbe26b58630f206491efaf5f3aa5e2e72c90fe18c6e3983556ac", "held_out_composition": false, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "16d195473759e881402e7589141c022dcb874383db18d4999dd583a0dcad2c96", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 0, "excavation": 0, "sitework_occupied_cells": 6, "replaced_cells": 3, "new_sitework_cells": 3, "strategies": [ "stepped" ], "signature": "de4c2a6c9d2752a79195e3ff5b4929bca547a3d6c8ed5cfcab3f7f594e5a45f8", "bearing_fill": 0 }, "blocks": 31422, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.12 ], [ 1, 0.52 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.0444 }
adaptation-13建造成功1331328102
查看数据
{ "label": "adaptation-13", "inputs": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 0.814364809860294 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": null, "digest": "96e0db82efdbdbe26b58630f206491efaf5f3aa5e2e72c90fe18c6e3983556ac", "held_out_composition": false, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "e7b3cbd2e642015d9deeeec557d931f818fbeef6fadebfc323a8c6cfb419ef37", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 0, "excavation": 0, "sitework_occupied_cells": 6, "replaced_cells": 3, "new_sitework_cells": 3, "strategies": [ "stepped" ], "signature": "de4c2a6c9d2752a79195e3ff5b4929bca547a3d6c8ed5cfcab3f7f594e5a45f8", "bearing_fill": 0 }, "blocks": 31328, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.12 ], [ 1, 0.52 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.1117 }
adaptation-14建造成功2331736135
查看数据
{ "label": "adaptation-14", "inputs": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 0.814364809860294 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": null, "digest": "96e0db82efdbdbe26b58630f206491efaf5f3aa5e2e72c90fe18c6e3983556ac", "held_out_composition": false, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "2b6d30835ed506da9bdeee13faaab366a6093afee944f6d36c5824c086274808", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 0, "excavation": 0, "sitework_occupied_cells": 6, "replaced_cells": 3, "new_sitework_cells": 3, "strategies": [ "stepped" ], "signature": "cca78d91e91dfd946f51e58967315f184d53ed2dd9fbddd7eb63cfff4b7c336d", "bearing_fill": 0 }, "blocks": 31736, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.12 ], [ 1, 0.52 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.1952 }
adaptation-15建造成功3330570112
查看数据
{ "label": "adaptation-15", "inputs": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 0.814364809860294 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": null, "digest": "96e0db82efdbdbe26b58630f206491efaf5f3aa5e2e72c90fe18c6e3983556ac", "held_out_composition": false, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "549d8fa7c0788e72f3b3e634b05eddff868a91f51b57514be25665876d7106f9", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 0, "excavation": 0, "sitework_occupied_cells": 6, "replaced_cells": 3, "new_sitework_cells": 3, "strategies": [ "stepped" ], "signature": "cf7b488deddbabdfc1cd4a449f672c728a32364891b571911cac52cb174eceeb", "bearing_fill": 0 }, "blocks": 30570, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.12 ], [ 1, 0.52 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.753 }
adaptation-16建造成功0434533102
查看数据
{ "label": "adaptation-16", "inputs": { "environment_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 0.5187285716175347 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": 5, "digest": "5c90903c03656a5eeedc1ab2a56ba88feed142de9ac82ea0911c8da1eaa171bf", "held_out_composition": false, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "58058ca06a9ebb53ffc5eb42d34bf6970923df923de061bbe00d8f2acc36d8dc", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 145, "excavation": 0, "sitework_occupied_cells": 154, "replaced_cells": 151, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "20332c7080ab09dc2bae5881fbf9e680c0d34916e3a51e7cbeb741a56629afd5", "bearing_fill": 3 }, "blocks": 34533, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.56 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8839 }
adaptation-17建造成功1434439102
查看数据
{ "label": "adaptation-17", "inputs": { "environment_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 0.5187285716175347 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": 5, "digest": "5c90903c03656a5eeedc1ab2a56ba88feed142de9ac82ea0911c8da1eaa171bf", "held_out_composition": false, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "aa01e453d6822942fc4593ccde9171360514a6280b9f4b89fcb26ac63e316630", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 145, "excavation": 0, "sitework_occupied_cells": 154, "replaced_cells": 151, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "20332c7080ab09dc2bae5881fbf9e680c0d34916e3a51e7cbeb741a56629afd5", "bearing_fill": 3 }, "blocks": 34439, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.56 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8727 }
adaptation-18建造成功2434847135
查看数据
{ "label": "adaptation-18", "inputs": { "environment_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 0.5187285716175347 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": 5, "digest": "5c90903c03656a5eeedc1ab2a56ba88feed142de9ac82ea0911c8da1eaa171bf", "held_out_composition": false, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "2797291279ef1d863ed7c772fb6cbe2668643250360e683d78197e8d17cf87ab", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 146, "excavation": 0, "sitework_occupied_cells": 155, "replaced_cells": 152, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "7cf981d71cc1c920e19b5d9341415f417760af5c0224119e26c9734537dcae0f", "bearing_fill": 3 }, "blocks": 34847, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.59 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9317 }
adaptation-19建造成功3433681112
查看数据
{ "label": "adaptation-19", "inputs": { "environment_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 0.5187285716175347 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": 5, "digest": "5c90903c03656a5eeedc1ab2a56ba88feed142de9ac82ea0911c8da1eaa171bf", "held_out_composition": false, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "1bf7657987cc80725c71421e45df0b84685453e0db2a2e3fc2ae005028099db8", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 72, "excavation": 0, "sitework_occupied_cells": 80, "replaced_cells": 77, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "78fdbb20364d0aafbaa2fe5f81ddf8acb64aa0f46e5a60fc6cecc3f927750625", "bearing_fill": 2 }, "blocks": 33681, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 2.34 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.5791 }
adaptation-20建造成功0537644102
查看数据
{ "label": "adaptation-20", "inputs": { "environment_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, 0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 4.831610348091849 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": 6, "digest": "4e20d6bb4f9f3cf14a5b7fb428e127f4eda875814caaa64784748d7a652ed422", "held_out_composition": false, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "d463e44f6259b684fa582fd17ffc15f2d23f5ee8726feeaf6f07a5be61e26810", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 230, "excavation": 0, "sitework_occupied_cells": 242, "replaced_cells": 239, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "d7ba3bc2c15e9e263c3bb85222d01631b98628187a7eb8d3aa96c945bb1be992", "bearing_fill": 3 }, "blocks": 37644, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 7.2 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8825 }
adaptation-21建造成功1537550102
查看数据
{ "label": "adaptation-21", "inputs": { "environment_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, 0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 4.831610348091849 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": 6, "digest": "4e20d6bb4f9f3cf14a5b7fb428e127f4eda875814caaa64784748d7a652ed422", "held_out_composition": false, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "563df2b20f49d6a7283f31daf0209e21d57669b767cb917b3c5ed8ba3b3bebba", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 230, "excavation": 0, "sitework_occupied_cells": 242, "replaced_cells": 239, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "d7ba3bc2c15e9e263c3bb85222d01631b98628187a7eb8d3aa96c945bb1be992", "bearing_fill": 3 }, "blocks": 37550, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 7.2 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.871 }
adaptation-22建造成功2537958135
查看数据
{ "label": "adaptation-22", "inputs": { "environment_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, 0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 4.831610348091849 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": 6, "digest": "4e20d6bb4f9f3cf14a5b7fb428e127f4eda875814caaa64784748d7a652ed422", "held_out_composition": false, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "b2c9d3ce4ad8366b2eee57d444f6662379ef4c4272e1ca3d37bb492ff2b64f87", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 235, "excavation": 0, "sitework_occupied_cells": 247, "replaced_cells": 244, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "509554f360f76ebc820323daef650470c5db963a424f24b0f7226c771b8bf4a7", "bearing_fill": 3 }, "blocks": 37958, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 7.35 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9559 }
adaptation-23建造成功3536792112
查看数据
{ "label": "adaptation-23", "inputs": { "environment_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, 0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 4.831610348091849 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": 6, "digest": "4e20d6bb4f9f3cf14a5b7fb428e127f4eda875814caaa64784748d7a652ed422", "held_out_composition": false, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "64ae498918e4d422e57c263daf56663d31c36a2fa84f8022879e957ea6cd7c7e", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 128, "excavation": 0, "sitework_occupied_cells": 140, "replaced_cells": 137, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "cd2ba461c8b8a0d20cb9c420627b9b1af2944dc29fb6f251102d890cfd23c575", "bearing_fill": 2 }, "blocks": 36792, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.14 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.5974 }
adaptation-24建造成功0634533102
查看数据
{ "label": "adaptation-24", "inputs": { "environment_seed": 6, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, 0, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 0.6542444831229557 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.4 ] } ] }, 2, 7 ] }, "water": 5, "digest": "8d11645017e24042cbb11bc5adb63ce365eadbfb6f13163e43c4ebfb0c4338d9", "held_out_composition": false, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "33786285886c6f34a1e8b7342a824b178cc9afa52c87ee37f2387a25985b45b4", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 144, "excavation": 0, "sitework_occupied_cells": 150, "replaced_cells": 147, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "5b9514b098a8e3178502f498ed552c6dabd458150e6b20b601a0297bb25b374a", "bearing_fill": 3 }, "blocks": 34533, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.44 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8596 }
adaptation-25建造成功1634439102
查看数据
{ "label": "adaptation-25", "inputs": { "environment_seed": 6, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, 0, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 0.6542444831229557 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.4 ] } ] }, 2, 7 ] }, "water": 5, "digest": "8d11645017e24042cbb11bc5adb63ce365eadbfb6f13163e43c4ebfb0c4338d9", "held_out_composition": false, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "d93be3caadd4dac762dcccbd55d77f473fe5c2eeab4b60cf05939a51f4c650c6", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 144, "excavation": 0, "sitework_occupied_cells": 150, "replaced_cells": 147, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "5b9514b098a8e3178502f498ed552c6dabd458150e6b20b601a0297bb25b374a", "bearing_fill": 3 }, "blocks": 34439, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.44 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8598 }
adaptation-26建造成功2634847135
查看数据
{ "label": "adaptation-26", "inputs": { "environment_seed": 6, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, 0, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 0.6542444831229557 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.4 ] } ] }, 2, 7 ] }, "water": 5, "digest": "8d11645017e24042cbb11bc5adb63ce365eadbfb6f13163e43c4ebfb0c4338d9", "held_out_composition": false, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "848d84ae2a59a5369af01e2173ae4f4f67e773d4e8af5391314f92efffbf3849", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 152, "excavation": 0, "sitework_occupied_cells": 158, "replaced_cells": 155, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "f6d898f6bd30749f8131b00f76c23ba1a066d484cf36925efa1978a9ff25813f", "bearing_fill": 3 }, "blocks": 34847, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.68 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9282 }
adaptation-27建造成功3633681112
查看数据
{ "label": "adaptation-27", "inputs": { "environment_seed": 6, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, 0, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 0.6542444831229557 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0.4 ] } ] }, 2, 7 ] }, "water": 5, "digest": "8d11645017e24042cbb11bc5adb63ce365eadbfb6f13163e43c4ebfb0c4338d9", "held_out_composition": false, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "4d54146ea3172ad669433075ca02d8d68dbd7c37a93312a85035cf153f79abb6", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 64, "excavation": 0, "sitework_occupied_cells": 70, "replaced_cells": 67, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "83048d139205f241eb0779a4f4d0f99bee6b2b26701716c2691f723782d808c4", "bearing_fill": 2 }, "blocks": 33681, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 2.04 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.5752 }
adaptation-28建造成功0737644102
查看数据
{ "label": "adaptation-28", "inputs": { "environment_seed": 7, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 0.4943872051732314 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": 6, "digest": "9fdea9ccf78cba68cae1b77dabb0f36997911b40e650447bbb7bf3b45b3baa16", "held_out_composition": false, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "3ede5e0724ee72cb57228be5c610a7891e3e20bb4273ce189466c696de1f5d47", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 180, "excavation": 0, "sitework_occupied_cells": 192, "replaced_cells": 189, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "386c566c78ebafc637086d9ad8bb030a5f7fde883a97942f6da90526c79a6795", "bearing_fill": 3 }, "blocks": 37644, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 5.7 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8975 }
adaptation-29建造成功1737550102
查看数据
{ "label": "adaptation-29", "inputs": { "environment_seed": 7, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 0.4943872051732314 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": 6, "digest": "9fdea9ccf78cba68cae1b77dabb0f36997911b40e650447bbb7bf3b45b3baa16", "held_out_composition": false, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "45a150c52eb671b878b8fb66b94e08df72d894d7e211f202a8ce9aa3a4cd50d4", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 180, "excavation": 0, "sitework_occupied_cells": 192, "replaced_cells": 189, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "386c566c78ebafc637086d9ad8bb030a5f7fde883a97942f6da90526c79a6795", "bearing_fill": 3 }, "blocks": 37550, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 5.7 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8741 }
adaptation-30建造成功2737958135
查看数据
{ "label": "adaptation-30", "inputs": { "environment_seed": 7, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 0.4943872051732314 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": 6, "digest": "9fdea9ccf78cba68cae1b77dabb0f36997911b40e650447bbb7bf3b45b3baa16", "held_out_composition": false, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "59143627bbcea96da140ff73a2f58aed32827bf2aa55e6aa197a789e871b8f94", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 201, "excavation": 0, "sitework_occupied_cells": 213, "replaced_cells": 210, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "7c0dc86b803fa8bafa3c68abcc38c0872c67072c4866f333e062ceb8508659bb", "bearing_fill": 3 }, "blocks": 37958, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 6.33 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.999 }
adaptation-31建造成功3736792112
查看数据
{ "label": "adaptation-31", "inputs": { "environment_seed": 7, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 0.4943872051732314 ] } ] }, { "op": "radial", "args": [ 7, 8, 22, 0 ] } ] }, 2, 7 ] }, "water": 6, "digest": "9fdea9ccf78cba68cae1b77dabb0f36997911b40e650447bbb7bf3b45b3baa16", "held_out_composition": false, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "7333776285b830f647e58bb230ca618234fa9b66ac4d0ca167e1f410760b825e", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 105, "excavation": 0, "sitework_occupied_cells": 117, "replaced_cells": 114, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "0d9746456de3366089412138642bc61869856f0eec23f52196b03eeb72aeaa9c", "bearing_fill": 2 }, "blocks": 36792, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 3.45 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.5995 }
adaptation-32建造成功0830029102
查看数据
{ "label": "adaptation-32", "inputs": { "environment_seed": 8, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 1.4906793537687184 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": null, "digest": "2e63123e44f63ed6bb126e0206d18e6702dc1de0fcb11befe7fb54245248c2a8", "held_out_composition": true, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "cd4970ba0179f42d56c30e442c060a13f969efc35a46a696ef7426f6167ac850", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 40, "excavation": 0, "sitework_occupied_cells": 46, "replaced_cells": 3, "new_sitework_cells": 43, "strategies": [ "stepped" ], "signature": "2479400e5e09b4a3a99ac253ae9a04f853f7c3f9d86fa205dac8d8abd3fd9342", "bearing_fill": 1 }, "blocks": 30029, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.52 ], [ 1, 0.92 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.0366 }
adaptation-33建造成功1829935102
查看数据
{ "label": "adaptation-33", "inputs": { "environment_seed": 8, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 1.4906793537687184 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": null, "digest": "2e63123e44f63ed6bb126e0206d18e6702dc1de0fcb11befe7fb54245248c2a8", "held_out_composition": true, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "8628b43ff83b698853a8bc85ca0d37f8c2c12849ab3180e85721748cfc61aecd", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 40, "excavation": 0, "sitework_occupied_cells": 46, "replaced_cells": 3, "new_sitework_cells": 43, "strategies": [ "stepped" ], "signature": "2479400e5e09b4a3a99ac253ae9a04f853f7c3f9d86fa205dac8d8abd3fd9342", "bearing_fill": 1 }, "blocks": 29935, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.52 ], [ 1, 0.92 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.0311 }
adaptation-34建造成功2830387135
查看数据
{ "label": "adaptation-34", "inputs": { "environment_seed": 8, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 1.4906793537687184 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": null, "digest": "2e63123e44f63ed6bb126e0206d18e6702dc1de0fcb11befe7fb54245248c2a8", "held_out_composition": true, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "edbe673544801eb1c208f1e71abda95c48207d4f68c092fe542e1b2f86272ca9", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 84, "excavation": 0, "sitework_occupied_cells": 90, "replaced_cells": 3, "new_sitework_cells": 87, "strategies": [ "stepped" ], "signature": "964daf58bf2502bfc352524d9988d6b32a90dbe9eefbf021d835120162e96e84", "bearing_fill": 1 }, "blocks": 30387, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.96 ], [ 1, 1.27 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.1502 }
adaptation-35建造成功3829161112
查看数据
{ "label": "adaptation-35", "inputs": { "environment_seed": 8, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 1.4906793537687184 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": null, "digest": "2e63123e44f63ed6bb126e0206d18e6702dc1de0fcb11befe7fb54245248c2a8", "held_out_composition": true, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "6d52dd661c1057db75f22e7c51606af7626475f985848ebff73ea09aafd929ec", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 24, "excavation": 0, "sitework_occupied_cells": 30, "replaced_cells": 3, "new_sitework_cells": 27, "strategies": [ "stepped" ], "signature": "413e4d26c3d97b6be9e90e464620a3c2d3a1742b6dfc9c19f722184429905df4", "bearing_fill": 1 }, "blocks": 29161, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.36 ], [ 1, 0.71 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-quality/final/adaptation-35.litematic", "audit": { "queries": 103, "inventories": 18, "nodes": 112, "digest": "6d52dd661c1057db75f22e7c51606af7626475f985848ebff73ea09aafd929ec" }, "seconds": 2.181 }
adaptation-36建造成功0937644102
查看数据
{ "label": "adaptation-36", "inputs": { "environment_seed": 9, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, -0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 5.129876042788569 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 6, "digest": "b1ad2b18771e9590495fad037971e5ae73d8c9362c543546a2ca47b773efe6c0", "held_out_composition": true, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "eaecaff1cfda85d03d5af413abd221e82c5e9f0a79f557cfb01d93bb76c6b59a", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 205, "excavation": 0, "sitework_occupied_cells": 214, "replaced_cells": 211, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "0afef37099a081ec8f36a5d41d07bfee1349e1ce1c325f5f7254b2c86901f326", "bearing_fill": 3 }, "blocks": 37644, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 6.36 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8788 }
adaptation-37建造成功1937550102
查看数据
{ "label": "adaptation-37", "inputs": { "environment_seed": 9, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, -0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 5.129876042788569 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 6, "digest": "b1ad2b18771e9590495fad037971e5ae73d8c9362c543546a2ca47b773efe6c0", "held_out_composition": true, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "0b67249bc9131c3d59d28ee5845025e098b0a78f99c1df72e542a228bb38995e", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 205, "excavation": 0, "sitework_occupied_cells": 214, "replaced_cells": 211, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "0afef37099a081ec8f36a5d41d07bfee1349e1ce1c325f5f7254b2c86901f326", "bearing_fill": 3 }, "blocks": 37550, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 6.36 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8817 }
adaptation-38建造成功2937958135
查看数据
{ "label": "adaptation-38", "inputs": { "environment_seed": 9, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, -0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 5.129876042788569 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 6, "digest": "b1ad2b18771e9590495fad037971e5ae73d8c9362c543546a2ca47b773efe6c0", "held_out_composition": true, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "710138ac818ea17dbb3f33ef47695888da75da67baba3b388aa6b1d295354c77", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 256, "excavation": 0, "sitework_occupied_cells": 265, "replaced_cells": 262, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "0da5b1a01a81e3f180bf7fe6d46e5d7b0e32ea9790f4ae3d4fa247313b0267d1", "bearing_fill": 3 }, "blocks": 37958, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 7.89 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9488 }
adaptation-39建造成功3936792112
查看数据
{ "label": "adaptation-39", "inputs": { "environment_seed": 9, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, -0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 5.129876042788569 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 6, "digest": "b1ad2b18771e9590495fad037971e5ae73d8c9362c543546a2ca47b773efe6c0", "held_out_composition": true, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "7357517f99140b9eaa4973715d30d072c001b19d7ac3d20a7d340220b5420afa", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 109, "excavation": 0, "sitework_occupied_cells": 118, "replaced_cells": 115, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "f37e67a01fb0f3f69f56c8c83d54cde3c43c46aec2eab7f4b00f692d270d12b4", "bearing_fill": 2 }, "blocks": 36792, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 3.48 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.5976 }
adaptation-40建造成功01030397102
查看数据
{ "label": "adaptation-40", "inputs": { "environment_seed": 10, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 4.544802917156937 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.035, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": null, "digest": "42908eba4ec4346b89d7b0a3d64976055aeeb4f3cfbe89ebf337af41ba8f597e", "held_out_composition": true, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "0c65004d6abdda5e891e72b31949f5cd5f19e27da931ad8735f9a00720932fe5", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 67, "excavation": 0, "sitework_occupied_cells": 74, "replaced_cells": 1, "new_sitework_cells": 73, "strategies": [ "stepped" ], "signature": "a7a78fb73ef80a289270539975e22a2811a6137afbcee1c966c2c9d8f997967f", "bearing_fill": 1 }, "blocks": 30397, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.76 ], [ 1, 1.06 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.0379 }
adaptation-41建造成功11030303102
查看数据
{ "label": "adaptation-41", "inputs": { "environment_seed": 10, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 4.544802917156937 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.035, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": null, "digest": "42908eba4ec4346b89d7b0a3d64976055aeeb4f3cfbe89ebf337af41ba8f597e", "held_out_composition": true, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "87a822f283bcb3dbbee6da4793331a02f1998244cef6431d4d5f54823479ba2e", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 67, "excavation": 0, "sitework_occupied_cells": 74, "replaced_cells": 1, "new_sitework_cells": 73, "strategies": [ "stepped" ], "signature": "a7a78fb73ef80a289270539975e22a2811a6137afbcee1c966c2c9d8f997967f", "bearing_fill": 1 }, "blocks": 30303, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.76 ], [ 1, 1.06 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.0364 }
adaptation-42建造成功21030691135
查看数据
{ "label": "adaptation-42", "inputs": { "environment_seed": 10, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 4.544802917156937 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.035, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": null, "digest": "42908eba4ec4346b89d7b0a3d64976055aeeb4f3cfbe89ebf337af41ba8f597e", "held_out_composition": true, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "caa0e4786b783ab5882169e68ef804880b763240457829f1a36e2b09b8f56c15", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 47, "excavation": 0, "sitework_occupied_cells": 54, "replaced_cells": 1, "new_sitework_cells": 53, "strategies": [ "stepped" ], "signature": "519ec2cba7eea84018df6372e79e703778cd9990ec187b6804050cf1638c3b20", "bearing_fill": 0 }, "blocks": 30691, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.56 ], [ 1, 0.81 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.1529 }
adaptation-43建造成功31029508112
查看数据
{ "label": "adaptation-43", "inputs": { "environment_seed": 10, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 4.544802917156937 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.035, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": null, "digest": "42908eba4ec4346b89d7b0a3d64976055aeeb4f3cfbe89ebf337af41ba8f597e", "held_out_composition": true, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "2ad81900c8f0dafce43495ec6ab0dea7e69edd8bcb9b229251f5f7f8631b67d6", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 33, "excavation": 0, "sitework_occupied_cells": 39, "replaced_cells": 3, "new_sitework_cells": 36, "strategies": [ "stepped" ], "signature": "8865f7bb2eb8cda3204332725a05b3a0e416d6721c290a01464d3257e9255a4a", "bearing_fill": 1 }, "blocks": 29508, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.45 ], [ 1, 0.74 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.7252 }
adaptation-44建造成功01134533102
查看数据
{ "label": "adaptation-44", "inputs": { "environment_seed": 11, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, -0.035, 4 ] }, { "op": "wave", "args": [ 0.8, 0.13, 0.11, 2.1696793309977784 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, -0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 5, "digest": "ccacffc044d46bc8047e50542aaf10b28a68de02a9d472912996fbe30ebe01d2", "held_out_composition": true, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "36bbac2d2e0fb52f1114d7aff3ea37148f40ebe1b29fcc52cae50fd04b546d6f", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 135, "excavation": 0, "sitework_occupied_cells": 141, "replaced_cells": 138, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "7de531d181925ba6e83ebecf4e2740498e54d4b6027e17568c7cc4148c6f50f0", "bearing_fill": 3 }, "blocks": 34533, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.17 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8677 }
adaptation-45建造成功11134439102
查看数据
{ "label": "adaptation-45", "inputs": { "environment_seed": 11, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, -0.035, 4 ] }, { "op": "wave", "args": [ 0.8, 0.13, 0.11, 2.1696793309977784 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, -0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 5, "digest": "ccacffc044d46bc8047e50542aaf10b28a68de02a9d472912996fbe30ebe01d2", "held_out_composition": true, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "680c74dbb861e44217446f96c1edf46e67651dba9515890f1be137eb9b142a17", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 135, "excavation": 0, "sitework_occupied_cells": 141, "replaced_cells": 138, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "7de531d181925ba6e83ebecf4e2740498e54d4b6027e17568c7cc4148c6f50f0", "bearing_fill": 3 }, "blocks": 34439, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.17 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8549 }
adaptation-46建造成功21134847135
查看数据
{ "label": "adaptation-46", "inputs": { "environment_seed": 11, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, -0.035, 4 ] }, { "op": "wave", "args": [ 0.8, 0.13, 0.11, 2.1696793309977784 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, -0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 5, "digest": "ccacffc044d46bc8047e50542aaf10b28a68de02a9d472912996fbe30ebe01d2", "held_out_composition": true, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "3d54abf97c07d2645685cf856fec0267b0f372191fcb1fe6456879c54f9f0059", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 192, "excavation": 0, "sitework_occupied_cells": 198, "replaced_cells": 195, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "a167157c62c21831e4d05a4c0174c8b355f4b947b2b82736f613f944ba0f6293", "bearing_fill": 3 }, "blocks": 34847, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 5.88 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9183 }
adaptation-47建造成功31133681112
查看数据
{ "label": "adaptation-47", "inputs": { "environment_seed": 11, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, -0.035, 4 ] }, { "op": "wave", "args": [ 0.8, 0.13, 0.11, 2.1696793309977784 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, -0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 5, "digest": "ccacffc044d46bc8047e50542aaf10b28a68de02a9d472912996fbe30ebe01d2", "held_out_composition": true, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "329a9709ef91011e5afd2124ee72c071682e5ca5ee00ee91287876bf931315e8", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 73, "excavation": 0, "sitework_occupied_cells": 79, "replaced_cells": 76, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "a41f52908bd3bbebc2e2bc08214a90ebb86957304464ff536e155e09991c58ee", "bearing_fill": 2 }, "blocks": 33681, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 2.31 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.5774 }
adaptation-48建造成功01234533102
查看数据
{ "label": "adaptation-48", "inputs": { "environment_seed": 12, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 1.3321687906112092 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.035, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 5, "digest": "e4ac69d47cbe020b99a63996c2d154f16254095a539a9b3e62dfb8c67d621cf1", "held_out_composition": true, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "60dccf577e6407e4dba3e2d8c4b400d26add29707374fc270823046c2b52497a", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 137, "excavation": 0, "sitework_occupied_cells": 144, "replaced_cells": 141, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "1be5a9b8c5feaa4af98fb24ba60e9c025a55e2d0bc08e0393558a505a7949eeb", "bearing_fill": 3 }, "blocks": 34533, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.26 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8567 }
adaptation-49建造成功11234439102
查看数据
{ "label": "adaptation-49", "inputs": { "environment_seed": 12, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 1.3321687906112092 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.035, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 5, "digest": "e4ac69d47cbe020b99a63996c2d154f16254095a539a9b3e62dfb8c67d621cf1", "held_out_composition": true, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "b11bec519afb6eb4921baef6a87aaf1f440953ac04777c44b4154f14c22d47ba", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 137, "excavation": 0, "sitework_occupied_cells": 144, "replaced_cells": 141, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "1be5a9b8c5feaa4af98fb24ba60e9c025a55e2d0bc08e0393558a505a7949eeb", "bearing_fill": 3 }, "blocks": 34439, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.26 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.846 }
adaptation-50建造成功21234847135
查看数据
{ "label": "adaptation-50", "inputs": { "environment_seed": 12, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 1.3321687906112092 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.035, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 5, "digest": "e4ac69d47cbe020b99a63996c2d154f16254095a539a9b3e62dfb8c67d621cf1", "held_out_composition": true, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "f1e752937942b777a9178f7d3ebe40f5896c1bdb62c7b155ffdfec6c13e6e0f4", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 127, "excavation": 0, "sitework_occupied_cells": 134, "replaced_cells": 131, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "71ece5bfffae3449f4a5bf8070f22af12f848c50cc09a04c6aafd9eaed7ee5ad", "bearing_fill": 3 }, "blocks": 34847, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 3.96 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9168 }
adaptation-51建造成功31233681112
查看数据
{ "label": "adaptation-51", "inputs": { "environment_seed": 12, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.035, 4 ] }, { "op": "wave", "args": [ 0.4, 0.13, 0.11, 1.3321687906112092 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.035, 0, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 5, "digest": "e4ac69d47cbe020b99a63996c2d154f16254095a539a9b3e62dfb8c67d621cf1", "held_out_composition": true, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "70dbad7265709ecf9010a2f6a50c18ba343cfb3224b91a6332e63eb74ee1b425", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 68, "excavation": 0, "sitework_occupied_cells": 74, "replaced_cells": 71, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "c42b2e523f513d8eab2144419045d97dc9319033120906040c23c2d92a9cb5c0", "bearing_fill": 2 }, "blocks": 33681, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 2.16 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.5787 }
adaptation-52建造成功01331885102
查看数据
{ "label": "adaptation-52", "inputs": { "environment_seed": 13, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.045, 0, 4 ] }, { "op": "wave", "args": [ 0.8, 0.13, 0.11, 3.358718313814367 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": null, "digest": "0d5e960996b34fcec7d4b138113eb0cb25b7d2096636fd96b2fb104c0007d1ea", "held_out_composition": true, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "68e971fe6d9ca5303564ae1379241399ec5f7865465f7504d9191601dcd1a1cd", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 0, "excavation": 0, "sitework_occupied_cells": 6, "replaced_cells": 3, "new_sitework_cells": 3, "strategies": [ "stepped" ], "signature": "de4c2a6c9d2752a79195e3ff5b4929bca547a3d6c8ed5cfcab3f7f594e5a45f8", "bearing_fill": 0 }, "blocks": 31885, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.12 ], [ 1, 0.52 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.06 }
adaptation-53建造成功11331791102
查看数据
{ "label": "adaptation-53", "inputs": { "environment_seed": 13, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.045, 0, 4 ] }, { "op": "wave", "args": [ 0.8, 0.13, 0.11, 3.358718313814367 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": null, "digest": "0d5e960996b34fcec7d4b138113eb0cb25b7d2096636fd96b2fb104c0007d1ea", "held_out_composition": true, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "e54901c194bed72a9f2e58c4789487563dc166901e1dce2026ae25edfca130fa", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 0, "excavation": 0, "sitework_occupied_cells": 6, "replaced_cells": 3, "new_sitework_cells": 3, "strategies": [ "stepped" ], "signature": "de4c2a6c9d2752a79195e3ff5b4929bca547a3d6c8ed5cfcab3f7f594e5a45f8", "bearing_fill": 0 }, "blocks": 31791, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.12 ], [ 1, 0.52 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.0387 }
adaptation-54建造成功21332199135
查看数据
{ "label": "adaptation-54", "inputs": { "environment_seed": 13, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.045, 0, 4 ] }, { "op": "wave", "args": [ 0.8, 0.13, 0.11, 3.358718313814367 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": null, "digest": "0d5e960996b34fcec7d4b138113eb0cb25b7d2096636fd96b2fb104c0007d1ea", "held_out_composition": true, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "6c1a741347c1512d37adb07ba0d0175f746ecdf1aa166a452669198eec14698d", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 0, "excavation": 0, "sitework_occupied_cells": 6, "replaced_cells": 3, "new_sitework_cells": 3, "strategies": [ "stepped" ], "signature": "cca78d91e91dfd946f51e58967315f184d53ed2dd9fbddd7eb63cfff4b7c336d", "bearing_fill": 0 }, "blocks": 32199, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.12 ], [ 1, 0.52 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.1597 }
adaptation-55建造成功31331033112
查看数据
{ "label": "adaptation-55", "inputs": { "environment_seed": 13, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.045, 0, 4 ] }, { "op": "wave", "args": [ 0.8, 0.13, 0.11, 3.358718313814367 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": null, "digest": "0d5e960996b34fcec7d4b138113eb0cb25b7d2096636fd96b2fb104c0007d1ea", "held_out_composition": true, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "81abae86ef772b068ceea02fd4aeeacc0bcbe1f3d87a930a57f4ed8d285daed1", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 0, "excavation": 0, "sitework_occupied_cells": 6, "replaced_cells": 3, "new_sitework_cells": 3, "strategies": [ "stepped" ], "signature": "cf7b488deddbabdfc1cd4a449f672c728a32364891b571911cac52cb174eceeb", "bearing_fill": 0 }, "blocks": 31033, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.12 ], [ 1, 0.52 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8011 }
adaptation-56建造成功01434533102
查看数据
{ "label": "adaptation-56", "inputs": { "environment_seed": 14, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, -0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 2.046650951809069 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, -0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 5, "digest": "77dcc3135313f9633c0dd1c3b6b441f52c7d81e45a15a202ef075e29b912b9a0", "held_out_composition": true, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "be4a4089b1d44aa323735208699cb4f63ff4cc9496f6d2b81c5b0296af616b45", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 139, "excavation": 0, "sitework_occupied_cells": 145, "replaced_cells": 142, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "887e7748b1f79ecd0ee98a12d67b60f3c63be34e06ad70ad7126016c2b2e6c40", "bearing_fill": 3 }, "blocks": 34533, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.29 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8535 }
adaptation-57建造成功11434439102
查看数据
{ "label": "adaptation-57", "inputs": { "environment_seed": 14, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, -0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 2.046650951809069 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, -0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 5, "digest": "77dcc3135313f9633c0dd1c3b6b441f52c7d81e45a15a202ef075e29b912b9a0", "held_out_composition": true, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "ee80b18283c4bca9f68d51e0f018c0e2b609d122f0460d01a3d96a16eb01fe48", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 139, "excavation": 0, "sitework_occupied_cells": 145, "replaced_cells": 142, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "887e7748b1f79ecd0ee98a12d67b60f3c63be34e06ad70ad7126016c2b2e6c40", "bearing_fill": 3 }, "blocks": 34439, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 4.29 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8495 }
adaptation-58建造成功21434847135
查看数据
{ "label": "adaptation-58", "inputs": { "environment_seed": 14, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, -0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 2.046650951809069 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, -0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 5, "digest": "77dcc3135313f9633c0dd1c3b6b441f52c7d81e45a15a202ef075e29b912b9a0", "held_out_composition": true, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "a728d73309fa0ca3934bf7ae64063ed12f12d205ef514873af2e19e5fa38d312", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 196, "excavation": 0, "sitework_occupied_cells": 202, "replaced_cells": 199, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "5b4732dd893c1a7069699d43bcbf773e66ba8f678dd77c55b2ed6fea9eea064f", "bearing_fill": 3 }, "blocks": 34847, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 6.0 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9428 }
adaptation-59建造成功31433681112
查看数据
{ "label": "adaptation-59", "inputs": { "environment_seed": 14, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.045, -0.035, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 2.046650951809069 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, -0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 5, "digest": "77dcc3135313f9633c0dd1c3b6b441f52c7d81e45a15a202ef075e29b912b9a0", "held_out_composition": true, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "4b9782f4787dde426de1adaf546942a186a50ed4f4a3b8f2f1be25ee06d18694", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 72, "excavation": 0, "sitework_occupied_cells": 78, "replaced_cells": 75, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "dbd2fd0f8c36451be5cc4fcead2b839e9ccd25530145bf2fee9e81dc0da9a5d8", "bearing_fill": 2 }, "blocks": 33681, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 2.28 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.5812 }
adaptation-60建造成功01537644102
查看数据
{ "label": "adaptation-60", "inputs": { "environment_seed": 15, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.045, 0, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 1.7100020316024998 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 6, "digest": "f82bc80879581470cbb4ce26879ddb7913e0620bab298172dc517745febeb208", "held_out_composition": true, "client": "hillside_home", "structure_seed": 0 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "2f8a06a53921e6e43fb0e583fb8cc4e1db73773392e62a41b7a0c071cf1c74df", "principal_signature": "521584b411aa4548737e1fc6a22517d70814d30fd79ac0fd73afc854f134401c", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 27, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "0188cad230b6e118451ba1c3b9f68ceb609561adb9d943ea45134819ceac35b7" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40bf30695e2752c629650fd9997c18a1d805aa177d853ba6e41dab7e51f4f711" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 171, "excavation": 0, "sitework_occupied_cells": 180, "replaced_cells": 177, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "77ddf64f03612e253cc5de865007c416af79da3e9d2d923163c3e6a6783e75aa", "bearing_fill": 3 }, "blocks": 37644, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 5.34 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-quality/final/adaptation-60.litematic", "audit": { "queries": 94, "inventories": 16, "nodes": 102, "digest": "2f8a06a53921e6e43fb0e583fb8cc4e1db73773392e62a41b7a0c071cf1c74df" }, "seconds": 2.7739 }
adaptation-61建造成功11537550102
查看数据
{ "label": "adaptation-61", "inputs": { "environment_seed": 15, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.045, 0, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 1.7100020316024998 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 6, "digest": "f82bc80879581470cbb4ce26879ddb7913e0620bab298172dc517745febeb208", "held_out_composition": true, "client": "hillside_home", "structure_seed": 1 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "557207d9f45cafdac8e254707daffcf894a52e4707e1da7e0bc2b6429957e67f", "principal_signature": "a46cc2ef2413dd7bca9eafbcf81b98ce7fe98f68d27108bb66a439ea7ab79e37", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 13 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 25, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "7963cf6d356ea0e339c40031804a5d79794c524f36387681a16d4c7f54fb4378" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "3a3c9dd9e4423eabf621c34dffc38f9800bf28acfdb0c5376ce6798d615936ac" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.kitchen", [ "west" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ] ] ], "contact": { "fill": 171, "excavation": 0, "sitework_occupied_cells": 180, "replaced_cells": 177, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "77ddf64f03612e253cc5de865007c416af79da3e9d2d923163c3e6a6783e75aa", "bearing_fill": 3 }, "blocks": 37550, "nodes": 102, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 5.34 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8733 }
adaptation-62建造成功21537958135
查看数据
{ "label": "adaptation-62", "inputs": { "environment_seed": 15, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.045, 0, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 1.7100020316024998 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 6, "digest": "f82bc80879581470cbb4ce26879ddb7913e0620bab298172dc517745febeb208", "held_out_composition": true, "client": "gabled_hall", "structure_seed": 2 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "1e750dfb1661bdd3c215bbc9148cf8c31f04612377bc6eba3c26e2344021c3fd", "principal_signature": "8fa981fd08a463935d790214c5dd5fb90e4775f60d9cbf58a3456c4079d21e71", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 26, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 14, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 14, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "51acf0c8d5cc6546f256efbd213726a9d83abceaa48a6002174adfb40913699e" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "189fd63f62d5435efd2ae802196cec66d7579be58d9c2169ed640316422b2253" ], [ "roof.profile", [ 11, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "80fc0aba16abd05a8b931073af75b5acb625dae23cdd72f667e401b794c8aeb8" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 11 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 194, "excavation": 0, "sitework_occupied_cells": 203, "replaced_cells": 200, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "43c3a98967e60b496e922054cab08dcb03fd7e41aeb371700e3f3d0b205f128b", "bearing_fill": 3 }, "blocks": 37958, "nodes": 135, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 6.03 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9408 }
adaptation-63建造成功31536792112
查看数据
{ "label": "adaptation-63", "inputs": { "environment_seed": 15, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.045, 0, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.11, 1.7100020316024998 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.045, 4 ] }, { "op": "wave", "args": [ 0.6, 0.07, 0.19, 0 ] } ] }, { "op": "transform", "args": [ { "op": "radial", "args": [ 8, 9, 28, 0.7 ] }, 2, -1, 1.2 ] } ] }, 2, 7 ] }, "water": 6, "digest": "f82bc80879581470cbb4ce26879ddb7913e0620bab298172dc517745febeb208", "held_out_composition": true, "client": "high_house", "structure_seed": 3 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "35b36b07c77d6dbc724aa451dba9e40923ce7041a95dcb62ec292bd2ca2da511", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 100, "excavation": 0, "sitework_occupied_cells": 109, "replaced_cells": 106, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "95edffec9060ec4257c02fe543b9403c74cc5407e9f79a69b92073cfea38130c", "bearing_fill": 2 }, "blocks": 36792, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 3.21 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.599 }
stress-00建造成功0200036328112
查看数据
{ "label": "stress-00", "inputs": { "environment_seed": 2000, "structure_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, -0.15, 4 ] }, { "op": "wave", "args": [ 2, 0.13, 0.17, 5.127977154011788 ] } ] }, -2, 20 ] }, "water": 5, "frozen_digest": "9ad307ab5cf5fbf4db3cfc9fa45a5f50b483d215ad4a42f984ad1286e015fbad" }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "d4338df1125549498f72547d9215e4f440cd3b3b1a144fda5bdc023e641b22ea", "principal_signature": "7564b878a6e96240b3a2337df191020a4be80837cad2ebe3950ffe6fe517421e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "north" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 105, "excavation": 0, "sitework_occupied_cells": 114, "replaced_cells": 68, "new_sitework_cells": 46, "strategies": [ "piers" ], "signature": "0b02fdd059836fbd48e2ed843053aa1b3b77b7a87fdfe1f52142f05fba426334", "bearing_fill": 2 }, "blocks": 36328, "nodes": 112, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 2.5 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.616 }
stress-01建造成功1200140687149
查看数据
{ "label": "stress-01", "inputs": { "environment_seed": 2001, "structure_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.2, 4 ] }, { "op": "wave", "args": [ 2, 0.13, 0.17, 2.3640698433630662 ] } ] }, -2, 20 ] }, "water": 5, "frozen_digest": "a3567f8be4b9afbd21fb0c37b63993ef05d6c4cfa909193257f234bf348e913e" }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "c58037af1a6ae302ad56b4faec0dd4a35333a99e69a925bf2f8c9b5b5ecd6de5", "principal_signature": "8b31d9fc1f3cc8d6cab158826fa3944a0437a3efda503207d5200023c410e6f7", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 11 ], { "height": 32, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 10, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 21, 14, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 11, "rise": [ 2, 1 ] }, "dabd215d7edac1cd125e7d085d50279a9cad1db2ac5e82cbccd509abec387d4a" ], [ "roof.profile", [ 11, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 2, 1 ] }, "8430ff95b5f3f28f966e2a97809a81a016bdba29022daf004b99357bfb87aa16" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 0, 6, 0 ], "room.library", [ "east" ], true, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 6, 0 ], "room.workshop", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 143, "excavation": 0, "sitework_occupied_cells": 186, "replaced_cells": 71, "new_sitework_cells": 115, "strategies": [ "piers" ], "signature": "68ee46a2367b84bba9543fbdc23183c2de256820f703896798c04eb031dcc9ab", "bearing_fill": 2 }, "blocks": 40687, "nodes": 149, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 3.28 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.855 }
stress-02拒绝建造:地面高差超限22002——
查看数据
{ "label": "stress-02", "inputs": { "environment_seed": 2002, "structure_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.45, -0.15, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.17, 4.736375910500318 ] } ] }, -2, 20 ] }, "water": null, "frozen_digest": "8a9a6b3dede9cffa0ce8cf580ecf4e17119eaf98871e1cd49cf89262677e75cc" }, "attempts": 2, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": "site-relief: /building at None: All declared alternatives violate the same condition: site-relief: /building at (0, 0, 0): Measured 11, permitted 5", "candidates": [ { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 11, permitted 5" }, { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 11, permitted 5" } ], "seconds": 0.3312 }
stress-03拒绝建造:地面高差超限32003——
查看数据
{ "label": "stress-03", "inputs": { "environment_seed": 2003, "structure_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.45, 0.2, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.17, 5.447432368230461 ] } ] }, -2, 20 ] }, "water": 5, "frozen_digest": "29fc26399b0927a831fc9da20bdf5168727e93465df879236c18b41aace18793" }, "attempts": 2, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": "site-relief: /building at None: All declared alternatives violate the same condition: site-relief: /building at (0, 0, 0): Measured 10, permitted 5", "candidates": [ { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 10, permitted 5" }, { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 10, permitted 5" } ], "seconds": 0.2334 }
stress-04建造成功4200436584111
查看数据
{ "label": "stress-04", "inputs": { "environment_seed": 2004, "structure_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, 0, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.17, 4.272017841902214 ] } ] }, -2, 20 ] }, "water": 5, "frozen_digest": "e9a2a6807f75e575207c68a363c4c36cb967edc427fea7153f56de3e900ef743" }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "d87a1b1dbb14fefd6fa4619ae78984d8af49eda6c211997cadf5a86b7a90d606", "principal_signature": "c996f1a3124234c7c03a93f7a8c50e7477a43fee099e552bcd057d8c0a3bba40", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 74, "excavation": 0, "sitework_occupied_cells": 89, "replaced_cells": 35, "new_sitework_cells": 54, "strategies": [ "piers" ], "signature": "6459ab7d5e112519fae87e4102ba3cc626009456023480cd5fe22a770405cdd6", "bearing_fill": 2 }, "blocks": 36584, "nodes": 111, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 1.59 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.5963 }
stress-05拒绝建造:地面高差超限52005——
查看数据
{ "label": "stress-05", "inputs": { "environment_seed": 2005, "structure_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.45, 0, 4 ] }, { "op": "wave", "args": [ 5, 0.13, 0.17, 3.1088324431440615 ] } ] }, -2, 20 ] }, "water": 12, "frozen_digest": "8877ea50dbfa8c51420669384be8320703e1391d3222f8d3f60b65cf20480b81" }, "attempts": 2, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": "site-relief: /building at None: All declared alternatives violate the same condition: site-relief: /building at (0, 0, 0): Measured 12, permitted 5", "candidates": [ { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 12, permitted 5" }, { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 12, permitted 5" } ], "seconds": 0.2255 }
stress-06拒绝建造:地面高差超限62006——
查看数据
{ "label": "stress-06", "inputs": { "environment_seed": 2006, "structure_seed": 6, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, -0.15, 4 ] }, { "op": "wave", "args": [ 5, 0.13, 0.17, 2.606113206720962 ] } ] }, -2, 20 ] }, "water": 12, "frozen_digest": "21d73695147e70be6f550b550ed894af73916c4cd2b57a79b9677ee358246a1e" }, "attempts": 2, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": "site-relief: /building at None: All declared alternatives violate the same condition: site-relief: /building at (0, 0, 0): Measured 10, permitted 5", "candidates": [ { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 10, permitted 5" }, { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 10, permitted 5" } ], "seconds": 0.3246 }
stress-07拒绝建造:地面高差超限72007——
查看数据
{ "label": "stress-07", "inputs": { "environment_seed": 2007, "structure_seed": 7, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.45, 0.2, 4 ] }, { "op": "wave", "args": [ 5, 0.13, 0.17, 0.7106689799805972 ] } ] }, -2, 20 ] }, "water": 12, "frozen_digest": "28a4417c18feb041b11ede6c0d08925af7b866e4fd6d683da63cb4ed9ece8ef6" }, "attempts": 2, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": "site-relief: /building at None: All declared alternatives violate the same condition: site-relief: /building at (0, 0, 0): Measured 8, permitted 5", "candidates": [ { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 8, permitted 5" }, { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 8, permitted 5" } ], "seconds": 0.2251 }
stress-08拒绝建造:地面高差超限02008——
查看数据
{ "label": "stress-08", "inputs": { "environment_seed": 2008, "structure_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.2, 4 ] }, { "op": "wave", "args": [ 5, 0.13, 0.17, 5.3468683245721005 ] } ] }, -2, 20 ] }, "water": 12, "frozen_digest": "e5d9b98db3b96f9ee8e74e7918e5007c11ea13f16cb47f39dd735c66081a6c26" }, "attempts": 2, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": "site-relief: /building at None: All declared alternatives violate the same condition: site-relief: /building at (0, 0, 0): Measured 10, permitted 5", "candidates": [ { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 10, permitted 5" }, { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 10, permitted 5" } ], "seconds": 0.2326 }
stress-09拒绝建造:地面高差超限12009——
查看数据
{ "label": "stress-09", "inputs": { "environment_seed": 2009, "structure_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, -0.15, 4 ] }, { "op": "wave", "args": [ 2, 0.13, 0.17, 4.043361591583398 ] } ] }, -2, 20 ] }, "water": 5, "frozen_digest": "615d19fcdb8adbdf2b33dfcc2b75d9f094d33985b6c79502c17dd8832595845d" }, "attempts": 2, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": "site-relief: /building at None: All declared alternatives violate the same condition: site-relief: /building at (0, 0, 0): Measured 8, permitted 5", "candidates": [ { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 8, permitted 5" }, { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 8, permitted 5" } ], "seconds": 0.3328 }
stress-10拒绝建造:地面高差超限22010——
查看数据
{ "label": "stress-10", "inputs": { "environment_seed": 2010, "structure_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.45, 0.2, 4 ] }, { "op": "wave", "args": [ 5, 0.13, 0.17, 1.458550053272991 ] } ] }, -2, 20 ] }, "water": 5, "frozen_digest": "865249ffe712abf4e3dda38e3a1b5dff57217b1532e111f2483de0b8e89136a2" }, "attempts": 2, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": "site-relief: /building at None: All declared alternatives violate the same condition: site-relief: /building at (0, 0, 0): Measured 19, permitted 5", "candidates": [ { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 19, permitted 5" }, { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 19, permitted 5" } ], "seconds": 0.3328 }
stress-11拒绝建造:地面高差超限32011——
查看数据
{ "label": "stress-11", "inputs": { "environment_seed": 2011, "structure_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.45, -0.15, 4 ] }, { "op": "wave", "args": [ 5, 0.13, 0.17, 3.7543484663529205 ] } ] }, -2, 20 ] }, "water": null, "frozen_digest": "314661e574d4aebd3c0cc8423d70a545e6c5a8eb883ca4d1f7fd4b9eadd07761" }, "attempts": 2, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": "site-relief: /building at None: All declared alternatives violate the same condition: site-relief: /building at (0, 0, 0): Measured 12, permitted 5", "candidates": [ { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 12, permitted 5" }, { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 12, permitted 5" } ], "seconds": 0.2317 }
stress-12建造成功4201236387111
查看数据
{ "label": "stress-12", "inputs": { "environment_seed": 2012, "structure_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, -0.15, 4 ] }, { "op": "wave", "args": [ 2, 0.13, 0.17, 2.959681125591585 ] } ] }, -2, 20 ] }, "water": 5, "frozen_digest": "fc37d1e7029d8b49c5f4de51b065bb697522eae61dcd79cdbd2f0cae05ff945f" }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "7812dedfff5034f0c363aa059ebbcf229351f136b834fc1a300b0111061edd1c", "principal_signature": "c996f1a3124234c7c03a93f7a8c50e7477a43fee099e552bcd057d8c0a3bba40", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 7, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 116, "excavation": 0, "sitework_occupied_cells": 137, "replaced_cells": 48, "new_sitework_cells": 89, "strategies": [ "piers" ], "signature": "a23b14e480bd5a0e078e6518644c3c5bdd288b1708bd40cc208e003b16dedb95", "bearing_fill": 2 }, "blocks": 36387, "nodes": 111, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 2.33 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.8195 }
stress-13拒绝建造:地面高差超限52013——
查看数据
{ "label": "stress-13", "inputs": { "environment_seed": 2013, "structure_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, 0.2, 4 ] }, { "op": "wave", "args": [ 2, 0.13, 0.17, 4.2240852806150215 ] } ] }, -2, 20 ] }, "water": 5, "frozen_digest": "bc801b42ce458c6e30d68c3c3275f845970155af257a0788a9229b877741b552" }, "attempts": 2, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": "site-relief: /building at None: All declared alternatives violate the same condition: site-relief: /building at (0, 0, 0): Measured 6, permitted 5", "candidates": [ { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 6, permitted 5" }, { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 6, permitted 5" } ], "seconds": 0.2517 }
stress-14建造成功6201435485125
查看数据
{ "label": "stress-14", "inputs": { "environment_seed": 2014, "structure_seed": 6, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, 0, 4 ] }, { "op": "wave", "args": [ 0, 0.13, 0.17, 3.926160249756597 ] } ] }, -2, 20 ] }, "water": null, "frozen_digest": "160a6c1d3cc88171e6eef7e0f8fe94fb63ee95550a3a2c46a24f3f5169d3baca" }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "03237810f7b7dd186d7530f3a8f26aceefff2a6fc970a1a7422120c34dc2cf34", "principal_signature": "9a4fa8463af657108769cfbcbf7e8f4fa7c9c6dad084be23b3e4dd5a891fa9fb", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 11 ], { "height": 32, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 10, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 21, 8, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 11, "rise": [ 2, 1 ] }, "dabd215d7edac1cd125e7d085d50279a9cad1db2ac5e82cbccd509abec387d4a" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "z", "span": 11, "rise": [ 2, 1 ] }, "8430ff95b5f3f28f966e2a97809a81a016bdba29022daf004b99357bfb87aa16" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 0, 6, 0 ], "room.library", [], true, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.kitchen", [ "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 78, "excavation": 0, "sitework_occupied_cells": 99, "replaced_cells": 3, "new_sitework_cells": 96, "strategies": [ "piers" ], "signature": "2aa6e3c2f5272ca25ac3e72b1e8c4570869b4b5dec2774a7dc32e7a45cba1a27", "bearing_fill": 2 }, "blocks": 35485, "nodes": 125, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.05 ], [ 0, 1.29 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 1.0391 }
stress-15拒绝建造:地面高差超限72015——
查看数据
{ "label": "stress-15", "inputs": { "environment_seed": 2015, "structure_seed": 7, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, 0, 4 ] }, { "op": "wave", "args": [ 2, 0.13, 0.17, 4.890932098229982 ] } ] }, -2, 20 ] }, "water": null, "frozen_digest": "8431cc1fbd03d1ac77af7e10981e3ff326545e7db7185f065c56843055ed1be1" }, "attempts": 2, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": "site-relief: /building at None: All declared alternatives violate the same condition: site-relief: /building at (0, 0, 0): Measured 8, permitted 5", "candidates": [ { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 8, permitted 5" }, { "rule": "site-relief", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Measured 8, permitted 5" } ], "seconds": 0.2447 }
0-high_house-5建造成功5300034019133
查看数据
{ "label": "0-high_house-5", "inputs": { "environment_seed": 3000, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.04, 0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 3.9604651402756024 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "29bcb08f41366f7d80aaf01074172db2ee52a37799aa5e811bbbc041d7677451", "client": "high_house", "structure_seed": 5 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "f47af3460430ad72da1266df6f98dabd99ef4ea73889bfc34866b6bea795c50f", "principal_signature": "ee761a9f3137e7db3859e62b8864d9ff848f4f34bcc65c70eb7082ec1d542a0a", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 14, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 13, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "east" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 6, 0 ], "room.workshop", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 50, "excavation": 0, "sitework_occupied_cells": 56, "replaced_cells": 53, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "3ad242d8fc64f9d1c01c3e58537b80508c02bef6a4461625bb85df49160b4170", "bearing_fill": 2 }, "blocks": 34019, "nodes": 133, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 1.62 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-quality/holdout/0-high_house-5.litematic", "audit": { "queries": 123, "inventories": 26, "nodes": 133, "digest": "f47af3460430ad72da1266df6f98dabd99ef4ea73889bfc34866b6bea795c50f" }, "seconds": 2.7403 }
0-gabled_hall-7建造成功7300035291154
查看数据
{ "label": "0-gabled_hall-7", "inputs": { "environment_seed": 3000, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.04, 0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 3.9604651402756024 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "29bcb08f41366f7d80aaf01074172db2ee52a37799aa5e811bbbc041d7677451", "client": "gabled_hall", "structure_seed": 7 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "346a6137405175dd0afb518bfae9a96dfe884f014814bde12092558dd5926210", "principal_signature": "60e929f4b5b066c96ca35111abd162a9541648eb82a123bb9d69de58154e672e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "8e9c7c26e445b0f1b4db089dc5d7ada41eb6147a9bd849a6946458e6eebe4f99" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "d4f853a881c8d0ef6771db722649eb1b6ba443473d52cab8060a84954e076b72" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "north", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 128, "excavation": 0, "sitework_occupied_cells": 134, "replaced_cells": 131, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "57fd9eea3b5b9d306a265083e16e61b79a37b474ef943735407c5f5e08dc7c5a", "bearing_fill": 3 }, "blocks": 35291, "nodes": 154, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 3.96 ] ], "chosen": 1 } ], "optional_omissions": [], "artifact": "samples/building-quality/holdout/0-gabled_hall-7.litematic", "audit": { "queries": 145, "inventories": 32, "nodes": 154, "digest": "346a6137405175dd0afb518bfae9a96dfe884f014814bde12092558dd5926210" }, "seconds": 2.8523 }
1-high_house-5建造成功5300137130133
查看数据
{ "label": "1-high_house-5", "inputs": { "environment_seed": 3001, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, -0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 4.560197649098296 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 6, "digest": "3fd3038ceb1872c8e7716c435791b06e79085c1c4aed0b9542186adf165f4b1f", "client": "high_house", "structure_seed": 5 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "b610607b3881e087e901681e4c6966f0ec271ae405397b792b1dec836694f0a6", "principal_signature": "ee761a9f3137e7db3859e62b8864d9ff848f4f34bcc65c70eb7082ec1d542a0a", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 14, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 13, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "east" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 6, 0 ], "room.workshop", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 96, "excavation": 0, "sitework_occupied_cells": 105, "replaced_cells": 102, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "1490da7746ba07c9995e60f09372a1b8b622c639b117f632166185908a8fa981", "bearing_fill": 2 }, "blocks": 37130, "nodes": 133, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 3.09 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.6684 }
1-gabled_hall-7建造成功7300138402154
查看数据
{ "label": "1-gabled_hall-7", "inputs": { "environment_seed": 3001, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, -0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 4.560197649098296 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 6, "digest": "3fd3038ceb1872c8e7716c435791b06e79085c1c4aed0b9542186adf165f4b1f", "client": "gabled_hall", "structure_seed": 7 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "51bf34068399412448b0a4c20a08afe6bbe1e023ec87af927ea51d151ac51de5", "principal_signature": "60e929f4b5b066c96ca35111abd162a9541648eb82a123bb9d69de58154e672e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "8e9c7c26e445b0f1b4db089dc5d7ada41eb6147a9bd849a6946458e6eebe4f99" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "d4f853a881c8d0ef6771db722649eb1b6ba443473d52cab8060a84954e076b72" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "north", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 257, "excavation": 0, "sitework_occupied_cells": 266, "replaced_cells": 263, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "3813e9b636a13a3f2da2abd773ad47f9f3a68b073011755dbf91599013a66edc", "bearing_fill": 3 }, "blocks": 38402, "nodes": 154, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 7.92 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.1057 }
2-high_house-5建造成功5300234190133
查看数据
{ "label": "2-high_house-5", "inputs": { "environment_seed": 3002, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.04, 0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 3.2115633617859816 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "33442db94e6d5b9d442150ef3f6b16e36070ec38d493053650d966eb240de1d0", "client": "high_house", "structure_seed": 5 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "e087f9951cec7410da876ffb12b11dfb13b13c59e8766ea11387eafd262f914e", "principal_signature": "ee761a9f3137e7db3859e62b8864d9ff848f4f34bcc65c70eb7082ec1d542a0a", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 14, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 13, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "east" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 6, 0 ], "room.workshop", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 49, "excavation": 0, "sitework_occupied_cells": 55, "replaced_cells": 52, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "cf482cf1f74c6f70fa789f3a72d852d64ccfe6e503265084da3d625c9f94fa01", "bearing_fill": 2 }, "blocks": 34190, "nodes": 133, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 1.59 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.6141 }
2-gabled_hall-7建造成功7300235462154
查看数据
{ "label": "2-gabled_hall-7", "inputs": { "environment_seed": 3002, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.04, 0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 3.2115633617859816 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "33442db94e6d5b9d442150ef3f6b16e36070ec38d493053650d966eb240de1d0", "client": "gabled_hall", "structure_seed": 7 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "8d77c53069ddcd7863d691ea680d42d55c63e85d38e4fa4cae23cc736a9d4679", "principal_signature": "60e929f4b5b066c96ca35111abd162a9541648eb82a123bb9d69de58154e672e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "8e9c7c26e445b0f1b4db089dc5d7ada41eb6147a9bd849a6946458e6eebe4f99" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "d4f853a881c8d0ef6771db722649eb1b6ba443473d52cab8060a84954e076b72" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "north", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 101, "excavation": 0, "sitework_occupied_cells": 107, "replaced_cells": 104, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "1e4598ef6c6b33e9a6bac7a3fb0b9e5acbf02743150f73473289728965e5a922", "bearing_fill": 3 }, "blocks": 35462, "nodes": 154, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 3.15 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.0784 }
3-high_house-5建造成功5300334019133
查看数据
{ "label": "3-high_house-5", "inputs": { "environment_seed": 3003, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 2.008807956041616 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "a4f3dd3069448018ce63ab0b8a26423676f170b58b4cfe956dd9249416b3fb2e", "client": "high_house", "structure_seed": 5 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "f01096c2803d916f343b19a7a6afb92c367d337b338603357f5137f004cd66e7", "principal_signature": "ee761a9f3137e7db3859e62b8864d9ff848f4f34bcc65c70eb7082ec1d542a0a", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 14, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 13, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "east" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 6, 0 ], "room.workshop", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 49, "excavation": 0, "sitework_occupied_cells": 55, "replaced_cells": 52, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "cf482cf1f74c6f70fa789f3a72d852d64ccfe6e503265084da3d625c9f94fa01", "bearing_fill": 2 }, "blocks": 34019, "nodes": 133, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 1.59 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.6097 }
3-gabled_hall-7建造成功7300335291154
查看数据
{ "label": "3-gabled_hall-7", "inputs": { "environment_seed": 3003, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 2.008807956041616 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "a4f3dd3069448018ce63ab0b8a26423676f170b58b4cfe956dd9249416b3fb2e", "client": "gabled_hall", "structure_seed": 7 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "788dc0367ad06302822d1ee493c0de5f1f66c8e9f67f17e14d8d79ede292d3fc", "principal_signature": "60e929f4b5b066c96ca35111abd162a9541648eb82a123bb9d69de58154e672e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "8e9c7c26e445b0f1b4db089dc5d7ada41eb6147a9bd849a6946458e6eebe4f99" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "d4f853a881c8d0ef6771db722649eb1b6ba443473d52cab8060a84954e076b72" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "north", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 117, "excavation": 0, "sitework_occupied_cells": 126, "replaced_cells": 123, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "d047c98ac75832f2f22e1a9321846f4ca6315bcbca42d0edd97c7a718be69018", "bearing_fill": 3 }, "blocks": 35291, "nodes": 154, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 3.72 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.0833 }
4-high_house-5建造成功5300434019133
查看数据
{ "label": "4-high_house-5", "inputs": { "environment_seed": 3004, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.04, -0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 4.568642839893792 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "a7007273bd822f246d872eb3545016d88225df2d3590c972f7c6e8335d7a8f64", "client": "high_house", "structure_seed": 5 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "7c470bbd0cc4be8c4b114cfed46edf186264ff5e75fe8654b299d7f2a1edd581", "principal_signature": "ee761a9f3137e7db3859e62b8864d9ff848f4f34bcc65c70eb7082ec1d542a0a", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 14, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 13, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "east" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 6, 0 ], "room.workshop", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 53, "excavation": 0, "sitework_occupied_cells": 59, "replaced_cells": 56, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "273a9de1bed16fce2b72a6d27acc254655315360401dae5115b27e39c8fe1ad6", "bearing_fill": 2 }, "blocks": 34019, "nodes": 133, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 1.71 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.638 }
4-gabled_hall-7建造成功7300435291154
查看数据
{ "label": "4-gabled_hall-7", "inputs": { "environment_seed": 3004, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.04, -0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 4.568642839893792 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "a7007273bd822f246d872eb3545016d88225df2d3590c972f7c6e8335d7a8f64", "client": "gabled_hall", "structure_seed": 7 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "3e9625b11230151a1ac6826b86b13178d59a040d38abe6686f2dac1684775836", "principal_signature": "60e929f4b5b066c96ca35111abd162a9541648eb82a123bb9d69de58154e672e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "8e9c7c26e445b0f1b4db089dc5d7ada41eb6147a9bd849a6946458e6eebe4f99" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "d4f853a881c8d0ef6771db722649eb1b6ba443473d52cab8060a84954e076b72" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "north", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 178, "excavation": 0, "sitework_occupied_cells": 184, "replaced_cells": 181, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "d10e7e4935f1d3917e0aa0b917aad838a2a7a8b33e54155af32bc5e73c9b3fc1", "bearing_fill": 3 }, "blocks": 35291, "nodes": 154, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 5.46 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.0823 }
5-high_house-5建造成功5300534019133
查看数据
{ "label": "5-high_house-5", "inputs": { "environment_seed": 3005, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.04, -0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 4.214052939583466 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "f9063ca9ea89bddc647f483aca6259fbc63ffab882ff90572bf48a44d6d8107e", "client": "high_house", "structure_seed": 5 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "6677e7d57280b7ba7d694e61223f2afac77b19562aca6d0e4428a27ab70853c7", "principal_signature": "ee761a9f3137e7db3859e62b8864d9ff848f4f34bcc65c70eb7082ec1d542a0a", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 14, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 13, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "east" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 6, 0 ], "room.workshop", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 53, "excavation": 0, "sitework_occupied_cells": 59, "replaced_cells": 56, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "273a9de1bed16fce2b72a6d27acc254655315360401dae5115b27e39c8fe1ad6", "bearing_fill": 2 }, "blocks": 34019, "nodes": 133, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 1.71 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.6077 }
5-gabled_hall-7建造成功7300535291154
查看数据
{ "label": "5-gabled_hall-7", "inputs": { "environment_seed": 3005, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.04, -0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 4.214052939583466 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "f9063ca9ea89bddc647f483aca6259fbc63ffab882ff90572bf48a44d6d8107e", "client": "gabled_hall", "structure_seed": 7 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "3d41ee832307e9828da8d48f83c16a04fedbff59fd10c7628d07c9019331c039", "principal_signature": "60e929f4b5b066c96ca35111abd162a9541648eb82a123bb9d69de58154e672e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "8e9c7c26e445b0f1b4db089dc5d7ada41eb6147a9bd849a6946458e6eebe4f99" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "d4f853a881c8d0ef6771db722649eb1b6ba443473d52cab8060a84954e076b72" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "north", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 176, "excavation": 0, "sitework_occupied_cells": 182, "replaced_cells": 179, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "c464711a3d6366c861ca0635c0506d2b38d2eccf850d5a1a650db977777eb2c6", "bearing_fill": 3 }, "blocks": 35291, "nodes": 154, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 5.4 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.0806 }
6-high_house-5建造成功5300634019133
查看数据
{ "label": "6-high_house-5", "inputs": { "environment_seed": 3006, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 0.38624098499448767 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "5d26de5bff946ce2c1e069f22c997c123a26fbb40339bcb2a8b02a3d44dc9673", "client": "high_house", "structure_seed": 5 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "8098caff29f2dc81c7e50de250f73e606422265540e9ae5824a59d908fb8b686", "principal_signature": "ee761a9f3137e7db3859e62b8864d9ff848f4f34bcc65c70eb7082ec1d542a0a", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 14, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 13, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "east" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 6, 0 ], "room.workshop", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 49, "excavation": 0, "sitework_occupied_cells": 55, "replaced_cells": 52, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "cf482cf1f74c6f70fa789f3a72d852d64ccfe6e503265084da3d625c9f94fa01", "bearing_fill": 2 }, "blocks": 34019, "nodes": 133, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 1.59 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.6069 }
6-gabled_hall-7建造成功7300635291154
查看数据
{ "label": "6-gabled_hall-7", "inputs": { "environment_seed": 3006, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 0.38624098499448767 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "5d26de5bff946ce2c1e069f22c997c123a26fbb40339bcb2a8b02a3d44dc9673", "client": "gabled_hall", "structure_seed": 7 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "69b2c886a0427528d977f313a29d8d5eabee969aeb7c6dfb9b37aa73ea567323", "principal_signature": "60e929f4b5b066c96ca35111abd162a9541648eb82a123bb9d69de58154e672e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "8e9c7c26e445b0f1b4db089dc5d7ada41eb6147a9bd849a6946458e6eebe4f99" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "d4f853a881c8d0ef6771db722649eb1b6ba443473d52cab8060a84954e076b72" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "north", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 116, "excavation": 0, "sitework_occupied_cells": 122, "replaced_cells": 119, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "2c89062acf3e90088f4fd7e47b2e0fe05f6f023dee16b93e6ab0fb078784f5e5", "bearing_fill": 3 }, "blocks": 35291, "nodes": 154, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 3.6 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.1052 }
7-high_house-5建造成功5300734019133
查看数据
{ "label": "7-high_house-5", "inputs": { "environment_seed": 3007, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.04, -0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 3.076591304124151 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "eb2445f2e618f9e63ecfba38198ff96f1451730ec034add72bf4c2f0463ae97d", "client": "high_house", "structure_seed": 5 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "02050a63c3f14062e2b4a27c4f27304fee1726966ef4145772f2679f7abe55b7", "principal_signature": "ee761a9f3137e7db3859e62b8864d9ff848f4f34bcc65c70eb7082ec1d542a0a", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 9 } ], [ "masonry.chimney", [ 3, 0, 9 ], { "height": 31, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 20, 6 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 17, 14, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.dormer", [ 8, 20, 2 ], { "tops": [ 5, 5, 5 ] }, "8cba8fa3e9a72ff63b980d2ef663695210ef851504ea42903bf9b38c149a5c2b" ], [ "roof.profile", [ 0, 19, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "d824b8e6570be4e050d7f2b5c2ad812f6176c39ae1d1430e9f886f46294c0465" ], [ "roof.profile", [ 9, 13, 0 ], { "axis": "z", "span": 9, "rise": [ 2, 1 ] }, "f0908e86950942bde6bb5286575a5e0c0465ca781d7a3758eb34f7f9bd79b980" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "east" ], true, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 0, 12, 0 ], "room.bedroom", [], false, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 0, 6, 0 ], "room.library", [ "east" ], true, "f40b714da9dc38d2cc7b647ce7a15d6fbfeb627b6255edfdee0690662e7ba81f" ], [ "room", [ 9, 0, 0 ], "room.kitchen", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ], [ "room", [ 9, 6, 0 ], "room.workshop", [ "west" ], false, "1a87adcdab17411140e351219c2dedb4072716c712d3e00e0ec33c116b7124e1" ] ] ], "contact": { "fill": 49, "excavation": 0, "sitework_occupied_cells": 55, "replaced_cells": 52, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "cf482cf1f74c6f70fa789f3a72d852d64ccfe6e503265084da3d625c9f94fa01", "bearing_fill": 2 }, "blocks": 34019, "nodes": 133, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 1.59 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.6112 }
7-gabled_hall-7建造成功7300735291154
查看数据
{ "label": "7-gabled_hall-7", "inputs": { "environment_seed": 3007, "expression": { "op": "clamp", "args": [ { "op": "transform", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.04, -0.03, 4 ] }, { "op": "wave", "args": [ 0.35, 0.17, 0.05, 3.076591304124151 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.03, 4 ] }, { "op": "radial", "args": [ 13, 10, 25, 0.7 ] } ] }, { "op": "radial", "args": [ 5, 8, 32, 0.8 ] } ] }, 2, -3, 1.1 ] }, 2, 7 ] }, "water": 5, "digest": "eb2445f2e618f9e63ecfba38198ff96f1451730ec034add72bf4c2f0463ae97d", "client": "gabled_hall", "structure_seed": 7 }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "c84305ea16e834e1de4517eb565530bd52826e194033f7cf2ca6ef28e8fc1015", "principal_signature": "60e929f4b5b066c96ca35111abd162a9541648eb82a123bb9d69de58154e672e", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 5, "width": 11 } ], [ "masonry.chimney", [ 4, 0, 22 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 13, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 16, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 2, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 20, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 6, 8, 21 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 9, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "8e9c7c26e445b0f1b4db089dc5d7ada41eb6147a9bd849a6946458e6eebe4f99" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "d4f853a881c8d0ef6771db722649eb1b6ba443473d52cab8060a84954e076b72" ], [ "room", [ 0, 0, 0 ], "room.library", [ "north", "south", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.living", [ "north", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 11, 0, 11 ], "room.kitchen", [ "north", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 169, "excavation": 0, "sitework_occupied_cells": 175, "replaced_cells": 172, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "297a695a9e3681e75cfc990fac116273fb1fcaa2893f595683cbe9869b1aeaaf", "bearing_fill": 3 }, "blocks": 35291, "nodes": 154, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 1, "rejected": [ { "rule": "contact-strategy", "component": "/building", "position": [ 0, 0, 0 ], "conditions": "Requested strategy incompatible with measured water/relief" } ], "scores": [ [ 1, 5.19 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.0854 }

成功后还选了 15 组完整建筑文件做保存检查:比较 2,265 个部件节点,查询 2,017 个有方块的部件,核对 314 个带物品数据的方块。默认五栋村落另有一次完整检查,共 908 个部件、868 次非空部件查询、88 个带物品数据的方块。检查对象有选择,不声称每个随机结果都已审查。默认结果核对。

08 · 真实错误出在哪一层

这轮最值得追查的是烟囱支撑问题。早期报告把一些尝试标成“搜索额度用完”,但继续读里面的具体诊断,可以看到支柱方案中烟囱下方真的缺支撑。不能因为最外层报错叫“额度用完”,就把实现错误说成正常拒绝。

阶段 原 64 次地形配对 错误或拒绝的性质
早期版本 31 次建成,33 次失败 33 次都涉及烟囱支撑缺陷,属于真实实现错误
加承托层后,最终版本重跑 64 次全部建成 保留原输入和限制,补上最多六格的小型承托层;不是把地形改平或放宽支撑限额
最终困难地形组 5 次建成,11 次拒绝 另一组输入,均因地面高差超限;不要与早期 33 次缺陷混为一谈
问题 主要负责哪一层 怎样处理,或还差什么
老虎窗顶盖沿大屋顶爬得太高 屋顶部件与安装规则 安装口定义明确的局部高度,老虎窗顶盖保持自己的水平屋脊
门廊柱子碰窗饰 门廊与立面部件的协调 利用已有墙作后方支撑,给遮蔽处调整装饰规则
入口勘察把头顶的木梁当成地面 接地适配代码的查询用法 测量时避开限定范围的上方装饰,仍保留真正向上延伸的地面台阶;不是改全局坐标算法
低屋顶碰到上层窗饰或植物 房屋的共享布置规则 屋顶和立面使用同一份相邻关系:被挡的窗不装,临近低屋檐使用平窗
种树候选位置太稀,找不到其实存在的合法位置 绿化部件与庭院组合 开放采样步距等设置,庭院用更密的候选点,保留原树木数量与间距要求
抬高花床内部没有连续土层 花床部件的支撑规则 补连续种植土层,边框仍单独支撑
烟囱放到支柱地基上缺支撑 烟囱接地适配,真实实现错误 小型承托层在真实支撑之间跨接,限制跨度并加破坏测试。没有改内核来放行
栏杆连接臂伸向没有邻居的方向 门廊部件的方块状态设置 根据实际邻居设置连接方向,四个旋转方向都检查;修正后重新跑测试和试建
查询命令不能把集合打印成 JSON 检查命令的配套代码 把集合按稳定顺序转换,再输出;当时建筑生成和保存已成功
完整渲染中部分栏杆看不清 渲染显示问题,具体根因未确定 文件与渲染器读取出的状态有栏杆,但整图显示异常尚未解决;不能猜成已证实的库错误或已修复问题
最终 11 次困难试建拒绝 具体输入超出部件支持范围 没造出建筑,是覆盖范围限制;不等于最终有 11 项自动测试失败

开发过程记录、早期失败批次、最终结果保留了证据。测试故意破坏的案例、开发中遇到的真实缺陷、最终仍存在的限制,分别记录,不能混成一个“失败数”。

09 · 时间、用量与运行方式

本轮从开始到验收、保存结束共 81.18 分钟。这不是在网页生成一栋房子的耗时。仍使用 gpt-6-astra、max 思考设置、4 个 CPU 和 8 GiB 内存,在原会话中继续工作。

本轮新增用量数值
模型请求94
输入 Token(含缓存)13,970,341
其中缓存输入13,342,464
输出 Token(含推理)131,352
其中推理输出63,235
输入与输出合计14,101,693
命令记录157
命令非零退出码21

Token 是模型处理文字的计量单位,不等于汉字数。缓存输入已包含在输入数中,推理输出也包含在输出数中,不能再重复相加。表中只算第三轮新发生的用量,不把前两轮累计记录再次计算。原用量记录。

命令返回非零状态,有时是在寻找真实缺陷,有时是故意试验错误输入;不能据此当作最终坏建筑的数量。原始命令和输出保存在命令记录。不同轮任务不同,不以时间长短或 Token 数给效率打分。

10 · 原任务与新增要求

第三轮发送的任务由第一轮完整原文加一段追加说明组成:优先把单栋建筑做得像 lodge 参考一样美观,保持原架构、可复用部件和轻量调用;若发现原架构有严重问题,就报告具体问题、反例和更合理方案并停止。

模型认为不需要触发停工条件,实际修改也没有碰六个内核文件。但它自己的最终评估仍明确承认“低于参考图质量”。这份报告同样把它记为尚未完成的目标,而不是把正常结束和验收通过解释成所有目标都实现。

完整发送的 prompt(原文与追加说明)

# Task: Contract-Based Procedural Composition, Adaptation, and Structural Provenance Build an extensible Python generation and validation library for Minecraft Java 1.21.1. First build its executable architecture, then use its public interfaces to generate complete, attractive, logically sound content. A higher-level program must be able to discover what a lower-level component offers, decide whether and how to use it, and compose it without reading its private implementation. Components may vary their realization with seed and surroundings while fulfilling their negotiated contracts. A composition must itself be a reusable component. Deliver working generation from small objects through rooms and buildings to a coherent settlement of 3-6 buildings. The kernel must support further growth toward cities and other complex content without treating this demonstration scale as a fundamental architectural limit. Users write short, high-level programs and explicitly control the seed. Running `python generate.py` must produce the complete default settlement as one region in `output.litematic`. The requirements below fix semantics and observable behavior, not Python class names, signatures, storage encodings, or a particular solver. Choose those details deliberately and document them. Requirement identifiers are used for the evidence ledger requested under Deliverables. ## 1. Priorities and reference policy **R01 - Architecture first, with real implementations.** Establish clear module boundaries, public protocols, component lifecycles, transactions, provenance, and tests before expanding into extensive building geometry. Deliver an executable foundation, not empty interfaces or a framework proposal. Then complete the generated results. Do not optimize library line count, file count, or implementation length. Write as much well-factored shared code as the result requires. Keep clients lightweight without code-golf, opaque configuration dumps, or long hidden building-specific example helpers. **R02 - References are aesthetic outcomes only.** Two source snapshot sets and their original reference images are supplied under `references/exp8/`, `references/lodge/`, and task-root image files. `references/README.md` indexes all 16 examples and records their provenance and hashes. The supplied reference programs and images are aesthetic examples of building outcomes only. They are not architectural or implementation templates for your library. You are not required to study or reuse their code, follow their algorithms, reproduce them one-to-one, read every source file, or cover an enumerated list of building families. Design the framework independently. You may run or render a reference solely to inspect its resulting architecture. Keep the supplied snapshots unchanged. The images are original reference images, not a claim that each historical program reproduced them exactly or passed the new requirements. New styles are welcome. **R03 - Maximize meaningful, valid variety.** Broaden the space of possible component compositions and compatible parameter combinations. Prioritize component counts, connection topology, massing, footprints, wings, storeys, room functions and adjacency, roof systems, entrances, circulation, attachments, and site organization. Materials, planting, weathering, and decoration also contribute, but rank below structural variation. Randomness must affect a client's structure and composition, not only surface texture. The public API supports explicit decisions and bounded seeded choices. Do not introduce a whole-building family selector, reference-name dispatch, or a collection of fixed buildings disguised by a short API. New compositions must be expressible through existing public capabilities. Finite implementations of useful primitives and engineering strategies are appropriate when they can compose and be extended through contracts. Make parameter domains and dependencies explicit. Do not silently discard explicit intent. Arbitrarily unbounded dimensions, extra seeds, new names, file hashes, global rotations, or translations alone are not meaningful additional types. Retain believable scale, proportions, correctness, and aesthetics. Do not calculate, estimate, enumerate, or report the total number of possible combinations. Report observed finite-sample diversity only. ## 2. Kernel and recursive public contracts **R04 - Separate responsibilities.** Keep a general composition kernel, environment/geometry services, component and rule implementations, and high-level user programs distinct. The kernel must not import concrete building implementations. Components use public kernel protocols; ordinary clients use public composition APIs. Separate generation from CLI handling, rendering, filesystem export, and harness execution. Keep generation usable as an importable library and straightforward to adapt to a future browser runtime. A Houdini installation is not required. The kernel handles component instances, contract negotiation, spatial transforms, attachment, permissions, transactions, dependencies, random scopes, provenance, and validation orchestration. Environment/geometry services expose fields, spatial queries, geometry operations, block states, storage, and transport. Concrete components and rules contain architectural knowledge. High-level programs describe intent, select capabilities, arrange relationships, and package new components. **R05 - Executable component contracts.** A component must expose enough information for another component or planner to use it without inspecting private fields or switching on its implementation type. Its contract must describe, as applicable: | Concern | Required semantics | | --- | --- | | Inputs and assumptions | Accepted dimensions, orientations, support and environmental conditions, style constraints, variable parameters, and locked decisions | | Spatial claims | Actual occupied geometry, conservative possible extent, affected region, support regions, and space that must remain clear | | Connection interfaces | Points, surfaces, or regions with local frames, directions, dimensions, capacity, and alignment conditions | | Environmental access | Public fields, nearby geometry, and constraints the component can query | | Modification authority | What may be replaced or excavated, where, under which conditions, and with what limits | | Adaptation capabilities | Parts that may change and connection strategies that may fulfill the interface | | Guarantees and obligations | Connectivity, sealing, support, lighting, and requirements that an enclosing composition must satisfy | | Validation and diagnostics | Checks over actual results, with failing rule, component path, position, and conflicting conditions | An interface is not necessarily a single coordinate. A wall can expose an installation region with sill heights, framing exclusions, margins, and bay alignment. Terrain can expose an irregular plantable surface. Separate a component's feasible capability/domain description from the concrete or conservative instance contract negotiated for one realization. A larger canopy or wider footing requires renegotiation if it exceeds the accepted envelope; realization cannot silently exceed it. **R06 - Recursive composition and substitution.** Leaves and composites must implement the same usable protocol. A room may internally compose walls, windows, doors, furniture, and lights, while exposing purpose, entrances, envelope, and internal reachability. A building may expose footprint, height envelope, access ports, attachment opportunities, environmental assumptions, and guarantees. The framework retains internal composition and validation evidence for recursive inspection; parents work through public interfaces. Contract-compatible implementations must be substitutable without changing their parent program. Provide high-level operations sufficient to select, attach, arrange, repeat, scatter, constrain, and encapsulate components. A high-level program can generate different composition graphs, not merely resize an immutable graph. Shared rules can coordinate multiple children: a facade planner can establish bay alignment and sill levels while independent window implementations vary within those rules. A room planner allocates functions and circulation while furniture components realize them. Avoid absolute voxel loops, blockstate edits, NBT handling, and geometry repair in ordinary clients. Adding a component or validator must integrate through extension points, not core dispatch edits or duplicated validation code. ## 3. Spatial authority and atomic composition **R07 - Conditional replacement and preservation.** Check where an operation writes, who currently owns or shares the affected content, which permissions its binding grants, and whether other live components still satisfy their assumptions afterward. A universal numeric priority or last-write-wins rule is insufficient. Required examples: | Operation | Expected behavior | | --- | --- | | A pool replaces ground | Allowed within an authorized excavation region, producing a valid basin, boundary, and updated surface | | A tree is planted on ground | Uses a planting interface and depends on substrate support; an ordinary tree cannot excavate the terrain | | A tree replaces grass | Allowed when the grass exposes permission for that planting replacement | | Grass attempts to replace a tree | Reject that candidate; a scatter operation may try another legal location | | A pool excavates beneath an existing tree | Reject because it destroys an active support requirement, even if the soil itself is editable | | A window is installed in a wall | Permit the scoped replacement while preserving agreed support, sealing, margins, and alignment | | Decoration enters stair headroom | Reject because the clearance obligation remains protected | Permissions can refine or consume a host capability: terrain need not promise that every original soil cell survives an authorized pool excavation, but existing consumers of that soil must remain valid. Identical block states do not by themselves authorize shared occupancy. Shared supports, ownership, and write authority need explicit semantics. Replacement must maintain whole logical objects and their records; do not leave half a door, half a tall plant, dangling ports, or stale claims. **R08 - Functional boundaries and atomic transactions.** Components receive explicit inputs, read-only environmental access, and scoped randomness, and return plans or effect sets. Efficient mutable internals are acceptable, but components cannot bypass the kernel to mutate shared scene state. Every committed geometry write must have a kernel-bound component context. Negotiate a binding, generate a candidate, inspect its tentative resulting geometry and affected contracts, then commit all effects together. Failed attempts must leave geometry, ports, claims, ownership, dependencies, and other random branches unchanged. Initial implementations may recheck all relevant contracts rather than implementing a complex incremental validator. **R09 - Construction phases and obligations.** Distinguish invariants that must hold throughout composition from obligations that must be discharged when the current scope is finalized. A room can acquire walls before lights; a completed room must have lighting and an accessible exit. A building supplies internal reachability; a settlement connects its entrance to a public path. Unfinished scopes can continue local construction but cannot be returned or exported as completed valid components. Each room needs access and lighting; it does not need its own private staircase. Vertical circulation is required where the composed levels require it. ## 4. Automatic block-to-structure provenance **R10 - Record semantic structure in the kernel.** At instantiation, automatically assign stable component instance IDs and record type, resolved parameters, and random scope. At composition and attachment, automatically record semantic relationships. At geometry submission, automatically associate blocks with their current semantic component and generating operation. Component authors declare component types and interfaces normally; high-level clients must not supply per-block owner maps, handwritten ancestor chains, or a post-generation tagging pass. Semantic objects such as windows and walls must actually be generated as components. Querying a window's glass must recover relationships such as: ```text glass block -> window instance -> host wall -> house -> plot or settlement ``` This comes from real composition and binding, not source-code stack traces, material names, or post-hoc geometry classification. A window installed by a higher-level facade program must still identify its host wall through the attachment interface. Helper functions must not become fake semantic ancestors merely because they were called during generation. **R11 - Distinguish meaning, dependencies, and history.** Represent current structural membership and typed associations separately from data/constraint dependencies and generation/modification records. A window replacing wall infill owns its glass while remaining attached to the wall. A later property adjustment preserves that semantic membership even if another operation performs the write. Tree-over-grass replacement changes current ownership; displaced grass must not appear as a current owner. Preserve useful compact operation records for explanation and replay. Shared walls, bridges, and platforms joining multiple buildings can relate to multiple structures. Expose a useful primary structural chain plus typed related structures without forcing every relationship into a single-parent tree. Record containment, attachment, connection, and support according to their actual meaning. **R12 - Queryable, synchronized provenance.** Provide public APIs and a runnable headless example to inspect a block by coordinate and return its state, instance ID, structural chain, typed related structures, and generating information. Also query the actual current cells of a component, with optional descendants, for future highlighting. A bounding box alone is not an exact membership map. Document coordinate spaces and conversion through export offsets, translations, and supported rotations. This experiment requires the underlying query functionality, not a clickable viewer. Maintain coordinate and appropriate reverse indexes. Share the structure graph rather than storing a complete ancestor string on every voxel or scanning the whole scene on each query. Keep provenance transactionally consistent with replacement, deletion, rollback, and regeneration. Removing a block removes its current block ownership; clearance reservations remain separate. Recomputed branches must not leave stale cells, structure nodes, or associations. **R13 - Persist and verify structural identity.** Export sufficient companion data with the schematic to restore the same public queries, contracts, and validation context after reload. Include format version, coordinate transforms, and a semantic geometry identity/digest to check the pairing. A mismatched record must not be treated as trustworthy structure metadata. Equivalent blockstate property ordering must not create a mismatch. Handle unknown or missing structural data explicitly. Do not claim that arbitrary schematic geometry alone recovers the original semantic component graph. ## 5. General procedural environments **R14 - Compose environments from general operations.** Use Houdini-inspired data flow, attributes, fields, masks, scattering, connections, and encapsulated subnetworks in Python. Environments should come from composable parameterized operations such as field layering and transforms, mask blending, local shape operations, material distribution, water volumes, and constrained scattering. Operations can nest, repeat, and be packaged into new components. Use appropriate procedural-generation data structures throughout the library. You may combine splines/parametric curves and polylines, graphs and trees, polygons and meshes, point clouds with attributes, heightfields, scalar/vector fields, signed distance fields (SDFs), sparse voxel grids, and spatial indexes. For example, curves can guide paths, rivers, branches, or swept profiles; graphs can express circulation and structural relationships; fields can guide density and blending. These are optional tools, not a required checklist or a closed vocabulary. Choose representations that make each operation clear and extensible; intermediate design geometry need not be limited to boxes or Minecraft voxels. When converting representations into blocks, preserve component identity, coordinate transforms, and contract meaning, and validate the realized voxel geometry. Do not define a fixed list of environment classes or a `terrain_type` selector that dispatches to handwritten whole-scene cases. Flat terrain, gradients, shorelines, and other recognizable conditions must emerge as special cases of general parameters and compositions. For example, zero perturbation can yield flat ground, a field gradient can yield a slope, and an intersection of terrain with water can yield a shoreline. These are explanatory examples, not a required classification or a finite coverage checklist. One environment may contain many interacting conditions simultaneously. Adaptation must not inspect environment implementation types, source recipe names, reference names, or particular seeds to choose special-case behavior. Branching on measured geometry or contract facts is appropriate: support depth, water presence, available clearance, or local height difference can justify different engineering strategies. A finite set of useful primitive algorithms is fine; it must support new combinations and implementations through the public contracts. **R15 - Public environmental queries and control.** Expose relevant elevation, slope, materials, water levels, actual support, obstacle distance, occupancy, protected regions, access opportunities, and shared style information. Initial terrain generation may use heightfields, but the public environment interface must also support actual three-dimensional solid/support/clearance queries. A surface height alone does not prove that the material below can support a footing. Queries have explicit coordinate frames, valid domains, and input versions or dependency identities. Unknown space is not silently treated as flat terrain or empty air. Distinguish hard constraints (protected regions, locked placement, headroom, edit limits) from preference fields (planting density, buildability preference, access proximity, landscape preservation). Masks can control an operation's extent and strength; a high preference or mask value does not grant write authority. ## 6. Context-sensitive realization and connection adapters **R16 - Reusable adapters.** Treat connection adapters as ordinary components with contracts, provenance, and validators. Capabilities can include stepped foundations, retaining work, footings, posts to the actual bed beneath water, window reveals for varying wall thickness, entrance platforms and stairs, and sealed roof junctions. These are examples of reusable engineering, not an exhaustive adapter registry hardcoded into the kernel. New techniques must be addable through public interfaces. **R17 - Adapt at placement time.** For a workflow that generates terrain before placing a building: 1. Query the candidate location and neighborhood for support, elevation differences, water, obstacles, access, and protected regions. 2. Establish explicit user decisions and the remaining permitted variation. 3. Negotiate the binding and propose suitable contact geometry, adapters, and any permitted terrain edits. 4. Check the resulting combined scene, including affected existing components, in a tentative transaction. 5. Compare feasible candidates and atomically commit the chosen complete result. By default allow local excavation/fill, plinths, posts, retaining walls, and approach changes within explicit bounds. Preserve the terrain's major shape, the building's principal design, and locked requirements. Keep buildings sensibly aligned to gravity rather than tilting them wholesale with a slope. Explicitly bound and expose edit extent, excavation/fill volume, support height, and access detours. Do not make everything succeed by leveling the entire site, adding enormous solid pedestals, or extending arbitrarily tall posts. Regenerate contact geometry from the environment, rather than only translating a rigid finished building vertically. Adaptation should generalize across scales: a window can fit wall thickness within its contract, an approach can respond to height differences, and permitted branch/canopy variation can preserve nearby clearance. Shared facade grids, material roles, proportion rules, and layout constraints keep independently varying children coherent. **R18 - Quality-aware bounded planning.** First satisfy hard conditions: authority, support, reachability, sealing, spatial bounds, and explicit architectural intent. Then evaluate permissible alternatives for terrain disturbance, support proportions, boundary transitions, entrance/path quality, alignment, palette coherence, and landscape relationships. Use seeded selection among acceptable alternatives to retain diversity rather than always converging on one fixed form. Prefer constraint propagation and feasible-domain construction to blindly rejecting random complete builds. Bounded local search or backtracking is allowed; replan the smallest affected composition where practical. Distinguish proven/established incompatibility from search-budget exhaustion and validated success. Never claim a failed bounded search proves no solution exists. Do not silently drop required components, move locked placements, relax hard constraints, or recover to the same fixed building across most seeds. Optional omissions must respect declared minimum counts and be reported, not used to disguise failures. Return useful failed constraints and component locations. ## 7. Dependencies, deterministic regeneration, and bounds **R19 - Re-evaluate actual dependencies.** Composition structure defines encapsulation and responsibility. A separate data/constraint dependency graph identifies which changes require regeneration or revalidation. Terrain changes must invalidate affected foundations, approaches, and paths. Initial implementations may recompute whole affected nodes; sophisticated caching is not required. Recompute from inputs and recorded operations, replacing obsolete output rather than accumulating repeated cuts or fills. Keep current provenance and spatial indexes synchronized. Coupled building/terrain adjustments belong inside an explicit bounded solve that jointly produces the building and terrain edits. Do not create hidden, endlessly oscillating update loops. Record the environmental inputs on which a component's validity depends. An invalidated old result must not remain presented as a valid completed component. **R20 - Hierarchical deterministic randomness.** Derive stable child random scopes from the user's root seed and stable instance/operation keys. Separate planning, geometry, adaptation, and decoration. Users can override a subtree seed. Keys must not depend on traversal order or Python's process-random `hash()`. Sort unordered candidates with deterministic tie-breakers. Failed retries must not consume other branches' randomness. Scope attempted alternatives deterministically. With unchanged interfaces and no changed spatial/global constraint dependencies, adding a planter must not alter an unrelated building's layout. Changes that really affect dependencies can require replanning, and their cause must be inspectable. Independent operations can commute; dependent replacement and attachment operations obey their contracts. Do not falsely promise order independence for tree/grass replacement. Document the seed domain and retain inputs, resolved decisions, component structure, environmental versions, seeds, and implementation versions for replay. The same inputs and seed must reproduce semantic schematic content in the same environment: dimensions, coordinates, actual block states, entities, and block-entity data. Timestamps, compression, palette numbering and property ordering may differ; byte-identical files are not required. Use scoped streams for this task; all stochastic choices must still derive from explicit seeds, never ambient global randomness. **R21 - Resource and coordinate bounds.** Expose configurable limits for dimensions, recursion, search effort, and generation cost. Derive final export bounds from the realized composition, including terrain, roofs, adapters, vegetation, and external connections. Never silently clip. Library boundaries must not bake in the demonstration's building count or an environment category. ## 8. Architecture-first work sequence **R22 - Implement and verify in this order.** 1. Write `ARCHITECTURE.md` in your workspace before extensive scene geometry. Explain module dependencies, public protocols, lifecycle, contracts, effects/transactions, automatic provenance, environment queries, seeds, persistence, and extension mechanisms. Include short intended client compositions that make the proposed abstractions concrete. 2. Implement the working kernel. Pass tests for composition, binding, conditional replacement, rollback, automatic ownership, transforms, queries, and persistence before expanding the content. 3. Build a small end-to-end composition using terrain, grass, trees, walls, and windows. Exercise recursive composition, real attachment, provenance, and adaptation. Repair inadequate abstractions. 4. Build complete furnished buildings, roofs, circulation, lights, and connection adapters using the same public protocols. Demonstrate substitution and an independent extension. 5. Compose settlements, broaden high-level programs, run multi-seed validation, inspect renders, and fix generic defects exposed by the corpus. Proceed autonomously through these stages; do not stop for approval at each stage. Architecture can evolve when evidence calls for it, but rerun foundational tests after changing its semantics. Update the design rationale. Do not satisfy this sequence by writing placeholder interfaces and then routing all real work through a monolithic mutable compiler or a building-specific bypass. Large coherent implementation is acceptable; incomplete promises of future extensibility are not the deliverable. ## 9. Validation and finite evidence **R23 - Contract and extensibility tests.** Provide meaningful `test/test_*.py` tests for: - At least two visibly different implementations satisfying the same contract, substituted with no parent-program change; a composite remains usable at a higher level through the same protocol. - An independent extension package adding one low-level and one composite component without editing the kernel; ordinary clients need no geometry repairs or copied validators. - All conditional replacement examples above, including existing-consumer support preservation, whole-object consistency, rejected candidates, shared occupancy rules, and complete rollback. - Translation and horizontal rotations transforming states, interfaces, claims, and provenance together. - Determinism, stable independent branches, and failed attempts not perturbing sibling random streams. **R24 - Provenance tests.** Query window glass and recover its real window/wall/building relationships. Two windows using identical glass must have distinct instance identities. High-level examples must not contain per-voxel ownership tables or handwritten ancestry. Test replacement, deletion, property updates, rollback, shared walls/connections, exact current-cell queries, and branch regeneration. No obsolete node or voxel reference may survive as current structure. Test export/reload and coordinate changes, as well as detecting mismatched geometry and companion records. **R25 - General environmental adaptation tests.** Generate test environments with the same general operations, not a hand-authored list of terrain cases. Organize tests around independent environment and building seeds, parameter boundaries and degenerate values, rule interactions, previously unused operation compositions, local perturbations, and contract-compatible environment implementations. Derive special inputs such as flat ground from the general generator's parameters. Persist failures as generating expressions, parameters, and seeds; fix general rules, not seed-specific exceptions. Retain at least 64 reproducible environment/building pairings as a finite adaptation test budget. This count does not enumerate environment classes or define capability boundaries. Define the sampling recipe and supported parameter domains before evaluating results. Generate and freeze environmental inputs independently before placing buildings; do not secretly shape terrain to suit one house. Include untried combinations when assessing generalization, rather than only development examples. For explicitly satisfiable test specifications within documented domains, require valid results: contact geometry actually responds to surroundings, locked principal layout/functions remain intact, protected objects and terrain outside authorized modifications are unchanged, and there are no floating joins, buried doors, disconnected approaches, or invalid supports. Exercise multiple compatible adaptation strategies without reducing every case to a flat platform. Also run bounded stress sampling. Keep and report all successes, incompatibilities, retries, and budget-exhausted cases. Separate per-input success rate from per-candidate acceptance rate. Report edit costs and runtime, with denominators and sampling policy, rather than hiding hard inputs by resampling until only successes remain. A finite corpus is not a proof about every possible composition. **R26 - Whole-building and settlement corpus.** Supply at least three distinct lightweight building composition programs, each exercised at seeds 0-7. Exercise a settlement program at seeds 0-7 and test both 3-building and 6-building count boundaries. Programs use the same shared API and exhibit actual structural choices; they are not named reference dispatchers. Include new high-level compositions written after the abstractions exist, without changing the library for each new client. **R27 - Actual-geometry validators and negative tests.** Check generated and reloaded blocks, not only declared plans or claims. Validate Java 1.21.1 blockstates, bounds, support, multi-block consistency, doors/windows, room reachability, at least two blocks of player headroom on required routes including stairs, usable vertical connections, actual lights, appropriate furnishing, enclosed-space integrity, pool containment, exterior approaches, and settlement path connections. Late decoration must preserve earlier guarantees. Distinguish intended open spaces from enclosed spaces in the contracts. Deliberately remove supports, block stairs or exits, break paired door parts, remove room light sources, and exceed edit permissions. Validators must detect the resulting defects and identify the rule, component, and location. Support assumptions and the movement/lighting model must be explicit; a metadata declaration is not evidence of physical reachability or a placed light. Use the proc toolset's `blockstates_equivalent` semantics for round trips. Compare parsed block names and explicit property mappings, ignoring property order only. Changed names, values, missing properties, and extra properties still fail; do not infer defaults during equivalence checking. MCIO can reorder properties even after a single write. Repeated writes to a coordinate can be valid when the contract permits them and the final state is correct. Retain checks for relevant block-entity NBT and inventories. You may copy the independent comparison helper into your library or implement equivalent semantics; do not couple library validation to the CLI entry point. **R28 - Diversity and visual quality.** Measure observed differences in actual massing, component connections, room topology, roofs, and settlement organization, both within a client's seeds and between compositions. Exclude cosmetic noise, instance names, and global transforms from structural signatures. Report contact/foundation adaptation separately so it cannot substitute for diversity in principal architecture. Preserve harmonious material roles, useful proportions, complete hidden sides and interiors, meaningful furnished spaces, coherent roof joins, clear access, and composed landscapes. Keep all corpus results and failures. Render representative structural and adaptation variations from multiple exterior angles and with cutaways for circulation and furnishing. Inspect the images and fix visible problems. Do not present only favorable seeds while leaving known reproducible defects unreported. Rules and tests constrain quality; renders support aesthetic assessment. Neither formal contracts nor passing sampled tests constitute a proof of beauty or exhaustive validity. Keep tests bounded and rerunnable. Temporary test files belong in temporary directories under `test/` and must be cleaned up. Persistent samples, rendered previews, and corpus reports are explicit batch outputs, not unnoticed side effects of unit tests. ## 10. Harness contract and deliverables **R29 - Public generation, inspection, and export.** Work inside `/work/generator/workspace`. `python generate.py` is a thin public-API client and must generate, validate, and export the complete default 3-6 building settlement as one region in `output.litematic`. Support `python generate.py --seed INTEGER --output PATH` and document the default seed. Every example and batch command supports explicit seeds. Use the proc toolset and create your own entry point and library; no generator template is seeded. Preserve valid export and semantic reload checks while keeping substantial shared implementation in the library. The harness independently runs the default command, two seed-0 replays with different PYTHONHASHSEED values, seed 1, and your pytest suite in isolated offline workspace copies. Each command has a 1800-second limit. This checks the program interface and replay, not all R01-R30 requirements. The finished package must work without invoking reference programs, depending on the harness CLI, or downloading additional assets. Keep public generation and inspection callable without file export. Include an example that selects a coordinate from a generated artifact, prints the real structural chain and typed related structures, retrieves its component's cells, exports, reloads, and demonstrates the same query. A clickable viewer, node-editor UI, HTML report, or full city generator is outside this experiment; provide the foundation those later tools can use. **R30 - Complete artifacts and evidence ledger.** Deliver: - An importable shared library: kernel, environmental operations, components, adapters, validators, automatic structural provenance, public inspection, deterministic generation, and persistence. - `ARCHITECTURE.md`: the actual design, public protocol, dependencies, lifecycle, and rationale, updated as implementation evolves. - `GENERATOR.md`: quickstart, short client compositions, seed behavior, domains/dependencies, adaptation policy, resource limits, inspection and export/reload usage, extension instructions, diagnostics, batch/test/render commands, and known limitations. - `generate.py`, lightweight runnable examples, and an independent extension demonstration. - `output.litematic` with its verified structural/validation companion data. - `test/test_*.py`, representative samples with a replay manifest, labeled previews/cutaways, and rerunnable finite-corpus/assessment commands. - An evidence ledger in the documentation mapping **every R01-R30 requirement** to the responsible public API or module, tests/examples/render evidence, and any incomplete part. Use actual results; do not mark an unimplemented interface or an unrun test as complete. Preserve all requirements when refining the implementation. Document tradeoffs and limitations rather than silently shrinking the task. Spend effort on the reusable architecture and its verified generated results. State plainly in your final message what is complete and what remains unfinished. Environment details, available libraries, rendering tools, and repository conventions are in the workspace `AGENTS.md`. --- ## Third continuation: improve individual buildings under the original task Continue in this same session and existing workspace from the work already completed. The full first-round task above is the governing specification again. This addendum supersedes the second-round extension agenda; do not restart the project or treat that agenda as the goal of this round. Focus this round's effort on the quality of individual buildings. Aim for buildings as beautiful, complete, and thoughtfully composed as the eight original lodge reference images (`reference_lodge_ref-1.png` through `reference_lodge_ref-8.png`, indexed in `references/README.md`). Open the actual images, render your own buildings, and inspect the exterior and interior while improving them. Keep meaningful seeded structural variety; a single hand-tuned showcase or cosmetic material changes alone do not satisfy the original task. Use the references for aesthetic outcomes only, as the original prompt specifies. Preserve the original overall program design: reusable nested components with public interfaces, shared generation and validation, environment-aware placement, automatic block-to-structure records, and lightweight high-level user code. Put improvements in the appropriate reusable components and rules. Retain existing working capabilities and tests, but spend this round's development effort on individual buildings rather than expanding the second round's bridge, boundary, or settlement demonstrations. Follow the original validation and visual-review requirements and report honestly what improved and what remains below the reference quality. IMPORTANT STOP CONDITION: If you judge that the architecture requested by the original first-round prompt has a serious flaw, stop implementation and experimentation instead of silently working around it, weakening the requirements, or redesigning it on your own. This applies both during your initial review and if you discover such a flaw later. Report the specific original requirement or architectural assumption, a concrete example showing why it is seriously problematic, how it differs from an ordinary implementation bug or missing component, and a more reasonable architecture with its tradeoffs and implications for existing code. Save that report as `ARCHITECTURE-REVIEW.md`, explain it in your final reply, and end this run awaiting the user's decision. This stop condition overrides the original instruction to continue autonomously. If there is no such serious architectural issue, proceed with the single-building improvements.

下载本轮完整任务 · 下载第一轮原文 · 参考文件来源与校验值。

11 · 模型结束时说了什么

这是第三轮模型在 2026-09-28 00:29:18 UTC 发出的最终回复,来自原始会话记录,不是报告作者替它写的总结。已经核对:这条回复与会话结束事件保存的最终消息完全相同。原文下载 · 来源、时间与校验记录。

中文翻译

已实现 Hearth 1.3,加入可复用的分段坡屋顶、附着式老虎窗、更有深度的立面、阳台、家具组合、有支撑的烟囱和入口庭院。三个轻量的建筑程序仍能通过随机编号生成不同结构。

没有发现严重的架构障碍。内核、保存与恢复协议、命令行接口保持不变;新增加的公开屋顶策略与建筑选项,无需访问内部几何实现。

已验证:

更新后的五栋建筑村落保存在 output.litematic 中,并附有配套的结构记录文件。另有预览和评估报告。

质量仍低于 lodge 参考图:房间模数偏规整、背面立面与景观偏空的问题仍然存在;阁楼不能居住。 尽管建筑文件中的几何内容已验证,有些小细节的渲染效果仍然不好。这轮没有重新测试浏览器执行。

英文完整原文

Implemented Hearth 1.3 with reusable profile roofs, attached dormers, deeper facades, balconies, furnishing groups, supported chimneys and garden courts. Three lightweight building programs retain seeded structural variation. No serious architectural blocker was found. The kernel, persistence protocol and CLI remain unchanged; new public roof policies and building options require no private geometry access. Verified: - **200 tests passed**, preserving all earlier tests. - **104/104 supported inputs validated**. - Stress: **5/16 succeeded**; 11 exceeded documented relief limits. - **18 structural signatures** across 24 building samples. - **20 exterior/cutaway renders inspected**. - Export/reload, complete provenance and hash-seed replay passed. The updated five-building settlement is in [output.litematic](/work/generator/workspace/output.litematic), with its companion. See [previews](/work/generator/workspace/previews/building-quality/README.md) and the [assessment](/work/generator/workspace/reports/building-quality/ASSESSMENT.md). Quality remains below the lodge references: regular bays, spare rear facades and landscaping remain visible; attics are nonhabitable. Some small details render poorly despite verified schematic geometry. Browser execution was not rerun.

原文中的 /work/generator/workspace/... 是实验容器内的路径,按原样保留。对应网页材料在建筑下载、图片章节和原评估报告。

最后一句“没有重新测试浏览器执行”说的是模型结束这次实验时的情况。后来制作本报告时,已经另外完成浏览器和公网验证,见测试章节。不要把这两个时间点混在一起。

12 · 下载与详细证据

本轮工具、示例和测试共 78 个 Python 文件、7430 行。代码长短不是质量评分。网页的运行桥接、控件、图表和查看器属于报告代码,不计入模型本轮交付的库规模。

生成自己的建筑后,在线区域的下载按钮会保存完整建筑、部件关系、调用代码和参数。只保存建筑文件,无法恢复本实验记录的完整方块归属关系。浏览器与原环境一致性的检查见测试章节。

全部源码文件

源码行数
generate.py21
hearth/space.py109
hearth/blocks.py83
hearth/randomness.py21
hearth/__init__.py8
hearth/persistence.py194
hearth/composition.py61
hearth/programs.py184
hearth/assessment.py163
hearth/lodges.py53
hearth/quality_assessment.py171
hearth/validators.py15
hearth/kernel/contracts.py150
hearth/kernel/errors.py32
hearth/kernel/view.py166
hearth/kernel/validation.py220
hearth/kernel/scene.py542
hearth/kernel/__init__.py5
hearth/environment/fields.py79
hearth/environment/terrain.py42
hearth/environment/__init__.py3
hearth/components/primitives.py191
hearth/components/__init__.py4
hearth/components/interior.py214
hearth/components/roofs.py160
hearth/components/building.py199
hearth/components/constraints.py19
hearth/components/landscape.py258
hearth/components/roofcraft.py261
hearth/components/joinery.py38
hearth/components/furnishing.py122
hearth/components/masonry.py32
hearth/components/grounds.py106
hearth/adapters/site.py137
hearth/adapters/__init__.py2
hearth/adapters/bearing.py29
hearth_extensions/interiors.py116
hearth_extensions/geometry.py133
hearth_extensions/interfaces.py38
hearth_extensions/__init__.py8
hearth_extensions/circulation.py227
hearth_extensions/boundaries.py125
hearth_extensions/sites.py38
hearth_extensions/halls.py211
hearth_extensions/graphs.py99
hearth_extensions/programs.py60
hearth_extensions/assessment.py208
extension_demo/__init__.py38
examples/courtyard.py25
examples/inspection.py28
examples/prototype.py33
examples/assess.py13
examples/gallery.py25
examples/building.py13
examples/extension.py27
examples/extension_audit.py94
examples/extension_generate.py23
examples/extension_views.py63
examples/extension_assess.py14
examples/extension_inspection.py34
examples/extension_replay.py49
examples/lodge.py16
examples/building_quality.py13
examples/building_views.py49
examples/lodge_inspection.py29
examples/building_holdout.py57
examples/verify_replay.py35
examples/__init__.py1
examples/preview.py62
test/conftest.py13
test/test_kernel.py122
test/test_contracts_provenance.py279
test/test_geometry_environment.py243
test/test_extension_protocol.py93
test/test_extension_geometry.py128
test/test_extension_failures.py149
test/test_extension_interiors.py70
test/test_building_quality.py235

展开阅读和复制每个 Python 文件

generate.py
# Generate, validate and export the default complete Hearth settlement. import argparse from pathlib import Path from hearth.programs import settlement_scene from hearth.persistence import export_scene, semantic_digest def main(): parser = argparse.ArgumentParser(description='Generate a contract-composed Minecraft Java 1.21.1 settlement.') parser.add_argument('--seed', type=int, default=0, help='Explicit integer seed, default 0') parser.add_argument('--output', type=Path, default=Path('output.litematic')) parser.add_argument('--count', type=int, choices=range(3, 7), help='Optional explicit building count, 3 through 6') args = parser.parse_args() scene = settlement_scene(args.seed, args.count) export_scene(scene, args.output) print(f'Validated {sum(n.type=="building.rooms" for n in scene.nodes.values())} buildings, {len(scene.blocks)} blocks, {len(scene.nodes)} components.') print(f'{args.output} | semantic SHA256 {semantic_digest(scene)}') if __name__ == '__main__': main()
hearth/space.py
# Integer geometry and explicit local-to-world transforms. from dataclasses import dataclass from itertools import product from typing import Iterable Pos = tuple[int, int, int] @dataclass(frozen=True) class Box: lo: Pos hi: Pos def __post_init__(self): object.__setattr__(self, 'lo', tuple(self.lo)) object.__setattr__(self, 'hi', tuple(self.hi)) if any(not isinstance(v, int) for v in (*self.lo, *self.hi)): raise TypeError('Box coordinates must be integers') if any(a > b for a, b in zip(self.lo, self.hi)): raise ValueError('Inverted box') def contains(self, p: Pos) -> bool: return all(a <= v <= b for a, v, b in zip(self.lo, p, self.hi)) def cells(self) -> Iterable[Pos]: return product(*(range(a, b + 1) for a, b in zip(self.lo, self.hi))) def corners(self): return product(*zip(self.lo, self.hi)) def intersection(self, other): low = tuple(max(a, b) for a, b in zip(self.lo, other.lo)) high = tuple(min(a, b) for a, b in zip(self.hi, other.hi)) return None if any(a > b for a, b in zip(low, high)) else Box(low, high) def expand(self, n: int): return Box(tuple(v - n for v in self.lo), tuple(v + n for v in self.hi)) @property def size(self): return tuple(b - a + 1 for a, b in zip(self.lo, self.hi)) @property def volume(self): x, y, z = self.size return x * y * z @classmethod def enclosing(cls, points): points = list(points) if not points: raise ValueError('No realized geometry') return cls(tuple(min(p[i] for p in points) for i in range(3)), tuple(max(p[i] for p in points) for i in range(3))) @dataclass(frozen=True) class Frame: origin: Pos = (0, 0, 0) turn: int = 0 def __post_init__(self): object.__setattr__(self, 'origin', tuple(self.origin)) if not isinstance(self.turn, int) or any(not isinstance(v, int) for v in self.origin): raise TypeError('Frames use integer coordinates and quarter turns') object.__setattr__(self, 'turn', self.turn % 4) def vector(self, p: Pos) -> Pos: x, y, z = p for _ in range(self.turn % 4): x, z = -z, x return x, y, z def point(self, p: Pos) -> Pos: return tuple(a + b for a, b in zip(self.origin, self.vector(p))) def inverse(self, p: Pos) -> Pos: return Frame(turn=-self.turn).vector(tuple(a - b for a, b in zip(p, self.origin))) def box(self, box: Box) -> Box: return Box.enclosing(self.point(p) for p in box.corners()) def compose(self, other): return Frame(self.point(other.origin), (self.turn + other.turn) % 4) def state(self, state: str) -> str: from .blocks import parse, state_of name, props = parse(state) dirs = ['north', 'east', 'south', 'west'] rotated = {} for key, value in props.items(): if key in dirs: key = dirs[(dirs.index(key) + self.turn) % 4] if key == 'facing' and value in dirs: value = dirs[(dirs.index(value) + self.turn) % 4] if key in ('shape', 'orientation') and any(v in dirs for v in value.split('_')): from .blocks import SCHEMA tokens = [dirs[(dirs.index(v) + self.turn) % 4] if v in dirs else v for v in value.split('_')] value = '_'.join(tokens) allowed = SCHEMA[name.removeprefix('minecraft:')][0][key] if value not in allowed: matches = [candidate for candidate in allowed if sorted(candidate.split('_')) == sorted(tokens)] if matches: value = sorted(matches)[0] if key == 'axis' and value in ('x', 'z') and self.turn % 2: value = 'z' if value == 'x' else 'x' if key == 'rotation': value = str((int(value) + 4 * self.turn) % 16) rotated[key] = value return state_of(name, **rotated)
hearth/blocks.py
# Canonical blockstates and a deliberately conservative physical model. import json import re from functools import lru_cache from pathlib import Path SCHEMA = json.loads((Path(__file__).parent / 'data' / 'blockstates-1.21.1.json').read_text()) AIR = 'minecraft:air' LIGHTS = {'lantern': 15, 'torch': 14, 'wall_torch': 14, 'glowstone': 15, 'sea_lantern': 15, 'shroomlight': 15, 'ochre_froglight': 15, 'pearlescent_froglight': 15, 'verdant_froglight': 15} SOFT = {'air', 'cave_air', 'water', 'short_grass', 'fern', 'dead_bush', 'dandelion', 'poppy', 'cornflower', 'allium', 'azure_bluet', 'oxeye_daisy', 'lily_of_the_valley', 'blue_orchid', 'torch', 'wall_torch', 'vine', 'snow', 'lily_pad', 'tall_grass', 'large_fern', 'sunflower', 'rose_bush', 'peony', 'lilac', 'wheat', 'carrots', 'potatoes'} @lru_cache(maxsize=4096) def parse(state: str): match = re.fullmatch(r'(minecraft:[a-z0-9_]+)(?:\[([^\]]+)\])?', state) if not match: raise ValueError(f'Invalid blockstate syntax: {state}') props = {} if match[2]: for part in match[2].split(','): key, value = part.split('=') if key in props: raise ValueError('Duplicate block property') props[key] = value return match[1], props def state_of(name: str, **properties) -> str: if not name.startswith('minecraft:'): name = 'minecraft:' + name return name + ('[' + ','.join(f'{k}={str(v).lower()}' for k, v in sorted(properties.items())) + ']' if properties else '') def canonical(state: str) -> str: name, props = parse(state) return state_of(name, **props) def blockstates_equivalent(left: str, right: str) -> bool: return parse(left) == parse(right) @lru_cache(maxsize=4096) def validate_state(state: str): name, props = parse(state) short = name.removeprefix('minecraft:') if short not in SCHEMA: raise ValueError(f'Unknown Java 1.21.1 block: {name}') domain = SCHEMA[short][0] for key, value in props.items(): if key not in domain or value not in domain[key]: raise ValueError(f'Invalid property {key}={value} for {name}') @lru_cache(maxsize=4096) def name_of(state: str) -> str: return parse(state)[0].removeprefix('minecraft:') def solid(state: str) -> bool: name = name_of(state) return name not in SOFT and not any(s in name for s in ('leaves', 'fence', 'pane', 'door', 'lantern', 'chain', 'flower_pot', 'potted_', 'carpet', 'bed', 'button')) def passable(state: str) -> bool: name = name_of(state) return name in SOFT - {'water'} or name.endswith('_door') or name.endswith('_carpet') def stairs(material='stone_brick', facing='north', half='bottom'): return state_of(material + '_stairs', facing=facing, half=half, shape='straight', waterlogged='false') def slab(material='stone_brick', half='bottom'): return state_of(material + '_slab', type=half, waterlogged='false') def log(material='spruce', axis='y'): return state_of(material + '_log', axis=axis) def leaves(material='spruce'): return state_of(material + '_leaves', distance='1', persistent='true', waterlogged='false')
hearth/randomness.py
# Stateless hierarchical scopes, with explicitly local random streams. import hashlib import json import random from dataclasses import dataclass @dataclass(frozen=True) class Scope: seed: int key: tuple[str, ...] = () def child(self, key: str, override: int | None = None): return Scope(self.seed, self.key + (key,)) if override is None else Scope(override, (key,)) def stream(self, purpose: str = 'plan') -> random.Random: payload = json.dumps([self.seed, self.key, purpose], separators=(',', ':')).encode() return random.Random(int.from_bytes(hashlib.sha256(payload).digest(), 'big')) def choose(self, values, purpose='plan'): return self.stream(purpose).choice(tuple(values))
hearth/__init__.py
# Hearth public library entry points. from .kernel import Binding, Child, ContractError, Limits, Scene from .space import Box, Frame __version__ = '1.3.0' # Register standard optional geometric validators outside the general kernel. from . import validators
hearth/persistence.py
# One-region Litematica transport paired with verified structural records. import hashlib import json import sys from dataclasses import fields, is_dataclass from pathlib import Path from . import __version__ from .blocks import canonical, AIR from .space import Box, Frame from .randomness import Scope from .kernel import contracts from .kernel.scene import Scene, Node, Cell, Limits from .kernel.errors import ContractError FORMAT_VERSION = 1 TYPES = {c.__name__: c for c in (Box, Frame, Scope, Node, Cell, Limits, contracts.Contract, contracts.Rule, contracts.Port, contracts.Grant, contracts.Binding, contracts.Capability, contracts.Domain)} def encode(value): if is_dataclass(value): return {'$type': type(value).__name__, **{f.name: encode(getattr(value, f.name)) for f in fields(value)}} if isinstance(value, tuple): return {'$tuple': [encode(v) for v in value]} if isinstance(value, set): return {'$set': [encode(v) for v in sorted(value)]} if isinstance(value, dict): return {k: encode(v) for k, v in value.items()} if isinstance(value, list): return [encode(v) for v in value] return value def decode(value): if isinstance(value, list): return [decode(v) for v in value] if isinstance(value, dict): if '$tuple' in value: return tuple(decode(v) for v in value['$tuple']) if '$set' in value: return set(decode(v) for v in value['$set']) if '$type' in value: return TYPES[value['$type']](**{k: decode(v) for k, v in value.items() if k != '$type'}) return {k: decode(v) for k, v in value.items()} return value def semantic_digest(scene): digest = hashlib.sha256() for p, c in sorted(scene.blocks.items()): digest.update(json.dumps([p, canonical(c.state), c.nbt], sort_keys=True, separators=(',', ':')).encode()) return digest.hexdigest() def companion_path(path: Path): return path.with_suffix(path.suffix + '.structure.json') def _mcio(): try: import mcio except ImportError: sys.path.insert(0, '/work/generator/MCIO') from mcio.sketch import LitematicCanvas from mcio.schematic import load_schematic from mcio.nbt import tag from mcio.nbt.nbt import File return LitematicCanvas, load_schematic, tag, File def _to_nbt(value, tag, key=''): if isinstance(value, dict): return tag.Compound({k: _to_nbt(v, tag, k) for k, v in value.items()}) if isinstance(value, list): if not value: return tag.List[tag.Compound]([]) items = [_to_nbt(v, tag) for v in value] return tag.List[type(items[0])](items) if isinstance(value, str): return tag.String(value) if isinstance(value, int): return tag.Byte(value) if key == 'Slot' else tag.Int(value) raise TypeError(type(value)) def _plain(value): if isinstance(value, dict): return {str(k): _plain(v) for k, v in value.items()} if isinstance(value, (list, tuple)): return [_plain(v) for v in value] if isinstance(value, str): return str(value) return int(value) def export_scene(scene, path: Path, verify=True): path = Path(path) scene.finalize() bounds = Box.enclosing(scene.blocks) if max(bounds.size) > scene.limits.dimension: raise ContractError('export-bounds', conditions=str(bounds)) if bounds.volume > scene.limits.export_volume: raise ContractError('export-volume', conditions=f'{bounds.volume} > {scene.limits.export_volume}') canvas_type, _, tag, nbtfile = _mcio() sx, sy, sz = bounds.size canvas = canvas_type((sy, sz, sx)) offset = bounds.lo block_entities = [] for p, cell in sorted(scene.blocks.items()): x, y, z = tuple(v - o for v, o in zip(p, offset)) canvas.block((y, z, x), cell.state) if cell.nbt is not None: block_entities.append(_to_nbt({**cell.nbt, 'x': x, 'y': y, 'z': z}, tag)) schematic = canvas.to_litematica(name='Hearth', author='Hearth procedural library', description='Contract-composed settlement; structural identity in companion JSON', minecraft_data_version=3955) nbt = schematic.write_to_nbt() nbt['Regions']['Hearth']['TileEntities'] = tag.List[tag.Compound](block_entities) nbt['Regions']['Hearth']['Entities'] = tag.List[tag.Compound]([]) path.parent.mkdir(parents=True, exist_ok=True) temporary = path.with_suffix(path.suffix + '.tmp') nbtfile(nbt).save(temporary) owners = sorted(scene.nodes) operations = sorted(scene.operations) owner_id, op_id = {v: i for i, v in enumerate(owners)}, {v: i for i, v in enumerate(operations)} data = {'format': 'hearth.structure', 'version': FORMAT_VERSION, 'implementation': __version__, 'minecraft_data_version': 3955, 'digest': semantic_digest(scene), 'offset': offset, 'size': bounds.size, 'seed': scene.seed, 'style': scene.style, 'preferences': {k: v.expression() for k, v in scene.preferences.items()}, 'domain': encode(scene.domain), 'limits': encode(scene.limits), 'scene_version': scene.version, 'nodes': encode(scene.nodes), 'relations': encode(scene.relations), 'dependencies': encode(scene.dependencies), 'operations': encode(scene.operations), 'erasures': [[list(p), owner] for p, owner in sorted(scene.erasures.items())], 'displaced': {k: [[list(p), encode(c)] for p, c in sorted(v.items())] for k, v in scene.displaced.items()}, 'events': encode(scene.events), 'port_uses': [[*k, v] for k, v in sorted(scene.port_uses.items())], 'owners': owners, 'operation_ids': operations, 'cells': [[*p, owner_id[c.owner], op_id[c.operation], list(c.shared)] for p, c in sorted(scene.blocks.items())]} target = companion_path(path) temporary_meta = target.with_suffix('.json.tmp') temporary_meta.write_text(json.dumps(data, sort_keys=True, separators=(',', ':'))) temporary.replace(path) temporary_meta.replace(target) if verify: restored = load_scene(path) if semantic_digest(restored) != semantic_digest(scene): raise ContractError('roundtrip', conditions='Semantic geometry differs') return path def load_scene(path: Path): path = Path(path) meta = companion_path(path) if not meta.exists(): raise ContractError('untrusted-structure', conditions='Missing companion; geometry cannot reconstruct semantic identity') data = json.loads(meta.read_text()) if data.get('format') != 'hearth.structure' or data.get('version') != FORMAT_VERSION: raise ContractError('untrusted-structure', conditions='Unknown companion format/version') _, load, _, nbtfile = _mcio() loaded = load(path) nbt = nbtfile.load_regardless_of_gzipped(filename=path) regions = nbt['Regions'] if len(regions) != 1 or int(nbt['MinecraftDataVersion']) != 3955: raise ContractError('transport', conditions='Require one Java 1.21.1 region') region = next(iter(regions.values())) if list(loaded.size_yzx) != [data['size'][1], data['size'][2], data['size'][0]]: raise ContractError('geometry-mismatch', conditions='Export dimensions changed') if region['Entities']: raise ContractError('geometry-mismatch', conditions='Unexpected entities') inventories = {} for entry in region['TileEntities']: item = _plain(entry) p = tuple(item.pop(k) + data['offset'][i] for i, k in enumerate(('x', 'y', 'z'))) inventories[p] = item from .environment.fields import from_expression scene = Scene(data['seed'], decode(data['limits']), decode(data['domain']), data.get('style'), {k: from_expression(v) for k, v in data.get('preferences', {}).items()}) scene.nodes = decode(data['nodes']) scene.relations = decode(data['relations']) for child, kind, parent in scene.relations: if kind in ('contained_by', 'attached_to'): scene.members.setdefault(parent, set()).add(child) scene.dependencies = decode(data['dependencies']) scene.operations = decode(data['operations']) scene.erasures = {tuple(p): owner for p, owner in data.get('erasures', [])} scene.events = decode(data['events']) scene.displaced = {k: {tuple(p): decode(c) for p, c in v} for k, v in data.get('displaced', {}).items()} scene.version = data['scene_version'] scene.port_uses = {(a, b): n for a, b, n in data['port_uses']} ownership = {tuple(row[:3]): row[3:] for row in data['cells']} scene.reverse = {k: set() for k in scene.nodes} ids = loaded.read_flat(0, loaded.volume).reshape(loaded.size_yzx) import numpy as np for y, z, x in np.argwhere(ids != 0): block = canonical(loaded.palette[int(ids[y, z, x])]) if block == AIR: continue p = tuple(int(v) + o for v, o in zip((x, y, z), data['offset'])) if p not in ownership: raise ContractError('geometry-mismatch', position=p, conditions='Unrecorded block') owner, op, shared = ownership[p] owner = data['owners'][owner] scene.blocks[p] = Cell(block, owner, data['operation_ids'][op], inventories.get(p), tuple(shared)) scene.reverse[owner].add(p) for participant in shared: scene.reverse_shared.setdefault(participant, set()).add(p) if set(ownership) != set(scene.blocks) or set(inventories) - set(scene.blocks) or semantic_digest(scene) != data['digest']: raise ContractError('geometry-mismatch', conditions='Schematic and structural companion are not a matching semantic pair') scene.finalize() return scene
hearth/composition.py
# High-level selection, arrangement, repetition, scattering and encapsulation. from dataclasses import dataclass from hearth.kernel import Capability, Contract, Plan, Child, ContractError, Rule from hearth.space import Box, Frame @dataclass(frozen=True) class Network: name: str envelope: Box recipe: object tags: tuple = ('composite',) rules: tuple[Rule, ...] = () def capability(self): return Capability(self.name, self.tags) def negotiate(self, ctx, parameters): return Contract(self.envelope, rules=self.rules) def realize(self, ctx, contract): return self.recipe(ctx) def encapsulate(name, envelope, recipe, tags=('composite',), rules=()): return Network(name, envelope, recipe, tags, rules) def attach(key, component, host, port, frame, verb='install', region=None): from hearth.kernel import Binding return Child(key, component, frame=frame, bindings=(Binding(host, port, verb, region),)) def arrange(components, origins, prefix='item'): components, origins = tuple(components), tuple(origins) if len(components) != len(origins): raise ValueError('One placement per component is required') return tuple(Child(f'{prefix}-{i}', c, frame=Frame(tuple(p))) for i, (c, p) in enumerate(zip(components, origins))) def repeat(component, origins, prefix='repeat'): return arrange([component for _ in origins], origins, prefix) def scatter(ctx, candidates, predicate, minimum, maximum, purpose='scatter'): candidates = sorted(set(candidates)) ctx.rng(purpose).shuffle(candidates) accepted = [] for p in candidates: if predicate(p, accepted): accepted.append(p) if len(accepted) >= maximum: break if len(accepted) < minimum: raise ContractError('scatter-minimum', ctx.path, conditions=f'Accepted {len(accepted)}, required {minimum}; finite candidate set exhausted') return tuple(accepted) def constrain(condition, rule, context, position=None, reason=''): if not condition: raise ContractError(rule, context.path, position, reason)
hearth/programs.py
# Lightweight high-level room-graph programs and settlement intent. from hearth import Scene, Box, Frame from hearth.randomness import Scope from hearth.kernel import Capability, Contract, Plan, Child, Binding, Rule, Port from hearth.environment import Terrain, gradient, wave, radial from hearth.components.building import Blueprint, Building, RoomSpec, adapted from hearth.components.landscape import PathNetwork, Landscape, LampPost, Terrace from hearth.components.primitives import Window from hearth.components.roofcraft import RoofDesign from hearth.composition import encapsulate def dwelling(seed): rng = Scope(seed).child('dwelling').stream('layout') rooms = [RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom')] if rng.choice((True, False)): rooms.append(RoomSpec(0, 1, 0, 'kitchen')) if rng.choice((True, False)): rooms.append(RoomSpec(1, 0, 0, 'library')) return Blueprint(tuple(rooms), bay=rng.choice((9, 11)), porch=True, roof_axis='auto', steep=True) def atelier(seed): rng = Scope(seed).child('atelier').stream('layout') rooms = [RoomSpec(0, 0, 0, 'workshop'), RoomSpec(1, 0, 0, 'storage')] if rng.choice((True, False)): rooms.append(RoomSpec(1, 0, 1, 'bedroom')) if rng.choice((True, False)): rooms.append(RoomSpec(0, 1, 0, 'kitchen')) return Blueprint(tuple(rooms), bay=rng.choice((9, 11)), porch=rng.choice((True, False)), roof_axis='x', roof_material='brick', steep=rng.choice((True, False)), window_component=Window(shutters=False)) def commons(seed): rng = Scope(seed).child('commons').stream('layout') rooms = [RoomSpec(0, 0, 0, 'library'), RoomSpec(0, 1, 0, 'living'), RoomSpec(1, 1, 0, 'kitchen')] for level in range(1, rng.choice((2, 3))): rooms.append(RoomSpec(0, 1, level, 'bedroom' if level == 1 else 'library')) if rng.choice((True, False)): rooms.append(RoomSpec(1, 0, 0, 'storage')) return Blueprint(tuple(rooms), bay=rng.choice((9, 11)), porch=True, roof_axis='z') PROGRAMS = {'dwelling': dwelling, 'atelier': atelier, 'commons': commons} def building_scene(design, seed=0, field=None, water=None): design.validate() b = design.bay width = (max(r.x for r in design.rooms) + 1) * b depth = (max(r.z for r in design.rooms) + 1) * b domain = Box((-8, -4, -18), (width + 8, 64, depth + 8)) scene = Scene(seed, domain=domain) expression = field if field is not None else gradient(base=4) + wave(.8, .1, .11, Scope(seed).stream('environment').random() * 6) scene.place('land', Terrain(domain, expression, water)) # Encapsulation preserves the public building instance as the selected child. choice = adapted('building', design, '/land') scene.compose_choice(choice) return scene.finalize() class Settlement: def __init__(self, designs, domain, terrain): self.designs = tuple(designs) self.domain = domain self.terrain = terrain def capability(self): return Capability('settlement.village', ('settlement', 'composite'), offers=('public-access',), guarantees=('building entrances connected',)) def negotiate(self, ctx, parameters): gateway = (0, ctx.elevation(0, -12) + 1, -12) interface = Box((-1, gateway[1] - 1, -12), (1, gateway[1] + 1, -12)) port = Port('public', 'public-access', Frame(gateway), interface, 10000, delegate=('connections', 'public')) return Contract(self.domain, ports=(port,), decisions={'buildings': len(self.designs), 'arrangement': 'opposed street with staggered frontage', 'circulation': ctx.scope.choose(('spine', 'loop'), 'circulation'), 'gateway': gateway}) def realize(self, ctx, contract): p = Plan() for i, design in enumerate(self.designs): row = i // 2 left = i % 2 == 0 z = row * 38 + ctx.scope.child(f'plot-{i}').choose((-2, 0, 2), 'frontage') origin = (-16, 0, z - design.bay // 2) if left else (16, 0, z + design.bay // 2) p.children.append(adapted(f'plot-{i}', design, self.terrain, Frame(origin, 1 if left else 3))) p.children.append(Child('square', Terrace(), frame=Frame((5, 0, 10)), bindings=(Binding(self.terrain, 'construction', 'fill'),))) p.children.append(Child('connections', SettlementConnections(len(self.designs), self.domain, self.terrain, contract.decisions['circulation'], contract.decisions['gateway']))) p.children.append(Child('landscape', Landscape(self.domain, self.terrain, 8, 12, 0.045))) return p class SettlementConnections: def __init__(self, count, domain, terrain, mode='spine', gateway=None): self.count = count self.domain = domain self.terrain = terrain self.mode = mode self.gateway = gateway def capability(self): return Capability('settlement.connections', ('connection', 'composite')) def negotiate(self, ctx, parameters): parent = ctx.path.rsplit('/', 1)[0] targets = tuple(ctx.local(ctx.view.port(f'{parent}/plot-{i}', 'street').frame.origin) for i in range(self.count)) targets = targets + (ctx.local(ctx.view.port(parent + '/square', 'entrance').frame.origin), self.gateway) interface = Box((self.gateway[0] - 1, self.gateway[1] - 1, self.gateway[2]), (self.gateway[0] + 1, self.gateway[1] + 1, self.gateway[2])) port = Port('public', 'public-access', Frame(self.gateway), interface, 10000, delegate=('paths', 'public')) return Contract(self.domain, ports=(port,), rules=(Rule('route', targets, self.domain, phase='complete'),)) def realize(self, ctx, contract): parent = ctx.path.rsplit('/', 1)[0] points = [] links = [] bindings = [Binding(self.terrain, 'construction', 'surface')] for i in range(self.count): host = f'{parent}/plot-{i}' port = ctx.view.port(host, 'street') x, y, z = ctx.local(port.frame.origin) lane = (-3 if x < 0 else 3) if self.mode == 'loop' else 0 points.extend(((x, y, z), (lane, ctx.elevation(lane, z) + 1, z))) links.append((2 * i, 2 * i + 1)) bindings.append(Binding(host, 'street', 'surface')) if i and self.mode == 'spine': links.append((2 * i - 1, 2 * i + 1)) if self.mode == 'loop': low = min(q[2] for q in points) high = max(q[2] for q in points) base = len(points) for x, z in ((-3, low), (-3, high), (3, high), (3, low)): points.append((x, ctx.elevation(x, z) + 1, z)) links.extend((base + i, base + (i + 1) % 4) for i in range(4)) square = ctx.local(ctx.view.port(parent + '/square', 'entrance').frame.origin) lane = 3 if self.mode == 'loop' else 0 points.extend((square, (lane, ctx.elevation(lane, square[2]) + 1, square[2]))) links.append((len(points) - 2, len(points) - 1)) if self.mode == 'spine': links.append((1, len(points) - 1)) points.append(self.gateway) links.append((1, len(points) - 1)) bindings.append(Binding(parent + '/square', 'entrance', 'surface')) p = Plan(children=[Child('paths', PathNetwork(tuple(points), tuple(links), gateway=self.gateway), bindings=tuple(bindings))]) for i in range(self.count): p.relations.append((ctx.path + '/paths', 'connects', f'{parent}/plot-{i}')) for i, z in enumerate(sorted({q[-1] for q in points[:self.count * 2]})): x = 5 if i % 2 else -5 y = ctx.elevation(x, z + 4) + 1 p.children.append(Child(f'lamp-{i}', LampPost(), frame=Frame((x, y, z + 4)))) return p def settlement_scene(seed=0, count=None): scope = Scope(seed) rng = scope.stream('settlement-layout') if count is None: count = rng.choice((3, 4, 5)) if count < 1: raise ValueError('A settlement needs at least one building') designs = [] for i in range(count): local = scope.child(f'building-{i}').stream('room-graph') rooms = [RoomSpec(0, 0, 0, local.choice(('living', 'workshop', 'library')))] for x, z in local.sample(((1, 0), (0, 1)), local.choice((0, 1, 2))): rooms.append(RoomSpec(x, z, 0, local.choice(('storage', 'kitchen', 'living')))) if local.choice((True, True, False)): column = local.choice(rooms) for level in range(1, local.choice((2, 2, 3))): rooms.append(RoomSpec(column.x, column.z, level, 'bedroom' if level == 1 else 'library')) bay = local.choice((9, 11)) porch = local.choice((True, True, False)) axis = local.choice(('auto', 'x', 'z')) material = local.choice(('deepslate_tile', 'brick')) steep = local.choice((True, True, False)) features = scope.child(f'building-{i}').stream('architectural-features') roof = RoofDesign(features.choice(((1, 2), (2, 1), (1, 1, 2))), features.choice((8, 10))) if steep else None balcony = porch and any((r.x, r.z, r.level) == (0, 0, 1) for r in rooms) and features.choice((True, False)) designs.append(Blueprint(tuple(rooms), bay=bay, porch=porch, roof_axis=axis, roof_material=material, steep=steep, roof_design=roof, porch_depth=features.choice((3, 4)), balcony=balcony, chimney=features.choice((True, False)))) rows = (count + 1) // 2 domain = Box((-49, -4, -23), (49, 64, (rows - 1) * 38 + 28)) field = gradient(.012, -.009, 4.8) + wave(.7, .075, .09, rng.random() * 6) + radial(-36, rows * 12, 26, 1.1) scene = Scene(seed, domain=domain) scene.place('land', Terrain(domain, field, edit_limit=20000)) scene.place('village', Settlement(designs, domain, '/land')) return scene.finalize()
hearth/assessment.py
# Reproducible corpus inputs, structural measurements and retained diagnostics. import hashlib import json import time from pathlib import Path from hearth.randomness import Scope from hearth.programs import PROGRAMS, building_scene, settlement_scene from hearth import Scene, Box from hearth.environment import Terrain from hearth.components.building import adapted from hearth.environment import gradient, wave, radial, constant from hearth.kernel import ContractError, SearchExhausted from hearth.persistence import semantic_digest, export_scene from hearth.blocks import name_of def adaptation_expression(environment_seed): rng = Scope(environment_seed).stream('frozen-environment') # Degenerate coefficients deliberately include exact flat ground. sx = rng.choice((-.045, 0, .045)) sz = rng.choice((-.035, 0, .035)) amplitude = rng.choice((0, .4, .8)) expression = gradient(sx, sz, 4) + wave(amplitude, .13, .11, rng.random() * 6) if environment_seed >= 8: mask = radial(8, 9, 28, .7).transformed(dx=2, dz=-1, scale=1.2) expression = expression.blend(gradient(-sz, sx, 4) + wave(.6, .07, .19), mask) else: expression = expression + radial(7, 8, 22, rng.choice((0, .4, .7))) expression = expression.clamp(2, 7) water = rng.choice((None, 5, 6)) return expression, water def freeze_environment(seed): expression, water = adaptation_expression(seed) scene = Scene(seed, domain=Box((-8, -4, -18), (34, 64, 34))) scene.place('land', Terrain(scene.domain, expression, water)) return scene.finalize() def adapt_frozen(environment, design, building_seed): scene = environment.fork(seed=building_seed) scene.compose_choice(adapted('building', design, '/land')) return scene.finalize() def principal_signature(scene): buildings = [] for path, node in sorted(scene.nodes.items()): if node.type != 'building.rooms': continue decision = node.contract.decisions # Realized node topology plus occupied envelope per room, normalized to building. rooms = [] roofs = [] for child, part in sorted(scene.nodes.items()): if not child.startswith(path + '/'): continue if part.type.startswith('room.'): origin = node.frame.inverse(part.frame.origin) occupied = scene.cells(child, True) relative = [part.frame.inverse(p) for p in occupied] bounds = [min(p[i] for p in relative) for i in range(3)] + [max(p[i] for p in relative) for i in range(3)] rooms.append([origin[0], origin[1] - decision['floor'], origin[2], part.type, part.contract.decisions['doors'], part.contract.decisions['stair_up'], bounds]) if part.type == 'roof.gable': roofs.append([part.contract.decisions['axis'], part.contract.decisions['span'], part.contract.decisions['steep'], len(scene.cells(child, True))]) buildings.append({'rooms': rooms, 'roofs': roofs, 'porch': decision['porch'], 'bay': decision['bay']}) layout = [] for node in scene.nodes.values(): if node.type == 'landscape.paths': pts = node.contract.decisions['waypoints'] layout.append({'points': [(p[0], p[-1]) for p in pts], 'links': node.contract.decisions['links']}) data = {'buildings': buildings, 'organization': layout} return hashlib.sha256(json.dumps(data, sort_keys=True, default=list).encode()).hexdigest(), data def contact_metrics(scene): foundations = [n for n in scene.nodes.values() if n.type == 'adapter.foundation'] data = [n.contract.decisions for n in foundations] edit_paths = {key for key, n in scene.nodes.items() if n.capability and set(n.capability.tags).intersection(('siteworks', 'path'))} occupied = sum(len(scene.cells(key)) for key in edit_paths) replacements = sum(len(scene.displaced.get(key, {})) for key in edit_paths) from hearth.blocks import solid, AIR excavated = sum(solid(old.state) and not solid(scene.blocks[p].state if p in scene.blocks else AIR) for key in edit_paths for p, old in scene.displaced.get(key, {}).items()) return {'fill': sum(d['fill'] for d in data), 'excavation': excavated, 'sitework_occupied_cells': occupied, 'replaced_cells': replacements, 'new_sitework_cells': occupied - replacements, 'strategies': [d['strategy'] for d in data], 'signature': hashlib.sha256(json.dumps(data, sort_keys=True).encode()).hexdigest()} def measured(label, recipe, inputs, output=None): start = time.perf_counter() result = {'label': label, 'inputs': inputs, 'attempts': 1, 'retries': 0} try: scene = recipe() scene.finalize() signature, structure = principal_signature(scene) choices = [e for e in scene.events if e['kind'] == 'candidate-selection'] if choices: result['attempts'] = sum(e['attempts'] for e in choices) result.update(status='validated', blocks=len(scene.blocks), components=len(scene.nodes), digest=semantic_digest(scene), principal_signature=signature, structure=structure, contact=contact_metrics(scene), accepted_candidates=sum(e['accepted'] for e in choices) if choices else 1, candidates=choices) # Hash independently frozen terrain before placement using persisted field input and current unchanged bed cells. if output: export_scene(scene, output) result['artifact'] = str(output) except SearchExhausted as exc: result.update(status='budget-exhausted', diagnostic=str(exc), accepted_candidates=0, attempts=getattr(exc, 'attempts', 1), candidates=getattr(exc, 'candidates', [])) except (ContractError, ValueError) as exc: result.update(status='incompatible' if isinstance(exc, ContractError) and exc.diagnostic.rule in ('site-relief', 'support-height', 'fill-volume', 'approach-detour') else 'defect', diagnostic=str(exc), accepted_candidates=0, attempts=getattr(exc, 'attempts', 1), candidates=getattr(exc, 'candidates', [])) result['seconds'] = round(time.perf_counter() - start, 4) return result def run_corpus(output: Path, seed=0, artifacts=False): output.mkdir(parents=True, exist_ok=True) rows = [] specs = [] environments = {} for env in range(16): expression, water = adaptation_expression(env + seed * 100) frozen = freeze_environment(env + seed * 100) environments[env + seed * 100] = frozen digest = semantic_digest(frozen) for build in range(4): specs.append({'environment_seed': env + seed * 100, 'building_seed': build, 'expression': expression.expression(), 'water': water, 'frozen_environment_digest': digest, 'environment_domain': [list(frozen.domain.lo), list(frozen.domain.hi)], 'held_out': env >= 8}) (output / 'adaptation-inputs.json').write_text(json.dumps(specs, indent=2)) for i, spec in enumerate(specs): expression, water = adaptation_expression(spec['environment_seed']) bs = spec['building_seed'] recipe = lambda e=environments[spec['environment_seed']], b=bs: adapt_frozen(e, PROGRAMS['dwelling'](b), b) artifact = Path('samples') / f'adaptation-{i:02d}.litematic' if artifacts and i in (0, 8, 35, 60) else None row = measured(f'adaptation-{i:02d}', recipe, spec, artifact) if semantic_digest(environments[spec['environment_seed']]) != spec['frozen_environment_digest']: raise AssertionError('Frozen environment mutated') rows.append(row) print(row['label'], row['status'], flush=True) for name, program in PROGRAMS.items(): for bs in range(8): artifact = Path('samples') / f'{name}-{bs}.litematic' if artifacts and bs in (0, 1, 6) else None row = measured(f'{name}-{bs}', lambda p=program, b=bs: building_scene(p(b), b), {'program': name, 'seed': bs}, artifact) rows.append(row) print(row['label'], row['status'], flush=True) for bs, count in [(s, None) for s in range(8)] + [(0, 3), (0, 6)]: label = f'settlement-{bs}-{count or "seeded"}' artifact = Path('samples') / (label + '.litematic') if artifacts and ((bs == 1 and count is None) or count in (3, 6)) else None row = measured(label, lambda b=bs, c=count: settlement_scene(b, c), {'program': 'settlement', 'seed': bs, 'count': count}, artifact) rows.append(row) print(label, row['status'], flush=True) for i in range(32): es = 1000 + seed * 100 + i rng = Scope(es).stream('stress') expression = (gradient(rng.choice((0, .12, .28, .45)), rng.choice((0, -.15, .2)), 4) + wave(rng.choice((0, 2, 5)), .13, .17, rng.random() * 6)).clamp(-2, 20) water = rng.choice((None, 5, 12)) bs = i % 8 row = measured(f'stress-{i:02d}', lambda e=expression, w=water, b=bs: building_scene(PROGRAMS['dwelling'](b), b, e, w), {'environment_seed': es, 'building_seed': bs, 'expression': expression.expression(), 'water': water}) rows.append(row) print(row['label'], row['status'], flush=True) (output / 'results.json').write_text(json.dumps(rows, indent=2)) summary = {} for name, subset in [('adaptation', rows[:64]), ('buildings', rows[64:88]), ('settlements', rows[88:98]), ('stress', rows[98:])]: good = [r for r in subset if r['status'] == 'validated'] summary[name] = {'inputs': len(subset), 'validated': len(good), 'incompatible': sum(r['status'] == 'incompatible' for r in subset), 'defects': sum(r['status'] == 'defect' for r in subset), 'budget_exhausted': sum(r['status'] == 'budget-exhausted' for r in subset), 'candidate_attempts': sum(r['attempts'] for r in subset), 'accepted_candidates': sum(r['accepted_candidates'] for r in subset), 'retries': sum(r['retries'] for r in subset), 'seconds': round(sum(r['seconds'] for r in subset), 3), 'observed_principal_signatures': len({r['principal_signature'] for r in good}), 'observed_contact_signatures': len({r['contact']['signature'] for r in good}), 'fill_range': [min((r['contact']['fill'] for r in good), default=0), max((r['contact']['fill'] for r in good), default=0)]} (output / 'summary.json').write_text(json.dumps(summary, indent=2)) manifest = [{'artifact': r['artifact'], 'inputs': r['inputs'], 'digest': r['digest'], 'status': r['status']} for r in rows if 'artifact' in r] (Path('samples') / 'replay-manifest.json').write_text(json.dumps(manifest, indent=2)) return summary
hearth/lodges.py
# Small architectural intent programs; all geometry remains in shared components. from hearth import Scene, Box from hearth.randomness import Scope from hearth.environment import Terrain, gradient, wave from hearth.components.building import Blueprint, RoomSpec, adapted from hearth.components.roofcraft import RoofDesign from hearth.components.grounds import GardenCourt def hillside_home(seed): rng = Scope(seed).stream('home-layout') rooms = [RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom'), RoomSpec(1, 0, 0, 'kitchen')] if rng.choice((True, False)): rooms += [RoomSpec(0, 1, 0, 'library')] return Blueprint(tuple(rooms), bay=rng.choice((11, 13)), roof_design=RoofDesign(rng.choice(((1, 2), (1, 1, 2)))), porch_depth=4, balcony=True, chimney=True) def gabled_hall(seed): rng = Scope(seed).stream('hall-layout') rooms = [RoomSpec(0, 0, 0, 'library'), RoomSpec(0, 1, 0, 'living'), RoomSpec(1, 1, 0, 'kitchen')] if rng.choice((True, False)): rooms += [RoomSpec(0, 1, 1, 'bedroom')] if rng.choice((True, False)): rooms += [RoomSpec(1, 0, 0, 'workshop')] return Blueprint(tuple(rooms), bay=rng.choice((9, 11)), roof_axis=rng.choice(('x', 'z')), roof_design=RoofDesign((1, 2), rng.choice((7, 10))), porch_depth=5, chimney=True) def high_house(seed): rng = Scope(seed).stream('vertical-layout') rooms = [RoomSpec(0, 0, level, purpose) for level, purpose in enumerate(('living', 'library', 'bedroom'))] rooms += [RoomSpec(1, 0, 0, 'kitchen')] if rng.choice((True, False)): rooms += [RoomSpec(1, 0, 1, 'workshop')] if rng.choice((True, False)): rooms += [RoomSpec(0, 1, 0, 'storage')] return Blueprint(tuple(rooms), bay=rng.choice((9, 11)), roof_design=RoofDesign((2, 1), 8), porch_depth=4, balcony=rng.choice((True, False)), chimney=True) def lodge_scene(design, seed=0, environment_seed=0, field=None, water=None, garden=True): """Freeze a general environment, then compose a building and its garden court.""" design.validate() w = (max(r.x for r in design.rooms) + 1) * design.bay d = (max(r.z for r in design.rooms) + 1) * design.bay domain = Box((-8, -3, -17), (w + 8, 72, d + 9)) rng = Scope(environment_seed).stream('environment') expression = field if field is not None else gradient(rng.choice((-.02, .02, .04)), .012, 2) + wave(.5, .12, .1, rng.random() * 6) scene = Scene(seed, domain=domain) scene.place('land', Terrain(domain, expression, water)) scene.finalize() scene.compose_choice(adapted('building', design, '/land')) if garden: scene.place('garden', GardenCourt('/building', '/land', domain)) return scene.finalize()
hearth/quality_assessment.py
# Finite individual-building assessment with independently frozen inputs and retained failures. from pathlib import Path import hashlib import json import time from hearth import Scene, Box, ContractError from hearth.kernel import SearchExhausted from hearth.randomness import Scope from hearth.environment import Terrain, gradient, wave from hearth.assessment import adaptation_expression, contact_metrics from hearth.components.building import adapted from hearth.lodges import hillside_home, gabled_hall, high_house, lodge_scene from hearth.persistence import export_scene, load_scene, semantic_digest, encode CLIENTS = {'home': hillside_home, 'hall': gabled_hall, 'high': high_house} DOMAIN = Box((-10, -4, -20), (40, 72, 40)) def fingerprint(value): return hashlib.sha256(json.dumps(value, sort_keys=True, default=list).encode()).hexdigest() def principal_signature(scene): """Measure current architecture independently of palette, contact and garden noise. Args: scene: A validated scene with automatic component records. Returns: A digest and its auditable normalized structural measurements. """ data = [] for path, node in sorted(scene.nodes.items()): if node.type != 'building.rooms': continue floor = node.contract.decisions['floor'] rows = [] for part in scene.nodes.values(): if not part.path.startswith(path + '/'): continue relative = node.frame.inverse(part.frame.origin) location = (relative[0], relative[1] - floor, relative[2]) if part.type.startswith('room.'): floor_cells = scene.cells(part.path + '/floor') footprint = sorted((part.frame.inverse(p)[0], part.frame.inverse(p)[2]) for p in floor_cells) rows.append(('room', location, part.type, part.contract.decisions['doors'], part.contract.decisions['stair_up'], fingerprint(footprint))) elif part.type in ('roof.profile', 'roof.gable', 'roof.dormer'): coordinates = sorted(part.frame.inverse(p) for p in scene.cells(part.path, descendants=True)) decisions = {k: v for k, v in part.contract.decisions.items() if k in ('axis', 'span', 'rise', 'steep', 'tops')} rows.append((part.type, location, decisions, fingerprint(coordinates))) elif part.type in ('attachment.porch', 'masonry.chimney'): rows.append((part.type, location, part.contract.decisions)) data.append(sorted(rows, key=lambda v: json.dumps(v, sort_keys=True))) return fingerprint(data), data def audit_pair(scene, path): """Verify complete structural records, actual cells, states, inventories and queries.""" restored = load_scene(path) for attr in ('nodes', 'relations', 'dependencies', 'operations', 'port_uses', 'displaced', 'reverse'): if encode(getattr(restored, attr)) != encode(getattr(scene, attr)): raise AssertionError('Roundtrip record mismatch: ' + attr) if semantic_digest(restored) != semantic_digest(scene): raise AssertionError('Geometry digest mismatch') queries = 0 for node in scene.nodes.values(): cells = scene.cells(node.path) if cells != restored.cells(node.path): raise AssertionError('Current-cell query mismatch') if cells: p = min(cells) if scene.inspect(p) != restored.inspect(p): raise AssertionError('Structural query mismatch') queries += 1 inventories = {p: c.nbt for p, c in scene.blocks.items() if c.nbt} if inventories != {p: c.nbt for p, c in restored.blocks.items() if c.nbt}: raise AssertionError('Inventory mismatch') return {'queries': queries, 'inventories': len(inventories), 'nodes': len(scene.nodes), 'digest': semantic_digest(restored)} def evaluate(label, inputs, recipe, artifact=None): start = time.perf_counter() row = {'label': label, 'inputs': inputs, 'attempts': 1, 'accepted_candidates': 0, 'retries': 0} try: scene = recipe() scene.finalize() events = [e for e in scene.events if e['kind'] == 'candidate-selection'] digest, architecture = principal_signature(scene) contact = contact_metrics(scene) contact['bearing_fill'] = sum(n.contract.decisions['fill'] for n in scene.nodes.values() if n.type == 'adapter.bearing-course') contact['fill'] += contact['bearing_fill'] row.update(status='validated', attempts=sum(e['attempts'] for e in events) or 1, accepted_candidates=sum(e['accepted'] for e in events) if events else 1, digest=semantic_digest(scene), principal_signature=digest, architecture=architecture, contact=contact, blocks=len(scene.blocks), nodes=len(scene.nodes), candidates=events, optional_omissions=[{'component': n.path, 'dormers': n.contract.decisions['omitted_optional_dormers']} for n in scene.nodes.values() if n.contract.decisions.get('omitted_optional_dormers')]) if artifact is not None: export_scene(scene, artifact) row.update(artifact=str(artifact), audit=audit_pair(scene, artifact)) except (ContractError, ValueError, AssertionError) as error: known = {'site-relief', 'support-height', 'fill-volume', 'contact-strategy', 'approach-detour', 'substrate-depth'} status = 'budget-exhausted' if isinstance(error, SearchExhausted) else 'incompatible' if isinstance(error, ContractError) and error.diagnostic.rule in known else 'defect' row.update(status=status, diagnostic=str(error), attempts=getattr(error, 'attempts', 1), candidates=getattr(error, 'candidates', [])) row['seconds'] = round(time.perf_counter() - start, 4) return row def summary(rows): valid = [r for r in rows if r['status'] == 'validated'] return {'inputs': len(rows), 'validated': len(valid), 'incompatible': sum(r['status'] == 'incompatible' for r in rows), 'defects': sum(r['status'] == 'defect' for r in rows), 'budget_exhausted': sum(r['status'] == 'budget-exhausted' for r in rows), 'candidate_attempts': sum(r['attempts'] for r in rows), 'accepted_candidates': sum(r['accepted_candidates'] for r in rows), 'seconds': round(sum(r['seconds'] for r in rows), 3), 'principal_signatures': len({r['principal_signature'] for r in valid}), 'contact_signatures': len({r['contact']['signature'] for r in valid}), 'fill_range': [min((r['contact']['fill'] for r in valid), default=0), max((r['contact']['fill'] for r in valid), default=0)]} def run(output, artifacts, seed=0): """Run the recorded finite recipe once per input without success-only resampling.""" output, artifacts = Path(output), Path(artifacts) output.mkdir(parents=True, exist_ok=True) artifacts.mkdir(parents=True, exist_ok=True) rows, frozen = [], {} specifications = [] for index in range(16): es = seed * 100 + index field, water = adaptation_expression(es) environment = Scene(es, domain=DOMAIN) environment.place('land', Terrain(DOMAIN, field, water)) environment.finalize() frozen[index] = environment specifications.append({'environment_seed': es, 'expression': field.expression(), 'water': water, 'digest': semantic_digest(environment), 'held_out_composition': index >= 8}) (output / 'frozen-inputs.json').write_text(json.dumps(specifications, indent=2)) def retain(row): rows.append(row) (output / 'results.json').write_text(json.dumps(rows, indent=2)) print(row['label'], row['status'], flush=True) for name, client in CLIENTS.items(): for bs in range(8): label = f'{name}-{bs}' artifact = artifacts / (label + '.litematic') if bs in (0, 1, 6) else None retain(evaluate(label, {'client': name, 'structure_seed': bs, 'environment_seed': bs + seed * 100}, lambda c=client, b=bs: lodge_scene(c(b), b, b + seed * 100), artifact)) structures = ((hillside_home, 0), (hillside_home, 1), (gabled_hall, 2), (high_house, 3)) for es, environment in frozen.items(): for index, (client, bs) in enumerate(structures): number = es * 4 + index label = f'adaptation-{number:02d}' inputs = {**specifications[es], 'client': client.__name__, 'structure_seed': bs} def place(e=environment, c=client, b=bs): scene = e.fork(seed=b) scene.compose_choice(adapted('building', c(b), '/land')) return scene.finalize() artifact = artifacts / (label + '.litematic') if number in (0, 8, 35, 60) else None retain(evaluate(label, inputs, place, artifact)) if semantic_digest(environment) != specifications[es]['digest']: raise AssertionError('Frozen environment changed') for index in range(16): es = 2000 + seed * 100 + index rng = Scope(es).stream('stress') field = (gradient(rng.choice((0, .12, .28, .45)), rng.choice((0, -.15, .2)), 4) + wave(rng.choice((0, 2, 5)), .13, .17, rng.random() * 6)).clamp(-2, 20) water = rng.choice((None, 5, 12)) environment = Scene(es, domain=DOMAIN) environment.place('land', Terrain(DOMAIN, field, water)) environment.finalize() bs = index % 8 def stress(e=environment, b=bs): s = e.fork(seed=b) s.compose_choice(adapted('building', high_house(b), '/land')) return s.finalize() retain(evaluate(f'stress-{index:02d}', {'environment_seed': es, 'structure_seed': bs, 'expression': field.expression(), 'water': water, 'frozen_digest': semantic_digest(environment)}, stress)) results = {'clients': summary(rows[:24]), 'adaptation': summary(rows[24:88]), 'stress': summary(rows[88:]), 'per_client': {name: summary([r for r in rows[:24] if r['inputs']['client'] == name]) for name in CLIENTS}} (output / 'summary.json').write_text(json.dumps(results, indent=2)) (artifacts / 'manifest.json').write_text(json.dumps([r for r in rows if 'artifact' in r], indent=2)) return results
hearth/validators.py
# Reusable geometric checks registered through the public validator extension point. from hearth.kernel.validation import validator, state, fail from hearth.blocks import solid, name_of @validator('vertical-cover') def vertical_cover(scene, node, rule): """Check actual weather cover along bounded world-vertical columns. Horizontal frame rotations preserve world Y. This is a voxel coverage check, not a fluid simulator or a structural-mechanics proof. """ for x, y, z in rule.cells: if not any(solid(state(scene, (x, yy, z))) or 'glass' in name_of(state(scene, (x, yy, z))) for yy in range(y, rule.box.hi[1] + 1)): yield fail('roof-cover', node, (x, y, z), 'Weather skin has an uncovered column')
hearth/kernel/contracts.py
# Serializable contracts, binding requests and pure candidate plans. from dataclasses import dataclass, field from typing import Any, Protocol from hearth.space import Box, Frame, Pos @dataclass(frozen=True) class Domain: minimum: float | None = None maximum: float | None = None choices: tuple = () def accepts(self, value): return (not self.choices or value in self.choices) and (self.minimum is None or value >= self.minimum) and (self.maximum is None or value <= self.maximum) @dataclass(frozen=True) class Capability: name: str tags: tuple[str, ...] parameters: dict[str, Domain] = field(default_factory=dict) offers: tuple[str, ...] = () assumptions: tuple[str, ...] = () adaptations: tuple[str, ...] = () guarantees: tuple[str, ...] = () version: str = '1' inputs: dict = field(default_factory=dict) locked: tuple[str, ...] = () @dataclass(frozen=True) class Rule: kind: str cells: tuple[Pos, ...] = () box: Box | None = None data: dict = field(default_factory=dict) phase: str = 'invariant' def transformed(self, frame): return Rule(self.kind, tuple(frame.point(p) for p in self.cells), frame.box(self.box) if self.box else None, self.data, self.phase) @dataclass(frozen=True) class Grant: key: str box: Box verbs: tuple[str, ...] tags: tuple[str, ...] = () limit: int = 100000 whole: bool = False @dataclass(frozen=True) class Port: key: str kind: str frame: Frame region: Box capacity: int = 1 grant: str | None = None alignment: int = 1 facts: dict = field(default_factory=dict) delegate: tuple[str, str] | None = None @dataclass(frozen=True) class Contract: envelope: Box ports: tuple[Port, ...] = () grants: tuple[Grant, ...] = () rules: tuple[Rule, ...] = () decisions: dict = field(default_factory=dict) reads: tuple[Box, ...] = () atomic_object: bool = False def transformed(self, frame): return Contract(frame.box(self.envelope), tuple(Port(p.key, p.kind, frame.compose(p.frame), frame.box(p.region), p.capacity, p.grant, p.alignment, p.facts, p.delegate) for p in self.ports), tuple(Grant(g.key, frame.box(g.box), g.verbs, g.tags, g.limit, g.whole) for g in self.grants), tuple(r.transformed(frame) for r in self.rules), self.decisions, tuple(frame.box(b) for b in self.reads), self.atomic_object) @dataclass(frozen=True) class Binding: host: str port: str verb: str = 'install' region: Box | None = None @dataclass(frozen=True) class Write: point: Pos state: str operation: str = 'realize' preserve_owner: bool = False nbt: dict | None = None @dataclass(frozen=True) class Child: key: str component: Any params: dict = field(default_factory=dict) frame: Frame = Frame() bindings: tuple[Binding, ...] = () seed: int | None = None @dataclass(frozen=True) class Choice: key: str candidates: tuple[Child, ...] score: Any tolerance: float = 0.5 @dataclass class Plan: writes: list[Write] = field(default_factory=list) children: list[Child] = field(default_factory=list) relations: list[tuple[str, str, str]] = field(default_factory=list) def block(self, point, state, operation='realize', **kwargs): self.writes.append(Write(tuple(point), state, operation, **kwargs)) def fill(self, box, state, operation='fill'): self.writes.extend(Write(p, state, operation) for p in box.cells()) class Component(Protocol): def capability(self) -> Capability: ... def negotiate(self, context, parameters: dict) -> Contract: ... def realize(self, context, contract: Contract) -> Plan: ... class Registry: def __init__(self): self.entries = {} def register(self, component): self.entries[component.capability().name] = component return component def select(self, *tags): return tuple(self.entries[k] for k in sorted(self.entries) if set(tags) <= set(self.entries[k].capability().tags))
hearth/kernel/errors.py
# Structured, stable diagnostics for failed contracts and searches. from dataclasses import dataclass @dataclass(frozen=True) class Diagnostic: rule: str component: str position: tuple | None conditions: str def __str__(self): return f'{self.rule}: {self.component} at {self.position}: {self.conditions}' class ContractError(ValueError): def __init__(self, rule, component='/', position=None, conditions=''): self.diagnostic = Diagnostic(rule, component, position, conditions) super().__init__(str(self.diagnostic)) class ValidationError(ContractError): def __init__(self, diagnostics): self.diagnostics = diagnostics self.diagnostic = diagnostics[0] ValueError.__init__(self, '\n'.join(map(str, diagnostics[:12]))) class SearchExhausted(ContractError): pass
hearth/kernel/view.py
# Read-only, domain-aware environmental observations. from dataclasses import dataclass from types import MappingProxyType import copy from hearth.blocks import AIR, solid, name_of, passable from hearth.kernel.errors import ContractError from hearth.space import Box @dataclass(frozen=True) class Observation: version: int region: Box elevation: int water: int | None material: str slope: int support_depth: int class ReadTrace: """Coalesce actual environmental reads and interface dependencies for one candidate.""" def __init__(self): self.low = None self.high = None self.sources = {} def point(self, p): if self.low is None: self.low = list(p) self.high = list(p) else: for i in range(3): self.low[i] = min(self.low[i], p[i]) self.high[i] = max(self.high[i], p[i]) def region(self, box): self.point(box.lo) self.point(box.hi) @property def bounds(self): return None if self.low is None else Box(tuple(self.low), tuple(self.high)) class View: def __init__(self, scene, trace=None): self.__scene = scene self.__trace = trace @property def version(self): return self.__scene.version @property def domain(self): return self.__scene.domain @property def style(self): return MappingProxyType(self.__scene.style) def preference(self, name, point): if self.domain and not self.domain.contains(point): raise ContractError("unknown-space", position=point) field = self.__scene.preferences.get(name) return None if field is None else field(point[0], point[2]) def state(self, p): p = tuple(p) if self.__trace: self.__trace.point(p) if self.domain and not self.domain.contains(p): raise ContractError('unknown-space', position=p, conditions='Outside explicit environment domain') record = self.__scene.blocks.get(p) return record.state if record else AIR def owner(self, p): if self.__trace: self.__trace.point(p) record = self.__scene.blocks.get(tuple(p)) return record.owner if record else None def supports(self, p): return solid(self.state(p)) def clear(self, box): return all(passable(self.state(p)) for p in box.cells()) def elevation(self, x, z, maximum=None): if self.domain is None: raise ContractError('unknown-space', position=(x, 0, z), conditions='No environmental domain') for y in range(self.domain.hi[1] if maximum is None else min(maximum, self.domain.hi[1]), self.domain.lo[1] - 1, -1): if self.supports((x, y, z)): return y raise ContractError('missing-substrate', position=(x, self.domain.lo[1], z), conditions='No actual solid substrate') def water(self, x, z): if self.domain is None: raise ContractError('unknown-space', position=(x, 0, z)) for y in range(self.domain.hi[1], self.domain.lo[1] - 1, -1): if name_of(self.state((x, y, z))) == 'water': return y return None def sample(self, x, z): y = self.elevation(x, z) heights = [self.elevation(x + dx, z + dz) for dx, dz in ((1, 0), (-1, 0), (0, 1), (0, -1)) if self.domain.contains((x + dx, y, z + dz))] depth = 0 for yy in range(y, self.domain.lo[1] - 1, -1): if not self.supports((x, yy, z)): break depth += 1 return Observation(self.version, Box((x, self.domain.lo[1], z), (x, self.domain.hi[1], z)), y, self.water(x, z), self.state((x, y, z)), max([abs(h - y) for h in heights] or [0]), depth) def port(self, host, key): node = self.__scene.nodes[host] for p in node.contract.ports: if p.key == key: if self.__trace: self.__trace.sources[host] = p.region return copy.deepcopy(p) raise ContractError('missing-port', host, conditions=key) def cost(self, path, tag=None): paths = [key for key, n in self.__scene.nodes.items() if (key == path or key.startswith(path + '/')) and (tag is None or (n.capability and tag in n.capability.tags))] occupied = sum(len(self.__scene.reverse.get(key, ())) for key in paths) replaced = sum(len(self.__scene.displaced.get(key, ())) for key in paths) return {'occupied': occupied, 'replaced': replaced, 'instances': len(paths)} def offers(self, host, kind=None): return tuple(copy.deepcopy(p) for p in self.__scene.nodes[host].contract.ports if kind is None or p.kind == kind) def capability(self, host): return copy.deepcopy(self.__scene.nodes[host].capability) def resolved_port(self, host, key): seen = set() while True: if (host, key) in seen: raise ContractError('port-cycle', host, conditions=key) seen.add((host, key)) port = self.port(host, key) if not port.delegate: return host, port child, key = port.delegate host = host + '/' + child def contract(self, path): if self.__trace: self.__trace.sources[path] = self.__scene.nodes[path].contract.envelope return copy.deepcopy(self.__scene.nodes[path].contract) def protected(self, box): if self.__trace: self.__trace.region(box) return any(r.kind in ('clear', 'protected') and any(box.contains(p) for p in r.cells) for n in self.__scene.nodes.values() for r in n.contract.rules) def obstacle_distance(self, p, radius=8): best = radius + 1 for q in Box(tuple(v - radius for v in p), tuple(v + radius for v in p)).cells(): if q in self.__scene.blocks and not passable(self.__scene.blocks[q].state): best = min(best, max(abs(a - b) for a, b in zip(p, q))) return best
hearth/kernel/validation.py
# Extensible actual-geometry validators and bounded player movement. from collections import deque from hearth.blocks import AIR, LIGHTS, name_of, parse, passable, solid, validate_state from hearth.kernel.errors import Diagnostic from hearth.space import Box VALIDATORS = {} def validator(name): def register(fn): VALIDATORS[name] = fn return fn return register def state(scene, p): record = scene.blocks.get(tuple(p)) return record.state if record else AIR def fail(kind, node, point, message): return Diagnostic(kind, node.path, point, message) @validator('protected') def protected(scene, node, rule): from hearth.blocks import blockstates_equivalent for p, expected in zip(rule.cells, rule.data['states']): if not blockstates_equivalent(state(scene, p), expected): yield fail('protected-region', node, p, 'Preserved geometry changed') @validator('support') def support(scene, node, rule): for p in rule.cells: if not solid(state(scene, p)): yield fail('support', node, p, 'Required actual load-bearing cell is missing') @validator('clear') def clear(scene, node, rule): for p in rule.cells: if not passable(state(scene, p)): yield fail('clearance', node, p, 'Protected player headroom is obstructed') @validator('sealed') def sealed(scene, node, rule): for p in rule.cells: if name_of(state(scene, p)) in ('air', 'water'): yield fail('enclosure', node, p, 'Enclosed boundary has a gap') @validator('expected') def expected(scene, node, rule): allowed = set(rule.data['names']) for p in rule.cells: if name_of(state(scene, p)) not in allowed: yield fail('expected-geometry', node, p, f'Expected one of {sorted(allowed)}') @validator('pool') def pool(scene, node, rule): for x, y, z in rule.cells: if name_of(state(scene, (x, y, z))) != 'water': yield fail('pool-water', node, (x, y, z), 'Pool water missing') for q in ((x, y - 1, z), (x - 1, y, z), (x + 1, y, z), (x, y, z - 1), (x, y, z + 1)): if not solid(state(scene, q)) and name_of(state(scene, q)) != 'water': yield fail('pool-containment', node, q, 'Basin leaks') def standable(scene, p): x, y, z = p return passable(state(scene, p)) and passable(state(scene, (x, y + 1, z))) and solid(state(scene, (x, y - 1, z))) def reachable(scene, start, box): if not standable(scene, start): return set() reached = {start} queue = deque([start]) while queue: x, y, z = queue.popleft() for dx, dz in ((1, 0), (-1, 0), (0, 1), (0, -1)): for dy in (0, 1, -1): q = (x + dx, y + dy, z + dz) if q not in reached and box.contains(q) and standable(scene, q): # Ascending requires clearance above the lower step as well. high = (x, y + 2, z) if dy == 1 else (q[0], q[1] + 2, q[2]) if dy and not passable(state(scene, high)): continue reached.add(q) queue.append(q) return reached @validator('route') def route(scene, node, rule): if not rule.cells or rule.box is None: yield fail('route-contract', node, None, 'Route needs start, targets and bounded search region') return reached = reachable(scene, rule.cells[0], rule.box) for p in rule.cells: if p not in reached: yield fail('reachability', node, p, 'No walkable route with two blocks of headroom from entrance') @validator('light') def light(scene, node, rule): sources = [p for p in rule.box.cells() if name_of(state(scene, p)) in LIGHTS] if not sources: yield fail('lighting', node, rule.box.lo, 'Completed room has no actual light source') return # Propagate actual sources through transmissive cells, with one unit attenuation. levels = {p: LIGHTS[name_of(state(scene, p))] for p in sources} queue = deque(sources) domain = rule.box.expand(1) while queue: p = queue.popleft() level = levels[p] - 1 if level < rule.data.get('minimum', 1): continue for dx, dy, dz in ((1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, -1, 0), (0, 0, 1), (0, 0, -1)): q = (p[0] + dx, p[1] + dy, p[2] + dz) if not domain.contains(q) or levels.get(q, 0) >= level: continue material = state(scene, q) if passable(material) or 'glass' in name_of(material) or name_of(material) == 'chain': levels[q] = level queue.append(q) for p in rule.cells: if levels.get(p, 0) < rule.data.get('minimum', 1): yield fail('lighting', node, p, 'Actual source attenuation/occlusion leaves required location dark') @validator('furnishing') def furnishing(scene, node, rule): names = {name_of(state(scene, p)) for p in rule.box.cells()} for group in rule.data['groups']: if not names.intersection(group): yield fail('furnishing', node, rule.box.lo, f'Missing functional furnishing: {group}') def validate(scene, final=False, completed_scope=None): diagnostics = [] for p, record in scene.blocks.items(): try: validate_state(record.state) except ValueError as exc: diagnostics.append(Diagnostic('blockstate', record.owner, p, str(exc))) continue if p not in scene.reverse.get(record.owner, set()): diagnostics.append(Diagnostic('reverse-index', record.owner, p, 'Current cell absent from reverse index')) if record.owner not in scene.nodes: diagnostics.append(Diagnostic('ownership', record.owner, p, 'Owner missing')) if record.nbt is not None: if record.nbt.get('id') != 'minecraft:' + name_of(record.state): diagnostics.append(Diagnostic('block-entity', record.owner, p, 'Block entity type mismatches actual block')) slots = set() for item in record.nbt.get('Items', []): if not 0 <= item.get('Slot', -1) < 27 or item['Slot'] in slots or not 1 <= item.get('count', 0) <= 64 or not item.get('id', '').startswith('minecraft:'): diagnostics.append(Diagnostic('inventory', record.owner, p, 'Invalid or duplicate inventory slot/item count')) slots.add(item.get('Slot')) name, props = parse(record.state) if name.endswith('_door') and not name.endswith('_trapdoor'): dy = 1 if props.get('half') == 'lower' else -1 q = (p[0], p[1] + dy, p[2]) other, op = parse(state(scene, q)) if other != name or op.get('half') == props.get('half') or any(op.get(k) != props.get(k) for k in ('facing', 'hinge', 'open', 'powered')): diagnostics.append(Diagnostic('door-pair', record.owner, p, 'Door halves absent or inconsistent')) if name.endswith('_bed'): direction = {'north': (0, -1), 'south': (0, 1), 'east': (1, 0), 'west': (-1, 0)}[props['facing']] sign = 1 if props['part'] == 'foot' else -1 q = (p[0] + direction[0] * sign, p[1], p[2] + direction[1] * sign) other, op = parse(state(scene, q)) if name != other or op.get('part') == props['part'] or op.get('facing') != props['facing']: diagnostics.append(Diagnostic('bed-pair', record.owner, p, 'Bed halves inconsistent')) if name_of(record.state) in ('sunflower', 'rose_bush', 'peony', 'lilac', 'tall_grass', 'large_fern'): dy = 1 if props.get('half') == 'lower' else -1 q = (p[0], p[1] + dy, p[2]) other, op = parse(state(scene, q)) if other != name or op.get('half') == props.get('half'): diagnostics.append(Diagnostic('plant-pair', record.owner, p, 'Tall plant halves inconsistent')) for owner, points in scene.reverse.items(): for p in points: if p not in scene.blocks or scene.blocks[p].owner != owner: diagnostics.append(Diagnostic('reverse-index', owner, p, 'Obsolete current membership')) for node in scene.nodes.values(): for port in node.contract.ports: if port.delegate and (node.complete or final): try: _, actual = scene.view.resolved_port(node.path, port.key) if (port.frame, port.region, port.kind) != (actual.frame, actual.region, actual.kind): diagnostics.append(Diagnostic('forwarded-interface', node.path, port.frame.origin, 'Child interface changed without parent renegotiation')) except (KeyError, ValueError): diagnostics.append(Diagnostic('forwarded-interface', node.path, port.frame.origin, 'Delegated port missing')) for parent in (node.parent, node.primary): if parent is not None and parent not in scene.nodes: diagnostics.append(Diagnostic('structure-graph', node.path, None, 'Current structural parent missing: ' + parent)) if final and (not node.complete or node.stale): diagnostics.append(Diagnostic('unfinished', node.path, None, 'Scope unfinished or dependent inputs stale')) for rule in node.contract.rules: if rule.phase == 'complete' and not final: scope = node closed = True while scope: closed = closed and scope.complete scope = scene.nodes.get(scope.parent) if completed_scope and (node.path == completed_scope or node.path.startswith(completed_scope + '/')): closed = node.complete if not closed: continue if rule.kind not in VALIDATORS: diagnostics.append(Diagnostic('unknown-validator', node.path, None, rule.kind)) else: diagnostics.extend(VALIDATORS[rule.kind](scene, node, rule)) return diagnostics
hearth/kernel/scene.py
# Transaction kernel, automatic ownership and separate semantic/dependency graphs. import copy from dataclasses import dataclass, field, replace, is_dataclass, fields from hearth.blocks import AIR, canonical, validate_state from hearth.space import Box, Frame from hearth.randomness import Scope from .contracts import Binding, Capability, Child, Choice, Contract, Domain, Plan from .errors import ContractError, ValidationError, SearchExhausted from .view import View, ReadTrace from .validation import validate @dataclass(frozen=True) class Limits: dimension: int = 512 blocks: int = 1000000 depth: int = 40 search: int = 24 instances: int = 10000 export_volume: int = 16000000 @dataclass(frozen=True) class Cell: state: str owner: str operation: str nbt: dict | None = None shared: tuple[str, ...] = () @dataclass class Node: path: str type: str version: str parameters: dict frame: Frame scope: Scope contract: Contract parent: str | None primary: str | None = None complete: bool = True stale: bool = False bindings: tuple = () capability: Capability | None = None shared_bindings: tuple = () @dataclass(frozen=True) class Context: path: str frame: Frame scope: Scope view: View bindings: tuple[Binding, ...] limits: Limits def rng(self, purpose='plan'): return self.scope.stream(purpose) def world(self, p): return self.frame.point(p) def local(self, p): return self.frame.inverse(p) def elevation(self, x, z, maximum=None): world = self.world((x, 0, z)) cap = None if maximum is None else maximum + self.frame.origin[1] return self.view.elevation(world[0], world[2], maximum=cap) - self.frame.origin[1] def water(self, x, z): world = self.world((x, 0, z)) level = self.view.water(world[0], world[2]) return None if level is None else level - self.frame.origin[1] def state(self, point): return self.view.state(self.world(point)) class Scene: def __init__(self, seed=0, limits=None, domain=None, style=None, preferences=None): if not isinstance(seed, int): raise TypeError('Seed must be an integer') self.seed = seed self.style = dict(style or {"timber": "spruce", "infill": "minecraft:smooth_sandstone", "roof": "deepslate_tile"}) self.preferences = dict(preferences or {}) self.limits = limits or Limits() self.domain = domain self.blocks = {} self.nodes = {} self.reverse = {} self.reverse_shared = {} self.relations = set() self.members = {} self.dependencies = [] self.operations = {} self.displaced = {} self.erasures = {} self.port_uses = {} self.version = 0 self.completed = False self._recipes = {} self.events = [] @property def view(self): return View(self) def _fork(self): other = copy.copy(self) other.blocks = self.blocks.copy() other.nodes = {p: copy.copy(n) for p, n in self.nodes.items()} other.reverse = {k: set(v) for k, v in self.reverse.items()} other.reverse_shared = {k: set(v) for k, v in self.reverse_shared.items()} other.relations = set(self.relations) other.members = {k: set(v) for k, v in self.members.items()} other.dependencies = list(self.dependencies) other.operations = copy.deepcopy(self.operations) other.displaced = {k: dict(v) for k, v in self.displaced.items()} other.erasures = dict(self.erasures) other.port_uses = dict(self.port_uses) other._recipes = self._recipes.copy() other.events = list(self.events) return other def fork(self, seed=None): """Copy a frozen composition; an optional seed controls future placements only.""" result = self._fork() if seed is not None: if not isinstance(seed, int): raise TypeError('Seed must be an integer') result.seed = seed return result def _commit(self, candidate): candidate.version += 1 candidate.completed = False self.__dict__.update(candidate.__dict__) def place(self, key, component, params=None, frame=Frame(), bindings=(), seed=None, complete=True): if not isinstance(key, str) or not key or any(c in key for c in '/#'): raise ContractError('instance-key', conditions='Keys must be nonempty and exclude / and #') candidate = self._fork() path = '/' + key candidate._instantiate(path, component, params or {}, frame, tuple(bindings), None, Scope(self.seed).child(key, seed), complete) candidate._check(False) self._commit(candidate) return path def compose_choice(self, choice): trial = self._fork() trial._select_child('', choice, Frame(), Scope(self.seed)) trial._check(False) self._commit(trial) return '/' + choice.key def choose(self, key, candidates, score=lambda scene, path: 0): accepted, failed = [], [] for index, child in enumerate(candidates): if index >= self.limits.search: break trial = self._fork() try: path = trial.place(key, child.component, child.params, child.frame, child.bindings, child.seed) accepted.append((score(trial, path), index, trial, path)) except ContractError as exc: failed.append(str(exc)) if not accepted: raise SearchExhausted('search-budget', '/' + key, conditions=f'No validated candidate within budget {self.limits.search}; failures={failed}') accepted.sort(key=lambda item: (item[0], item[1])) best_score = accepted[0][0] best = [c for c in accepted if c[0] <= best_score + 0.1] chosen = Scope(self.seed).child(key).choose(best, 'alternatives') self._commit(chosen[2]) self.events.append({'kind': 'search', 'key': key, 'accepted': len(accepted), 'rejected': len(failed), 'failures': failed}) return chosen[3] def _instantiate(self, path, component, params, frame, bindings, parent, scope, complete=True): if path in self.nodes: raise ContractError('duplicate-instance', path) if len(self.nodes) >= self.limits.instances: raise ContractError('instance-budget', path) if len(path.split('/')) > self.limits.depth: raise ContractError('recursion-budget', path) cap = component.capability() for key, value in params.items(): if key not in cap.parameters or not cap.parameters[key].accepts(value): raise ContractError('parameter-domain', path, conditions=f'{key}={value!r}') for key, domain in cap.inputs.items(): if not isinstance(domain, Domain): continue value = frame if key.startswith('frame.') else component parts = key.split('.')[1:] if key.startswith('frame.') else key.split('.') for part in parts: if part.startswith('_') or not hasattr(value, part): raise ContractError('capability-input', path, conditions=key) value = getattr(value, part) if not domain.accepts(value): raise ContractError('input-domain', path, conditions=f'{key}={value!r}') trace = ReadTrace() ctx = Context(path, frame, scope, View(self, trace), bindings, self.limits) local = component.negotiate(ctx, dict(params)) contract = local.transformed(frame) if max(contract.envelope.size) > self.limits.dimension: raise ContractError('dimension-budget', path) if parent and not all(self.nodes[parent].contract.envelope.contains(p) for p in contract.envelope.corners()): raise ContractError('child-envelope', path, contract.envelope.lo, f'Exceeds accepted parent {parent}') self.nodes[path] = Node(path, cap.name, cap.version, {"construction": describe_inputs(component), "arguments": dict(params)}, frame, scope, contract, parent, complete=False, bindings=bindings, capability=cap) self.displaced[path] = {} self.reverse[path] = set() self._recipes[path] = (component, params, frame, bindings, parent, scope, complete) if parent: self.relations.add((path, 'contained_by', parent)) self.members.setdefault(parent, set()).add(path) grants = [] for binding in bindings: if binding.host not in self.nodes: raise ContractError('missing-host', path, conditions=binding.host) effective_host, port = self.view.resolved_port(binding.host, binding.port) host = self.nodes[effective_host] use_key = (binding.host, binding.port) if self.port_uses.get(use_key, 0) >= port.capacity: raise ContractError('port-capacity', path, port.frame.origin, binding.port) self.port_uses[use_key] = self.port_uses.get(use_key, 0) + 1 if binding.verb == 'install': if not port.region.contains(frame.origin): raise ContractError('port-alignment', path, frame.origin, 'Origin outside installation region') if port.frame.inverse(frame.origin)[0] % port.alignment or frame.turn % 4 != port.frame.turn % 4: raise ContractError('port-alignment', path, frame.origin, 'Outside facade bay grid') grant = next((g for g in host.contract.grants if g.key == port.grant), None) if grant and binding.verb != 'connect': if binding.verb not in grant.verbs or (grant.tags and not set(cap.tags).intersection(grant.tags)): raise ContractError('permission-kind', path, frame.origin, f'{cap.tags} cannot {binding.verb} {binding.host}') grants.append((Binding(effective_host, port.key, binding.verb, binding.region), grant)) elif binding.verb != 'connect': raise ContractError('no-write-grant', path) kind = 'attached_to' if binding.verb == 'install' else ('connected_to' if binding.verb == 'connect' else 'supported_by') self.relations.add((path, kind, binding.host)) if kind == 'attached_to': self.members.setdefault(binding.host, set()).add(path) if kind == 'attached_to' and self.nodes[path].primary is None: self.nodes[path].primary = binding.host self.dependencies.append({'consumer': path, 'source': binding.host, 'version': self.version, 'region': binding.region or port.region.intersection(contract.envelope.expand(1)) or contract.envelope, 'reason': binding.verb}) for region in contract.reads: self.dependencies.append({'consumer': path, 'source': 'environment', 'version': self.version, 'region': region, 'reason': 'spatial-query'}) plan = component.realize(ctx, local) if trace.bounds: self.dependencies.append({'consumer': path, 'source': 'environment', 'version': self.version, 'region': trace.bounds, 'reason': 'observed-spatial-input'}) for source, region in sorted(trace.sources.items()): if source != path: self.dependencies.append({'consumer': path, 'source': source, 'version': self.version, 'region': region, 'reason': 'observed-interface-input'}) if not isinstance(plan, Plan): raise TypeError('Components return Plan effect sets') existing_consumers = set(self.nodes) - {path} final_writes = {} for write in plan.writes: p = frame.point(write.point) final_writes[p] = write protected_rules = [(n.path, r.box) for n in self.nodes.values() for r in n.contract.rules if r.kind == "protected" and r.box] retired = set() counts = {} for p, write in final_writes.items(): if not contract.envelope.contains(p): raise ContractError('envelope', path, p, 'Realization exceeds negotiated bounds') for protector, region in protected_rules: if region.contains(p) and protector != path: raise ContractError('protected-region', path, p, 'Immutable region held by ' + protector) old = self.blocks.get(p) if old and old.shared and not write.preserve_owner: raise ContractError('shared-consumer', path, p, 'Shared support requires explicit consumer rebinding') if old and write.preserve_owner and old.state.split('[')[0] != write.state.split('[')[0]: raise ContractError('property-update', path, p, 'Property adjustment must retain block type') if old and old.owner != path: authorization = next(((b, g) for b, g in grants if b.host == old.owner and g.box.contains(p) and (b.region is None or b.region.contains(p))), None) if authorization is None: raise ContractError('write-authority', path, p, f'Owned by {old.owner}; no scoped grant') binding, grant = authorization count_key = (binding.host, grant.key) counts[count_key] = counts.get(count_key, 0) + 1 if counts[count_key] > grant.limit: raise ContractError('edit-limit', path, p, f'Limit {grant.limit}') if self.nodes[old.owner].contract.atomic_object and not write.preserve_owner: if not grant.whole or not self.reverse[old.owner].issubset(final_writes): raise ContractError('whole-object', path, p, f'Partial replacement of {old.owner}') retired.add(old.owner) if old and old.owner != path: self.displaced[path].setdefault(p, old) if old: self.reverse[old.owner].discard(p) try: world_state = frame.state(write.state) validate_state(world_state) except ValueError as exc: raise ContractError('blockstate', path, p, str(exc)) from exc opid = path + '#' + write.operation operation = self.operations.setdefault(opid, {'component': path, 'name': write.operation, 'writes': 0, 'replaced': set()}) operation['writes'] += 1 if old: operation['replaced'].add(old.owner) if world_state == AIR: self.blocks.pop(p, None) self.erasures[p] = path else: self.erasures.pop(p, None) owner = old.owner if old and write.preserve_owner else path self.blocks[p] = Cell(canonical(world_state), owner, opid, write.nbt, old.shared if old and write.preserve_owner else ()) self.reverse[owner].add(p) for dependency in self.dependencies: consumer = dependency["consumer"] if consumer in existing_consumers and consumer != parent and not path.startswith(consumer + "/") and any(dependency["region"].contains(p) for p in final_writes): # Binding consumers remain valid only if their actual invariants hold. self.events.append({"kind": "revalidated-input", "consumer": consumer, "cause": path, "version": self.version}) for old in retired: self._retire(old) for child in plan.children: if isinstance(child, Choice): self._select_child(path, child, frame, scope) continue if not child.key or any(c in child.key for c in '/#'): raise ContractError('instance-key', path, conditions=child.key) self._instantiate(path + '/' + child.key, child.component, child.params, frame.compose(child.frame), child.bindings, path, scope.child(child.key, child.seed)) for port in contract.ports: if port.delegate: target, actual = self.view.resolved_port(path, port.key) if actual.frame != port.frame or actual.region != port.region or actual.kind != port.kind: raise ContractError('forwarded-interface', path, port.frame.origin, 'Realized child changed the negotiated public interface') self.relations.add((path, 'exposes', target)) for source, kind, target in plan.relations: if source not in self.nodes or target not in self.nodes: raise ContractError("dangling-relation", path, conditions=f"{source} {kind} {target}") self.relations.add((source, kind, target)) self.nodes[path].complete = complete if len(self.blocks) > self.limits.blocks: raise ContractError('block-budget', path) def _select_child(self, parent, choice, frame, scope): accepted = [] rejected = [] path = parent + '/' + choice.key for i, option in enumerate(choice.candidates[:self.limits.search]): trial = self._fork() try: trial._instantiate(path, option.component, option.params, frame.compose(option.frame), option.bindings, parent or None, scope.child(choice.key, option.seed).child(f'alternative-{i}')) trial._check(False, completed_scope=path) accepted.append((choice.score(trial.view, path), i, trial)) except ContractError as exc: rejected.append(exc.diagnostic) if not accepted: rules = {d.rule for d in rejected} if len(rules) == 1 and len(choice.candidates) <= self.limits.search: error = ContractError(next(iter(rules)), path, conditions='All declared alternatives violate the same condition: ' + str(rejected[0])) else: error = SearchExhausted('search-budget', path, conditions=str(rejected)) error.attempts = len(rejected) error.candidates = [d.__dict__ for d in rejected] raise error accepted.sort(key=lambda item: (item[0], item[1])) feasible = [a for a in accepted if a[0] <= accepted[0][0] + choice.tolerance] chosen = scope.child(choice.key).choose(feasible, 'adaptation-selection') self.__dict__.update(chosen[2].__dict__) self.events.append({'kind': 'candidate-selection', 'component': path, 'attempts': len(accepted) + len(rejected), 'accepted': len(accepted), 'rejected': [d.__dict__ for d in rejected], 'scores': [(a[1], round(a[0], 4)) for a in accepted], 'chosen': chosen[1]}) def _retire(self, path): if self.reverse.get(path): raise ContractError('whole-object', path, conditions='Cannot retire occupied instance') node = self.nodes.get(path) if node: for binding in node.bindings: key = (binding.host, binding.port) self.port_uses[key] = max(0, self.port_uses.get(key, 0) - 1) if node: for shared_host, shared_port, point in node.shared_bindings: key = (shared_host, shared_port) self.port_uses[key] = max(0, self.port_uses.get(key, 0) - 1) self.members.pop(path, None) for children in self.members.values(): children.discard(path) self.nodes.pop(path, None) self.reverse.pop(path, None) self._recipes.pop(path, None) self.relations = {r for r in self.relations if r[0] != path and r[2] != path} self.dependencies = [d for d in self.dependencies if d['consumer'] != path and d['source'] != path] self.port_uses = {k: v for k, v in self.port_uses.items() if k[0] != path} def _check(self, final, completed_scope=None): errors = validate(self, final, completed_scope) if errors: raise ValidationError(errors) def finalize(self): self._check(True) self.completed = True return self def finish_scope(self, path): trial = self._fork() trial.nodes[path].complete = True trial._check(True) self._commit(trial) def descendants(self, path): result = set() pending = [path] while pending: current = pending.pop() if current in result: continue result.add(current) pending.extend(sorted(self.members.get(current, ()))) return frozenset(result) def cells(self, path, descendants=False, shared=False): paths = [path] if descendants: paths = list(self.descendants(path)) return frozenset(p for k in paths for p in (self.reverse.get(k, set()) | (self.reverse_shared.get(k, set()) if shared else set()))) def inspect(self, point): point = tuple(point) record = self.blocks.get(point) if not record: return {'position': point, 'state': AIR, 'instance': None, 'chain': [], 'related': [], 'operation': None} chain, seen = [], set() path = record.owner while path and path not in seen: seen.add(path) node = self.nodes[path] chain.append({'id': path, 'type': node.type}) path = node.primary or node.parent related = sorted(r for r in self.relations if r[0] in seen or r[2] in seen) return {'position': point, 'state': record.state, 'instance': record.owner, 'chain': chain, 'related': related, 'operation': self.operations.get(record.operation), 'shared': record.shared, 'nbt': record.nbt} def share(self, point, participant, host, port): trial = self._fork() p = tuple(point) record = trial.blocks[p] offered = trial.view.port(host, port) if record.owner != host or offered.kind != 'shared-support' or not offered.region.contains(p) or participant not in trial.nodes: raise ContractError('shared-authority', participant, p) if participant in record.shared: return use_key = (host, port) if trial.port_uses.get(use_key, 0) >= offered.capacity: raise ContractError('port-capacity', participant, p) trial.port_uses[use_key] = trial.port_uses.get(use_key, 0) + 1 trial.reverse_shared.setdefault(participant, set()).add(p) from .contracts import Rule node = trial.nodes[participant] node.shared_bindings = node.shared_bindings + ((host, port, p),) node.contract = replace(node.contract, rules=node.contract.rules + (Rule('support', (p,)),)) trial.blocks[p] = replace(record, shared=tuple(sorted(set(record.shared + (participant,))))) trial.relations.add((participant, 'shares_support', host)) trial._check(False) self._commit(trial) def remove(self, path): trial = self._fork() trial._remove_branch(path) trial._check(False) self._commit(trial) def _remove_branch(self, path): paths = {k for k in self.nodes if k == path or k.startswith(path + '/')} affected = set() for k in sorted(paths, reverse=True): current = set(self.reverse[k]) | set(self.displaced.get(k, {})) for p in current: record = self.blocks.get(p) if record is None and self.erasures.get(p) not in paths: continue if record is not None and record.owner not in paths and self.operations[record.operation]['component'] not in paths: continue affected.add(p) if record is not None: self.reverse[record.owner].discard(p) self.erasures.pop(p, None) previous = self.displaced.get(k, {}).get(p) if previous and previous.owner in self.nodes and previous.owner not in paths: self.blocks[p] = previous self.reverse[previous.owner].add(p) else: self.blocks.pop(p, None) self.displaced.pop(k, None) for d in self.dependencies: if d['consumer'] not in paths and (d['source'] in paths or any(d['region'].contains(p) for p in affected)): self.nodes[d['consumer']].stale = True for k in sorted(paths, reverse=True): self.reverse_shared.pop(k, None) self.reverse[k].clear() self._retire(k) self.relations = {r for r in self.relations if r[0] in self.nodes and r[2] in self.nodes} for p, record in list(self.blocks.items()): if set(record.shared).intersection(paths): self.blocks[p] = replace(record, shared=tuple(s for s in record.shared if s not in paths)) def regenerate(self, path, component=None, params=None, dependents=(), seed=None, replacements=None): trial = self._fork() targets = [path] + list(dependents) updates = dict(replacements or {}) if set(updates) - set(targets) or len(set(targets)) != len(targets): raise ContractError('replay-targets', path, conditions='Replacements must name distinct explicit replay targets') if component is not None: if path in updates: raise ContractError('replay-targets', path, conditions='Supply a root replacement only once') updates[path] = component recipes = {} for p in targets: if p in trial._recipes: recipes[p] = trial._recipes[p] elif p in updates: n = trial.nodes[p] recipes[p] = (updates[p], n.parameters.get('arguments', {}), n.frame, n.bindings, n.parent, n.scope, n.complete) else: raise ContractError('replay-implementation', p, conditions='Reloaded branch needs an explicitly supplied component implementation') for p in targets: trial._remove_branch(p) for p in targets: comp, oldparams, frame, bindings, parent, scope, complete = recipes[p] if p == path and seed is not None: scope = scope.child('override', seed) trial._instantiate(p, updates.get(p, comp), params if p == path and params is not None else oldparams, frame, bindings, parent, scope, complete) trial._check(True) self._commit(trial) self.events.append({'kind': 'regenerated', 'targets': targets}) def describe_inputs(value): """Record declared public inputs without concrete-component dispatch.""" if value is None or isinstance(value, (str, int, float, bool)): return value if isinstance(value, (list, tuple)): return [describe_inputs(v) for v in value] if isinstance(value, dict): return {str(k): describe_inputs(v) for k, v in value.items()} if is_dataclass(value): return {'type': type(value).__module__ + '.' + type(value).__qualname__, 'inputs': {f.name: describe_inputs(getattr(value, f.name)) for f in fields(value)}} if callable(value): return {'program': value.__module__ + '.' + value.__qualname__} return {'type': type(value).__module__ + '.' + type(value).__qualname__, 'inputs': {k: describe_inputs(v) for k, v in vars(value).items() if not k.startswith('_')}}
hearth/kernel/__init__.py
# Public composition kernel, independent of architectural implementations. from .contracts import Binding, Capability, Child, Choice, Component, Contract, Domain, Grant, Plan, Port, Registry, Rule, Write from .errors import ContractError, Diagnostic, SearchExhausted, ValidationError from .scene import Context, Limits, Scene from .validation import validate, validator
hearth/environment/fields.py
# Serializable scalar-field expressions; recognizable terrain emerges from parameters. from dataclasses import dataclass import math @dataclass(frozen=True) class Field: op: str args: tuple def __call__(self, x, z): a = self.args if self.op == 'constant': return a[0] if self.op == 'gradient': return a[0] * x + a[1] * z + a[2] if self.op == 'wave': return a[0] * math.sin(x * a[1] + a[3]) * math.cos(z * a[2] + a[3]) if self.op == 'radial': return a[3] * max(0, 1 - math.hypot(x - a[0], z - a[1]) / a[2]) if self.op == 'add': return a[0](x, z) + a[1](x, z) if self.op == 'multiply': return a[0](x, z) * a[1](x, z) if self.op == 'blend': mask = min(1, max(0, a[2](x, z))) return (1 - mask) * a[0](x, z) + mask * a[1](x, z) if self.op == 'transform': return a[0]((x - a[1]) / a[3], (z - a[2]) / a[3]) if self.op == 'clamp': return max(a[1], min(a[2], a[0](x, z))) raise ValueError(self.op) def __add__(self, other): return Field('add', (self, as_field(other))) def __mul__(self, other): return Field('multiply', (self, as_field(other))) def blend(self, other, mask): return Field('blend', (self, as_field(other), as_field(mask))) def transformed(self, dx=0, dz=0, scale=1): if scale <= 0: raise ValueError('Scale must be positive') return Field('transform', (self, dx, dz, scale)) def clamp(self, low, high): return Field('clamp', (self, low, high)) def expression(self): return {'op': self.op, 'args': [a.expression() if isinstance(a, Field) else a for a in self.args]} def as_field(value): return value if isinstance(value, Field) else constant(value) def constant(value=0): return Field('constant', (value,)) def gradient(x=0, z=0, base=0): return Field('gradient', (x, z, base)) def wave(amplitude=1, frequency_x=0.1, frequency_z=0.1, phase=0): return Field('wave', (amplitude, frequency_x, frequency_z, phase)) def radial(x, z, radius, amplitude): if radius <= 0: raise ValueError('Radius must be positive') return Field('radial', (x, z, radius, amplitude)) def from_expression(expression): """Restore only declared field operations, never execute a serialized program.""" return Field(expression['op'], tuple(from_expression(a) if isinstance(a, dict) and 'op' in a else a for a in expression['args']))
hearth/environment/terrain.py
# Frozen field sampling, strata and water under scoped edit interfaces. import math from dataclasses import dataclass from hearth.space import Box, Frame from hearth.blocks import state_of from hearth.kernel import Capability, Contract, Grant, Port, Plan, Rule from .fields import Field @dataclass(frozen=True) class Terrain: area: Box field: Field water_level: int | None = None edit_limit: int = 2500 def capability(self): return Capability('terrain.field', ('environment', 'ground'), offers=('construction', 'planting'), guarantees=('frozen field inputs', 'actual 3D substrate')) def negotiate(self, ctx, parameters): ports = tuple(Port(k, k, Frame(self.area.lo), self.area, capacity=100000, grant=k) for k in ('construction', 'planting')) grants = (Grant('construction', self.area, ('excavate', 'fill', 'surface'), ('siteworks', 'path', 'pool'), self.edit_limit), Grant('planting', self.area, ('plant',), ('plant',), 0)) return Contract(self.area, ports, grants, decisions={'expression': self.field.expression(), 'water': self.water_level, 'edit_limit': self.edit_limit}) def realize(self, ctx, contract): plan = Plan() x0, bottom, z0 = self.area.lo x1, top, z1 = self.area.hi for x in range(x0, x1 + 1): for z in range(z0, z1 + 1): height = math.floor(self.field(x, z)) if not bottom <= height < top: raise ValueError(f'Terrain field exceeds negotiated vertical domain at {(x,z)}') for y in range(bottom, height + 1): material = 'stone' if y < height - 2 else ('dirt' if y < height else 'grass_block') if self.water_level is not None and height < self.water_level: material = 'gravel' if y == height else material plan.block((x, y, z), state_of(material), 'strata') if self.water_level is not None: for y in range(height + 1, self.water_level + 1): plan.block((x, y, z), state_of('water', level='0'), 'water-volume') return plan
hearth/environment/__init__.py
# Public environment operations. from .fields import Field, constant, gradient, radial, wave from .terrain import Terrain
hearth/components/primitives.py
# Small architectural components with executable contracts. from dataclasses import dataclass from hearth.space import Box, Frame from hearth.blocks import AIR, state_of, log, leaves, name_of from hearth.kernel import Capability, Contract, Domain, Grant, Port, Rule, Plan, Child, Binding, ContractError @dataclass(frozen=True) class Volume: box: Box material: str role: str = 'masonry' def capability(self): return Capability('volume.' + self.role, (self.role,)) def negotiate(self, ctx, parameters): return Contract(self.box) def realize(self, ctx, contract): plan = Plan() plan.fill(self.box, self.material) return plan @dataclass(frozen=True) class Grass: tall: bool = False def capability(self): return Capability('plant.grass', ('plant',), offers=('replacement',), assumptions=('substrate',)) def negotiate(self, ctx, parameters): box = Box((0, 0, 0), (0, int(self.tall), 0)) return Contract(box, (Port('replacement', 'planting', Frame(), box, grant='replace'),), (Grant('replace', box, ('plant',), ('tree',), 2, True),), (Rule('support', ((0, -1, 0),)),), atomic_object=True) def realize(self, ctx, contract): plan = Plan() if self.tall: for y, half in enumerate(('lower', 'upper')): plan.block((0, y, 0), state_of('tall_grass', half=half)) else: plan.block((0, 0, 0), state_of('short_grass')) return plan @dataclass(frozen=True) class Tree: height: int = 10 radius: int = 3 def capability(self): return Capability('plant.conifer', ('plant', 'tree'), {'height': Domain(5, 18), 'radius': Domain(1, 4)}, assumptions=('substrate',), adaptations=('prune canopy against obstacles within accepted radius',)) def negotiate(self, ctx, parameters): h, r = parameters.get('height', self.height), parameters.get('radius', self.radius) if not 5 <= h <= 18 or not 1 <= r <= 4: raise ContractError('tree-domain', ctx.path) return Contract(Box((-r, 0, -r), (r, h, r)), rules=(Rule('support', ((0, -1, 0),)), Rule('expected', ((0, 0, 0),), data={'names': ['spruce_log']})), decisions={'height': h, 'radius': r}, reads=(Box((-r, -1, -r), (r, h, r)),)) def realize(self, ctx, contract): p = Plan() h = contract.decisions['height'] radius = contract.decisions['radius'] for y in range(h): p.block((0, y, 0), log()) for y in range(3, h + 1): if y % 3 == 0 and y != h: continue r = min(radius, max(0, (h - y + 1) // 2)) if y % 3 == 0: r = max(0, r - 1) for x in range(-r, r + 1): for z in range(-r, r + 1): if abs(x) + abs(z) > r + 1 or (x == 0 and z == 0 and y < h): continue q = ctx.world((x, y, z)) if ctx.view.domain and not ctx.view.domain.contains(q): continue if name_of(ctx.view.state(q)) == 'air': p.block((x, y, z), leaves()) return p @dataclass(frozen=True) class Wall: width: int = 9 height: int = 5 thickness: int = 1 infill: str | None = None timber: str = 'stripped_spruce' def capability(self): return Capability('wall.framed', ('wall', 'enclosure'), offers=('window', 'door'), assumptions=('floor below',), guarantees=('frame preserved', 'sealed infill'), inputs={'width': Domain(5, 64), 'height': Domain(4, 12), 'thickness': Domain(1, 3), 'frame.turn': Domain(choices=(0, 1, 2, 3))}, locked=('width', 'height', 'thickness', 'infill')) def negotiate(self, ctx, parameters): w, h, t = self.width, self.height, self.thickness if not 5 <= w <= 64 or not 4 <= h <= 12 or not 1 <= t <= 3: raise ContractError('wall-domain', ctx.path) box = Box((0, 0, 0), (w - 1, h - 1, t - 1)) install = Box((1, 0, 0), (w - 2, h - 2, t - 1)) ports = (Port('infill', 'wall-installation', Frame((1, 0, 0)), install, 20, 'install', 1, {'thickness': t, 'sill': 1, 'margin': 1}),) grants = (Grant('install', install, ('install',), ('window', 'door'), w * h * t),) boundary = tuple(box.cells()) frame = tuple((x, y, z) for x in (0, w - 1) for y in range(-1, h) for z in range(t)) return Contract(box, ports, grants, (Rule('support', frame), Rule('sealed', boundary, phase='complete')), decisions={'width': w, 'height': h, 'thickness': t}) def realize(self, ctx, contract): p = Plan() p.fill(contract.envelope, self.infill or ctx.view.style['infill']) for x in (0, self.width - 1): p.fill(Box((x, 0, 0), (x, self.height - 1, self.thickness - 1)), log(self.timber)) p.fill(Box((0, self.height - 1, 0), (self.width - 1, self.height - 1, self.thickness - 1)), log(self.timber, 'x')) return p @dataclass(frozen=True) class Window: width: int = 2 height: int = 2 shutters: bool = True glass: str = 'minecraft:glass' def capability(self): return Capability('window.shuttered' if self.shutters else 'window.lattice', ('window', 'sealed-opening'), offers=('daylight',), adaptations=('depth reveal',), guarantees=('sealed opening', 'frame margins')) def negotiate(self, ctx, parameters): if not ctx.bindings: raise ContractError('window-host', ctx.path) port = ctx.view.port(ctx.bindings[0].host, ctx.bindings[0].port) depth = port.facts['thickness'] box = Box((-1, -1, -1), (self.width, self.height - 1, depth - 1)) inner = Box((0, 0, 0), (self.width - 1, self.height - 1, depth - 1)) if not all(port.region.contains(ctx.world(q)) for q in inner.corners()): raise ContractError('window-margins', ctx.path, ctx.frame.origin, 'Opening crosses excluded framing') return Contract(box, rules=(Rule('sealed', tuple(inner.cells())),), decisions={'depth': depth}) def realize(self, ctx, contract): p = Plan() d = contract.decisions['depth'] for z in range(d): p.fill(Box((0, 0, z), (self.width - 1, self.height - 1, z)), self.glass, 'glazing') if self.shutters: from hearth.blocks import slab for x in (-1, self.width): for y in range(self.height): p.block((x, y, -1), state_of('spruce_trapdoor', facing='north', half='bottom', open='true', powered='false', waterlogged='false'), 'shutters') for x in range(self.width): p.block((x, -1, -1), slab('spruce', 'top'), 'sill') else: for x in range(self.width): p.block((x, self.height - 1, -1), state_of('spruce_trapdoor', facing='north', half='top', open='false', powered='false', waterlogged='false'), 'hood') return p @dataclass(frozen=True) class Pool: width: int = 7 depth: int = 6 def capability(self): return Capability('water.basin', ('pool', 'siteworks'), adaptations=('bounded excavation',), guarantees=('contained water',)) def negotiate(self, ctx, parameters): box = Box((0, -2, 0), (self.width - 1, 0, self.depth - 1)) water = tuple(Box((1, -1, 1), (self.width - 2, 0, self.depth - 2)).cells()) return Contract(box, rules=(Rule('pool', water),), decisions={'excavation_limit': box.volume}) def realize(self, ctx, contract): p = Plan() p.fill(contract.envelope, state_of('smooth_sandstone'), 'basin') p.fill(Box((1, -1, 1), (self.width - 2, 0, self.depth - 2)), state_of('water', level='0'), 'water') return p @dataclass(frozen=True) class Assembly: name: str envelope: Box children: tuple[Child, ...] rules: tuple[Rule, ...] = () ports: tuple[Port, ...] = () def capability(self): return Capability(self.name, ('composite',)) def negotiate(self, ctx, parameters): return Contract(self.envelope, ports=self.ports, rules=self.rules) def realize(self, ctx, contract): return Plan(children=list(self.children))
hearth/components/__init__.py
# Public architectural components and their explicit intent records. from .building import Blueprint, Building, RoomSpec, adapted from .interior import Room, Light, Furniture, Door, Stair from .primitives import Wall, Window, Tree, Grass, Pool, Assembly
hearth/components/interior.py
# Usable doors, lights and furnished rooms assembled as semantic children. from dataclasses import dataclass from hearth.space import Box, Frame from hearth.blocks import state_of, stairs, slab, log from hearth.kernel import Capability, Contract, Domain, Grant, Port, Rule, Plan, Child, Binding, ContractError from .primitives import Volume, Wall, Window from .roofcraft import FlushWindow @dataclass(frozen=True) class Door: material: str = 'spruce' def capability(self): return Capability('opening.door', ('door', 'access'), guarantees=('paired halves', 'support', 'operable exit')) def negotiate(self, ctx, parameters): return Contract(Box((0, 0, 0), (0, 1, 0)), rules=(Rule('support', ((0, -1, 0),)),), atomic_object=True) def realize(self, ctx, contract): p = Plan() for y, half in enumerate(('lower', 'upper')): p.block((0, y, 0), state_of(self.material + '_door', facing='north', half=half, hinge='left', open='false', powered='false')) return p @dataclass(frozen=True) class Light: hanging: bool = True def capability(self): return Capability('light.lantern', ('light', 'room-light'), guarantees=('actual light source',)) def negotiate(self, ctx, parameters): return Contract(Box((0, 0, 0), (0, 1, 0)), rules=(Rule('expected', ((0, 0, 0),), data={'names': ['lantern']}),)) def realize(self, ctx, contract): p = Plan() p.block((0, 0, 0), state_of('lantern', hanging=str(self.hanging).lower(), waterlogged='false')) if self.hanging: p.block((0, 1, 0), state_of('chain', axis='y', waterlogged='false')) return p @dataclass(frozen=True) class Furniture: purpose: str = 'living' width: int = 11 depth: int = 11 def capability(self): return Capability('furniture.' + self.purpose, ('furniture', self.purpose), guarantees=('usable function',)) def negotiate(self, ctx, parameters): if self.purpose not in ('living', 'bedroom', 'workshop', 'library', 'kitchen', 'storage'): raise ContractError('room-function', ctx.path, conditions=self.purpose) return Contract(Box((1, 0, 1), (self.width - 2, 2, self.depth - 2))) def realize(self, ctx, contract): p = Plan() w, d = self.width, self.depth inventory = {'id': 'minecraft:barrel', 'Items': [{'Slot': 0, 'id': 'minecraft:bread', 'count': 6}, {'Slot': 1, 'id': 'minecraft:torch', 'count': 12}]} p.block((1, 0, d - 2), state_of('barrel', facing='north', open='false'), 'supplies', nbt=inventory) if self.purpose == 'bedroom': for z, part in ((2, 'foot'), (3, 'head')): p.block((2, 0, z), state_of('red_bed', facing='south', part=part, occupied='false'), 'bed') p.block((2, 0, d - 3), state_of('bookshelf')) elif self.purpose == 'library': for x in (2, 3, w - 3): for y in range(2): p.block((x, y, d - 2), state_of('bookshelf')) p.block((2, 0, 2), state_of('lectern', facing='south', has_book='false', powered='false')) elif self.purpose == 'workshop': p.block((2, 0, 2), state_of('crafting_table')) p.block((3, 0, 2), state_of('smithing_table')) p.block((2, 0, d - 3), state_of('anvil', facing='north')) elif self.purpose == 'kitchen': p.block((2, 0, 2), state_of('smoker', facing='south', lit='false')) p.block((3, 0, 2), state_of('furnace', facing='south', lit='false')) p.block((2, 0, d - 3), state_of('crafting_table')) else: for z in (2, 3): p.block((2, 0, z), stairs('spruce', 'east'), 'bench') p.block((w - 3, 0, d - 1 - z), stairs('spruce', 'west'), 'bench') p.block((3, 0, 2), state_of('spruce_fence', north='false', south='false', east='false', west='false', waterlogged='false')) p.block((3, 1, 2), state_of('spruce_pressure_plate', powered='false'), 'table') # Rugs avoid the central circulation cross and door landings. for x in (3, 4): for z in (d - 4, d - 3): p.block((x, 0, z), state_of('red_carpet'), 'rug') return p @dataclass(frozen=True) class Stair: rise: int = 6 width: int = 2 def capability(self): return Capability('circulation.stair', ('stairs', 'vertical-access'), guarantees=('walkable flight', 'two-block headroom')) def negotiate(self, ctx, parameters): points = tuple((x, i + 1, i) for i in range(self.rise) for x in range(self.width)) clear = tuple((x, i + k, i) for i in range(self.rise) for x in range(self.width) for k in (1, 2, 3)) support = tuple((x, i, i) for i in range(self.rise) for x in range(self.width)) box = Box((0, 0, -1), (self.width - 1, self.rise + 2, self.rise)) return Contract(box, rules=(Rule('support', support), Rule('clear', clear), Rule('route', points, box, phase='complete'))) def realize(self, ctx, contract): p = Plan() for i in range(self.rise): for x in range(self.width): for y in range(max(0, i - 1), i): p.block((x, y, i), state_of('spruce_planks'), 'stringer') p.block((x, i, i), stairs('spruce', 'south'), 'tread') return p @dataclass(frozen=True) class Room: purpose: str width: int = 11 depth: int = 11 doors: tuple[str, ...] = ('north',) windows: tuple[str, ...] = ('north', 'east', 'south', 'west') upper_open: bool = False stair_up: bool = False stair_down: bool = False window_component: object = None light_component: object = None sheltered_sides: tuple[str, ...] = () flush_sides: tuple[str, ...] = () def capability(self): return Capability('room.' + self.purpose, ('room', 'habitable', 'composite'), offers=('access',), guarantees=('lit', 'furnished', 'reachable', 'enclosed'), adaptations=('facade grid', 'substitutable windows and lights'), inputs={'width': Domain(choices=(9, 11, 13)), 'depth': Domain(choices=(9, 11, 13)), 'purpose': Domain(choices=('living', 'bedroom', 'library', 'workshop', 'kitchen', 'storage'))}, locked=('purpose', 'width', 'depth', 'doors', 'stair_up', 'stair_down')) def negotiate(self, ctx, parameters): w, d = self.width, self.depth if w not in (9, 11, 13) or d not in (9, 11, 13): raise ContractError('room-domain', ctx.path) doors = {'north': (w // 2, 1, 0), 'south': (w // 2, 1, d - 1), 'west': (0, 1, d // 2), 'east': (w - 1, 1, d // 2)} points = [doors[k] for k in self.doors] + [(w // 2, 1, d // 2)] if not self.doors: points = [(w // 2, 1, d // 2)] interior = Box((1, 1, 1), (w - 2, 5, d - 2)) boundary = [] for x in range(w): for z in range(d): # Upper landing leaves only the required stair slot open. if not (self.stair_down and x in (w - 4, w - 3) and 2 <= z <= 7): boundary.append((x, 0, z)) if not (self.stair_up and x in (w - 4, w - 3) and 2 <= z <= 7): boundary.append((x, 6, z)) function = {'bedroom': [['red_bed'], ['barrel']], 'workshop': [['crafting_table'], ['smithing_table']], 'library': [['bookshelf'], ['lectern']], 'kitchen': [['smoker'], ['furnace']], 'living': [['spruce_stairs'], ['barrel']], 'storage': [['barrel']]} rules = (Rule('route', tuple(points), Box((0, 1, 0), (w - 1, 8, d - 1)), phase='complete'), Rule('light', tuple(points), Box((0, 1, 0), (w - 1, 5, d - 1)), {'minimum': 1}, 'complete'), Rule('furnishing', box=interior, data={'groups': function[self.purpose]}, phase='complete'), Rule('sealed', tuple(boundary), phase='complete')) ports = tuple(Port(side, 'access', Frame(p), Box(p, (p[0], p[1] + 1, p[2])), 10) for side, p in doors.items() if side in self.doors) return Contract(Box((-1, 0, -1), (w, 9, d)), ports=ports, rules=rules, decisions={'purpose': self.purpose, 'doors': self.doors, 'windows': self.windows, 'stair_up': self.stair_up, 'stair_down': self.stair_down, 'flush_sides': self.flush_sides, 'sheltered_sides': self.sheltered_sides}) def realize(self, ctx, contract): w, d = self.width, self.depth p = Plan() floor = Plan() for x in range(w): for z in range(d): if not (self.stair_down and x in (w - 4, w - 3) and 2 <= z <= 7): floor.block((x, 0, z), state_of('dark_oak_planks' if x in (1, w - 2) or z in (1, d - 2) else 'spruce_planks')) p.children.append(Child('floor', Pattern('floor', Box((0, 0, 0), (w - 1, 0, d - 1)), tuple(floor.writes)))) if not self.upper_open: p.children.append(Child('ceiling', Volume(Box((0, 6, 0), (w - 1, 6, d - 1)), state_of('spruce_planks'), 'ceiling'))) walls = {'north': (Frame((0, 1, 0)), w), 'south': (Frame((w - 1, 1, d - 1), 2), w), 'east': (Frame((w - 1, 1, 1), 1), d - 2), 'west': (Frame((0, 1, d - 2), 3), d - 2)} for side, (frame, length) in walls.items(): wallpath = ctx.path + '/wall-' + side p.children.append(Child('wall-' + side, Wall(length, 5), frame=frame)) if side in self.doors: at = frame.compose(Frame((length // 2, 0, 0))) p.children.append(Child('door-' + side, Door(), frame=at, bindings=(Binding(wallpath, 'infill'),))) if side in self.windows: bays = (2, length - 4) if length >= 11 else ((1, length - 3) if length >= 9 else ((length - 2) // 2,)) for i, bay in enumerate(bays): if side in self.doors and abs(bay - length // 2) < 2: continue at = frame.compose(Frame((bay, 2, 0))) p.children.append(Child(f'window-{side}-{i}', self.window_component or (FlushWindow(2, 2) if side in self.flush_sides else Window()), frame=at, bindings=(Binding(wallpath, 'infill'),))) from .joinery import FacadeRelief for side, (frame, length) in walls.items(): if side in self.windows and side not in self.sheltered_sides: p.children.append(Child('joinery-' + side, FacadeRelief(length, access=side in self.doors), frame=frame, bindings=(Binding(ctx.path + '/wall-' + side, 'infill', 'connect'),))) from .furnishing import FurnishingLayout p.children.append(Child('furniture', FurnishingLayout(self.purpose, w, d, self.stair_up or self.stair_down), frame=Frame((0, 1, 0)))) for i, (x, z) in enumerate(((2, d - 3), (w - 3, 2))): if self.stair_up and i == 1: x = w // 2 p.children.append(Child(f'light-{i}', self.light_component or Light(), frame=Frame((x, 4, z)))) from .landscape import FacadeGarden p.children.append(Child('facade-garden', FacadeGarden(w, d, tuple(s for s in self.windows if s not in self.doors and s not in self.sheltered_sides and s not in self.flush_sides)))) if self.stair_up: p.children.append(Child('stairs', Stair(), frame=Frame((w - 4, 1, 2)))) return p @dataclass(frozen=True) class Pattern: role: str envelope: Box writes: tuple def capability(self): return Capability('surface.' + self.role, (self.role,)) def negotiate(self, ctx, parameters): return Contract(self.envelope) def realize(self, ctx, contract): return Plan(writes=list(self.writes))
hearth/components/roofs.py
# Pitched roof surfaces and open porch attachments with explicit overlap policy. from dataclasses import dataclass from hearth.space import Box, Frame from hearth.blocks import state_of, stairs, slab, log, name_of from hearth.kernel import Capability, Contract, Grant, Port, Rule, Plan, Child from .interior import Light from .primitives import Window @dataclass(frozen=True) class Roof: width: int depth: int axis: str = 'z' material: str = 'deepslate_tile' steep: bool = True def capability(self): return Capability('roof.gable', ('roof', 'enclosure'), offers=('junction',), adaptations=('abut taller wall', 'merge shared eaves'), guarantees=('pitched weather skin',)) def negotiate(self, ctx, parameters): span = self.width if self.axis == 'z' else self.depth height = (span + 2) // 2 + 2 box = Box((-1, -1, -1), (self.width, height, self.depth)) return Contract(box, (Port('junction', 'roof-seam', Frame(), box, 100, 'junction'),), (Grant('junction', box, ('join',), ('roof',), box.volume),), decisions={'axis': self.axis, 'span': span, 'steep': self.steep, 'material': self.material}) def realize(self, ctx, contract): p = Plan() w, d = self.width, self.depth span = w if self.axis == 'z' else d length = d if self.axis == 'z' else w for cross in range(-1, span + 1): step = min(cross + 1, span - cross) y = step if self.steep else (step + 1) // 2 face = ('east' if cross < span / 2 else 'west') if self.axis == 'z' else ('south' if cross < span / 2 else 'north') for along in range(-1, length + 1): x, z = (cross, along) if self.axis == 'z' else (along, cross) q = ctx.world((x, y, z)) existing = name_of(ctx.view.state(q)) if existing != 'air': # Negotiated abutment is only to actual masonry/roof boundaries. continue trim = along in (-1, length) material = 'dark_oak' if trim else self.material p.block((x, y, z), stairs(material, face), 'roof-course') for end in (0, length - 1): frame = Frame((0, 0, end)) if self.axis == 'z' else Frame((end, 0, span - 1), 3) p.children.append(Child(f'gable-{end}', Gable(span, self.steep), frame=frame)) for cross in (-1, span): for along in range(length): x, z = (cross, along) if self.axis == 'z' else (along, cross) if name_of(ctx.view.state(ctx.world((x, -1, z)))) == 'air': p.block((x, -1, z), slab('spruce', 'top'), 'eave') mid = span // 2 peak = min(mid + 1, span - mid) if self.steep else (min(mid + 1, span - mid) + 1) // 2 for along in range(-1, length + 1): x, z = (mid, along) if self.axis == 'z' else (along, mid) if name_of(ctx.view.state(ctx.world((x, peak + 1, z)))) == 'air': p.block((x, peak + 1, z), slab('dark_oak'), 'ridge') for along in (-1, length): x, z = (mid, along) if self.axis == 'z' else (along, mid) if name_of(ctx.view.state(ctx.world((x, peak + 2, z)))) == 'air': p.block((x, peak + 2, z), state_of('dark_oak_fence', north='false', south='false', east='false', west='false', waterlogged='false'), 'finial') return p @dataclass(frozen=True) class Porch: width: int depth: int = 3 balcony: bool = False def capability(self): return Capability('attachment.porch', ('attachment', 'access', 'composite'), offers=('access',), guarantees=('sheltered access', 'supported canopy', 'usable upper terrace when requested')) def negotiate(self, ctx, parameters): if not 3 <= self.depth <= 5: from hearth import ContractError raise ContractError('porch-depth', ctx.path) center = self.width // 2 clear = tuple((x, y, z) for x in range(center - 1, center + 2) for y in (1, 2) for z in range(-self.depth, 0)) support = tuple((x, y, -self.depth) for x in (0, self.width - 1) for y in range(6)) + tuple((x, 5, 0) for x in (0, self.width - 1)) rules = [Rule('clear', clear), Rule('support', support), Rule('route', ((center, 1, -1), (center, 1, -self.depth)), Box((0, 0, -self.depth), (self.width - 1, 3, 0)), phase='complete')] if self.balcony: guards = tuple((x, 7, -self.depth) for x in range(self.width)) + tuple((x, 7, z) for x in (0, self.width - 1) for z in range(-self.depth + 1, 0)) rules += [Rule('expected', guards, data={'names': ['spruce_fence']}), Rule('support', tuple((x, 6, z) for x in range(self.width) for z in range(-self.depth, 0)))] rules += [Rule('clear', tuple((center, y, z) for y in (7, 8) for z in range(-self.depth + 1, 1))), Rule('route', ((center, 7, 0), (center, 7, -self.depth + 1)), Box((0, 6, -self.depth), (self.width - 1, 9, 0)), phase='complete')] return Contract(Box((0, 0, -self.depth), (self.width - 1, 9, -1)), rules=tuple(rules), decisions={'balcony': self.balcony, 'depth': self.depth, 'width': self.width}) def realize(self, ctx, contract): p = Plan() w, d = self.width, self.depth p.fill(Box((0, 0, -d), (w - 1, 0, -1)), state_of('spruce_planks'), 'deck') for x in (0, w - 1): for z in (-d,): p.block((x, 1, z), state_of('stone_bricks'), 'post-shoe') p.fill(Box((x, 2, z), (x, 5, z)), log(), 'post') for x in range(w): p.block((x, 5, -d), log('spruce', 'x'), 'front-beam') if self.balcony: for z in range(-d, 0): p.block((x, 6, z), state_of('spruce_planks'), 'balcony-deck') else: for z in range(-d, 0): y = 6 + (z + d) // 3 p.block((x, y, z), stairs('deepslate_tile', 'south'), 'canopy') for x, facing in ((1, 'east'), (w - 2, 'west')): p.block((x, 4, -d), stairs('spruce', facing, half='top'), 'brace') rails = [] for x in range(w): if abs(x - w // 2) > 1: rails.append((x, 1, -d)) for x in (0, w - 1): rails.extend((x, 1, z) for z in range(-d + 1, -1)) if self.balcony: rails.extend((x, 7, -d) for x in range(w)) rails.extend((x, 7, z) for x in (0, w - 1) for z in range(-d + 1, 0)) rail_points = set(rails) neighbors = {'north': (0, 0, -1), 'south': (0, 0, 1), 'east': (1, 0, 0), 'west': (-1, 0, 0)} for x, y, z in rails: if (x in (0, w - 1) and y == 1 and z in (-d, -1)): continue connections = {side: str((x + dx, y + dy, z + dz) in rail_points).lower() for side, (dx, dy, dz) in neighbors.items()} p.block((x, y, z), state_of('spruce_fence', waterlogged='false', **connections), 'balustrade') for x in (1, w - 2): p.children.append(Child('lantern-' + str(x), Light(), frame=Frame((x, 3, -d + 1)))) if d >= 4: p.block((1, 1, -2), stairs('spruce', 'east'), 'porch-seat') p.block((w - 2, 1, -2), stairs('spruce', 'west'), 'porch-seat') return p @dataclass(frozen=True) class Gable: span: int steep: bool = True def capability(self): return Capability('wall.gable', ('wall', 'enclosure'), offers=('window',), adaptations=('abut existing upper wall',)) def negotiate(self, ctx, parameters): height = (self.span + 1) // 2 region = Box((1, 0, 0), (self.span - 2, height - 2, 0)) box = Box((0, -1, -1), (self.span - 1, height - 1, 0)) return Contract(box, (Port('infill', 'wall-installation', Frame((1, 0, 0)), region, 4, 'install', facts={'thickness': 1}),), (Grant('install', region, ('install',), ('window',), 30),)) def realize(self, ctx, contract): p = Plan() for x in range(self.span): step = min(x + 1, self.span - x) y = step if self.steep else (step + 1) // 2 for yy in range(y): if name_of(ctx.view.state(ctx.world((x, yy, 0)))) == 'air': p.block((x, yy, 0), log('spruce') if x in (0, self.span // 2, self.span - 1) else state_of('smooth_sandstone'), 'gable-infill') available = {w.point for w in p.writes} at = (self.span // 2 - 1, 0, 0) if self.steep and all((at[0] + x, y, 0) in available for x in range(2) for y in (0, 1)) and all(name_of(ctx.view.state(ctx.world((at[0] + x, 1, -1)))) == 'air' for x in range(2)): from hearth.kernel import Binding p.children.append(Child('window', Window(2, 2, False), frame=Frame(at), bindings=(Binding(ctx.path, 'infill'),))) return p
hearth/components/building.py
# Room-graph building composition and shared facade/roof planning. from dataclasses import dataclass from hearth.space import Box, Frame from hearth.kernel import Capability, Contract, Domain, Port, Plan, Child, Choice, Binding, Rule, ContractError from hearth.adapters.site import survey, Foundation, Approach, SiteLimits from .interior import Room from .roofs import Roof, Porch @dataclass(frozen=True) class RoomSpec: x: int z: int level: int purpose: str @dataclass(frozen=True) class Blueprint: rooms: tuple[RoomSpec, ...] bay: int = 11 porch: bool = True roof_axis: str = 'auto' roof_material: str = 'deepslate_tile' steep: bool = True window_component: object = None light_component: object = None roof_design: object = None porch_depth: int = 3 balcony: bool = False chimney: bool = False def normalized(self): return tuple(sorted(self.rooms, key=lambda r: (r.level, r.z, r.x, r.purpose))) @property def footprint(self): return tuple(sorted((r.x * self.bay + x, r.z * self.bay + z) for r in self.rooms if r.level == 0 for x in range(self.bay) for z in range(self.bay))) @property def chimney_anchor(self): back = max(r.z for r in self.rooms if r.level == 0) column = min(r.x for r in self.rooms if r.level == 0 and r.z == back) return (column * self.bay + self.bay // 2 - 1, (back + 1) * self.bay) @property def contact_footprint(self): cells = set(self.footprint) if self.porch: cells |= {(x, z) for x in range(self.bay) for z in range(-self.porch_depth, 0)} if self.chimney: cx, cz = self.chimney_anchor cells |= {(cx + x, cz + z) for x in range(3) for z in range(2)} return tuple(sorted(cells)) def validate(self): cells = {(r.x, r.z, r.level) for r in self.rooms} if len(cells) != len(self.rooms) or (0, 0, 0) not in cells or min(min(r.x, r.z, r.level) for r in self.rooms) < 0: raise ValueError('Unique nonnegative rooms and entrance room (0,0,0) required') if self.bay not in (9, 11, 13): raise ValueError('Supported room bays: 9, 11, 13') if not 3 <= self.porch_depth <= 5: raise ValueError('Porch depth must be 3..5') if self.balcony and (not self.porch or (0, 0, 1) not in cells): raise ValueError('Balcony requires porch and front upper room') for x, z, level in cells: if level and (x, z, level - 1) not in cells: raise ValueError('Upper rooms require a supporting lower room') reached = {(0, 0, 0)} while True: more = {p for p in cells if any(sum(abs(a - b) for a, b in zip(p, q)) == 1 for q in reached)} if more <= reached: break reached |= more if reached != cells: raise ValueError('Room adjacency graph disconnected') def roof_runs(rooms, preferred_axis='auto'): """Partition exposed room tops into contiguous runs with explicit ridge axes.""" cells = {(r.x, r.z, r.level) for r in rooms} top = {q for q in cells if (q[0], q[1], q[2] + 1) not in cells} groups = [] while top: x, z, level = min(top, key=lambda v: (v[2], v[1], v[0])) axis = preferred_axis if axis == 'auto': axis = 'x' if (x + 1, z, level) in top else 'z' run = [(x, z, level)] while (run[-1][0] + (axis == 'x'), run[-1][1] + (axis == 'z'), level) in top: run.append((run[-1][0] + (axis == 'x'), run[-1][1] + (axis == 'z'), level)) top -= set(run) groups.append((x, z, level, axis, len(run))) return tuple(groups) @dataclass(frozen=True) class Building: design: Blueprint terrain: str site_limits: SiteLimits = SiteLimits() support_strategy: str | None = None def capability(self): return Capability('building.rooms', ('building', 'habitable', 'composite'), offers=('entrance', 'street', 'attachment'), assumptions=('known ground', 'bounded relief'), adaptations=('foundation', 'approach', 'roof junction'), guarantees=('locked room graph', 'internal reachability', 'furnishing', 'lighting'), inputs={'design.bay': Domain(choices=(9, 11, 13)), 'room_graph': 'connected integer grid with supported levels', 'relief_limit': self.site_limits.relief, 'support_height_limit': self.site_limits.support_height, 'frame.turn': Domain(choices=(0, 1, 2, 3))}, locked=('design.rooms', 'design.bay', 'design.roof_axis', 'design.porch', 'frame.x', 'frame.z')) def negotiate(self, ctx, parameters): self.design.validate() b = self.design.bay rooms = self.design.normalized() measured = survey(ctx, self.design.contact_footprint, self.site_limits) if self.support_strategy is not None: if self.support_strategy not in measured['feasible_strategies']: raise ContractError('contact-strategy', ctx.path, ctx.frame.origin, 'Requested strategy incompatible with measured water/relief') measured['strategy'] = self.support_strategy floor = measured['floor'] height = max(r.level for r in rooms) * 6 width = (max(r.x for r in rooms) + 1) * b depth = (max(r.z for r in rooms) + 1) * b minimum = min(v[0] for v in measured['samples'].values()) front = self.site_limits.approach_length + (self.design.porch_depth if self.design.porch else 0) box = Box((-1, min(minimum - self.site_limits.bed_thickness + 1, 0), -front), (width, floor + height + b + 16, depth + (3 if self.design.chimney else 0))) points = tuple((r.x * b + b // 2, floor + r.level * 6 + 1, r.z * b + b // 2) for r in rooms) entrance = (b // 2, floor + 1, 0) route = Rule('route', (entrance,) + points, box, phase='complete') port = Port('entrance', 'access', Frame(entrance), Box(entrance, (entrance[0], entrance[1] + 1, entrance[2])), 10) decisions = {'floor': floor, 'relief': measured['relief'], 'wet': measured['wet'], 'foundation': measured['strategy'], 'rooms': [(r.x, r.z, r.level, r.purpose) for r in rooms], 'bay': b, 'roof_axis': self.design.roof_axis, 'porch': self.design.porch, 'roof_material': self.design.roof_material, 'steep': self.design.steep, 'balcony': self.design.balcony, 'porch_depth': self.design.porch_depth, 'chimney': self.design.chimney} approach = Approach(b // 2, floor, self.design.porch_depth if self.design.porch else 0, self.site_limits).negotiate(ctx, {}) access = approach.ports[0] route = Rule('route', (entrance,) + points + (access.frame.origin,), box, phase='complete') street = Port('street', access.kind, access.frame, access.region, access.capacity, facts={'external_connection_required': True}, delegate=('approach', 'street')) return Contract(box, ports=(port, street), rules=(route,), decisions=decisions, reads=(Box((0, minimum, 0), (width - 1, floor, depth - 1)),)) def realize(self, ctx, contract): p = Plan() b = self.design.bay floor = contract.decisions['floor'] rooms = self.design.normalized() cells = {(r.x, r.z, r.level) for r in rooms} groups = roof_runs(rooms, self.design.roof_axis) roof_axes = {(x + i * (axis == 'x'), z + i * (axis == 'z'), level): axis for x, z, level, axis, length in groups for i in range(length)} p.children.append(Child('foundation', Foundation(self.design.contact_footprint, floor, contract.decisions['foundation'], self.site_limits), bindings=(Binding(self.terrain, 'construction', 'fill', ctx.frame.box(contract.envelope)),))) # A spanning tree of vertical access: one flight per upper horizontal component. stair_columns = set() for level in sorted({r.level for r in rooms if r.level}): remaining = {(x, z) for x, z, l in cells if l == level} while remaining: seed = min(remaining) connected = {seed} while True: expanded = {v for v in remaining if any(abs(v[0] - q[0]) + abs(v[1] - q[1]) == 1 for q in connected)} if expanded <= connected: break connected |= expanded root = min(connected) stair_columns.add((root[0], root[1], level - 1)) remaining -= connected for r in rooms: adjacent = {'north': (r.x, r.z - 1, r.level), 'south': (r.x, r.z + 1, r.level), 'west': (r.x - 1, r.z, r.level), 'east': (r.x + 1, r.z, r.level)} doors = tuple(side for side, q in adjacent.items() if q in cells or (side == 'north' and (r.x, r.z, r.level) in ({(0, 0, 0), (0, 0, 1)} if self.design.balcony else {(0, 0, 0)}))) abutments = {side for side, (x, z, level) in adjacent.items() if level and (x, z, level - 1) in roof_axes and roof_axes[(x, z, level - 1)] == ('z' if side in ('north', 'south') else 'x')} windows = tuple(side for side, q in adjacent.items() if q not in cells and side not in abutments and not (self.design.chimney and side == 'south' and (r.x * b + b // 2 - 1, (r.z + 1) * b) == self.design.chimney_anchor)) key = f'room-{r.x}-{r.z}-{r.level}' flush = tuple(side for side, (x, z, level) in adjacent.items() if r.level and (x, z, level - 1) in cells and (x, z, level) not in cells) room = Room(r.purpose, b, b, doors, windows, (r.x, r.z, r.level + 1) in cells, (r.x, r.z, r.level) in stair_columns, (r.x, r.z, r.level - 1) in stair_columns, self.design.window_component, self.design.light_component, ('north',) if self.design.porch and r.x == 0 and r.z == 0 and r.level <= 1 else (), flush) p.children.append(Child(key, room, frame=Frame((r.x * b, floor + r.level * 6, r.z * b)))) if self.design.porch: p.children.append(Child('porch', Porch(b, self.design.porch_depth, self.design.balcony), frame=Frame((0, floor, 0)), bindings=(Binding(ctx.path + '/room-0-0-0', 'north', 'connect'),))) p.children.append(Child('approach', Approach(b // 2, floor, self.design.porch_depth if self.design.porch else 0, self.site_limits), bindings=(Binding(self.terrain, 'construction', 'surface', ctx.frame.box(contract.envelope)),))) if self.design.chimney: from .masonry import Chimney from hearth.adapters.bearing import BearingCourse cx, cz = self.design.chimney_anchor level = max(r.level for r in rooms if (r.x * b + b // 2 - 1, (r.z + 1) * b) == (cx, cz)) peak = max(self.design.roof_design.heights(b)) if self.design.roof_design else (b + 1) // 2 stack_height = level * 6 + 7 + peak + 4 p.children.append(Child('chimney-bearing', BearingCourse(3, 2), frame=Frame((cx, floor - 1, cz)), bindings=(Binding(self.terrain, 'construction', 'fill'),))) p.children.append(Child('chimney', Chimney(stack_height), frame=Frame((cx, floor, cz)))) # Roof and facade planners use the same public run partition. for i, (x, z, l, axis, length) in enumerate(groups): w = b * (length if axis == 'x' else 1) d = b * (length if axis == 'z' else 1) cover = self.design.roof_design.component(w, d, axis, self.design.roof_material) if self.design.roof_design else Roof(w, d, axis, self.design.roof_material, self.design.steep) p.children.append(Child(f'roof-{i}', cover, frame=Frame((x * b, floor + l * 6 + 7, z * b)))) return p def contact_quality(view, path): """Score actual candidate sitework plus exposed-support proportions.""" facts = view.contract(path).decisions cost = view.cost(path, 'siteworks') exposure = 0.4 if facts['foundation'] == 'piers' and not facts['wet'] and facts['relief'] < 2 else 0 return cost['occupied'] / 100 + cost['replaced'] / 50 + exposure def adapted(key, design, terrain, frame=Frame(), limits=SiteLimits()): """Compare complete bounded support alternatives with the principal design locked.""" candidates = tuple(Child(key, Building(design, terrain, limits, strategy), frame=frame) for strategy in ('stepped', 'piers')) return Choice(key, candidates, contact_quality)
hearth/components/constraints.py
# Reusable hard preservation and clearance components. from dataclasses import dataclass from hearth.kernel import Capability, Contract, Plan, Rule from hearth.space import Box @dataclass(frozen=True) class Preserve: region: Box def capability(self): return Capability('constraint.preserve', ('constraint', 'protected-region'), guarantees=('immutable existing region',)) def negotiate(self, ctx, parameters): cells = tuple(self.region.cells()) return Contract(self.region, rules=(Rule('protected', cells, self.region, {'states': [ctx.view.state(ctx.world(p)) for p in cells]}),)) def realize(self, ctx, contract): return Plan()
hearth/components/landscape.py
# Public paths, planted borders, lamps and constrained landscape compositions. from dataclasses import dataclass from hearth.space import Box, Frame from hearth.blocks import state_of, stairs, slab, log, leaves, name_of from hearth.kernel import Capability, Contract, Port, Grant, Rule, Plan, Child, Binding, ContractError from hearth.composition import scatter from .primitives import Tree, Grass from .interior import Light @dataclass(frozen=True) class PathNetwork: waypoints: tuple[tuple[int, int], ...] links: tuple[tuple[int, int], ...] width: int = 3 gateway: tuple | None = None def capability(self): return Capability('landscape.paths', ('path', 'connection'), offers=('public-access',), adaptations=('terrain treads', 'bounded retaining edges'), guarantees=('connected public routes',)) def _points(self): points = set() for a, b in self.links: x, z = self.waypoints[a][0], self.waypoints[a][-1] xx, zz = self.waypoints[b][0], self.waypoints[b][-1] dx = 1 if xx >= x else -1 dz = 1 if zz >= z else -1 offsets = range(-(self.width // 2), self.width // 2 + 1) if x != xx: for px in range(x, xx + dx, dx): for offset in offsets: points.add((px, z + offset)) if z != zz: for pz in range(z, zz + dz, dz): for offset in offsets: points.add((xx + offset, pz)) if x == xx and z == zz: for ox in offsets: for oz in offsets: points.add((x + ox, z + oz)) return sorted(points) def negotiate(self, ctx, parameters): points = [] for x, z in self._points(): hint = min(self.waypoints, key=lambda q: abs(q[0] - x) + abs(q[-1] - z)) maximum = hint[1] + ctx.frame.origin[1] if len(hint) == 3 else None wx, _, wz = ctx.world((x, 0, z)) h = ctx.view.elevation(wx, wz, maximum=maximum) - ctx.frame.origin[1] points.append((x, h, z)) if not points: raise ContractError('empty-path', ctx.path) box = Box.enclosing(points).expand(2) targets = [] surface = {(x, z): y for x, y, z in points} for q in self.waypoints: x, z = q[0], q[-1] targets.append((x, surface[(x, z)] + 1, z)) clears = tuple((x, y + k, z) for x, y, z in points for k in (1, 2)) public = self.gateway or targets[0] interface = Box((public[0] - 1, public[1] - 1, public[2]), (public[0] + 1, public[1] + 1, public[2])) return Contract(box, ports=(Port('public', 'public-access', Frame(public), interface, 10000, 'join'),), grants=(Grant('join', interface, ('surface',), ('path',), 9),), rules=(Rule('support', tuple(points)), Rule('clear', clears), Rule('route', tuple(targets), box, phase='complete')), decisions={'surface': points, 'waypoints': self.waypoints, 'links': self.links}, reads=(box,)) def realize(self, ctx, contract): p = Plan() rng = ctx.rng('materials') heights = {(x, z): y for x, y, z in contract.decisions['surface']} for x, y, z in contract.decisions['surface']: uphill = [] for dx, dz, face in ((1, 0, 'east'), (-1, 0, 'west'), (0, 1, 'south'), (0, -1, 'north')): if heights.get((x + dx, z + dz), y) > y: uphill.append(face) material = stairs('stone_brick', uphill[0]) if uphill else state_of(rng.choice(('stone_bricks', 'stone_bricks', 'andesite', 'cobblestone', 'mossy_stone_bricks'))) p.block((x, y, z), material, 'paving') return p @dataclass(frozen=True) class Planter: width: int = 3 flowers: tuple[str, ...] = ('cornflower', 'azure_bluet', 'allium') def capability(self): return Capability('garden.planter', ('decoration', 'plant'), guarantees=('grounded bed',)) def negotiate(self, ctx, parameters): return Contract(Box((0, 0, 0), (self.width - 1, 1, 1)), rules=(Rule('support', tuple((x, -1, z) for x in range(self.width) for z in range(2))),)) def realize(self, ctx, contract): p = Plan() rng = ctx.rng('flowers') for x in range(self.width): p.block((x, 0, 0), state_of('dirt'), 'soil') p.block((x, 1, 0), state_of(rng.choice(self.flowers)), 'flower') p.block((x, 0, 1), state_of('spruce_trapdoor', facing='south', half='bottom', open='true', powered='false', waterlogged='false'), 'edging') return p @dataclass(frozen=True) class LampPost: def capability(self): return Capability('landscape.lamppost', ('light', 'outdoor-light', 'composite')) def negotiate(self, ctx, parameters): return Contract(Box((0, 0, 0), (1, 4, 0)), rules=(Rule('support', ((0, -1, 0),)),)) def realize(self, ctx, contract): p = Plan() p.block((0, 0, 0), state_of('stone_bricks')) for y in range(1, 4): p.block((0, y, 0), state_of('spruce_fence', north='false', south='false', east='false', west='false', waterlogged='false')) p.block((0, 4, 0), slab('spruce')) p.block((1, 4, 0), slab('spruce')) p.children.append(Child('lantern', Light(), frame=Frame((1, 2, 0)))) return p @dataclass(frozen=True) class Landscape: area: Box terrain: str tree_minimum: int = 6 tree_maximum: int = 14 density: float = 0.08 sample_step: int = 4 spacing: int = 10 heights: tuple[int, ...] = (9, 11, 13, 15) def capability(self): return Capability('landscape.scatter', ('landscape', 'composite'), adaptations=('clearance-aware scattering',), guarantees=('minimum tree count', 'preserved routes')) def negotiate(self, ctx, parameters): if not 1 <= self.sample_step <= 8 or self.spacing < 7 or not self.heights or any(h < 5 or h > 18 for h in self.heights): raise ContractError('landscape-domain', ctx.path) return Contract(self.area, decisions={'minimum_trees': self.tree_minimum, 'maximum_trees': self.tree_maximum, 'density': self.density}) def realize(self, ctx, contract): p = Plan() x0, _, z0 = self.area.lo x1, _, z1 = self.area.hi candidates = [(x, z) for x in range(x0 + 4, x1 - 3, self.sample_step) for z in range(z0 + 4, z1 - 3, self.sample_step)] def legal(q, accepted): x, z = q if any(abs(x - a) + abs(z - b) < self.spacing for a, b in accepted): return False h = ctx.elevation(x, z) if name_of(ctx.state((x, h, z))) != 'grass_block': return False box = Box((x - 3, h + 1, z - 3), (x + 3, h + max(self.heights) + 1, z + 3)) return all(ctx.view.domain.contains(ctx.world(c)) for c in box.corners()) and ctx.view.clear(ctx.frame.box(box)) and not ctx.view.protected(ctx.frame.box(Box((x - 3, h, z - 3), (x + 3, h + 2, z + 3)))) chosen = scatter(ctx, candidates, legal, self.tree_minimum, self.tree_maximum, 'trees') for i, (x, z) in enumerate(chosen): y = ctx.elevation(x, z) + 1 h = ctx.scope.child(f'tree-{i}').choose(self.heights, 'height') p.children.append(Child(f'tree-{i}', Tree(h), frame=Frame((x, y, z)), bindings=(Binding(self.terrain, 'planting', 'plant'),))) rng = ctx.rng('groundcover') for x in range(x0 + 1, x1): for z in range(z0 + 1, z1): if rng.random() > self.density or any(abs(x - a) <= 3 and abs(z - b) <= 3 for a, b in chosen): continue h = ctx.elevation(x, z) if name_of(ctx.state((x, h, z))) != 'grass_block': continue if name_of(ctx.state((x, h + 1, z))) != 'air': continue if ctx.view.protected(ctx.frame.box(Box((x, h + 1, z), (x, h + 2, z)))): continue p.children.append(Child(f'grass-{x}-{z}', Grass(), frame=Frame((x, h + 1, z)), bindings=(Binding(self.terrain, 'planting', 'plant'),))) return p @dataclass(frozen=True) class FacadeGarden: width: int depth: int sides: tuple[str, ...] def capability(self): return Capability('facade.garden', ('decoration', 'plant'), adaptations=('avoid facade openings',), guarantees=('unobstructed doorways',)) def negotiate(self, ctx, parameters): return Contract(Box((-1, 0, -1), (self.width, 3, self.depth))) def realize(self, ctx, contract): p = Plan() w, d = self.width, self.depth frames = {'north': Frame((0, 0, -1)), 'south': Frame((w - 1, 0, d), 2), 'east': Frame((w, 0, 0), 1), 'west': Frame((-1, 0, d - 1), 3)} for side in self.sides: f = frames[side] length = w if side in ('north', 'south') else d for y in range(1, 4): q = f.point((1, y, 0)) if name_of(ctx.view.state(ctx.world(q))) == 'air': p.block(q, leaves('oak'), 'climber') for x in (2, length - 3): q = f.point((x, 0, 0)) above = f.point((x, 1, 0)) if name_of(ctx.view.state(ctx.world(q))) == 'air' and name_of(ctx.view.state(ctx.world(above))) == 'air': p.block(q, slab('spruce', 'top'), 'flower-shelf') p.block(above, state_of('potted_poppy' if x == 2 else 'potted_fern'), 'pot') return p @dataclass(frozen=True) class Well: def capability(self): return Capability('square.well', ('amenity', 'composite'), guarantees=('contained water', 'grounded cover')) def negotiate(self, ctx, parameters): basin = tuple((x, 1, z) for x in range(1, 3) for z in range(1, 3)) return Contract(Box((-1, 0, -1), (4, 6, 4)), rules=(Rule('support', tuple((x, -1, z) for x in range(4) for z in range(4))), Rule('pool', basin), Rule('support', tuple((x, y, z) for x, z in ((0, 0), (3, 3)) for y in range(2, 6))))) def realize(self, ctx, contract): p = Plan() p.fill(Box((0, 0, 0), (3, 1, 3)), state_of('stone_bricks'), 'basin') p.fill(Box((1, 1, 1), (2, 1, 2)), state_of('water', level='0'), 'water') for x, z in ((0, 0), (3, 3)): p.fill(Box((x, 2, z), (x, 5, z)), log(), 'post') for x in range(-1, 5): for z in range(-1, 5): p.block((x, 5 if x in (-1, 4) else 6, z), slab('dark_oak'), 'shelter') return p @dataclass(frozen=True) class Terrace: width: int = 10 depth: int = 10 def capability(self): return Capability('site.terrace', ('siteworks', 'composite'), adaptations=('small local fill', 'retaining border'), guarantees=('level civic amenity pad',)) def negotiate(self, ctx, parameters): heights = [ctx.view.elevation(ctx.world((x, 0, z))[0], ctx.world((x, 0, z))[2]) - ctx.frame.origin[1] for x in range(self.width) for z in range(self.depth)] top = max(heights) if top - min(heights) > 3: raise ContractError('terrace-relief', ctx.path, conditions='Small terrace limit is 3') region = Box((0, top, 0), (self.width - 1, top + 2, self.depth - 1)) return Contract(Box((0, min(heights), 0), (self.width - 1, top + 8, self.depth - 1)), ports=(Port('entrance', 'public-access', Frame((0, top + 1, self.depth // 2)), region, 10, 'paving'),), grants=(Grant('paving', region, ('surface',), ('path',), 32),), decisions={'height': top, 'fill': sum(top - h for h in heights), 'excavation': 0}) def realize(self, ctx, contract): p = Plan() top = contract.decisions['height'] for x in range(self.width): for z in range(self.depth): wx, _, wz = ctx.world((x, 0, z)) bed = ctx.view.elevation(wx, wz) - ctx.frame.origin[1] for y in range(bed, top + 1): material = 'cobblestone' if y < top else ('stone_bricks' if x in (0, self.width - 1) or z in (0, self.depth - 1) else 'andesite') p.block((x, y, z), state_of(material), 'terrace-paving') p.children.append(Child('well', Well(), frame=Frame((3, top + 1, 3)))) for i, x in enumerate((1, self.width - 2)): p.children.append(Child(f'planter-{i}', Planter(2), frame=Frame((x if i == 0 else x - 1, top + 1, 1)))) return p
hearth/components/roofcraft.py
# Profile-driven roof assemblies with scoped, replaceable dormer openings. from dataclasses import dataclass from hearth import Box, Frame, ContractError from hearth.kernel import Capability, Contract, Domain, Port, Grant, Rule, Plan, Child, Binding from hearth.blocks import AIR, name_of, solid, state_of, stairs, slab, log from .primitives import Window @dataclass(frozen=True) class RoofDesign: """Specify rising courses, spacing of dormers, and coherent material roles.""" rise: tuple[int, ...] = (1, 2) dormer_spacing: int = 8 dormer_sides: tuple[str, ...] = ('left', 'right') trim: str = 'dark_oak' def heights(self, span): if not self.rise or any(v not in (1, 2) for v in self.rise): raise ValueError('Roof rise sequence must contain only 1 or 2') if self.dormer_spacing and not 7 <= self.dormer_spacing <= 16: raise ValueError('Dormer spacing is zero or 7..16') if len(set(self.dormer_sides)) != len(self.dormer_sides) or set(self.dormer_sides) - {'left', 'right'}: raise ValueError('Dormer sides must be distinct left/right') levels = [0] for i in range((span + 1) // 2): levels.append(levels[-1] + self.rise[i % len(self.rise)]) return tuple(levels[min(x + 1, span - x)] for x in range(-1, span + 1)) def component(self, width, depth, axis, material): return ProfileRoof(width, depth, axis, material, self) @dataclass(frozen=True) class ProfileRoof: width: int depth: int axis: str = 'z' material: str = 'deepslate_tile' design: RoofDesign = RoofDesign() def capability(self): return Capability('roof.profile', ('roof', 'enclosure', 'composite'), inputs={'width': Domain(7, 64), 'depth': Domain(7, 128), 'axis': Domain(choices=('x', 'z'))}, guarantees=('continuous weather cover', 'sealed attached dormers'), version='1') def negotiate(self, ctx, parameters): span = self.width if self.axis == 'z' else self.depth levels = self.design.heights(span) bearings = tuple((x, -1, z) for x in (0, self.width - 1) for z in range(0, self.depth, 4)) + tuple((x, -1, z) for z in (0, self.depth - 1) for x in range(0, self.width, 4)) return Contract(Box((-1, -1, -1), (self.width, max(levels) + 4, self.depth)), rules=(Rule('support', bearings),), decisions={'axis': self.axis, 'span': span, 'rise': self.design.rise, 'dormer_spacing': self.design.dormer_spacing, 'dormer_sides': self.design.dormer_sides}) def realize(self, ctx, contract): span = self.width if self.axis == 'z' else self.depth length = self.depth if self.axis == 'z' else self.width frame = Frame() if self.axis == 'z' else Frame((0, 0, span - 1), 3) return Plan(children=[Child('cover', RoofCover(span, length, self.material, self.design), frame=frame)]) @dataclass(frozen=True) class RoofCover: span: int length: int material: str design: RoofDesign populate: bool = True def capability(self): return Capability('roof.weather-cover', ('roof', 'enclosure', 'composite'), offers=('roof-installation',), adaptations=('measured solid abutments', 'scoped dormer cuts'), guarantees=('actual projected weather skin', 'bounded opening authority')) def negotiate(self, ctx, parameters): levels = self.design.heights(self.span) peak = max(levels) box = Box((-1, -1, -1), (self.span, peak + 4, self.length)) mounts, rejected = [], [] if self.design.dormer_spacing: centers = range(4, self.length - 3, self.design.dormer_spacing) for side in self.design.dormer_sides: for center in centers: frame = Frame((self.span - 1, 1, center - 2), 1) if side == 'right' else Frame((0, 1, center + 2), 3) region = frame.box(Box((0, 0, 0), (4, peak + 2, 2))) # Avoid prospective dormer intersection with an existing upper room/wing. if all(name_of(ctx.state(q)) == 'air' for q in region.cells()): mounts.append((f'{side}-{center}', frame, region)) else: rejected.append((side, center, 'existing upper volume')) ports = tuple(Port(key, 'roof-installation', frame, region, 1, key, facts={'width': 5, 'depth': 3, 'rise': self.design.rise, 'peak': peak}) for key, frame, region in mounts) grants = tuple(Grant(key, region, ('install',), ('dormer',), region.volume) for key, frame, region in mounts) # Every intended roof column must retain actual solid cover after modifications. columns = tuple((x, levels[x + 1], z) for x in range(self.span) for z in range(self.length)) rule = Rule('vertical-cover', columns, box, phase='complete') return Contract(box, ports, grants, (rule,), decisions={'levels': levels, 'mounts': [(key, f.origin, f.turn) for key, f, _ in mounts], 'omitted_optional_dormers': rejected, 'peak': peak}) def realize(self, ctx, contract): p = Plan() levels = contract.decisions['levels'] span, length = self.span, self.length for x in range(-1, span + 1): y = levels[x + 1] previous = levels[max(0, x)] if x < span // 2 else levels[min(span + 1, x + 2)] for z in range(-1, length + 1): material = self.design.trim if z in (-1, length) else self.material facing = 'east' if x < span // 2 else 'west' # Two-rise courses have a full riser; stair treads alone leave a visible slit. for yy in range(previous + 1, y): if name_of(ctx.state((x, yy, z))) == 'air': p.block((x, yy, z), state_of(material + '_planks') if material in ('spruce', 'dark_oak') else state_of(material + 's'), 'riser') if name_of(ctx.state((x, y, z))) == 'air': p.block((x, y, z), stairs(material, facing), 'weather-course') elif x not in (-1, span) and z not in (-1, length) and not solid(ctx.state((x, y, z))): raise ContractError('roof-abutment', ctx.path, ctx.world((x, y, z)), 'Roof may abut actual solid boundaries only; found ' + ctx.state((x, y, z)) + ' owned by ' + str(ctx.view.owner(ctx.world((x, y, z))))) for x in (-1, span): for z in range(length): if name_of(ctx.state((x, -1, z))) == 'air': p.block((x, -1, z), slab('spruce', 'top'), 'eave-fascia') mid = span // 2 for z in range(-1, length + 1): if name_of(ctx.state((mid, max(levels) + 1, z))) == 'air': p.block((mid, max(levels) + 1, z), slab(self.design.trim), 'ridge-cap') for z in (-1, length): if name_of(ctx.state((mid, max(levels) + 2, z))) != 'air': continue p.block((mid, max(levels) + 2, z), state_of('dark_oak_fence', north='false', south='false', east='false', west='false', waterlogged='false'), 'ridge-finial') p.children.append(Child('gable-front', ProfileGable(span, levels))) p.children.append(Child('gable-rear', ProfileGable(span, levels), frame=Frame((span - 1, 0, length - 1), 2))) for key, origin, turn in contract.decisions['mounts'] if self.populate else (): p.children.append(Child('dormer-' + key, Dormer(self.material, self.design.trim), frame=Frame(tuple(origin), turn), bindings=(Binding(ctx.path, key),))) return p @dataclass(frozen=True) class ProfileGable: span: int levels: tuple[int, ...] def capability(self): return Capability('wall.profile-gable', ('wall', 'enclosure', 'composite'), offers=('wall-installation',), guarantees=('framed infill',)) def negotiate(self, ctx, parameters): mid = self.span // 2 height = min(self.levels[mid], self.levels[mid + 2]) region = Box((mid - 1, 0, 0), (mid + 1, height - 1, 0)) box = Box((0, -1, -1), (self.span - 1, max(self.levels), 0)) return Contract(box, (Port('infill', 'wall-installation', Frame((mid - 1, 0, 0)), region, 1, 'install', facts={'thickness': 1}),), (Grant('install', region, ('install',), ('window',), region.volume),)) def realize(self, ctx, contract): p = Plan() available = set() for x in range(self.span): for y in range(self.levels[x + 1]): if name_of(ctx.state((x, y, 0))) == 'air': material = log('spruce') if x in (0, self.span // 2, self.span - 1) or y == 0 else state_of('smooth_sandstone') p.block((x, y, 0), material, 'gable-frame') available.add((x, y, 0)) mid = self.span // 2 height = min(3, self.levels[mid] - 2) if height >= 2 and all(name_of(ctx.state((x, y, -1))) == 'air' for x in range(mid - 2, mid + 3) for y in range(height + 1)) and all((x, y, 0) in available for x in range(mid - 1, mid + 2) for y in range(1, height + 1)): p.children.append(Child('window', Window(3, height), frame=Frame((mid - 1, 1, 0)), bindings=(Binding(ctx.path, 'infill'),))) return p @dataclass(frozen=True) class Dormer: material: str = 'deepslate_tile' trim: str = 'dark_oak' def capability(self): return Capability('roof.dormer', ('dormer', 'roof', 'composite'), offers=('daylight',), assumptions=('compatible roof-installation region',), guarantees=('sealed cheeks and glazing', 'opening to attic')) def negotiate(self, ctx, parameters): if len(ctx.bindings) != 1: raise ContractError('dormer-host', ctx.path) port = ctx.view.port(ctx.bindings[0].host, ctx.bindings[0].port) if port.kind != 'roof-installation' or port.frame != ctx.frame or port.facts.get('width') != 5 or port.facts.get('depth') != 3: raise ContractError('dormer-interface', ctx.path, ctx.frame.origin, 'Require aligned 5 by 3 roof mount') box = Box((0, 0, 0), (4, port.facts['peak'] + 2, 2)) if not all(port.region.contains(ctx.world(q)) for q in box.corners()): raise ContractError('dormer-envelope', ctx.path) # The back roof rises into the main roof; cap each column above its measured intersection. tops = [] for z in range(3): top = max([y for x in range(5) for y in range(box.hi[1] + 1) if solid(ctx.state((x, y, z)))] or [0]) tops.append(max(4, top + 1)) tops = [max(tops)] * 3 if max(tops) + 2 > box.hi[1]: raise ContractError('dormer-height', ctx.path, conditions='Insufficient height within the negotiated roof mount') boundary = tuple((x, tops[z] + min(x, 4 - x), z) for x in range(5) for z in range(3)) cheeks = tuple((x, y, z) for x in (0, 4) for z in range(3) for y in range(0, tops[z])) face = tuple((x, y, 0) for x in range(1, 4) for y in range(tops[0] + min(x, 4 - x))) return Contract(box, rules=(Rule('sealed', boundary + cheeks + face, phase='complete'),), decisions={'tops': tops}) def realize(self, ctx, contract): p = Plan() tops = contract.decisions['tops'] # Cut only the owned weather cover, leaving an open rear into the roof void. for x in range(1, 4): for z in range(1, 3): for y in range(tops[z]): if name_of(ctx.state((x, y, z))) != 'air': p.block((x, y, z), AIR, 'roof-opening') for x in (0, 4): for z in range(3): for y in range(tops[z]): p.block((x, y, z), log('spruce') if z == 0 else state_of('spruce_planks'), 'cheek') for x in range(5): for z in range(3): roof = tops[z] + min(x, 4 - x) for y in range(tops[z], roof): if z == 0 and 0 < x < 4: continue p.block((x, y, z), state_of('spruce_planks'), 'roof-riser') p.block((x, roof, z), stairs(self.trim if z == 0 else self.material, 'east' if x < 2 else 'west'), 'dormer-cap') for x in range(1, 4): for y in range(tops[0] + min(x, 4 - x)): if name_of(ctx.state((x, y, 0))) != 'air': p.block((x, y, 0), AIR, 'face-reveal') # A semantic wall owns its glass attachment. Its bottom beam preserves the roof joint. p.children.append(Child('face', DormerFace(tops[0]))) return p @dataclass(frozen=True) class DormerFace: height: int def capability(self): return Capability('wall.dormer-face', ('wall', 'enclosure', 'composite'), offers=('wall-installation',)) def negotiate(self, ctx, parameters): region = Box((1, 1, 0), (3, self.height - 1, 0)) return Contract(Box((1, 0, 0), (3, self.height + 1, 0)), ports=(Port('infill', 'wall-installation', Frame((1, 1, 0)), region, 1, 'install', facts={'thickness': 1}),), grants=(Grant('install', region, ('install',), ('window',), region.volume),)) def realize(self, ctx, contract): p = Plan() for x in range(1, 4): for y in range(self.height + min(x, 4 - x)): p.block((x, y, 0), log('spruce', 'x') if y in (0, self.height - 1) else state_of('smooth_sandstone'), 'frame') # Glazing has no exterior shutter projection outside the accepted roof mount. p.children.append(Child('window', FlushWindow(3, 2), frame=Frame((1, 1, 0)), bindings=(Binding(ctx.path, 'infill'),))) return p @dataclass(frozen=True) class FlushWindow: width: int = 3 height: int = 2 def capability(self): return Capability('window.flush', ('window', 'sealed-opening'), guarantees=('sealed glazing within host',)) def negotiate(self, ctx, parameters): if not ctx.bindings: raise ContractError('window-host', ctx.path) port = ctx.view.port(ctx.bindings[0].host, ctx.bindings[0].port) depth = port.facts['thickness'] box = Box((0, 0, 0), (self.width - 1, self.height - 1, depth - 1)) if not all(port.region.contains(ctx.world(q)) for q in box.corners()): raise ContractError('window-margins', ctx.path) return Contract(box, rules=(Rule('sealed', tuple(box.cells())),)) def realize(self, ctx, contract): p = Plan() p.fill(contract.envelope, state_of('glass'), 'glazing') return p
hearth/components/joinery.py
# Depth and joinery fitted to public wall interfaces without replacing openings. from dataclasses import dataclass from hearth import Box, ContractError from hearth.kernel import Capability, Contract, Plan, Rule from hearth.blocks import name_of, log, stairs, slab @dataclass(frozen=True) class FacadeRelief: """Fit external beams and brackets around an already installed facade.""" width: int height: int = 5 access: bool = False def capability(self): return Capability('facade.joinery', ('decoration', 'timber-frame'), assumptions=('wall-installation host',), adaptations=('preserve shutters and other occupied facade cells',), guarantees=('one-cell projection',)) def negotiate(self, ctx, parameters): if len(ctx.bindings) != 1 or ctx.view.port(ctx.bindings[0].host, ctx.bindings[0].port).kind != 'wall-installation': raise ContractError('joinery-host', ctx.path) points = {} for x in range(self.width): points[(x, self.height - 1, -1)] = log('spruce', 'x') if not (self.access and abs(x - self.width // 2) <= 1): points[(x, -1, -1)] = slab('dark_oak', 'top') for x in (0, self.width - 1): for y in range(self.height - 1): points[(x, y, -1)] = log('stripped_spruce') for x, direction in ((1, 'east'), (self.width - 2, 'west')): points[(x, self.height - 2, -1)] = stairs('spruce', direction, 'top') available = [(q, s) for q, s in sorted(points.items()) if name_of(ctx.state(q)) == 'air'] return Contract(Box((0, -1, -1), (self.width - 1, self.height - 1, 0)), rules=(Rule('support', ((0, self.height - 1, 0), (self.width - 1, self.height - 1, 0))),), decisions={'members': available, 'preserved_occupied_cells': len(points) - len(available)}) def realize(self, ctx, contract): p = Plan() for q, block in contract.decisions['members']: p.block(q, block, 'joinery') return p
hearth/components/furnishing.py
# Functional furniture groups and circulation-aware furnishing of rectangular rooms. from dataclasses import dataclass from hearth import Box, Frame, ContractError from hearth.kernel import Capability, Contract, Domain, Rule, Port, Plan, Child from hearth.blocks import state_of, stairs, slab GROUPS = {'living': [['spruce_stairs'], ['barrel']], 'bedroom': [['red_bed'], ['barrel']], 'library': [['bookshelf'], ['lectern']], 'kitchen': [['smoker'], ['furnace']], 'workshop': [['crafting_table'], ['smithing_table']], 'storage': [['barrel']]} def supplies(): return {'id': 'minecraft:barrel', 'Items': [{'Slot': 0, 'id': 'minecraft:bread', 'count': 6}, {'Slot': 1, 'id': 'minecraft:torch', 'count': 12}]} @dataclass(frozen=True) class FurnitureGroup: purpose: str def capability(self): return Capability('furnishing.group.' + self.purpose, ('furniture', self.purpose), offers=('interaction',), inputs={'purpose': Domain(choices=tuple(GROUPS))}, guarantees=('complete functional group', 'supported', 'clear interaction space')) def negotiate(self, ctx, parameters): area = Box((0, 0, 0), (1, 2, 1)) interaction = Box((0, 0, 2), (1, 1, 2)) return Contract(Box((0, 0, 0), (1, 2, 2)), ports=(Port('use', 'interaction', Frame((0, 0, 2)), interaction, 4),), rules=(Rule('support', tuple((x, -1, z) for x in range(2) for z in range(3))), Rule('clear', tuple(interaction.cells())), Rule('furnishing', box=area, data={'groups': GROUPS[self.purpose]}, phase='complete')), atomic_object=True) def realize(self, ctx, contract): p = Plan() barrel = state_of('barrel', facing='south', open='false') p.block((1, 0, 0), barrel, 'supplies', nbt=supplies()) if self.purpose == 'bedroom': for z, part in ((0, 'head'), (1, 'foot')): p.block((0, 0, z), state_of('red_bed', facing='north', part=part, occupied='false'), 'bed') p.block((1, 1, 0), state_of('potted_fern'), 'bedside') p.block((1, 0, 1), state_of('red_carpet'), 'bedside-rug') elif self.purpose == 'library': for y in range(3): p.block((0, y, 0), state_of('bookshelf'), 'bookcase') p.block((0, 0, 1), state_of('lectern', facing='south', has_book='false', powered='false'), 'lectern') p.block((1, 1, 0), state_of('bookshelf'), 'bookcase') p.block((1, 2, 0), slab('spruce'), 'shelf-cap') p.block((1, 0, 1), stairs('spruce', 'north'), 'reading-seat') elif self.purpose in ('kitchen', 'workshop'): a, b = ('smoker', 'furnace') if self.purpose == 'kitchen' else ('crafting_table', 'smithing_table') props = {'facing': 'south', 'lit': 'false'} if self.purpose == 'kitchen' else {} p.block((0, 0, 0), state_of(a, **props), 'workstation') p.block((0, 0, 1), state_of(b, **props), 'workstation') p.block((1, 0, 1), state_of('crafting_table') if self.purpose == 'kitchen' else state_of('anvil', facing='north'), 'counter') for x in range(2): p.block((x, 2, 0), slab('spruce', 'top'), 'shelf') elif self.purpose == 'living': p.block((0, 0, 0), stairs('spruce', 'south'), 'seat') p.block((1, 0, 1), stairs('spruce', 'west'), 'seat') p.block((0, 0, 1), state_of('spruce_fence', north='false', south='false', east='false', west='false', waterlogged='false'), 'table') p.block((0, 1, 1), state_of('spruce_pressure_plate', powered='false'), 'tabletop') p.block((1, 1, 0), state_of('potted_poppy'), 'flowers') else: for x, y, z in ((0, 0, 0), (0, 1, 0), (1, 1, 0), (0, 0, 1)): p.block((x, y, z), barrel, 'storage', nbt=supplies()) for x in range(2): p.block((x, 2, 0), slab('spruce'), 'shelf-cap') return p @dataclass(frozen=True) class FurnishingLayout: purpose: str width: int depth: int stair: bool = False def capability(self): return Capability('furniture.' + self.purpose, ('furniture', 'composite'), guarantees=('two or four accessible furniture groups', 'clear circulation cross'), inputs={'width': Domain(choices=(9, 11, 13)), 'depth': Domain(choices=(9, 11, 13))}) def negotiate(self, ctx, parameters): if self.purpose not in GROUPS: raise ContractError('room-function', ctx.path) w, d = self.width, self.depth frames = [Frame((1, 0, 1)), Frame((1, 0, d - 2), 3)] if not self.stair: frames += [Frame((w - 2, 0, 1), 1), Frame((w - 2, 0, d - 2), 2)] table_frames = [Frame((3, 0, 2)), Frame((3, 0, d - 5))] if w >= 11 and d >= 11 else [] # Tables occupy the wider western bays while preserving the central aisles. targets = ((w // 2, 0, d // 2), *(f.point((0, 0, 2)) for f in frames), *(f.point((0, 0, 2)) for f in table_frames)) cross = tuple((x, y, z) for x in range(1, w - 1) for z in range(1, d - 1) if (x == w // 2 or z == d // 2) and not (self.stair and x >= w - 4 and 2 <= z <= 7) for y in (0, 1)) box = Box((1, 0, 1), (w - 2, 3, d - 2)) return Contract(box, rules=(Rule('clear', cross), Rule('route', targets, box, phase='complete')), decisions={'frames': [(f.origin, f.turn) for f in frames], 'groups': len(frames), 'purpose': self.purpose, 'tables': [(f.origin, f.turn) for f in table_frames]}) def realize(self, ctx, contract): p = Plan() functions = {'living': ('living', 'library', 'living', 'storage'), 'bedroom': ('bedroom', 'storage', 'bedroom', 'library'), 'kitchen': ('kitchen', 'storage', 'kitchen', 'living'), 'library': ('library', 'living', 'library', 'storage'), 'workshop': ('workshop', 'storage', 'workshop', 'library'), 'storage': ('storage',) * 4} for i, (origin, turn) in enumerate(contract.decisions['frames']): p.children.append(Child('group-' + str(i), FurnitureGroup(functions[self.purpose][i]), frame=Frame(tuple(origin), turn))) for i, (origin, turn) in enumerate(contract.decisions['tables']): p.children.append(Child('table-' + str(i), TableSetting(min(3, self.width // 2 - 3)), frame=Frame(tuple(origin), turn))) # One continuous runner occupies only the circulation cross, never the stair slot. for z in range(2, self.depth - 2): p.block((self.width // 2, 0, z), state_of('red_carpet'), 'runner') return p @dataclass(frozen=True) class TableSetting: width: int = 3 def capability(self): return Capability('furnishing.table-setting', ('furniture', 'seating'), inputs={'width': Domain(choices=(2, 3))}, offers=('interaction',), guarantees=('accessible seats and table',)) def negotiate(self, ctx, parameters): area = Box((0, 0, 0), (self.width - 1, 1, 2)) clear = tuple((x, y, 2) for x in range(self.width) for y in (0, 1)) return Contract(area, rules=(Rule('clear', clear), Rule('support', tuple((x, -1, z) for x in range(self.width) for z in range(3))), Rule('furnishing', box=area, data={'groups': [['spruce_stairs'], ['spruce_pressure_plate']]}, phase='complete')), ports=(Port('use', 'interaction', Frame((0, 0, 2)), Box((0, 0, 2), (self.width - 1, 1, 2)), 4),)) def realize(self, ctx, contract): p = Plan() table_x = 1 if self.width == 3 else 0 for z in range(2): p.block((table_x, 0, z), state_of('spruce_fence', north=str(z > 0).lower(), south=str(z == 0).lower(), east='false', west='false', waterlogged='false'), 'table') p.block((table_x, 1, z), state_of('spruce_pressure_plate', powered='false'), 'tabletop') for x in range(self.width): if x != table_x: p.block((x, 0, z), stairs('spruce', 'east' if x < table_x else 'west'), 'chair') return p
hearth/components/masonry.py
# Grounded masonry stacks composed with measured foundations and roof abutments. from dataclasses import dataclass from hearth import Box from hearth.kernel import Capability, Contract, Domain, Rule, Plan from hearth.blocks import state_of, slab @dataclass(frozen=True) class Chimney: height: int def capability(self): return Capability('masonry.chimney', ('chimney', 'support'), inputs={'height': Domain(10, 48)}, assumptions=('supported three by two base',), guarantees=('continuous masonry shaft', 'capped flue')) def negotiate(self, ctx, parameters): load = tuple((x, y, z) for x in (0, 2) for z in range(2) for y in range(-1, self.height)) return Contract(Box((-1, 0, -1), (3, self.height + 2, 2)), rules=(Rule('support', load),), decisions={'height': self.height, 'function': 'exterior flue; no simulated indoor heating'}) def realize(self, ctx, contract): p = Plan() rng = ctx.rng('masonry') for x in range(3): for z in range(2): for y in range(self.height): material = 'stone_bricks' if y in (0, 1, self.height - 3, self.height - 1) else rng.choice(('stone_bricks', 'stone_bricks', 'andesite', 'cobblestone')) p.block((x, y, z), state_of(material), 'shaft') for x in range(-1, 4): for z in range(-1, 3): p.block((x, self.height, z), slab('stone_brick', 'top'), 'cap') for z in range(2): p.block((1, self.height + 1, z), state_of('cobblestone_wall', north='low' if z else 'none', south='none' if z else 'low', east='none', west='none', up='true', waterlogged='false'), 'flue') return p
hearth/components/grounds.py
# Domestic garden courts using public access ports and bounded garden foundations. from dataclasses import dataclass from hearth import Box, Frame, ContractError from hearth.kernel import Capability, Contract, Plan, Child, Binding from hearth.adapters.site import Foundation, SiteLimits from hearth.blocks import state_of, stairs from .landscape import PathNetwork, Planter, Landscape, LampPost @dataclass(frozen=True) class RaisedBed: terrain: str width: int = 3 def capability(self): return Capability('garden.raised-bed', ('garden', 'composite'), adaptations=('bounded stepped footing',)) def negotiate(self, ctx, parameters): heights = [ctx.elevation(x, z) for x in range(self.width + 2) for z in range(4)] if max(heights) - min(heights) > 2: raise ContractError('garden-relief', ctx.path) floor = max(heights) + 1 return Contract(Box((0, min(heights) - 1, 0), (self.width + 1, floor + 1, 3)), decisions={'floor': floor}) def realize(self, ctx, contract): floor = contract.decisions['floor'] return Plan(children=[Child('footing', Foundation.rectangular(self.width + 2, 4, floor, limits=SiteLimits(support_height=3, fill_volume=60)), bindings=(Binding(self.terrain, 'construction', 'fill'),)), Child('soil', GardenSoil(self.width, floor - 1), bindings=(Binding(self.terrain, 'construction', 'fill'),)), Child('bed', Planter(self.width), frame=Frame((1, floor, 1))), Child('edging', BedBorder(self.width + 2, 4), frame=Frame((0, floor, 0)))]) @dataclass(frozen=True) class GardenSoil: width: int top: int def capability(self): return Capability('garden.soil-lift', ('siteworks', 'support'), guarantees=('continuous substrate below planting bed', 'at most two cells of fill')) def negotiate(self, ctx, parameters): from hearth.kernel import Rule columns = [(x, ctx.elevation(x, z), z) for x in range(1, self.width + 1) for z in (1, 2)] if any(self.top - y > 2 or y > self.top for x, y, z in columns): raise ContractError('garden-soil-depth', ctx.path) support = tuple((x, self.top, z) for x, _, z in columns) return Contract(Box((1, min(y for _, y, _ in columns), 1), (self.width, self.top, 2)), rules=(Rule('support', support),), decisions={'columns': columns}) def realize(self, ctx, contract): p = Plan() for x, bottom, z in contract.decisions['columns']: for y in range(bottom + 1, self.top + 1): p.block((x, y, z), state_of('dirt'), 'soil-fill') return p @dataclass(frozen=True) class BedBorder: width: int depth: int def capability(self): return Capability('garden.stone-edging', ('garden', 'masonry'), guarantees=('supported planting boundary',)) def negotiate(self, ctx, parameters): from hearth.kernel import Rule edge = tuple((x, 0, z) for x in range(self.width) for z in range(self.depth) if x in (0, self.width - 1) or z in (0, self.depth - 1)) return Contract(Box((0, 0, 0), (self.width - 1, 0, self.depth - 1)), rules=(Rule('support', tuple((x, -1, z) for x, _, z in edge)),), decisions={'edge': edge}) def realize(self, ctx, contract): p = Plan() for x, y, z in contract.decisions['edge']: face = 'south' if z == 0 else 'north' if z == self.depth - 1 else 'east' if x == 0 else 'west' p.block((x, y, z), stairs('stone_brick', face), 'edging') return p @dataclass(frozen=True) class GardenCourt: building: str terrain: str area: Box beds: int = 4 trees: int = 3 def capability(self): return Capability('garden.domestic-court', ('garden', 'composite'), assumptions=('access street port',), guarantees=('clear path to public entrance', 'bounded garden beds', 'retained building circulation')) def negotiate(self, ctx, parameters): port = ctx.view.port(self.building, 'street') if port.kind != 'access': raise ContractError('garden-access', ctx.path) access = ctx.local(port.frame.origin) gateway = (access[0], ctx.elevation(access[0], self.area.lo[2] + 2) + 1, self.area.lo[2] + 2) return Contract(self.area, decisions={'access': access, 'gateway': gateway, 'beds': self.beds, 'trees': self.trees}) def realize(self, ctx, contract): access, gateway = contract.decisions['access'], contract.decisions['gateway'] p = Plan(children=[Child('walk', PathNetwork((access, gateway), ((0, 1),)), bindings=(Binding(self.terrain, 'construction', 'surface'), Binding(self.building, 'street', 'surface')))]) for i in range(self.beds): side = -1 if i % 2 == 0 else 1 x = access[0] + (side * 5) - (2 if side < 0 else 0) z = gateway[2] + 2 + (i // 2) * 4 p.children.append(Child(f'bed-{i}', RaisedBed(self.terrain), frame=Frame((x, 0, z)))) for i, x in enumerate((access[0] - 3, access[0] + 3)): y = ctx.elevation(x, gateway[2] + 1) + 1 p.children.append(Child(f'light-{i}', LampPost(), frame=Frame((x, y, gateway[2] + 1)))) p.children.append(Child('planting', Landscape(self.area, self.terrain, self.trees, self.trees + 1, .035, sample_step=2, heights=(9, 11, 13)))) return p
hearth/adapters/site.py
# Measured, bounded support and access strategies independent of terrain recipes. from dataclasses import dataclass from hearth.space import Box, Frame from hearth.blocks import state_of, log, stairs, name_of, solid from hearth.kernel import Capability, Contract, Port, Grant, Rule, Plan, ContractError @dataclass(frozen=True) class SiteLimits: relief: int = 5 support_height: int = 8 approach_length: int = 12 fill_volume: int = 1600 excavation_volume: int = 300 bed_thickness: int = 2 def survey(ctx, footprint, limits=SiteLimits()): samples = {} for x, z in sorted(footprint): wx, _, wz = ctx.world((x, 0, z)) obs = ctx.view.sample(wx, wz) if obs.support_depth < limits.bed_thickness: raise ContractError('substrate-depth', ctx.path, (wx, obs.elevation, wz), f'Require {limits.bed_thickness} contiguous solid bed cells, found {obs.support_depth}') samples[(x, z)] = (obs.elevation - ctx.frame.origin[1], None if obs.water is None else obs.water - ctx.frame.origin[1], obs.support_depth) heights = [v[0] for v in samples.values()] relief = max(heights) - min(heights) if relief > limits.relief: raise ContractError('site-relief', ctx.path, ctx.frame.origin, f'Measured {relief}, permitted {limits.relief}') surface = max(max(v[0], v[1] if v[1] is not None else v[0]) for v in samples.values()) floor = surface + 1 if floor - min(heights) > limits.support_height: raise ContractError('support-height', ctx.path, ctx.frame.origin, 'Bounded support depth exceeded') wet = any(v[1] is not None and v[1] >= v[0] for v in samples.values()) strategies = ['piers'] if wet or relief >= 3 else ['stepped', 'piers'] strategy = ctx.scope.choose(strategies, 'adaptation') return {'floor': floor, 'relief': relief, 'wet': wet, 'strategy': strategy, 'samples': samples, 'feasible_strategies': strategies} @dataclass(frozen=True) class Foundation: footprint: tuple[tuple[int, int], ...] floor: int strategy: str limits: SiteLimits = SiteLimits() @classmethod def rectangular(cls, width, depth, floor, strategy='stepped', limits=SiteLimits()): """Create a rectangular contact component without client voxel operations.""" if width < 1 or depth < 1: raise ValueError('Positive footprint dimensions required') return cls(tuple((x, z) for x in range(width) for z in range(depth)), floor, strategy, limits) def capability(self): return Capability('adapter.foundation', ('siteworks', 'support'), offers=('support',), assumptions=('actual bed within bounded depth',), adaptations=('stepped perimeter', 'piers to bed'), guarantees=('grounded support grid',)) def negotiate(self, ctx, parameters): positions = set(self.footprint) supports = [] columns = [] for x, z in sorted(positions): boundary = any((x + dx, z + dz) not in positions for dx, dz in ((1, 0), (-1, 0), (0, 1), (0, -1))) grid = (x % 4 == 0 and z % 4 == 0) # Piers include perimeter every third cell and all corners. edge_pier = boundary and (x % 3 == 0 or z % 3 == 0 or sum((x + dx, z + dz) not in positions for dx, dz in ((1, 0), (-1, 0), (0, 1), (0, -1))) >= 2) if not (grid or (boundary if self.strategy == 'stepped' else edge_pier)): continue wx, _, wz = ctx.world((x, 0, z)) bed = ctx.view.elevation(wx, wz) - ctx.frame.origin[1] if self.floor - bed > self.limits.support_height: raise ContractError('support-height', ctx.path, ctx.world((x, bed, z))) supports.extend((x, bed - k, z) for k in range(self.limits.bed_thickness)) columns.append((x, bed, z, self.floor - 1)) count = sum(max(0, top - bed) for x, bed, z, top in columns) if count > self.limits.fill_volume: raise ContractError('fill-volume', ctx.path, conditions=f'{count} > {self.limits.fill_volume}') for x, bed, z, top in columns: supports.extend((x, y, z) for y in range(bed + 1, top + 1)) box = Box.enclosing([(x, bed - self.limits.bed_thickness + 1, z) for x, bed, z, top in columns] + [(x, self.floor - 1, z) for x, bed, z, top in columns]) return Contract(box, rules=(Rule('support', tuple(supports)),), decisions={'columns': columns, 'strategy': self.strategy, 'fill': count, 'excavation': 0}, reads=(box,)) def realize(self, ctx, contract): p = Plan() for x, bed, z, top in contract.decisions['columns']: for y in range(bed + 1, top + 1): material = log('spruce') if self.strategy == 'piers' and y > bed + 1 else state_of('stone_bricks') p.block((x, y, z), material, 'contact') return p @dataclass(frozen=True) class Approach: center: int floor: int porch: int = 0 limits: SiteLimits = SiteLimits() def capability(self): return Capability('adapter.approach', ('siteworks', 'access'), offers=('street', 'surface'), adaptations=('stairs', 'landing', 'bounded fill'), guarantees=('two-block headroom', 'entrance connection')) def negotiate(self, ctx, parameters): rows = [] for step in range(1, self.limits.approach_length + 1): z = -self.porch - step wx, _, wz = ctx.world((self.center, 0, z)) ground = max(max(ctx.view.elevation(ctx.world((x, 0, z))[0], ctx.world((x, 0, z))[2], maximum=self.floor + ctx.frame.origin[1] + 2), (ctx.view.water(ctx.world((x, 0, z))[0], ctx.world((x, 0, z))[2]) or -10000) + 1) - ctx.frame.origin[1] for x in range(self.center - 1, self.center + 2)) y = max(ground, self.floor - step + 1) rows.append((z, y)) if y == ground: break else: raise ContractError('approach-detour', ctx.path, ctx.frame.origin, 'Cannot meet terrain within length bound') cells = [] support = [] for z, y in rows: cells.extend((x, y + k, z) for x in range(self.center - 1, self.center + 2) for k in (1, 2)) support.extend((x, y, z) for x in range(self.center - 1, self.center + 2)) low = min(ctx.view.elevation(*((lambda p: (p[0], p[2]))(ctx.world((x, 0, z)))), maximum=self.floor + ctx.frame.origin[1] + 2) - ctx.frame.origin[1] for z, y in rows for x in range(self.center - 1, self.center + 2)) box = Box((self.center - 1, low, rows[-1][0]), (self.center + 1, max(y for z, y in rows) + 3, -self.porch - 1)) end = (self.center, rows[-1][1] + 1, rows[-1][0]) region = Box((self.center - 1, rows[-1][1], rows[-1][0]), (self.center + 1, max(self.floor, max(h for _, h in rows)) + 2, min(-self.porch - 1, rows[-1][0] + 1))) port = Port('street', 'access', Frame(end), region, 10, 'surface') grant = Grant('surface', region, ('surface',), ('path',), 18) route = tuple((self.center, y + 1, z) for z, y in rows) return Contract(box, (port,), (grant,), (Rule('clear', tuple(cells)), Rule('support', tuple(support)), Rule('route', route, box.expand(1), phase='complete')), decisions={'rows': rows, 'end': end}, reads=(box,)) def realize(self, ctx, contract): p = Plan() rows = contract.decisions['rows'] for index, (z, y) in enumerate(rows): for x in range(self.center - 1, self.center + 2): wx, _, wz = ctx.world((x, 0, z)) bed = ctx.view.elevation(wx, wz, maximum=self.floor + ctx.frame.origin[1] + 2) - ctx.frame.origin[1] for yy in range(bed + 1, y): p.block((x, yy, z), state_of('cobblestone'), 'step-footing') p.block((x, y, z), stairs('stone_brick', 'south') if index and rows[index - 1][1] > y else state_of('stone_bricks'), 'treads') return p
hearth/adapters/__init__.py
# Reusable environmental contact and circulation adapters. from .site import Foundation, Approach, SiteLimits, survey
hearth/adapters/bearing.py
# Small continuous bearing courses spanning explicitly measured support columns. from dataclasses import dataclass from hearth import Box, ContractError from hearth.kernel import Capability, Contract, Domain, Rule, Plan from hearth.blocks import state_of, solid @dataclass(frozen=True) class BearingCourse: width: int depth: int span: int = 2 def capability(self): return Capability('adapter.bearing-course', ('siteworks', 'support'), inputs={'width': Domain(1, 7), 'depth': Domain(1, 7), 'span': Domain(0, 3)}, assumptions=('actual support beneath a bounded plate',), guarantees=('continuous bearing surface', 'bounded taxicab span to actual supports')) def negotiate(self, ctx, parameters): cells = tuple((x, 0, z) for x in range(self.width) for z in range(self.depth)) anchors = tuple((x, -1, z) for x, _, z in cells if solid(ctx.state((x, -1, z)))) if not anchors or any(min(abs(x - a) + abs(z - b) for a, _, b in anchors) > self.span for x, _, z in cells): raise ContractError('bearing-span', ctx.path, ctx.frame.origin, f'Need support within {self.span} cells of every bearing cell') missing = tuple(p for p in cells if not solid(ctx.state(p))) return Contract(Box((0, -1, 0), (self.width - 1, 0, self.depth - 1)), rules=(Rule('support', cells + anchors),), decisions={'anchors': anchors, 'fill_cells': missing, 'fill': len(missing), 'span': self.span}) def realize(self, ctx, contract): p = Plan() for q in contract.decisions['fill_cells']: p.block(q, state_of('stone_bricks'), 'bearing-course') return p
hearth_extensions/interiors.py
# Functional furnishing stations arranged around protected circulation in polygon interiors. from dataclasses import dataclass from hearth import Box, Frame, ContractError from hearth.kernel import Capability, Contract, Domain, Port, Rule, Plan, Child from hearth.blocks import state_of, stairs, passable from .geometry import Polygon, perimeter, bounds2 FUNCTION_GROUPS = {'library': [['bookshelf'], ['lectern']], 'workshop': [['crafting_table'], ['smithing_table']], 'kitchen': [['smoker'], ['furnace']], 'bedroom': [['red_bed']], 'living': [['spruce_stairs']], 'storage': [['barrel']]} @dataclass(frozen=True) class WorkBay: purpose: str def capability(self): return Capability('extension.work-bay', ('furniture', self.purpose), offers=('interaction',), inputs={'purpose': Domain(choices=tuple(FUNCTION_GROUPS))}, guarantees=('functionally furnished', 'supported', 'clear interaction space')) def negotiate(self, ctx, parameters): interaction = ((0, 0, 2), (1, 0, 2)) support = tuple((x, -1, z) for x in range(2) for z in range(3)) clear = tuple((x, y, 2) for x in range(2) for y in range(2)) area = Box((0, 0, 0), (1, 1, 1)) return Contract(Box((0, -1, 0), (1, 1, 2)), ports=(Port('use', 'interaction', Frame(interaction[0]), Box(interaction[0], (1, 1, 2)), 4),), rules=(Rule('support', support), Rule('clear', clear), Rule('furnishing', box=area, data={'groups': FUNCTION_GROUPS[self.purpose]}, phase='complete')), atomic_object=True) def realize(self, ctx, contract): plan = Plan() barrel = state_of('barrel', facing='south', open='false') inventory = {'id': 'minecraft:barrel', 'Items': [{'Slot': 0, 'id': 'minecraft:bread', 'count': 6}, {'Slot': 1, 'id': 'minecraft:torch', 'count': 12}]} plan.block((1, 0, 0), barrel, 'supplies', nbt=inventory) if self.purpose == 'library': for y in range(2): plan.block((0, y, 0), state_of('bookshelf'), 'shelving') plan.block((0, 0, 1), state_of('lectern', facing='south', has_book='false', powered='false'), 'reading') plan.block((1, 0, 1), stairs('spruce', 'north'), 'seat') elif self.purpose in ('workshop', 'kitchen'): a, b = ('crafting_table', 'smithing_table') if self.purpose == 'workshop' else ('smoker', 'furnace') properties = {'facing': 'south', 'lit': 'false'} if self.purpose == 'kitchen' else {} plan.block((0, 0, 0), state_of(a, **properties), 'workstation') plan.block((0, 0, 1), state_of(b, **properties), 'workstation') plan.block((1, 0, 1), stairs('spruce', 'north'), 'seat') elif self.purpose == 'bedroom': for z, part in ((0, 'head'), (1, 'foot')): plan.block((0, 0, z), state_of('red_bed', facing='north', part=part, occupied='false'), 'bed') plan.block((1, 0, 1), state_of('red_carpet'), 'bedside') elif self.purpose == 'living': plan.block((0, 0, 0), stairs('spruce', 'south'), 'seat') plan.block((1, 0, 1), stairs('spruce', 'north'), 'seat') plan.block((0, 0, 1), state_of('spruce_fence', north='false', south='false', east='false', west='false', waterlogged='false'), 'table') plan.block((0, 1, 1), state_of('spruce_pressure_plate', powered='false'), 'table') else: for x, y, z in ((0, 0, 0), (0, 1, 0), (0, 0, 1)): plan.block((x, y, z), barrel, 'storage', nbt=inventory) return plan @dataclass(frozen=True) class HallInterior: footprint: Polygon purpose: str minimum: int = 2 maximum: int = 8 area_per_bay: int = 42 def capability(self): return Capability('extension.hall-interior', ('interior', 'furniture', 'composite'), inputs={'purpose': Domain(choices=tuple(FUNCTION_GROUPS)), 'minimum': Domain(1, 8), 'maximum': Domain(1, 12), 'area_per_bay': Domain(16, 100)}, adaptations=('fit functional bays around a circulation cross',), guarantees=('accessible furnishing stations', 'protected three-cell central aisles')) def negotiate(self, ctx, parameters): footprint = set(self.footprint.cells()) inside = footprint - set(perimeter(footprint, diagonal=True)) width = max(x for x, z in footprint) + 1 depth = max(z for x, z in footprint) + 1 cx, cz = width // 2, depth // 2 if self.minimum > self.maximum: raise ContractError('interior-domain', ctx.path, conditions='Minimum exceeds maximum') aisle = {(x, z) for x, z in inside if abs(x - cx) <= 1 or abs(z - cz) <= 1} candidates = [] rng = ctx.rng('planning') for x, z in sorted(inside): for turn in range(4): frame = Frame((x, 0, z), turn) cells = {(frame.point((u, 0, v))[0], frame.point((u, 0, v))[2]) for u in range(2) for v in range(3)} body = {(frame.point((u, 0, v))[0], frame.point((u, 0, v))[2]) for u in range(2) for v in range(2)} if not cells <= inside or body & aisle: continue front = frame.point((0, 0, 2)) if (front[0] - x) * (cx - x) + (front[2] - z) * (cz - z) <= 0: continue if not all(passable(ctx.state((u, y, v))) for u, v in cells for y in range(2)): continue quadrant = (x < cx, z < cz) candidates.append((frame, cells, body, quadrant, rng.random())) wanted = min(self.maximum, max(self.minimum, len(inside) // self.area_per_bay)) selected = [] used = set() while candidates and len(selected) < wanted: def score(item): frame, cells, body, quadrant, tie = item x, _, z = frame.origin separation = min((abs(x - v[0].origin[0]) + abs(z - v[0].origin[2]) for v in selected), default=width + depth) balance = sum(v[3] == quadrant for v in selected) return (balance, -separation, min(x, z, width - 1 - x, depth - 1 - z), tie, frame.origin, frame.turn) choice = min(candidates, key=score) selected.append(choice) used |= choice[1] candidates = [v for v in candidates if not v[1] & used and all(abs(v[0].origin[0] - old[0].origin[0]) + abs(v[0].origin[2] - old[0].origin[2]) >= 4 for old in selected)] if len(selected) < self.minimum: raise ContractError('interior-capacity', ctx.path, conditions=f'{len(selected)} bays fit; {self.minimum} required') targets = ((cx, 0, cz), *(v[0].point((0, 0, 2)) for v in selected)) clear = tuple((x, y, z) for x, z in sorted(aisle) for y in (0, 1)) envelope = bounds2(footprint, -1, 2) return Contract(envelope, rules=(Rule('clear', clear), Rule('route', targets, envelope, phase='complete')), decisions={'frames': [(v[0].origin, v[0].turn) for v in selected], 'requested_bays': wanted, 'placed_bays': len(selected), 'minimum_bays': self.minimum, 'omitted_optional': wanted - len(selected), 'purpose': self.purpose}) def realize(self, ctx, contract): return Plan(children=[Child(f'bay-{i}', WorkBay(self.purpose), frame=Frame(tuple(origin), turn)) for i, (origin, turn) in enumerate(contract.decisions['frames'])])
hearth_extensions/geometry.py
# Portable design geometry and deterministic voxelization shared by extension components. from dataclasses import dataclass import math from hearth.space import Box CARDINAL = ((1, 0), (-1, 0), (0, 1), (0, -1)) def lattice(value): """Round consistently across native Python and browser Python.""" return math.floor(value + 0.5) @dataclass(frozen=True) class Polyline: points: tuple[tuple[float, float], ...] def __post_init__(self): object.__setattr__(self, 'points', tuple(tuple(p) for p in self.points)) if len(self.points) < 2 or any(len(p) != 2 or not all(math.isfinite(v) for v in p) for p in self.points): raise ValueError('A finite polyline needs at least two two-dimensional points') if any(a == b for a, b in zip(self.points, self.points[1:])): raise ValueError('Repeated consecutive control points') @classmethod def bezier(cls, controls, segments=32): if len(controls) != 4 or not 4 <= segments <= 256: raise ValueError('Cubic curves require four controls and 4..256 samples') points = [] for i in range(segments + 1): t = i / segments weights = ((1 - t)**3, 3 * t * (1 - t)**2, 3 * t * t * (1 - t), t**3) points.append(tuple(sum(w * p[k] for w, p in zip(weights, controls)) for k in (0, 1))) return cls(tuple(points)) @property def length(self): return sum(math.dist(a, b) for a, b in zip(self.points, self.points[1:])) def nearest(self, point): """Return distance, arc length, tangent and projection with stable tie breaks.""" best, walked = None, 0.0 for index, (a, b) in enumerate(zip(self.points, self.points[1:])): dx, dz = b[0] - a[0], b[1] - a[1] length = math.hypot(dx, dz) t = max(0, min(1, ((point[0] - a[0]) * dx + (point[1] - a[1]) * dz) / length**2)) q = (a[0] + t * dx, a[1] + t * dz) item = (math.dist(point, q), walked + t * length, index, (dx / length, dz / length), q) if best is None or item[:3] < best[:3]: best = item walked += length return best[0], best[1], best[3], best[4] def cells(self): """Rasterize a connected cardinal chain, retaining explicit diagonal turns.""" result = [] for a, b in zip(self.points, self.points[1:]): count = max(1, math.ceil(math.dist(a, b) * 4)) for i in range(count + 1): target = tuple(lattice(a[k] + (b[k] - a[k]) * i / count) for k in (0, 1)) if not result: result.append(target) while result[-1] != target: x, z = result[-1] tx, tz = target candidates = [] if x != tx: candidates.append((x + (1 if tx > x else -1), z)) if z != tz: candidates.append((x, z + (1 if tz > z else -1))) result.append(min(candidates, key=lambda p: (self.nearest(p)[0], p))) return tuple(result) def ribbon(self, radius, caps=False): xmin = math.floor(min(p[0] for p in self.points) - radius) xmax = math.ceil(max(p[0] for p in self.points) + radius) zmin = math.floor(min(p[1] for p in self.points) - radius) zmax = math.ceil(max(p[1] for p in self.points) + radius) a, b = self.points[0], self.points[-1] start = (self.points[1][0] - a[0], self.points[1][1] - a[1]) end = (b[0] - self.points[-2][0], b[1] - self.points[-2][1]) result = [] for x in range(xmin, xmax + 1): for z in range(zmin, zmax + 1): distance, station, _, _ = self.nearest((x, z)) if not caps and ((station <= 1e-9 and (x - a[0]) * start[0] + (z - a[1]) * start[1] < 0) or (station >= self.length - 1e-9 and (x - b[0]) * end[0] + (z - b[1]) * end[1] > 0)): continue if distance <= radius + 0.05: result.append((x, z)) return tuple(result) @dataclass(frozen=True) class Polygon: vertices: tuple[tuple[int, int], ...] def __post_init__(self): object.__setattr__(self, 'vertices', tuple(tuple(p) for p in self.vertices)) if len(self.vertices) < 3: raise ValueError('At least three polygon vertices required') @classmethod def chamfered(cls, width, depth, corner=0): if not 9 <= width <= 27 or not 9 <= depth <= 27 or not 0 <= corner <= min(width, depth) // 3: raise ValueError('Footprint domain: dimensions 9..27, corner 0..one third') x, z, c = width - 1, depth - 1, corner return cls(((0, 0), (x, 0), (x, z), (0, z)) if not c else ((c, 0), (x - c, 0), (x, c), (x, z - c), (x - c, z), (c, z), (0, z - c), (0, c))) def cells(self): result = [] for x in range(min(p[0] for p in self.vertices), max(p[0] for p in self.vertices) + 1): for z in range(min(p[1] for p in self.vertices), max(p[1] for p in self.vertices) + 1): inside = False edge = False for a, b in zip(self.vertices, self.vertices[1:] + self.vertices[:1]): cross = (x - a[0]) * (b[1] - a[1]) - (z - a[1]) * (b[0] - a[0]) if cross == 0 and min(a[0], b[0]) <= x <= max(a[0], b[0]) and min(a[1], b[1]) <= z <= max(a[1], b[1]): edge = True if (a[1] > z) != (b[1] > z) and x < (b[0] - a[0]) * (z - a[1]) / (b[1] - a[1]) + a[0]: inside = not inside if edge or inside: result.append((x, z)) return tuple(result) def perimeter(cells, diagonal=False): points = set(cells) steps = tuple((x, z) for x in (-1, 0, 1) for z in (-1, 0, 1) if x or z) if diagonal else CARDINAL return tuple(sorted(p for p in points if any((p[0] + dx, p[1] + dz) not in points for dx, dz in steps))) def bounds2(points, low, high): return Box((min(p[0] for p in points), low, min(p[1] for p in points)), (max(p[0] for p in points), high, max(p[1] for p in points)))
hearth_extensions/interfaces.py
# Public endpoint discovery and orientation checks shared by circulation components. from dataclasses import dataclass from hearth import Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Plan, Rule @dataclass(frozen=True) class Endpoint: host: str port: str def binding(self): return Binding(self.host, self.port, 'connect') def resolve(self, ctx): port = ctx.view.port(self.host, self.port) if port.kind not in ('access', 'public-access'): raise ContractError('endpoint-kind', ctx.path, port.frame.origin, 'Require an access or public-access port') at = ctx.local(port.frame.origin) turn = (port.frame.turn - ctx.frame.turn) % 4 outward = Frame(turn=turn).vector((0, 0, -1)) return port, at, (outward[0], outward[2]) @dataclass(frozen=True) class EndpointContact: endpoint: Endpoint def capability(self): return Capability('extension.endpoint-contact', ('connection',), guarantees=('unchanged supported endpoint',)) def negotiate(self, ctx, parameters): port, at, direction = self.endpoint.resolve(ctx) from hearth.space import Box return Contract(Box(at, at).expand(1), rules=(Rule('support', ((at[0], at[1] - 1, at[2]),)), Rule('clear', (at, (at[0], at[1] + 1, at[2]))))) def realize(self, ctx, contract): return Plan()
hearth_extensions/__init__.py
# Components developed against Hearth's public protocol in the second development phase. from .geometry import Polyline, Polygon from .interfaces import Endpoint, EndpointContact from .circulation import Link, connection from .boundaries import Boundary, BoundaryLantern, IlluminateBoundary from .sites import Platform from .halls import Pavilion, PolygonShell, HipRoof, Facade from .interiors import HallInterior, WorkBay
hearth_extensions/circulation.py
# Measured ribbon circulation, support grids and guard geometry through public contracts. from dataclasses import dataclass import math from hearth import Box, Frame, Binding, ContractError from hearth.blocks import state_of, stairs, slab, log, solid, passable, name_of from hearth.kernel import Capability, Domain, Contract, Port, Grant, Plan, Rule, Child, validator, Diagnostic from .geometry import Polyline, CARDINAL, bounds2, perimeter, lattice from .interfaces import Endpoint @validator('extension.guard') def guard_rule(scene, node, rule): for p in rule.cells: if name_of(scene.view.state(p)) not in ('spruce_fence', 'spruce_log', 'stone_brick_wall'): yield Diagnostic('bridge-guard', node.path, p, 'A required outer guard cell is absent') @validator('extension.span') def span_rule(scene, node, rule): supports = [node.frame.point(tuple(p)) for p in rule.data['anchors']] for p in rule.cells: if not supports or min(abs(p[0] - q[0]) + abs(p[2] - q[2]) for q in supports) > rule.data['maximum']: yield Diagnostic('unsupported-span', node.path, p, 'Deck exceeds declared supported horizontal span') @dataclass(frozen=True) class Surface: points: tuple role: str = 'deck' material: str = 'spruce_planks' def capability(self): tags = ('surface', self.role) + (('path', 'siteworks') if self.role in ('deck', 'platform') else ()) return Capability('extension.' + self.role, tags) def negotiate(self, ctx, parameters): box = Box.enclosing(self.points) return Contract(box, rules=(Rule('support', self.points),)) def realize(self, ctx, contract): p = Plan() heights = {(x, z): y for x, y, z in self.points} for x, y, z in self.points: uphill = next((face for dx, dz, face in ((1, 0, 'east'), (-1, 0, 'west'), (0, 1, 'south'), (0, -1, 'north')) if heights.get((x + dx, z + dz), y) == y + 1), None) p.block((x, y, z), stairs('spruce', uphill) if uphill else state_of(self.material), 'walk-surface') return p @dataclass(frozen=True) class Trestles: columns: tuple maximum: int = 8 def capability(self): return Capability('extension.trestles', ('siteworks', 'support'), adaptations=('posts to actual bed', 'stone shoes'), inputs={'maximum': Domain(2, 8)}) def negotiate(self, ctx, parameters): cells = tuple((x, y, z) for x, bed, z, top, wet in self.columns for y in range(bed - 1, top + 1)) if any(top - bed > self.maximum for x, bed, z, top, wet in self.columns): raise ContractError('connection-support-height', ctx.path, conditions=f'Post exceeds {self.maximum}') return Contract(Box.enclosing(cells), rules=(Rule('support', cells),), decisions={'columns': self.columns}) def realize(self, ctx, contract): p = Plan() for x, bed, z, top, wet in self.columns: for y in range(bed + 1, top + 1): p.block((x, y, z), state_of('stone_bricks') if y == bed + 1 or not wet else log(), 'pier') return p @dataclass(frozen=True) class Guards: points: tuple covered: bool = False roof: tuple = () def capability(self): return Capability('extension.guards', ('railing', 'roof' if self.covered else 'guard'), guarantees=('continuous outer guard',)) def negotiate(self, ctx, parameters): return Contract(Box.enclosing((*self.points, *self.roof)).expand(1), rules=(Rule('extension.guard', self.points),)) def realize(self, ctx, contract): p = Plan() occupied = {(x, z) for x, y, z in self.points} for i, (x, y, z) in enumerate(self.points): connections = {face: str((x + dx, z + dz) in occupied).lower() for dx, dz, face in ((1, 0, 'east'), (-1, 0, 'west'), (0, 1, 'south'), (0, -1, 'north'))} p.block((x, y, z), state_of('spruce_fence', waterlogged='false', **connections), 'guard') if self.covered: for yy in (y + 1, y + 2): p.block((x, yy, z), log() if i % 5 == 0 else state_of('spruce_fence', waterlogged='false', **connections), 'gallery-frame') for x, y, z in self.roof: p.block((x, y, z), slab('dark_oak', 'top'), 'gallery-canopy') return p @dataclass(frozen=True) class Link: start: Endpoint end: Endpoint terrain: str via: tuple = () curve: Polyline | None = None width: int = 3 rise: int = 0 covered: bool = False max_post: int = 8 max_span: int = 6 max_length: int = 120 fill_limit: int = 800 def capability(self): return Capability('extension.gallery' if self.covered else 'extension.bridge', ('connection', 'path', 'composite'), offers=('access',), adaptations=('bounded height profile', 'actual-bed trestles', 'supported deck reuse at endpoints'), guarantees=('both public endpoints reachable', 'two-cell headroom', 'outer guard'), inputs={'width': Domain(choices=(3, 5)), 'rise': Domain(0, 3), 'max_post': Domain(2, 8), 'max_span': Domain(3, 6)}, locked=('start', 'end', 'via', 'curve', 'width', 'covered')) def negotiate(self, ctx, parameters): pa, a, da = self.start.resolve(ctx) pb, b, db = self.end.resolve(ctx) required = {(self.start.host, self.start.port), (self.end.host, self.end.port)} if not required.issubset({(v.host, v.port) for v in ctx.bindings if v.verb == 'connect'}): raise ContractError('endpoint-binding', ctx.path, conditions='Both endpoints need explicit read-only connection bindings') points = ((a[0], a[2]), (a[0] + 3 * da[0], a[2] + 3 * da[1]), *self.via, (b[0] + 3 * db[0], b[2] + 3 * db[1]), (b[0], b[2])) curve = self.curve or Polyline(tuple(points)) if curve.points[0] != (a[0], a[2]) or curve.points[-1] != (b[0], b[2]): raise ContractError('endpoint-disconnected', ctx.path, ctx.world(a), 'Curve ends must match the negotiated public ports') for point, next_point, direction in ((curve.points[0], curve.points[1], da), (curve.points[-1], curve.points[-2], db)): delta = (next_point[0] - point[0], next_point[1] - point[1]) if delta[0] * direction[1] - delta[1] * direction[0] != 0 or delta[0] * direction[0] + delta[1] * direction[1] <= 0: raise ContractError('endpoint-frame', ctx.path, ctx.world((int(point[0]), a[1], int(point[1]))), 'First and last tangents must point out of the host') if curve.length > self.max_length or curve.length < 7: raise ContractError('connection-domain', ctx.path, conditions='Route length exceeds the negotiated preparation budget') center = curve.cells() if len(set(center)) != len(center): raise ContractError('connection-domain', ctx.path, conditions='Need a simple route of length 7..maximum') radius = self.width // 2 + 1 deck = curve.ribbon(radius + .2) station = {p: min(range(len(center)), key=lambda i: (math.dist(p, center[i]), i)) for p in deck} count = len(center) # Preserve the host's offered mouth width, then flare to the body width. mouth_widths = [] for port in (pa, pb): horizontal = [port.frame.inverse(q)[0] for q in port.region.corners()] mouth_widths.append(max(horizontal) - min(horizontal) + 1) if min(mouth_widths) < 3: raise ContractError('endpoint-width', ctx.path, ctx.world(a), 'Connection needs an offered mouth at least three cells wide') deck = tuple(p for p in deck if (station[p] >= 3 or abs(pa.frame.inverse(ctx.world((p[0], a[1], p[1])))[0]) <= mouth_widths[0] // 2) and (station[p] < count - 3 or abs(pb.frame.inverse(ctx.world((p[0], b[1], p[1])))[0]) <= mouth_widths[1] // 2)) heights = [lattice((a[1] - 1) * (1 - i / (count - 1)) + (b[1] - 1) * i / (count - 1) + self.rise * math.sin(math.pi * i / (count - 1))) for i in range(count)] beds = {} waters = {} endpoint_regions = (pa.region, pb.region) for x, z in deck: cap = max(a[1], b[1]) + self.rise + 2 bed = ctx.elevation(x, z, maximum=cap) water = ctx.water(x, z) beds[(x, z)] = bed waters[(x, z)] = water i = station[(x, z)] heights[i] = max(heights[i], bed, water + 1 if water is not None else bed) # Minimal upward propagation, preserving fixed endpoint elevations. for i in range(1, count): heights[i] = max(heights[i], heights[i - 1] - 1) for i in range(count - 2, -1, -1): heights[i] = max(heights[i], heights[i + 1] - 1) if heights[0] != a[1] - 1 or heights[-1] != b[1] - 1: raise ContractError('endpoint-grade', ctx.path, ctx.world(a), 'Measured ground/water cannot meet the locked endpoint heights') outer = set(perimeter(deck)) guards = [] clear = [] all_deck = [] writes = [] for x, z in deck: i = station[(x, z)] y = heights[i] q = ctx.world((x, y, z)) host_region = any(region.contains(q) for region in endpoint_regions) is_guard = (x, z) in outer and 2 < i < count - 3 and not host_region all_deck.append((x, y, z)) if is_guard: guards.append((x, y + 1, z)) else: clear.extend(((x, y + 1, z), (x, y + 2, z))) existing = ctx.view.state(q) if solid(existing) and host_region: continue writes.append((x, y, z)) anchors = [] for x, z in sorted(deck, key=lambda p: (station[p], p)): if any(abs(x - u) + abs(z - v) <= self.max_span for u, v in anchors): continue # Prefer the central route where possible, then cover wide diagonal corners. near = center[station[(x, z)]] anchor = near if near in beds else (x, z) if anchor in anchors: anchor = (x, z) anchors.append(anchor) columns = [] for x, z in anchors: top = heights[station[(x, z)]] - 1 bed = min(beds[(x, z)], top) while not ctx.view.supports(ctx.world((x, bed, z))): bed -= 1 if top - bed > self.max_post: raise ContractError('connection-support-height', ctx.path, ctx.world((x, top, z))) if not ctx.view.supports(ctx.world((x, bed - 1, z))): raise ContractError('connection-bed', ctx.path, ctx.world((x, bed - 1, z)), 'Need two actual supporting bed cells') columns.append((x, bed, z, top, waters[(x, z)] is not None)) fill = sum(max(0, top - bed) for x, bed, z, top, wet in columns) if fill > self.fill_limit: raise ContractError('connection-fill-limit', ctx.path, conditions=f'{fill}>{self.fill_limit}') roof = tuple((x, y + 5, z) for x, y, z in all_deck if self.covered and 3 < station[(x, z)] < count - 4) guard_points = tuple(guards) low = min(min(beds.values()) - 1, min(heights)) envelope = bounds2(deck, low, max(heights) + 7).expand(1) center_route = tuple((x, heights[i] + 1, z) for i, (x, z) in enumerate(center)) rules = (Rule('route', (a, *center_route, b), envelope, phase='complete'), Rule('support', tuple(all_deck)), Rule('clear', tuple(clear)), Rule('extension.span', tuple(all_deck), data={'anchors': [(x, 0, z) for x, z in anchors], 'maximum': self.max_span})) return Contract(envelope, ports=(Port('start', 'access', Frame(a), Box(a, a), 8), Port('end', 'access', Frame(b), Box(b, b), 8)), rules=rules, decisions={'curve': curve.points, 'center': center, 'profile': heights, 'deck': all_deck, 'writes': writes, 'guards': guard_points, 'columns': columns, 'roof': roof, 'fill': fill, 'width': self.width, 'covered': self.covered, 'rise': self.rise, 'endpoint_regions': [[r.lo, r.hi] for r in endpoint_regions]}, reads=(envelope,)) def realize(self, ctx, contract): d = contract.decisions terrain = (Binding(self.terrain, 'construction', 'fill', ctx.frame.box(contract.envelope)),) p = Plan(children=[Child('supports', Trestles(tuple(d['columns']), self.max_post), bindings=terrain), Child('deck', Surface(tuple(d['writes'])), bindings=terrain), Child('guards', Guards(tuple(d['guards']), self.covered, tuple(d['roof'])))]) p.relations.extend(((ctx.path, 'connects', self.start.host), (ctx.path, 'connects', self.end.host))) return p def connection(key, start, end, terrain, **parameters): """Create a fully bound link through public endpoint references.""" return Child(key, Link(start, end, terrain, **parameters), bindings=(start.binding(), end.binding()))
hearth_extensions/boundaries.py
# Curve-following masonry with sampled installation sockets and grounded adaptation. from dataclasses import dataclass from hearth import Box, Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Domain, Port, Grant, Plan, Rule, Child from hearth.blocks import state_of, slab from .geometry import Polyline, bounds2 @dataclass(frozen=True) class Boundary: curve: Polyline height: int = 2 spacing: int = 7 max_step: int = 1 def capability(self): return Capability('extension.curved-boundary', ('boundary', 'siteworks', 'composite'), offers=('mount',), inputs={'height': Domain(1, 5), 'spacing': Domain(4, 12), 'max_step': Domain(0, 1)}, adaptations=('terrain-following base', 'stepped coping'), guarantees=('continuous cardinal contour', 'grounded boundary', 'mount sockets')) def negotiate(self, ctx, parameters): center = self.curve.cells() if len(center) > 220 or len(set(center)) != len(center): raise ContractError('boundary-domain', ctx.path, conditions='Simple open contour, at most 220 raster cells') levels = [ctx.elevation(x, z) for x, z in center] if any(abs(a - b) > self.max_step for a, b in zip(levels, levels[1:])): raise ContractError('boundary-grade', ctx.path, conditions='Adjacent wall foundations exceed step bound') ports = [] grants = [] for i in range(2, len(center) - 2, self.spacing): x, z = center[i] y = levels[i] + self.height + 2 x0, z0 = center[max(0, i - 1)] x1, z1 = center[min(len(center) - 1, i + 1)] turn = 0 if abs(x1 - x0) >= abs(z1 - z0) else 1 at = (x, y, z) key = f'mount-{i}' box = Box(at, at) ports.append(Port(key, 'mount', Frame(at, turn), box, 1, key, facts={'support': (x, y - 1, z), 'load': 'small-fixture'})) grants.append(Grant(key, box, ('install',), ('fixture',), 0)) supports = tuple((x, levels[i], z) for i, (x, z) in enumerate(center)) shell = tuple((x, y, z) for i, (x, z) in enumerate(center) for y in range(levels[i] + 1, levels[i] + self.height + 2)) box = Box.enclosing((*supports, *shell)).expand(2) return Contract(box, tuple(ports), tuple(grants), (Rule('support', supports), Rule('sealed', shell)), decisions={'center': center, 'levels': levels, 'height': self.height}, reads=(box,)) def realize(self, ctx, contract): p = Plan() d = contract.decisions rng = ctx.rng('masonry') for i, (x, z) in enumerate(d['center']): for y in range(d['levels'][i] + 1, d['levels'][i] + self.height + 1): p.block((x, y, z), state_of(rng.choice(('stone_bricks', 'stone_bricks', 'mossy_stone_bricks'))), 'contour-masonry') p.block((x, d['levels'][i] + self.height + 1, z), slab('stone_brick', 'top'), 'coping') return p @dataclass(frozen=True) class BoundaryLantern: def capability(self): return Capability('extension.boundary-lantern', ('fixture', 'light'), guarantees=('mounted actual light',)) def negotiate(self, ctx, parameters): return Contract(Box((0, 0, 0), (0, 1, 0)), rules=(Rule('support', ((0, -1, 0),)), Rule('expected', ((0, 0, 0),), data={'names': ['lantern']})), atomic_object=True) def realize(self, ctx, contract): p = Plan() p.block((0, 0, 0), state_of('lantern', hanging='false', waterlogged='false'), 'lamp') return p @dataclass(frozen=True) class IlluminateBoundary: host: str every: int = 1 def capability(self): return Capability('extension.boundary-lighting', ('composite',)) def negotiate(self, ctx, parameters): ports = ctx.view.offers(self.host, 'mount')[::self.every] if not ports: raise ContractError('missing-mounts', ctx.path) return Contract(Box.enclosing(ctx.local(p.frame.origin) for p in ports).expand(1)) def realize(self, ctx, contract): p = Plan() for port in ctx.view.offers(self.host, 'mount')[::self.every]: frame = Frame(ctx.local(port.frame.origin), (port.frame.turn - ctx.frame.turn) % 4) p.children.append(Child(port.key, BoundaryLantern(), frame=frame, bindings=(Binding(self.host, port.key),))) return p @dataclass(frozen=True) class BoundaryChain: curve: Polyline height: int = 2 spacing: int = 7 chunk: int = 96 def capability(self): return Capability('extension.boundary-chain', ('boundary', 'composite'), offers=('mount',), inputs={'chunk': Domain(4, 220), 'height': Domain(1, 5), 'spacing': Domain(4, 12)}, guarantees=('continuous contour across component joins',)) def parts(self): cells = self.curve.cells() if len(set(cells)) != len(cells): raise ContractError('boundary-self-intersection', conditions='A simple open contour is required') count = max(1, (len(cells) + self.chunk - 1) // self.chunk) size = (len(cells) + count - 1) // count return tuple(Boundary(Polyline(cells[i:i + size]), self.height, self.spacing) for i in range(0, len(cells), size)) def negotiate(self, ctx, parameters): boxes = [] ports = [] last_height = None for i, part in enumerate(self.parts()): local = part.negotiate(ctx, {}) if last_height is not None and abs(local.decisions['levels'][0] - last_height) > part.max_step: raise ContractError('boundary-grade', ctx.path, conditions='Grade bound also applies at component joins') last_height = local.decisions['levels'][-1] boxes.append(local.envelope) for p in local.ports: ports.append(Port(f'segment-{i}-{p.key}', p.kind, p.frame, p.region, p.capacity, facts=p.facts, delegate=(f'segment-{i}', p.key))) return Contract(Box.enclosing(p for box in boxes for p in box.corners()), ports=tuple(ports), decisions={'segments': len(boxes), 'curve': self.curve.points}) def realize(self, ctx, contract): return Plan(children=[Child(f'segment-{i}', part) for i, part in enumerate(self.parts())])
hearth_extensions/sites.py
# Accessible platforms with measured supports and oriented edge ports. from dataclasses import dataclass from hearth import Box, Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Plan, Child, Port, Rule, Domain from hearth.blocks import state_of from hearth.adapters.site import Foundation, SiteLimits, survey from .geometry import Polygon, bounds2 from .circulation import Surface DIRECTIONS = {'north': (0, -1, 0), 'east': (1, 0, 1), 'south': (0, 1, 2), 'west': (-1, 0, 3)} def edge_frames(width, depth, height): return {'north': Frame((width // 2, height, 0), 0), 'east': Frame((width - 1, height, depth // 2), 1), 'south': Frame((width // 2, height, depth - 1), 2), 'west': Frame((0, height, depth // 2), 3)} @dataclass(frozen=True) class Platform: terrain: str width: int = 9 depth: int = 9 freeboard: int = 1 def capability(self): return Capability('extension.platform', ('platform', 'composite', 'access'), offers=('access',), inputs={'width': Domain(5, 27), 'depth': Domain(5, 27), 'freeboard': Domain(1, 3)}) def negotiate(self, ctx, parameters): footprint = tuple((x, z) for x in range(self.width) for z in range(self.depth)) samples = survey(ctx, footprint) y = samples['floor'] + self.freeboard - 1 region = bounds2(footprint, min(v[0] for v in samples['samples'].values()) - 1, y + 3) ports = tuple(Port(k, 'access', f, f.box(Box((-2, -1, 0), (2, 1, 0))), 8) for k, f in edge_frames(self.width, self.depth, y + 1).items()) return Contract(region, ports=ports, decisions={'floor': y, 'footprint': footprint, 'strategy': samples['strategy']}, rules=(Rule('route', tuple(f.frame.origin for f in ports), region, phase='complete'),)) def realize(self, ctx, contract): d = contract.decisions p = Plan(children=[Child('foundation', Foundation(tuple(d['footprint']), d['floor'], d['strategy']), bindings=(Binding(self.terrain, 'construction', 'fill'),)), Child('deck', Surface(tuple((x, d['floor'], z) for x, z in d['footprint']), role='platform'))]) return p
hearth_extensions/halls.py
# Polygon halls, public facade installation and concentric hipped roof components. from dataclasses import dataclass from hearth import Box, Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Port, Grant, Rule, Plan, Child, Domain, Context from hearth.blocks import state_of, log, slab, stairs from hearth.adapters.site import survey, Foundation, Approach, SiteLimits from hearth.components.interior import Door, Light from hearth.components.primitives import Window from .geometry import Polygon, CARDINAL, bounds2, perimeter from .sites import edge_frames from .circulation import Surface from .interiors import HallInterior, FUNCTION_GROUPS @dataclass(frozen=True) class PolygonShell: footprint: Polygon height: int = 5 entrances: tuple = ('north', 'south') def capability(self): return Capability('extension.polygon-shell', ('wall', 'enclosure'), offers=('wall-installation',), guarantees=('continuous enclosure', 'protected floor support'), inputs={'height': Domain(5, 7)}) def negotiate(self, ctx, parameters): footprint = self.footprint.cells() shell = perimeter(footprint, diagonal=True) xs = [x for x, z in footprint] zs = [z for x, z in footprint] width, depth = max(xs) + 1, max(zs) + 1 if min(xs) != 0 or min(zs) != 0: raise ContractError('polygon-origin', ctx.path, conditions='Normalize footprint minimum to (0,0)') frames = edge_frames(width, depth, 0) ports = [] grants = [] for side, f in frames.items(): for role, offset, size, base in [('entry', 0, 1, 0)] if side in self.entrances else []: at = f.compose(Frame((offset, base, 0))) region = at.box(Box((0, 0, 0), (size - 1, 2, 0))) if not all((p[0], p[2]) in shell for p in region.cells()): raise ContractError('polygon-entry', ctx.path, at.origin, 'Requested cardinal entry is not on the footprint boundary') key = 'entry-' + side ports.append(Port(key, 'wall-installation', at, region, 1, key, facts={'thickness': 1, 'role': role, 'side': side})) grants.append(Grant(key, region, ('install',), ('door',), 3)) for i, offset in enumerate((-4, 3)): at = f.compose(Frame((offset, 1, 0))) region = at.box(Box((0, 0, 0), (1, 1, 0))) if all((p[0], p[2]) in shell for p in region.cells()): key = f'window-{side}-{i}' ports.append(Port(key, 'wall-installation', at, region, 1, key, facts={'thickness': 1, 'role': 'window', 'side': side})) grants.append(Grant(key, region, ('install',), ('window',), 4)) blocks = tuple((x, y, z) for x, z in shell for y in range(self.height)) return Contract(bounds2(footprint, 0, self.height - 1), tuple(ports), tuple(grants), rules=(Rule('sealed', blocks), Rule('support', tuple((x, -1, z) for x, z in shell))), decisions={'shell': shell, 'height': self.height}) def realize(self, ctx, contract): p = Plan() vertices = set(self.footprint.vertices) for x, z in contract.decisions['shell']: for y in range(self.height): frame = (x, z) in vertices or y == self.height - 1 p.block((x, y, z), log() if frame else state_of('smooth_sandstone'), 'frame' if frame else 'infill') return p @dataclass(frozen=True) class Facade: host: str shutters: bool = True def capability(self): return Capability('extension.facade-installations', ('composite',)) def negotiate(self, ctx, parameters): box = ctx.view.contract(self.host).envelope return Contract(Box.enclosing(ctx.local(p) for p in box.corners()).expand(2)) def realize(self, ctx, contract): p = Plan() for port in ctx.view.offers(self.host, 'wall-installation'): component = Door() if port.facts['role'] == 'entry' else Window(shutters=self.shutters) frame = Frame(ctx.local(port.frame.origin), (port.frame.turn - ctx.frame.turn) % 4) p.children.append(Child(port.key, component, frame=frame, bindings=(Binding(self.host, port.key),))) return p @dataclass(frozen=True) class HipRoof: footprint: Polygon run: int = 2 lantern: bool = False material: str = 'deepslate_tile' def capability(self): return Capability('extension.hip-roof', ('roof', 'composite'), adaptations=('polygon inset courses',), inputs={'run': Domain(choices=(1, 2, 3))}, guarantees=('continuous concentric weather surface',)) def negotiate(self, ctx, parameters): points = set(self.footprint.cells()) points |= {(x + dx, z + dz) for x, z in tuple(points) for dx, dz in CARDINAL} remaining = set(points) depths = {} depth = 0 while remaining: ring = perimeter(remaining) for p in ring: depths[p] = depth remaining -= set(ring) depth += 1 courses = tuple((x, depths[(x, z)] // self.run, z) for x, z in sorted(points)) peak = max(y for x, y, z in courses) cx = (min(x for x, z in points) + max(x for x, z in points)) // 2 cz = (min(z for x, z in points) + max(z for x, z in points)) // 2 return Contract(bounds2(points, -1, peak + (15 if self.lantern else 7)), rules=(Rule('sealed', courses),), decisions={'courses': courses, 'peak': peak, 'center': (cx, cz), 'run': self.run, 'lantern': self.lantern}) def realize(self, ctx, contract): p = Plan() d = contract.decisions heights = {(x, z): y for x, y, z in d['courses']} for x, y, z in d['courses']: face = next((f for dx, dz, f in ((1, 0, 'east'), (-1, 0, 'west'), (0, 1, 'south'), (0, -1, 'north')) if heights.get((x + dx, z + dz), y) > y), None) material = 'dark_oak' if y == 0 else self.material p.block((x, y, z), stairs(material, face) if face else slab(material, 'top'), 'hip-course') if self.lantern: cx, cz = d['center'] p.children.append(Child('lantern', RoofLantern(), frame=Frame((cx - 2, d['peak'] + 1, cz - 2)))) return p @dataclass(frozen=True) class RoofLantern: def capability(self): return Capability('extension.roof-lantern', ('roof', 'daylight', 'composite')) def negotiate(self, ctx, parameters): return Contract(Box((-1, -3, -1), (5, 13, 5))) def realize(self, ctx, contract): p = Plan() for x in range(5): for z in range(5): bed = ctx.elevation(x, z, maximum=0) if bed < -4: raise ContractError('lantern-support', ctx.path, ctx.world((x, bed, z))) for y in range(bed + 1, 1): p.block((x, y, z), state_of('spruce_planks'), 'ring-beam') if x in (0, 4) or z in (0, 4): for y in (1, 2): p.block((x, y, z), log() if x in (0, 4) and z in (0, 4) else state_of('glass'), 'clerestory') p.children.append(Child('cap', HipRoof(Polygon(((0, 0), (4, 0), (4, 4), (0, 4))), run=2), frame=Frame((0, 3, 0)))) return p @dataclass(frozen=True) class Pavilion: footprint: Polygon terrain: str purpose: str = 'library' entrances: tuple = ('north', 'south') height: int = 5 roof_run: int = 2 lantern: bool = False limits: SiteLimits = SiteLimits() def capability(self): return Capability('extension.pavilion', ('building', 'habitable', 'composite'), offers=('access',), adaptations=('polygon support grid', 'independently measured approaches'), guarantees=('connected entrances', 'furnished lit enclosed hall'), inputs={'height': Domain(5, 7), 'purpose': Domain(choices=('living', 'library', 'workshop', 'kitchen', 'bedroom', 'storage'))}, locked=('footprint', 'purpose', 'entrances', 'height', 'roof_run', 'lantern')) def negotiate(self, ctx, parameters): points = self.footprint.cells() width = max(x for x, z in points) + 1 depth = max(z for x, z in points) + 1 if not 13 <= width <= 25 or not 13 <= depth <= 25 or not self.entrances: raise ContractError('hall-domain', ctx.path, conditions='Footprints 13..25, at least one declared entrance') measured = survey(ctx, points, self.limits) floor = measured['floor'] ports = [] approaches = [] frames = edge_frames(width, depth, 0) low = min(v[0] for v in measured['samples'].values()) - 1 roof = HipRoof(self.footprint, self.roof_run, self.lantern).negotiate(ctx, {}) boxes = [bounds2(points, low, floor + self.height + 3).expand(3), Frame((0, floor + self.height + 2, 0)).box(roof.envelope)] targets = [(width // 2, floor + 1, depth // 2)] for side in self.entrances: if side not in frames: raise ContractError('hall-entrance', ctx.path, conditions=side) f = frames[side] comp = Approach(0, floor, limits=self.limits) ac = comp.negotiate(Context(ctx.path, ctx.frame.compose(f), ctx.scope.child('approach-' + side), ctx.view, (), ctx.limits), {}) local = ac.transformed(f) port = local.ports[0] ports.append(Port(side, 'access', Frame(port.frame.origin, f.turn), port.region, 8, delegate=('approach-' + side, 'street'))) approaches.append((side, f, comp)) boxes.append(local.envelope) targets.extend(((f.origin[0], floor + 1, f.origin[2]), port.frame.origin)) envelope = Box.enclosing(p for box in boxes for p in box.corners()) interior = Box((1, floor + 1, 1), (width - 2, floor + self.height - 1, depth - 2)) return Contract(envelope, tuple(ports), rules=(Rule('route', tuple(targets), envelope, phase='complete'), Rule('light', tuple(targets[:1]), interior, {'minimum': 1}, 'complete'), Rule('furnishing', box=interior, data={'groups': FUNCTION_GROUPS[self.purpose]}, phase='complete')), decisions={'floor': floor, 'width': width, 'depth': depth, 'footprint': points, 'vertices': self.footprint.vertices, 'strategy': measured['strategy'], 'entrances': self.entrances, 'height': self.height, 'purpose': self.purpose, 'roof_run': self.roof_run, 'lantern': self.lantern}) def realize(self, ctx, contract): d = contract.decisions floor = d['floor'] w = d['width'] depth = d['depth'] p = Plan(children=[Child('foundation', Foundation(tuple(d['footprint']), floor, d['strategy'], self.limits), bindings=(Binding(self.terrain, 'construction', 'fill'),)), Child('floor', Surface(tuple((x, floor, z) for x, z in d['footprint']), role='hall-floor')), Child('ceiling', Surface(tuple((x, floor + self.height + 1, z) for x, z in d['footprint']), role='hall-ceiling')), Child('shell', PolygonShell(self.footprint, self.height, self.entrances), frame=Frame((0, floor + 1, 0))), Child('facade', Facade(ctx.path + '/shell'))]) for side in self.entrances: f = edge_frames(w, depth, 0)[side] p.children.append(Child('approach-' + side, Approach(0, floor, limits=self.limits), frame=f, bindings=(Binding(self.terrain, 'construction', 'surface'),))) p.children.append(Child('furnishings', HallInterior(self.footprint, self.purpose), frame=Frame((0, floor + 1, 0)))) for x in range(4, w - 3, 5): for z in range(4, depth - 3, 5): p.children.append(Child(f'light-{x}-{z}', Light(), frame=Frame((x, floor + self.height - 1, z)))) p.children.append(Child('roof', HipRoof(self.footprint, self.roof_run, self.lantern), frame=Frame((0, floor + self.height + 2, 0)))) return p
hearth_extensions/graphs.py
# Reusable campus graph composes arbitrary public building and circulation components. from dataclasses import dataclass from hearth import Box, Frame, ContractError from hearth.kernel import Capability, Contract, Port, Rule, Plan, Child, Context from .interfaces import Endpoint from .circulation import connection from .boundaries import BoundaryChain, IlluminateBoundary from hearth.components.landscape import Landscape @dataclass(frozen=True) class Vertex: key: str component: object frame: Frame @dataclass(frozen=True) class Edge: a: str a_port: str b: str b_port: str covered: bool = False via: tuple = () rise: int = 0 width: int = 3 @dataclass(frozen=True) class Campus: vertices: tuple[Vertex, ...] edges: tuple[Edge, ...] terrain: str envelope: Box boundary: object = None landscape: bool = True def capability(self): return Capability('extension.campus', ('settlement', 'composite'), offers=('public-access',), guarantees=('declared graph connected', 'usable realized building connections'), locked=('vertices', 'edges')) def negotiate(self, ctx, parameters): keys = {v.key for v in self.vertices} if len(keys) != len(self.vertices) or not keys: raise ContractError('graph-vertices', ctx.path) connected = {self.vertices[0].key} for edge in self.edges: if edge.a not in keys or edge.b not in keys or edge.a == edge.b: raise ContractError('graph-edge', ctx.path, conditions=str(edge)) while True: more = {v for e in self.edges if e.a in connected or e.b in connected for v in (e.a, e.b)} if more <= connected: break connected |= more if connected != keys: raise ContractError('graph-disconnected', ctx.path, conditions=str(sorted(keys - connected))) first = self.vertices[0] context = Context(ctx.path + '/' + first.key, ctx.frame.compose(first.frame), ctx.scope.child(first.key), ctx.view, (), ctx.limits) offered = first.component.negotiate(context, {}).transformed(first.frame).ports port = next((p for p in offered if p.kind in ('access', 'public-access')), None) if port is None: raise ContractError('graph-access', ctx.path, conditions='First vertex must expose usable access') gateway = Port('public', 'access', port.frame, port.region, port.capacity, delegate=(first.key, port.key)) return Contract(self.envelope, ports=(gateway,), decisions={'vertices': [v.key for v in self.vertices], 'edges': [(e.a, e.a_port, e.b, e.b_port, e.covered, e.width) for e in self.edges]}) def realize(self, ctx, contract): p = Plan(children=[Child(v.key, v.component, frame=v.frame) for v in self.vertices]) p.children.append(Child('circulation', Connections(ctx.path, self.edges, self.terrain, self.envelope))) if self.boundary is not None: p.children.extend((Child('boundary', BoundaryChain(self.boundary)), Child('boundary-lights', IlluminateBoundary(ctx.path + '/boundary', 2)))) if self.landscape: p.children.append(Child('landscape', Landscape(self.envelope, self.terrain, 8, 12, 0.025))) return p @dataclass(frozen=True) class Connections: parent: str edges: tuple[Edge, ...] terrain: str envelope: Box def capability(self): return Capability('extension.connection-graph', ('connection', 'composite')) def negotiate(self, ctx, parameters): targets = [] for edge in self.edges: for key, port in ((edge.a, edge.a_port), (edge.b, edge.b_port)): targets.append(ctx.local(ctx.view.port(self.parent + '/' + key, port).frame.origin)) return Contract(self.envelope, rules=(Rule('route', tuple(targets), self.envelope, phase='complete'),)) def realize(self, ctx, contract): p = Plan() for i, edge in enumerate(self.edges): a = Endpoint(self.parent + '/' + edge.a, edge.a_port) b = Endpoint(self.parent + '/' + edge.b, edge.b_port) p.children.append(connection(f'link-{i}', a, b, self.terrain, via=edge.via, covered=edge.covered, rise=edge.rise, width=edge.width)) return p
hearth_extensions/programs.py
# Lightweight graph clients using frozen generic fields and interchangeable public buildings. from hearth import Scene, Box, Frame from hearth.randomness import Scope from hearth.environment import Terrain, gradient, wave, radial from hearth.components.building import Blueprint, RoomSpec, Building from hearth.persistence import semantic_digest from .geometry import Polygon, Polyline from .halls import Pavilion from .graphs import Campus, Vertex, Edge DOMAIN = Box((-18, -4, -18), (95, 70, 95)) def frozen_site(environment_seed=0, domain=DOMAIN): rng = Scope(environment_seed).stream('environment') field = gradient(rng.choice((-.012, 0, .012)), rng.choice((-.009, .009)), 5) + wave(.5, .07, .09, rng.random() * 6) + radial(30, 31, 24, -3.8) scene = Scene(environment_seed, domain=domain) scene.place('land', Terrain(domain, field, water_level=3, edit_limit=2500)) return scene.finalize() def branching_campus(seed=0): rng = Scope(seed).stream('branching-graph') hub = Pavilion(Polygon.chamfered(17, 17, 4), '/land', 'library', ('north', 'east', 'south', 'west'), height=6, lantern=True) west = Pavilion(Polygon.chamfered(13, rng.choice((13, 17)), 2), '/land', 'workshop', ('north', 'south'), height=5) east = Pavilion(Polygon.chamfered(rng.choice((13, 17)), 13, 2), '/land', 'kitchen', ('west', 'south'), height=rng.choice((5, 6))) rooms = [RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom')] if rng.choice((False, True)): rooms.append(RoomSpec(0, 1, 0, 'storage')) lodge = Building(Blueprint(tuple(rooms), bay=9, porch=True), '/land') vertices = [Vertex('hall', hub, Frame((23, 0, 23))), Vertex('workshop', west, Frame((0, 0, 0))), Vertex('kitchen', east, Frame((51, 0, 0))), Vertex('lodge', lodge, Frame((48, 0, 51)))] edges = [Edge('hall', 'north', 'workshop', 'south', covered=True), Edge('hall', 'east', 'kitchen', 'west', rise=rng.choice((0, 1))), Edge('hall', 'south', 'lodge', 'street', covered=True)] if rng.choice((False, True)): vertices.append(Vertex('archive', Pavilion(Polygon.chamfered(13, 13, 2), '/land', 'library', ('east',)), Frame((0, 0, 51)))) edges.append(Edge('hall', 'west', 'archive', 'east', rise=1)) boundary = Polyline.bezier(((-12, 0), (-30, 120), (115, 120), (84, 0))) return Campus(tuple(vertices), tuple(edges), '/land', DOMAIN, boundary) def perimeter_cluster(seed=0): rng = Scope(seed).stream('perimeter-graph') widths = (rng.choice((17, 21, 25)), rng.choice((13, 17)), rng.choice((13, 17))) market = Pavilion(Polygon.chamfered(widths[0], 13, 2), '/land', 'workshop', ('north', 'east', 'south'), height=5, roof_run=3) reading = Pavilion(Polygon.chamfered(widths[1], 17, 3), '/land', 'library', ('north', 'south'), height=6, lantern=rng.choice((True, False))) dining = Pavilion(Polygon.chamfered(widths[2], 13, 2), '/land', 'living', ('east', 'west'), height=5) vertices = (Vertex('market', market, Frame((0, 0, 0))), Vertex('reading', reading, Frame((50, 0, 10))), Vertex('dining', dining, Frame((20, 0, 57)))) edges = (Edge('market', 'east', 'reading', 'north', via=((40, -5),), covered=False, rise=1), Edge('reading', 'south', 'dining', 'east', covered=True), Edge('dining', 'west', 'market', 'south', via=((9, 42),), rise=rng.choice((0, 1)))) boundary = Polyline.bezier(((-12, 0), (-30, 120), (115, 120), (84, 0))) return Campus(vertices, edges, '/land', DOMAIN, boundary) def extension_scene(program=branching_campus, seed=0, environment_seed=0): environment = frozen_site(environment_seed) original = semantic_digest(environment) scene = environment.fork(seed=seed) scene.place('campus', program(seed)) scene.finalize() if semantic_digest(environment) != original: raise AssertionError('Frozen input mutated') return scene
hearth_extensions/assessment.py
# Frozen extension inputs, actual principal/contact signatures and retained outcomes. import hashlib import json import time from pathlib import Path from dataclasses import replace from collections import Counter from hearth import Scene, Box, Frame, Binding from hearth.kernel import ContractError, SearchExhausted, validate from hearth.environment import Terrain, gradient, wave, radial from hearth.randomness import Scope from hearth.persistence import semantic_digest, export_scene from hearth.blocks import solid from .geometry import Polyline, Polygon from .sites import Platform from .interfaces import Endpoint from .circulation import Link from .boundaries import BoundaryChain, IlluminateBoundary from .halls import Pavilion from .programs import frozen_site, branching_campus, perimeter_cluster PROBE_DOMAIN = Box((-8, -4, -8), (45, 52, 45)) def probe_expression(environment_seed): rng = Scope(environment_seed).stream('probe-field') return (gradient(rng.choice((-.025, 0, .035)), rng.choice((0, .015)), 2) + wave(rng.choice((0, .35, .7)), .11, .09, rng.random() * 6) + radial(16, 18, 14, -rng.choice((0, 1, 2)))).clamp(-1, 5), rng.choice((None, 3)) def freeze_probe(environment_seed): field, water = probe_expression(environment_seed) s = Scene(environment_seed, domain=PROBE_DOMAIN) s.place('land', Terrain(s.domain, field, water)) return s.finalize() def connector_scene(environment, structure_seed): s = environment.fork(seed=structure_seed) rng = Scope(structure_seed).stream('connection-intent') s.place('a', Platform('/land')) s.place('b', Platform('/land'), frame=Frame((18, 0, 27))) a, b = Endpoint('/a', 'south'), Endpoint('/b', 'north') link = Link(a, b, '/land', via=((rng.choice((9, 12, 15)), rng.choice((16, 18, 20))),), width=rng.choice((3, 5)), rise=rng.choice((0, 1, 2)), covered=rng.choice((True, False))) s.place('link', link, bindings=(a.binding(), b.binding())) return s.finalize() def boundary_scene(environment, structure_seed): rng = Scope(structure_seed).stream('boundary-intent') controls = ((0, 0), (8, rng.choice((0, 10, 23))), (28, rng.choice((0, 5, 18))), (37, 18)) curve = Polyline(((0, 0), (37, 18))) if structure_seed == 0 else Polyline.bezier(controls) s = environment.fork(seed=structure_seed) s.place('boundary', BoundaryChain(curve, height=rng.choice((1, 2, 3)), spacing=rng.choice((4, 7, 10)))) s.place('lights', IlluminateBoundary('/boundary')) return s.finalize() def hall_scene(seed, environment_seed=None): rng = Scope(seed).stream('hall-intent') domain = Box((-12, -4, -12), (42, 65, 42)) es = seed if environment_seed is None else environment_seed field = gradient(.012, -.008, 4) + wave(.5, .1, .12, Scope(es).stream('hall-field').random() * 6) env = Scene(es, domain=domain) env.place('land', Terrain(domain, field)) env.finalize() s = env.fork(seed=seed) shape = Polygon.chamfered(rng.choice((13, 17, 21, 25)), rng.choice((13, 17, 21)), rng.choice((0, 2, 4))) s.place('hall', Pavilion(shape, '/land', rng.choice(('library', 'workshop', 'living')), ('north', 'south', 'east') if rng.choice((True, False)) else ('north', 'west'), height=rng.choice((5, 6, 7)), roof_run=rng.choice((2, 3)), lantern=rng.choice((True, False)))) return s.finalize() def signatures(scene): """Measure current semantic geometry, omitting cosmetic material and contact height.""" halls = [] links = [] boundaries = [] organization = [] for path, node in sorted(scene.nodes.items()): d = node.contract.decisions if node.type == 'extension.pavilion': footprint = sorted((node.frame.inverse(p)[0], node.frame.inverse(p)[2]) for p in scene.cells(path + '/floor')) halls.append({'footprint': footprint, 'height': d['height'], 'function': d['purpose'], 'entrances': d['entrances'], 'roof_run': d['roof_run'], 'lantern': d['lantern']}) if node.type in ('extension.bridge', 'extension.gallery'): pts = [node.frame.inverse(p) for p in scene.cells(path + '/deck')] x0, z0 = d['center'][0] links.append({'body': sorted((p[0] - x0, p[2] - z0) for p in pts), 'width': d['width'], 'covered': d['covered'], 'rise': d['rise']}) if node.type == 'extension.boundary-chain': pts = [node.frame.inverse(p) for p in scene.cells(path, True) if 'boundary-lantern' not in scene.nodes[scene.inspect(p)['instance']].type] x0 = min(p[0] for p in pts) z0 = min(p[2] for p in pts) columns = {} for x, y, z in pts: columns.setdefault((x, z), []).append(y) boundaries.append({'plan': sorted(set((p[0] - x0, p[2] - z0) for p in pts)), 'section_heights': sorted({max(ys) - min(ys) + 1 for ys in columns.values()})}) if node.type == 'extension.campus': vertex_keys = d['vertices'] vertices = [] for key in vertex_keys: v = scene.nodes[path + '/' + key] at = node.frame.inverse(v.frame.origin) vertices.append((at[0], at[2], v.capability.tags)) topology = sorted((vertex_keys.index(a), pa, vertex_keys.index(b), pb, covered, width) for a, pa, b, pb, covered, width in d['edges']) organization.append({'positions': vertices, 'topology': topology}) from hearth.assessment import principal_signature legacy = principal_signature(scene)[1]['buildings'] principal = {'halls': halls, 'links': links, 'boundaries': boundaries, 'organization': organization, 'legacy': legacy} contact = [] fill = 0 replaced = 0 excavated = 0 edit_occupied = 0 for path, node in sorted(scene.nodes.items()): if node.type in ('extension.trestles', 'adapter.foundation', 'adapter.approach'): contact.append((node.type, node.contract.decisions)) fill += len(scene.cells(path)) if node.type == 'extension.curved-boundary': contact.append((node.type, [node.frame.inverse(p) for r in node.contract.rules if r.kind == 'support' for p in r.cells])) if node.capability and set(node.capability.tags).intersection(('siteworks', 'path')): edit_occupied += len(scene.cells(path)) replaced += len(scene.displaced.get(path, {})) excavated += sum(solid(old.state) and (p not in scene.blocks or not solid(scene.blocks[p].state)) for p, old in scene.displaced.get(path, {}).items()) digest = lambda x: hashlib.sha256(json.dumps(x, sort_keys=True, default=list).encode()).hexdigest() interiors = [n for n in scene.nodes.values() if n.type == 'extension.hall-interior'] return {'principal_signature': digest(principal), 'structure': principal, 'contact_signature': digest(contact), 'contact_cells': fill, 'contact_replacements': replaced, 'sitework_occupied_cells': edit_occupied, 'excavated_solid_cells': excavated, 'furnishing_bays': sum(n.contract.decisions['placed_bays'] for n in interiors), 'omitted_optional_furnishing_bays': sum(n.contract.decisions['omitted_optional'] for n in interiors)} def measured(label, recipe, inputs, artifact=None): start = time.perf_counter() row = {'label': label, 'inputs': inputs, 'candidate_attempts': 1, 'accepted_candidates': 0, 'retries': 0} try: scene = recipe() scene.finalize() row.update(status='validated', accepted_candidates=1, blocks=len(scene.blocks), instances=len(scene.nodes), digest=semantic_digest(scene), **signatures(scene)) if artifact: export_scene(scene, artifact) row['artifact'] = str(artifact) except ContractError as exc: limits = ('site-relief', 'support-height', 'connection-support-height', 'connection-fill-limit', 'boundary-grade', 'endpoint-grade', 'approach-detour', 'connection-domain') row.update(status='budget-exhausted' if isinstance(exc, SearchExhausted) else ('incompatible' if exc.diagnostic.rule in limits else 'defect'), diagnostic=exc.diagnostic.__dict__, all_diagnostics=[d.__dict__ for d in getattr(exc, 'diagnostics', [exc.diagnostic])]) except Exception as exc: row.update(status='defect', diagnostic={'exception': type(exc).__name__, 'message': str(exc)}) row['seconds'] = round(time.perf_counter() - start, 4) return row def run(output, root_seed=0, artifacts=False, sample_output=Path('samples/extensions')): output = Path(output) output.mkdir(parents=True, exist_ok=True) rows = [] frozen = {} inputs = [] for es in range(root_seed * 100, root_seed * 100 + 8): frozen[es] = freeze_probe(es) field, water = probe_expression(es) inputs.append({'environment_seed': es, 'expression': field.expression(), 'water': water, 'digest': semantic_digest(frozen[es])}) (output / 'frozen-inputs.json').write_text(json.dumps(inputs, indent=2)) def record(label, fn, parameters, keep=False): path = Path(sample_output) / (label + '.litematic') if keep and artifacts else None row = measured(label, fn, parameters, path) rows.append(row) print(label, row['status'], flush=True) for i, es in enumerate(frozen): for bs in range(6): record(f'connector-{i}-{bs}', lambda e=frozen[es], b=bs: connector_scene(e, b), {'environment': inputs[i], 'structure_seed': bs}, (i, bs) in ((0, 0), (1, 2), (4, 3), (7, 5))) assert semantic_digest(frozen[es]) == inputs[i]['digest'] for es in range(4): # Independent dry substrates use the same field expression with water omitted. field, _ = probe_expression(es + root_seed * 100) env = Scene(es + root_seed * 100, domain=PROBE_DOMAIN) env.place('land', Terrain(env.domain, field)) env.finalize() for bs in range(4): record(f'boundary-{es}-{bs}', lambda e=env, b=bs: boundary_scene(e, b), {'environment_seed': es + root_seed * 100, 'expression': field.expression(), 'structure_seed': bs}, (es, bs) in ((0, 1), (3, 3))) for seed in range(12): record(f'hall-{seed}', lambda b=seed: hall_scene(b, root_seed * 100 + b), {'structure_seed': seed, 'environment_seed': root_seed * 100 + seed}, seed in (0, 4, 7)) for name, program in (('campus', branching_campus), ('perimeter', perimeter_cluster)): for seed in range(6): environment = frozen_site(root_seed * 100 + seed) identity = semantic_digest(environment) def recipe(e=environment, b=seed, p=program): s = e.fork(seed=b) s.place('campus', p(b)) return s.finalize() record(f'{name}-{seed}', recipe, {'program': name, 'structure_seed': seed, 'environment_seed': root_seed * 100 + seed, 'frozen_digest': identity}, seed in (0, 3)) assert semantic_digest(environment) == identity for i in range(24): es = 2000 + root_seed * 100 + i rng = Scope(es).stream('stress') field = (gradient(rng.choice((0, .12, .28)), rng.choice((0, -.12, .15)), 2) + wave(rng.choice((0, 2, 4)), .13, .1, rng.random() * 6)).clamp(-2, 18) water = rng.choice((None, 3, 9, 12)) env = Scene(es, domain=PROBE_DOMAIN) env.place('land', Terrain(env.domain, field, water)) env.finalize() record(f'stress-{i:02}', lambda e=env, b=i % 6: connector_scene(e, b), {'environment_seed': es, 'structure_seed': i % 6, 'expression': field.expression(), 'water': water}) (output / 'results.json').write_text(json.dumps(rows, indent=2)) summary = {} for name in ('connector', 'boundary', 'hall', 'campus', 'perimeter', 'stress'): part = [r for r in rows if r['label'].startswith(name + '-')] good = [r for r in part if r['status'] == 'validated'] summary[name] = {'inputs': len(part), 'outcomes': dict(Counter(r['status'] for r in part)), 'candidate_attempts': sum(r['candidate_attempts'] for r in part), 'accepted_candidates': sum(r['accepted_candidates'] for r in part), 'retries': sum(r['retries'] for r in part), 'principal_signatures': len({r['principal_signature'] for r in good}), 'contact_signatures': len({r['contact_signature'] for r in good}), 'contact_cells_range': [min((r['contact_cells'] for r in good), default=0), max((r['contact_cells'] for r in good), default=0)], 'contact_replacement_range': [min((r['contact_replacements'] for r in good), default=0), max((r['contact_replacements'] for r in good), default=0)], 'seconds': round(sum(r['seconds'] for r in part), 3)} (output / 'summary.json').write_text(json.dumps(summary, indent=2)) if artifacts: (Path(sample_output) / 'replay-manifest.json').write_text(json.dumps([{k: r[k] for k in ('label', 'inputs', 'artifact', 'digest', 'status')} for r in rows if 'artifact' in r], indent=2)) return summary
extension_demo/__init__.py
# Independent component package; imports only Hearth's public protocols and components. from dataclasses import dataclass from hearth.kernel import Capability, Contract, Plan, Child, Rule, Port from hearth.space import Box, Frame from hearth.blocks import state_of, slab from hearth.components.interior import Room @dataclass(frozen=True) class Pendant: def capability(self): return Capability('extension.pendant', ('light', 'room-light'), guarantees=('actual light source',)) def negotiate(self, context, parameters): return Contract(Box((0, 0, 0), (0, 1, 0)), rules=(Rule('expected', ((0, 0, 0),), data={'names': ['ochre_froglight']}),)) def realize(self, context, contract): plan = Plan() plan.block((0, 0, 0), state_of('ochre_froglight', axis='y')) plan.block((0, 1, 0), slab('dark_oak')) return plan @dataclass(frozen=True) class ReadingSuite: width: int = 11 def capability(self): return Capability('extension.reading-suite', ('room', 'habitable', 'composite'), offers=('access',), guarantees=('lit', 'furnished', 'enclosed', 'reachable')) def negotiate(self, context, parameters): entry = (self.width // 2, 1, 0) port = Port('north', 'access', Frame(entry), Box(entry, (entry[0], 2, 0)), 10, delegate=('reading-room', 'north')) return Contract(Box((-1, 0, -1), (self.width, 9, self.width)), ports=(port,)) def realize(self, context, contract): return Plan(children=[Child('reading-room', Room('library', self.width, self.width, light_component=Pendant()))])
examples/courtyard.py
# New composition written after the core abstractions; no library changes needed. import argparse from pathlib import Path from hearth.components.building import Blueprint, RoomSpec from hearth.programs import building_scene from hearth.randomness import Scope from hearth.persistence import export_scene def build(seed): rng = Scope(seed).stream('courtyard') ring = ((0, 0), (1, 0), (2, 0), (2, 1), (2, 2), (1, 2), (0, 2), (0, 1)) functions = ('living', 'library', 'workshop', 'storage', 'kitchen', 'bedroom', 'bedroom', 'storage') rooms = [RoomSpec(x, z, 0, purpose) for (x, z), purpose in zip(ring, functions)] for x, z in rng.sample(((0, 0), (2, 0), (0, 2), (2, 2)), rng.choice((1, 2))): rooms.append(RoomSpec(x, z, 1, 'bedroom')) return building_scene(Blueprint(tuple(rooms), bay=9, porch=True, roof_axis='auto'), seed) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('samples/courtyard.litematic')) a = p.parse_args() export_scene(build(a.seed), a.output)
examples/inspection.py
# Generate a real glass query, highlight membership, export and repeat after reload. import argparse import json from pathlib import Path from hearth.programs import dwelling, building_scene from hearth.persistence import export_scene, load_scene from hearth.blocks import name_of def demonstrate(seed, output): scene = building_scene(dwelling(seed), seed) point = next(p for p, c in sorted(scene.blocks.items()) if name_of(c.state) == 'glass' and 'room-' in c.owner) query = scene.inspect(point) print(json.dumps(query, default=lambda v: sorted(v), indent=2)) print('Exact current component cells:', sorted(scene.cells(query['instance']))) export_scene(scene, output) restored = load_scene(output) assert restored.inspect(point) == query print('Reloaded query identical; world coordinate:', point) return query if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('samples/inspection.litematic')) a = p.parse_args() demonstrate(a.seed, a.output)
examples/prototype.py
# Run the small terrain, planting and attached-window composition before full buildings. import argparse from pathlib import Path from hearth import Scene, Box, Frame, Binding from hearth.environment import Terrain, gradient, wave from hearth.components.primitives import Wall, Window, Grass, Tree from hearth.adapters.site import Foundation from hearth.composition import encapsulate from hearth.kernel import Plan, Child from hearth.persistence import export_scene def build(seed=0): scene = Scene(seed, domain=Box((-8, -3, -8), (20, 24, 20))) scene.place('land', Terrain(scene.domain, gradient(base=2) + wave(0.6, 0.2, 0.2))) def facade(ctx): return Plan(children=[Child('wall', Wall(thickness=2)), Child('window', Window(), frame=Frame((3, 1, 0)), bindings=(Binding(ctx.path + '/wall', 'infill'),))]) scene.place('footing', Foundation.rectangular(9, 2, 4), bindings=(Binding('/land', 'construction', 'fill'),)) scene.place('facade', encapsulate('facade', Box((-1, 0, -2), (10, 6, 3)), facade), frame=Frame((0, 4, 0))) y = scene.view.elevation(13, 9) + 1 scene.place('grass', Grass(True), frame=Frame((13, y, 9)), bindings=(Binding('/land', 'planting', 'plant'),)) scene.place('tree', Tree(), frame=Frame((13, y, 9)), bindings=(Binding('/land', 'planting', 'plant'), Binding('/grass', 'replacement', 'plant'))) return scene.finalize() if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--seed', type=int, default=0) parser.add_argument('--output', type=Path, default=Path('samples/prototype.litematic')) args = parser.parse_args() export_scene(build(args.seed), args.output)
examples/assess.py
# Explicit finite batch output, never an unnoticed unit-test side effect. import argparse import json from pathlib import Path from hearth.assessment import run_corpus if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('reports/corpus')) p.add_argument('--artifacts', action='store_true') a = p.parse_args() print(json.dumps(run_corpus(a.output, a.seed, a.artifacts), indent=2))
examples/gallery.py
# A later client composes a public gallery with connected reading and work rooms. import argparse from pathlib import Path from hearth.components.building import Blueprint, RoomSpec from hearth.programs import building_scene from hearth.randomness import Scope from hearth.persistence import export_scene from extension_demo import Pendant def build(seed): rng = Scope(seed).stream('gallery-layout') length = rng.choice((2, 3)) rooms = [RoomSpec(0, z, 0, 'library' if z % 2 else 'living') for z in range(length)] rooms.append(RoomSpec(1, length - 1, 0, 'workshop')) rooms.append(RoomSpec(0, length - 1, 1, 'bedroom')) return building_scene(Blueprint(tuple(rooms), bay=9, roof_axis='z', light_component=Pendant()), seed) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('samples/gallery.litematic')) a = p.parse_args() export_scene(build(a.seed), a.output)
examples/building.py
# Run any of the three short room-composition programs with an explicit seed. import argparse from pathlib import Path from hearth.programs import PROGRAMS, building_scene from hearth.persistence import export_scene if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('program', choices=PROGRAMS) p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('samples/building.litematic')) a = p.parse_args() export_scene(building_scene(PROGRAMS[a.program](a.seed), a.seed), a.output)
examples/extension.py
# Substitute independent lighting and encapsulate an independently packaged room. import argparse from pathlib import Path from hearth import Scene, Box, Frame from hearth.kernel import Registry from hearth.components.interior import Light from hearth.components.building import Blueprint, RoomSpec from hearth.programs import building_scene from hearth.persistence import export_scene from extension_demo import Pendant, ReadingSuite def build(seed): registry = Registry() registry.register(Light()) registry.register(Pendant()) lights = registry.select('room-light') design = Blueprint((RoomSpec(0, 0, 0, 'library'), RoomSpec(0, 0, 1, 'bedroom')), light_component=lights[seed % len(lights)]) return building_scene(design, seed) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('samples/extension.litematic')) a = p.parse_args() export_scene(build(a.seed), a.output)
examples/extension_audit.py
# Replay the frozen extension manifest and compare complete structural records and actual NBT. import argparse import json from pathlib import Path import subprocess import sys import tempfile from hearth import Scene from hearth.environment import Terrain from hearth.environment.fields import from_expression from hearth.persistence import load_scene, semantic_digest, encode from hearth_extensions.assessment import PROBE_DOMAIN, freeze_probe, connector_scene, boundary_scene, hall_scene from hearth_extensions.programs import extension_scene, branching_campus, perimeter_cluster def replay(row): """Reconstruct one explicit assessment recipe from its recorded inputs. Args: row (dict): A selected row in the extension replay manifest. Returns: Scene: A validated, freshly generated scene without filesystem output. """ inputs = row['inputs'] seed = inputs['structure_seed'] group = row['label'].split('-')[0] if group == 'connector': environment = freeze_probe(inputs['environment']['environment_seed']) if semantic_digest(environment) != inputs['environment']['digest']: raise AssertionError('Frozen terrain changed') return connector_scene(environment, seed) if group == 'boundary': environment = Scene(inputs['environment_seed'], domain=PROBE_DOMAIN) environment.place('land', Terrain(PROBE_DOMAIN, from_expression(inputs['expression']))) environment.finalize() return boundary_scene(environment, seed) if group == 'hall': return hall_scene(seed, inputs['environment_seed']) programs = {'campus': branching_campus, 'perimeter': perimeter_cluster} return extension_scene(programs[inputs['program']], seed, inputs['environment_seed']) def audit(seed: int, manifest: Path, output: Path, cli: bool = False): """Check replay identity, structural graphs, queries, inventories and optional original CLI. Args: seed (int): Root assessment seed, used to verify the selected manifest. manifest (Path): Explicit batch artifact manifest. output (Path): Audit report destination. cli (bool): Also exercise the unchanged no-argument and seed-1 CLI in a temporary directory. Returns: dict: Completed audit with every selected input and result. """ entries = json.loads(manifest.read_text()) if entries[0]['inputs']['environment']['environment_seed'] != seed * 100: raise ValueError('Root seed does not match the selected assessment manifest') rows = [] for row in entries: native = replay(row) restored = load_scene(Path(row['artifact'])) assert semantic_digest(native) == row['digest'] == semantic_digest(restored), row['label'] for field in ('nodes', 'relations', 'dependencies', 'operations', 'port_uses', 'displaced'): assert encode(getattr(native, field)) == encode(getattr(restored, field)), (row['label'], field) assert native.reverse == restored.reverse, row['label'] assert {p: c.nbt for p, c in native.blocks.items()} == {p: c.nbt for p, c in restored.blocks.items()} points = [min(native.cells(n)) for n in sorted(native.nodes) if native.cells(n)] for point in points: assert native.inspect(point) == restored.inspect(point), (row['label'], point) rows.append({'label': row['label'], 'digest': row['digest'], 'nodes': len(native.nodes), 'blocks': len(native.blocks), 'component_queries': len(points), 'inventories': sum(c.nbt is not None for c in native.blocks.values()), 'verified': True}) cli_rows = [] if cli: root = Path(__file__).resolve().parents[1] with tempfile.TemporaryDirectory(dir=root / 'test', prefix='tmp-extension-cli-') as directory: temporary = Path(directory) for name, arguments, filename in (('default', [], 'output.litematic'), ('seed-1', ['--seed', '1', '--output', str(temporary / 'explicit path with spaces.litematic')], 'explicit path with spaces.litematic')): subprocess.run([sys.executable, str(root / 'generate.py'), *arguments], cwd=temporary, check=True) scene = load_scene(temporary / filename) cli_rows.append({'command': name, 'seed': scene.seed, 'blocks': len(scene.blocks), 'nodes': len(scene.nodes), 'digest': semantic_digest(scene), 'verified': True}) result = {'root_seed': seed, 'manifest': str(manifest), 'verified': True, 'artifacts': rows, 'original_cli': cli_rows} output.parent.mkdir(parents=True, exist_ok=True) output.write_text(json.dumps(result, indent=2)) return result if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--seed', type=int, default=0) parser.add_argument('--manifest', type=Path, default=Path('samples/extensions/replay-manifest.json')) parser.add_argument('--output', type=Path, default=Path('reports/extension-corpus/artifact-audit.json')) parser.add_argument('--cli', action='store_true') args = parser.parse_args() audit(args.seed, args.manifest, args.output, args.cli)
examples/extension_generate.py
# Explicit client selection for new graph compositions, preserving the original default CLI. import argparse from pathlib import Path from hearth.persistence import export_scene, semantic_digest from hearth_extensions.programs import extension_scene, branching_campus, perimeter_cluster PROGRAMS = {'campus': branching_campus, 'perimeter': perimeter_cluster} def main(): parser = argparse.ArgumentParser() parser.add_argument('program', choices=PROGRAMS) parser.add_argument('--seed', type=int, default=0) parser.add_argument('--environment-seed', type=int, default=0) parser.add_argument('--output', type=Path, default=Path('samples/extensions/composition.litematic')) args = parser.parse_args() scene = extension_scene(PROGRAMS[args.program], args.seed, args.environment_seed) export_scene(scene, args.output) print(args.output, semantic_digest(scene), len(scene.blocks), 'blocks', len(scene.nodes), 'instances') if __name__ == '__main__': main()
examples/extension_views.py
# Render extension artifact pairs and explicitly labeled geometry-only inspection sections. import argparse import json from pathlib import Path import subprocess import sys import hearth_extensions from hearth.persistence import load_scene, companion_path from examples.preview import render, CUTAWAY def views(seed, source, output, size=1100, sections=False, focus=None): scene = load_scene(source) if scene.seed != seed: raise ValueError('Explicit seed must match artifact') output.mkdir(parents=True, exist_ok=True) records = [] offset = list(json.loads(companion_path(source).read_text())['offset']) render_source = source if focus: box = scene.view.contract(focus).envelope for index, axis in enumerate('xyz'): for keep_above, limit in ((False, box.hi[index]), (True, box.lo[index] - 1)): target = output / f'focus-{axis}-{int(keep_above)}.litematic' command = [sys.executable, str(CUTAWAY), '--input', str(render_source), '--output', str(target), '--axis', axis, '--max', str(limit - offset[index]), '--name', 'focus-preview'] if keep_above: command.append('--keep-above') subprocess.run(command, check=True) if keep_above: offset[index] = limit + 1 render_source = target for label, azimuth, elevation in (('front', 215, 36), ('rear', 35, 32), ('side', 120, 27)): target = output / (label + '.png') render(render_source, target, azimuth, elevation, size, 3.6) records.append({'source': str(source), 'seed': seed, 'label': label, 'azimuth': azimuth, 'elevation': elevation, 'image': str(target), 'focus': focus, 'geometry_preview_only': focus is not None}) if sections: halls = [n for n in scene.nodes.values() if n.type == 'extension.pavilion'] links = [n for n in scene.nodes.values() if n.type in ('extension.bridge', 'extension.gallery')] height = max(n.frame.origin[1] + n.contract.decisions['floor'] + 3 for n in halls) if halls else max(p[1] for n in links for p in scene.cells(n.path + '/deck')) + 1 cuts = [('floor-cut', 'y', height, 215, 65)] if links: points = scene.cells(links[0].path + '/deck') cuts.append(('connection-section', 'x', (min(p[0] for p in points) + max(p[0] for p in points)) // 2, 110, 20)) for label, axis, world, azimuth, elevation in cuts: target = output / (label + '.litematic') limit = world - offset['xyz'.index(axis)] subprocess.run([sys.executable, str(CUTAWAY), '--input', str(render_source), '--output', str(target), '--axis', axis, '--max', str(limit), '--name', label], check=True) image = output / (label + '.png') render(target, image, azimuth, elevation, size, 3.6) records.append({'source': str(source), 'seed': seed, 'label': label, 'axis': axis, 'world_cut': world, 'export_local_cut': limit, 'geometry_preview_only': True, 'image': str(image), 'focus': focus}) (output / 'views.json').write_text(json.dumps(records, indent=2)) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--input', type=Path, required=True) p.add_argument('--output', type=Path, required=True) p.add_argument('--size', type=int, default=1100) p.add_argument('--sections', action='store_true') p.add_argument('--focus', help='Optional public component path for a geometry-only detail crop') a = p.parse_args() views(a.seed, a.input, a.output, a.size, a.sections, a.focus)
examples/extension_assess.py
# Rerun the retained extension sampling policy without altering first-phase evidence. import argparse import json from pathlib import Path from hearth_extensions.assessment import run if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('reports/extension-corpus/final')) p.add_argument('--artifacts', action='store_true') p.add_argument('--samples', type=Path, default=Path('samples/extensions')) a = p.parse_args() print(json.dumps(run(a.output, a.seed, a.artifacts, a.samples), indent=2))
examples/extension_inspection.py
# Inspect real extension structures and verify the same public queries after reload. import argparse import json from pathlib import Path import hearth_extensions from hearth.persistence import load_scene, export_scene def inspect(source, seed, output): scene = load_scene(source) if scene.seed != seed: raise ValueError('Explicit seed must match input artifact') queries = [] for tag in ('deck', 'window', 'fixture'): candidate = next((n for n in scene.nodes.values() if n.capability and tag in n.capability.tags and scene.cells(n.path)), None) if candidate is None: continue point = min(scene.cells(candidate.path)) queries.append({'tag': tag, 'query': scene.inspect(point), 'exact_cell_count': len(scene.cells(candidate.path)), 'descendant_cell_count': len(scene.cells(candidate.path, True))}) export_scene(scene, output) restored = load_scene(output) for entry in queries: assert restored.inspect(entry['query']['position']) == entry['query'] assert len(restored.cells(entry['query']['instance'])) == entry['exact_cell_count'] print(json.dumps({'source': str(source), 'seed': seed, 'verified_after_reload': True, 'queries': queries}, default=lambda v: sorted(v), indent=2)) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--input', type=Path, required=True) p.add_argument('--output', type=Path, default=Path('samples/extensions/inspection.litematic')) a = p.parse_args() inspect(a.input, a.seed, a.output)
examples/extension_replay.py
# Cross-process extension replay with full semantic graph and query comparisons. import argparse import json import os from pathlib import Path import subprocess import sys import tempfile CHILD = ''' import sys,json,hashlib from pathlib import Path from hearth_extensions.programs import extension_scene,perimeter_cluster from hearth_extensions.assessment import signatures from hearth.persistence import export_scene,load_scene,semantic_digest,encode scene=extension_scene(perimeter_cluster,int(sys.argv[1]),int(sys.argv[2])) p=next(p for p,c in sorted(scene.blocks.items()) if c.state=='minecraft:glass' and 'facade' in c.owner) query=scene.inspect(p) nodes=json.dumps(encode(scene.nodes),sort_keys=True,separators=(',',':')) output=Path(sys.argv[3]);export_scene(scene,output) restored=load_scene(output) assert restored.inspect(p)==query assert encode(restored.nodes)==encode(scene.nodes) print(json.dumps({'digest':semantic_digest(scene),'principal':signatures(scene)['principal_signature'],'nodes_digest':hashlib.sha256(nodes.encode()).hexdigest(),'nodes':len(scene.nodes),'glass_query':query},default=lambda v:sorted(v),sort_keys=True)) ''' def replay(seed, environment_seed, output): root = Path(__file__).resolve().parents[1] rows = [] with tempfile.TemporaryDirectory(dir=root / 'test', prefix='tmp-extension-replay-') as temporary: for hash_seed in ('5', '918273'): artifact = Path(temporary) / f'seed {seed} hash {hash_seed}.litematic' result = subprocess.run([sys.executable, '-c', CHILD, str(seed), str(environment_seed), str(artifact)], cwd=root, env=dict(os.environ, PYTHONHASHSEED=hash_seed), capture_output=True, text=True, check=True) rows.append({'PYTHONHASHSEED': hash_seed, 'result': json.loads(result.stdout)}) if rows[0]['result'] != rows[1]['result']: raise AssertionError('Extension replay mismatch') output.parent.mkdir(parents=True, exist_ok=True) output.write_text(json.dumps({'verified': True, 'seed': seed, 'environment_seed': environment_seed, 'runs': rows}, indent=2)) print('Verified extension content, nodes, signatures, glass query and paired reload across two Python hash seeds.') if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=3) p.add_argument('--environment-seed', type=int, default=7) p.add_argument('--output', type=Path, default=Path('reports/extension-corpus/replay.json')) a = p.parse_args() replay(a.seed, a.environment_seed, a.output)
examples/lodge.py
# Generate an individual building composition and composed garden with explicit seeds. import argparse from pathlib import Path from hearth.lodges import hillside_home, gabled_hall, high_house, lodge_scene from hearth.persistence import export_scene PROGRAMS = {'home': hillside_home, 'hall': gabled_hall, 'high': high_house} if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('program', choices=PROGRAMS) parser.add_argument('--seed', type=int, default=0) parser.add_argument('--environment-seed', type=int, default=0) parser.add_argument('--output', type=Path, default=Path('samples/building-quality/lodge.litematic')) args = parser.parse_args() export_scene(lodge_scene(PROGRAMS[args.program](args.seed), args.seed, args.environment_seed), args.output)
examples/building_quality.py
# Rerun the recorded individual-building corpus, keeping every result and paired artifact. import argparse import json from pathlib import Path from hearth.quality_assessment import run if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--seed', type=int, default=0) parser.add_argument('--output', type=Path, default=Path('reports/building-quality/final')) parser.add_argument('--artifacts', type=Path, default=Path('samples/building-quality/final')) args = parser.parse_args() print(json.dumps(run(args.output, args.artifacts, args.seed), indent=2))
examples/building_views.py
# Three exterior angles and circulation/interior slices for a verified individual-building pair. import argparse import json import subprocess import sys from pathlib import Path from hearth.persistence import load_scene, companion_path from examples.preview import render, CUTAWAY def preview(source, output, seed, size=1200): scene = load_scene(source) if scene.seed != seed: raise ValueError('Explicit seed does not match artifact') output.mkdir(parents=True, exist_ok=True) records = [] for label, azimuth, elevation in (('front', 215, 28), ('rear', 35, 28), ('side', 120, 26)): target = output / (label + '.png') render(source, target, azimuth, elevation, size, 3.4) records.append({'label': label, 'image': str(target), 'azimuth': azimuth, 'elevation': elevation, 'complete': True}) building = next(n for n in scene.nodes.values() if n.type == 'building.rooms') floor = building.frame.origin[1] + building.contract.decisions['floor'] offset = json.loads(companion_path(source).read_text())['offset'] cuts = [('interior', 'y', floor + 2 - offset[1], 215, 66)] stairs = [n for n in scene.nodes.values() if n.type == 'circulation.stair'] if stairs: cells = scene.cells(stairs[0].path) axis = min((0, 2), key=lambda k: max(p[k] for p in cells) - min(p[k] for p in cells)) cut = max(p[axis] for p in cells) + 1 - offset[axis] cuts.append(('circulation', 'xz'[axis // 2], cut, 110 if axis == 0 else 20, 26)) for label, axis, limit, azimuth, elevation in cuts: cut = output / (label + '.litematic') subprocess.run([sys.executable, str(CUTAWAY), '--input', str(source), '--output', str(cut), '--axis', axis, '--max', str(limit), '--name', label], check=True) target = output / (label + '.png') render(cut, target, azimuth, elevation, size, 3.2) records.append({'label': label, 'image': str(target), 'axis': axis, 'limit_export_local': limit, 'azimuth': azimuth, 'elevation': elevation, 'geometry_only_cutaway': True}) manifest = {'source': str(source), 'seed': seed, 'views': records} (output / 'views.json').write_text(json.dumps(manifest, indent=2)) return manifest if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--seed', type=int, default=0) parser.add_argument('--input', type=Path, required=True) parser.add_argument('--output', type=Path, required=True) parser.add_argument('--size', type=int, default=1200) args = parser.parse_args() preview(args.input, args.output, args.seed, args.size)
examples/lodge_inspection.py
# Query real glass ownership and related structures before and after paired persistence. import argparse import json from pathlib import Path from hearth.lodges import hillside_home, lodge_scene from hearth.persistence import export_scene, load_scene, semantic_digest from hearth.blocks import name_of def inspect(seed, environment_seed, output): scene = lodge_scene(hillside_home(seed), seed, environment_seed) windows = [n for n in scene.nodes.values() if 'sealed-opening' in scene.view.capability(n.path).tags] coordinates = sorted(p for node in windows for p in scene.cells(node.path) if name_of(scene.blocks[p].state) == 'glass') point = next(p for p in coordinates if any('roof' in scene.view.capability(n['id']).tags for n in scene.inspect(p)['chain'])) query = scene.inspect(point) cells = scene.cells(query['instance']) export_scene(scene, output) restored = load_scene(output) assert restored.inspect(point) == query and restored.cells(query['instance']) == cells return {'seed': seed, 'environment_seed': environment_seed, 'world_coordinate': point, 'query': query, 'exact_current_cells': sorted(cells), 'reloaded_query_matches': True, 'digest': semantic_digest(restored)} if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--seed', type=int, default=0) parser.add_argument('--environment-seed', type=int, default=0) parser.add_argument('--output', type=Path, default=Path('samples/building-quality/inspection.litematic')) args = parser.parse_args() print(json.dumps(inspect(args.seed, args.environment_seed, args.output), default=lambda value: sorted(value), indent=2))
examples/building_holdout.py
# New post-fix operation compositions, predeclared separately from the regression corpus. import argparse import json from pathlib import Path from hearth import Scene from hearth.environment import Terrain, gradient, wave, radial from hearth.randomness import Scope from hearth.components.building import adapted from hearth.lodges import high_house, gabled_hall from hearth.quality_assessment import DOMAIN, evaluate, summary from hearth.persistence import semantic_digest def run(seed, output, artifacts): output.mkdir(parents=True, exist_ok=True) artifacts.mkdir(parents=True, exist_ok=True) environments, inputs, rows = [], [], [] for index in range(8): es = 3000 + seed * 100 + index rng = Scope(es).stream('new-expression') field = (gradient(rng.choice((-.04, 0, .04)), rng.choice((-.03, 0, .03)), 4) + wave(.35, .17, .05, rng.random() * 6)) field = field.blend(gradient(-.02, .03, 4) + radial(13, 10, 25, .7), radial(5, 8, 32, .8)).transformed(dx=2, dz=-3, scale=1.1).clamp(2, 7) water = rng.choice((None, 5, 6)) env = Scene(es, domain=DOMAIN) env.place('land', Terrain(DOMAIN, field, water)) env.finalize() environments.append(env) inputs.append({'environment_seed': es, 'expression': field.expression(), 'water': water, 'digest': semantic_digest(env)}) (output / 'frozen-inputs.json').write_text(json.dumps(inputs, indent=2)) for index, env in enumerate(environments): for client, bs in ((high_house, 5), (gabled_hall, 7)): def recipe(e=env, c=client, b=bs): s = e.fork(seed=b) s.compose_choice(adapted('building', c(b), '/land')) return s.finalize() label = f'{index}-{client.__name__}-{bs}' artifact = artifacts / (label + '.litematic') if index == 0 else None rows.append(evaluate(label, {**inputs[index], 'client': client.__name__, 'structure_seed': bs}, recipe, artifact)) if semantic_digest(env) != inputs[index]['digest']: raise AssertionError('Frozen input mutated') (output / 'results.json').write_text(json.dumps(rows, indent=2)) print(label, rows[-1]['status'], flush=True) report = summary(rows) (output / 'summary.json').write_text(json.dumps(report, indent=2)) (artifacts / 'manifest.json').write_text(json.dumps([r for r in rows if 'artifact' in r], indent=2)) return report if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--seed', type=int, default=0) parser.add_argument('--output', type=Path, default=Path('reports/building-quality/holdout')) parser.add_argument('--artifacts', type=Path, default=Path('samples/building-quality/holdout')) args = parser.parse_args() print(json.dumps(run(args.seed, args.output, args.artifacts), indent=2))
examples/verify_replay.py
# Explicit cross-process hash-seed replay and paired metadata verification. import argparse import json import os from pathlib import Path import subprocess import sys import tempfile from hearth.persistence import load_scene, semantic_digest from hearth.space import Box def verify(seed, output): root = Path(__file__).resolve().parents[1] rows = [] with tempfile.TemporaryDirectory(dir=root / 'test', prefix='tmp-replay-') as temporary: for hash_seed in ('3', '8675309'): path = Path(temporary) / f'seed {seed} hash {hash_seed}.litematic' env = dict(os.environ, PYTHONHASHSEED=hash_seed) subprocess.run([sys.executable, str(root / 'generate.py'), '--seed', str(seed), '--output', str(path)], check=True, cwd=root, env=env) scene = load_scene(path) rows.append({'seed': seed, 'PYTHONHASHSEED': hash_seed, 'digest': semantic_digest(scene), 'bounds': [Box.enclosing(scene.blocks).lo, Box.enclosing(scene.blocks).hi], 'blocks': len(scene.blocks), 'buildings': sum(n.type == 'building.rooms' for n in scene.nodes.values())}) if rows[0]['digest'] != rows[1]['digest'] or rows[0]['bounds'] != rows[1]['bounds']: raise AssertionError('Cross-process replay mismatch') output.parent.mkdir(parents=True, exist_ok=True) output.write_text(json.dumps({'verified': True, 'runs': rows}, indent=2)) return rows if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('reports/replay.json')) a = p.parse_args() verify(a.seed, a.output)
examples/__init__.py
# Runnable public-API examples and explicit assessment tools.
examples/preview.py
# Render labeled exterior views and geometry-only slices with the optional proc tools. import argparse import json from pathlib import Path import subprocess import sys from hearth.persistence import export_scene, load_scene, companion_path from hearth.programs import settlement_scene RENDER = Path('/opt/tools/render_schematic.mjs') CUTAWAY = Path('/opt/tools/cutaway.py') VITE = Path('/work/generator/MCRender/node_modules/.bin/vite-node') def render(source, target, azimuth, elevation, size, radius): subprocess.run(['xvfb-run', '-a', str(VITE), '--script', str(RENDER), '--', '--input', str(source), '--output', str(target), '--size', str(size), '--azimuth', str(azimuth), '--elevation', str(elevation), '--radius', str(radius), '--fov', '30', '--ambient', '0.8'], check=True) def preview(seed, source, output, size=1200, cutaways=False): output.mkdir(parents=True, exist_ok=True) if source is None: source = output / 'source.litematic' export_scene(settlement_scene(seed), source) scene = load_scene(source) if scene.seed != seed: raise ValueError(f'--seed {seed} does not match the input artifact seed {scene.seed}') views = [('front', 210, 28, 3.5), ('rear', 30, 26, 3.5)] records = [] for label, azimuth, elevation, radius in views: target = output / (label + '.png') render(source, target, azimuth, elevation, size, radius) records.append({'source': str(source), 'seed': seed, 'label': label, 'image': str(target), 'azimuth': azimuth, 'elevation': elevation}) if cutaways: building = next(n for n in scene.nodes.values() if n.type == 'building.rooms') floor = building.contract.decisions['floor'] + building.frame.origin[1] offset = json.loads(companion_path(source).read_text())['offset'] cuts = [('floor-cut', 'y', floor + 4 - offset[1], 210, 64)] stair = next((n for n in scene.nodes.values() if n.type == 'circulation.stair'), None) if stair is not None: occupied = scene.cells(stair.path) # Cut beside the actual flight, including flights in a remote wing. axis = min((0, 2), key=lambda i: max(p[i] for p in occupied) - min(p[i] for p in occupied)) limit = max(p[axis] for p in occupied) + 1 - offset[axis] cuts.append(('stair-cut', 'xz'[axis // 2], limit, 110 if axis == 0 else 20, 26)) for label, axis, limit, azimuth, elevation in cuts: cut = output / (label + '.litematic') subprocess.run([sys.executable, str(CUTAWAY), '--input', str(source), '--output', str(cut), '--axis', axis, '--max', str(limit), '--name', label], check=True) target = output / (label + '.png') render(cut, target, azimuth, elevation, size, 3.2) records.append({'source': str(source), 'seed': seed, 'label': label, 'axis': axis, 'export_local_cut': limit, 'image': str(target), 'geometry_preview_only': True}) (output / 'views.json').write_text(json.dumps(records, indent=2)) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--input', type=Path) p.add_argument('--output', type=Path, default=Path('previews/default')) p.add_argument('--size', type=int, default=1200) p.add_argument('--cutaways', action='store_true') a = p.parse_args() preview(a.seed, a.input, a.output, a.size, a.cutaways)
test/conftest.py
# Tests keep transient artifacts under test/ and remove them after each test. import sys import tempfile from pathlib import Path import pytest sys.path.insert(0, str(Path(__file__).parents[1])) @pytest.fixture def work(): with tempfile.TemporaryDirectory(dir=Path(__file__).parent, prefix='tmp-') as name: yield Path(name)
test/test_kernel.py
# Foundation tests run before extending architectural content. from dataclasses import dataclass import pytest from hearth import Scene, Box, Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Plan, Child, Rule from hearth.components.primitives import Assembly, Volume, Wall, Window, Grass, Tree, Pool from hearth.environment import Terrain, constant from hearth.blocks import state_of, blockstates_equivalent from hearth.persistence import export_scene, load_scene, semantic_digest def land(): s = Scene(12, domain=Box((-10, -3, -10), (20, 25, 20))) s.place('terrain', Terrain(s.domain, constant(0))) return s def test_composite_attachment_automatic_chain(): s = Scene(4) children = (Child('base', Volume(Box((0, 0, 0), (8, 0, 0)), state_of('stone'))), Child('wall', Wall(), frame=Frame((0, 1, 0))), Child('window', Window(), frame=Frame((2, 2, 0)), bindings=(Binding('/house/wall', 'infill'),))) s.place('house', Assembly('house', Box((-1, 0, -2), (10, 8, 3)), children)) q = s.inspect((2, 2, 0)) assert [n['type'] for n in q['chain']] == ['window.shuttered', 'wall.framed', 'house'] assert len(s.cells('/house/window')) == 10 assert s.cells('/house/window') <= s.cells('/house', True) def test_substitution_same_parent(): def parent(window): return Assembly('room', Box((-1, -1, -2), (10, 8, 3)), (Child('base', Volume(Box((0, -1, 0), (8, -1, 0)), state_of('stone'))), Child('wall', Wall()), Child('window', window, frame=Frame((2, 1, 0)), bindings=(Binding('/room/wall', 'infill'),)))) a, b = Scene(), Scene() a.place('room', parent(Window())) b.place('room', parent(Window(shutters=False))) assert semantic_digest(a) != semantic_digest(b) assert a.nodes['/room/window'].contract.envelope == b.nodes['/room/window'].contract.envelope def test_tree_grass_and_pool_preserve_support(): s = land() s.place('grass', Grass(), frame=Frame((0, 1, 0)), bindings=(Binding('/terrain', 'planting', 'plant'),)) s.place('tree', Tree(), frame=Frame((0, 1, 0)), bindings=(Binding('/terrain', 'planting', 'plant'), Binding('/grass', 'replacement', 'plant'))) assert '/grass' not in s.nodes assert s.inspect((0, 1, 0))['instance'] == '/tree' before = semantic_digest(s) nodes = set(s.nodes) ops = set(s.operations) with pytest.raises(ContractError): s.place('pool', Pool(), frame=Frame((-2, 0, -2)), bindings=(Binding('/terrain', 'construction', 'excavate'),)) assert semantic_digest(s) == before and set(s.nodes) == nodes and set(s.operations) == ops with pytest.raises(ContractError): s.place('grass2', Grass(), frame=Frame((0, 1, 0))) s.place('pool-ok', Pool(), frame=Frame((6, 0, 6)), bindings=(Binding('/terrain', 'construction', 'excavate'),)) s.finalize() def test_tall_grass_whole_object_and_no_tree_excavation(): s = land() s.place('grass', Grass(True), frame=Frame((0, 1, 0))) with pytest.raises(ContractError): s.place('ordinary-tree', Tree(), frame=Frame((0, 0, 0)), bindings=(Binding('/terrain', 'construction', 'excavate'),)) s.place('tree', Tree(), frame=Frame((0, 1, 0)), bindings=(Binding('/grass', 'replacement', 'plant'),)) assert '/grass' not in s.nodes def test_transforms_and_persistence(work): frame = Frame((14, 3, -7), 1) s = Scene(-42) s.place('beam', Volume(Box((0, 0, 0), (2, 0, 0)), state_of('oak_log', axis='x')), frame=frame) assert s.inspect((14, 3, -5))['state'] == state_of('oak_log', axis='z') path = work / 'space name.litematic' export_scene(s, path) restored = load_scene(path) assert restored.inspect((14, 3, -5)) == s.inspect((14, 3, -5)) assert blockstates_equivalent('minecraft:oak_stairs[facing=north,half=bottom]', 'minecraft:oak_stairs[half=bottom,facing=north]') assert not blockstates_equivalent('minecraft:oak_log', 'minecraft:oak_log[axis=y]') import json meta = path.with_suffix('.litematic.structure.json') data = json.loads(meta.read_text()) data['digest'] = 'bad' meta.write_text(json.dumps(data)) with pytest.raises(ContractError, match='geometry-mismatch'): load_scene(path) def test_clearance_rollback_and_bounds(): s = Scene() s.place('stairs', Assembly('circulation', Box((0, 0, 0), (3, 5, 3)), (), (Rule('clear', ((1, 2, 1), (1, 3, 1))),))) with pytest.raises(ContractError, match='clearance'): s.place('decoration', Volume(Box((1, 3, 1), (1, 3, 1)), state_of('stone'))) assert set(s.nodes) == {'/stairs'} and not s.blocks @dataclass class Escaper: def capability(self): return Capability('bad', ()) def negotiate(self, c, p): return Contract(Box((0, 0, 0), (0, 0, 0))) def realize(self, c, b): p = Plan() p.block((1, 0, 0), state_of('stone')) return p with pytest.raises(ContractError, match='envelope'): s.place('bad', Escaper()) def test_seed_stability_and_regeneration(): from hearth.randomness import Scope a = Scope(123).child('house') before = a.stream('layout').getrandbits(64) Scope(123).child('failed').stream().random() assert before == a.stream('layout').getrandbits(64) s = Scene() s.place('beam', Volume(Box((0, 0, 0), (2, 0, 0)), state_of('stone'))) s.regenerate('/beam', Volume(Box((0, 0, 0), (1, 0, 0)), state_of('oak_planks'))) assert s.inspect((2, 0, 0))['instance'] is None assert len(s.cells('/beam')) == 2
test/test_contracts_provenance.py
# Mutation, sharing, phases, rotations, extension and synchronized provenance tests. from dataclasses import dataclass, replace import json import pytest from hearth import Scene, Box, Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Grant, Port, Rule, Plan, Child, Limits, SearchExhausted from hearth.blocks import state_of from hearth.components.primitives import Volume, Assembly, Window, Wall, Grass, Tree, Pool from hearth.kernel.scene import Cell from hearth.persistence import export_scene, load_scene, semantic_digest from hearth.randomness import Scope from hearth.composition import encapsulate, repeat, arrange, scatter from extension_demo import Pendant, ReadingSuite @dataclass(frozen=True) class Editable: def capability(self): return Capability('editable', ('support',)) def negotiate(self, c, p): b = Box((0, 0, 0), (0, 0, 0)) return Contract(b, (Port('edit', 'adjust', Frame(), b, 10, 'edit'), Port('shared', 'shared-support', Frame(), b, 4)), (Grant('edit', b, ('adjust', 'excavate'), ('editor',), 1),)) def realize(self, c, b): p = Plan() p.block((0, 0, 0), state_of('oak_log', axis='y')) return p @dataclass(frozen=True) class Editor: material: str preserve: bool = True def capability(self): return Capability('editor', ('editor',)) def negotiate(self, c, p): return Contract(Box((0, 0, 0), (0, 0, 0))) def realize(self, c, b): p = Plan() p.block((0, 0, 0), self.material, preserve_owner=self.preserve) return p def test_adjustment_membership_history_deletion_and_reload(work): s = Scene() s.place('owner', Editable()) s.place('adjust', Editor(state_of('oak_log', axis='x')), bindings=(Binding('/owner', 'edit', 'adjust'),)) q = s.inspect((0, 0, 0)) assert q['instance'] == '/owner' and q['operation']['component'] == '/adjust' assert s.cells('/adjust') == frozenset() export_scene(s, work / 'adjust.litematic') r = load_scene(work / 'adjust.litematic') assert r.inspect((0, 0, 0)) == q s.remove('/adjust') assert s.inspect((0, 0, 0))['state'] == state_of('oak_log', axis='y') s.place('erase', Editor(state_of('air'), False), bindings=(Binding('/owner', 'edit', 'excavate'),)) assert s.inspect((0, 0, 0))['instance'] is None and not s.cells('/owner') s.remove('/erase') assert s.cells('/owner') == {(0, 0, 0)} def test_identical_blocks_do_not_grant_sharing_and_explicit_shared_support(): s = Scene() s.place('support', Editable()) s.place('bridge', Assembly('bridge', Box((0, 0, 0), (2, 2, 2)), ())) with pytest.raises(ContractError, match='write-authority'): s.place('intruder', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('oak_log', axis='y'))) s.share((0, 0, 0), '/bridge', '/support', 'shared') assert s.cells('/bridge', shared=True) == {(0, 0, 0)} assert ('/bridge', 'shares_support', '/support') in s.inspect((0, 0, 0))['related'] with pytest.raises(ContractError, match='support'): s.remove('/support') s.remove('/bridge') assert not s.inspect((0, 0, 0))['shared'] def test_partial_tall_plant_replacement_atomicity(): from hearth.environment import Terrain, constant s = Scene(domain=Box((-2, -2, -2), (4, 15, 4))) s.place('terrain', Terrain(s.domain, constant(0))) s.place('grass', Grass(True), frame=Frame((0, 1, 0))) @dataclass class Pruner: def capability(self): return Capability('pruner', ('tree',)) def negotiate(self, c, p): return Contract(Box((0, 0, 0), (0, 0, 0))) def realize(self, c, b): p = Plan() p.block((0, 0, 0), state_of('oak_log', axis='y')) return p snapshot = (semantic_digest(s), set(s.nodes), set(s.relations), dict(s.port_uses), list(s.dependencies)) with pytest.raises(ContractError, match='whole-object'): s.place('prune', Pruner(), frame=Frame((0, 1, 0)), bindings=(Binding('/grass', 'replacement', 'plant'),)) assert snapshot == (semantic_digest(s), set(s.nodes), set(s.relations), dict(s.port_uses), list(s.dependencies)) @pytest.mark.parametrize('turn', range(4)) def test_rotated_attachment_ports_claims_membership(turn, work): frame = Frame((-13, 5, 17), turn) def compose(c): return Plan(children=[Child('base', Volume(Box((0, -1, 0), (8, -1, 2)), state_of('stone'))), Child('wall', Wall(thickness=3)), Child('a', Window(), frame=Frame((2, 1, 0)), bindings=(Binding(c.path + '/wall', 'infill'),)), Child('b', Window(shutters=False), frame=Frame((6, 1, 0)), bindings=(Binding(c.path + '/wall', 'infill'),))]) s = Scene(31) s.place('house', encapsulate('house', Box((-1, -1, -2), (10, 8, 4)), compose), frame=frame) a, b = frame.point((2, 1, 0)), frame.point((6, 1, 0)) assert s.inspect(a)['instance'] != s.inspect(b)['instance'] assert [n['type'] for n in s.inspect(a)['chain']] == ['window.shuttered', 'wall.framed', 'house'] assert s.nodes['/house/wall'].contract.ports[0].frame.turn == turn assert all(s.nodes['/house/a'].contract.envelope.contains(p) for p in s.cells('/house/a')) export_scene(s, work / 'rotated.litematic') assert load_scene(work / 'rotated.litematic').inspect(a) == s.inspect(a) def test_completion_obligation_and_late_decoration(): s = Scene() b = Box((0, 0, 0), (3, 4, 3)) s.place('unfinished', Assembly('room', b, (), (Rule('light', ((1, 1, 1),), b, phase='complete'),)), complete=False) with pytest.raises(ContractError): s.finalize() s.place('lamp', Pendant(), frame=Frame((1, 2, 1))) s.finish_scope('/unfinished') s.finalize() with pytest.raises(ContractError, match='lighting'): s.remove('/lamp') def test_extension_low_level_composite_and_nested_protocol(): s = Scene(4) room = ReadingSuite() wrapper = encapsulate('independent-suite', Box((-2, 0, -2), (14, 11, 14)), lambda c: Plan(children=[Child('suite', room)])) s.place('hall', wrapper) s.finalize() assert any(n.type == 'extension.pendant' for n in s.nodes.values()) assert any(n.type == 'extension.reading-suite' for n in s.nodes.values()) def test_independent_order_and_failed_alternative_streams(): @dataclass class Seeded: def capability(self): return Capability('seeded', ()) def negotiate(self, c, p): return Contract(Box((0, 0, 0), (2, 0, 0))) def realize(self, c, b): p = Plan() p.block((c.rng('geometry').randrange(3), 0, 0), state_of('stone')) return p a, b = Scene(81), Scene(81) for scene, order in ((a, ('one', 'two')), (b, ('two', 'one'))): for key in order: scene.place(key, Seeded(), frame=Frame((10 if key == 'two' else 0, 0, 0))) assert semantic_digest(a) == semantic_digest(b) before = a.cells('/one') with pytest.raises(SearchExhausted): a.choose('failed', [Child('x', Volume(Box((0, 0, 0), (2, 0, 0)), state_of('dirt')))]) a.place('planter', Seeded(), frame=Frame((20, 0, 0))) assert a.cells('/one') == before c = Scene(81) c.place('one', Seeded(), seed=123) assert c.nodes['/one'].scope.seed == 123 def test_regeneration_restores_displaced_terrain_and_no_stale_cells(): from hearth.environment import Terrain, constant s = Scene(domain=Box((-2, -3, -2), (12, 20, 12))) s.place('land', Terrain(s.domain, constant(0))) before = semantic_digest(s) s.place('pool', Pool(), frame=Frame((1, 0, 1)), bindings=(Binding('/land', 'construction', 'excavate'),)) s.remove('/pool') assert semantic_digest(s) == before assert not any('/pool' in (a, c) for a, b, c in s.relations) def test_edit_limits_unknown_space_and_budget(): from hearth.environment import Terrain, constant s = Scene(domain=Box((-3, -3, -3), (12, 20, 12))) s.place('land', Terrain(s.domain, constant(0), edit_limit=1)) with pytest.raises(ContractError, match='edit-limit'): s.place('pool', Pool(), bindings=(Binding('/land', 'construction', 'excavate'),)) with pytest.raises(ContractError, match='unknown-space'): s.view.state((100, 1, 1)) s = Scene(limits=Limits(blocks=1)) with pytest.raises(ContractError, match='block-budget'): s.place('large', Volume(Box((0, 0, 0), (3, 0, 0)), state_of('stone'))) assert not s.nodes and not s.blocks def test_attachment_membership_across_encapsulation_boundaries(): s = Scene() s.place('house', Assembly('house', Box((-2, -1, -2), (12, 8, 5)), (Child('base', Volume(Box((0, -1, 0), (8, -1, 0)), state_of('stone'))), Child('wall', Wall())))) s.place('facade-window', Window(), frame=Frame((3, 1, 0)), bindings=(Binding('/house/wall', 'infill'),)) assert s.cells('/facade-window') <= s.cells('/house/wall', descendants=True) assert s.cells('/facade-window') <= s.cells('/house', descendants=True) assert s.inspect((3, 1, 0))['chain'][-1]['id'] == '/house' with pytest.raises(ContractError): s.remove('/house') s.regenerate('/house', dependents=('/facade-window',)) assert s.inspect((3, 1, 0))['instance'] == '/facade-window' def test_public_readonly_contracts_and_protected_preference(): from hearth.components.constraints import Preserve from hearth.environment import Terrain, constant s = Scene(domain=Box((-3, -3, -3), (12, 20, 12)), preferences={'planting': constant(100)}) s.place('land', Terrain(s.domain, constant(0))) s.place('reserve', Preserve(Box((1, -2, 1), (3, 1, 3)))) assert s.view.preference('planting', (2, 0, 2)) == 100 with pytest.raises(ContractError, match='protected-region'): s.place('pool', Pool(), bindings=(Binding('/land', 'construction', 'excavate'),)) original = s.nodes['/land'].contract.decisions['water'] public = s.view.contract('/land') public.decisions['water'] = 99 assert s.nodes['/land'].contract.decisions['water'] == original def test_explicit_candidate_budget_exhaustion(): from hearth.kernel import Choice s = Scene(limits=Limits(search=1)) s.place('occupied', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))) choice = Choice('choice', (Child('bad', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('dirt'))), Child('valid', Volume(Box((3, 0, 0), (3, 0, 0)), state_of('stone')))), lambda view, path: 0) with pytest.raises(SearchExhausted, match='search-budget'): s.compose_choice(choice) assert '/choice' not in s.nodes s.limits = replace(s.limits, search=2) s.compose_choice(choice) assert s.cells('/choice') == {(3, 0, 0)} def test_validator_extension_and_negotiated_domain(): from hearth.kernel import validator, Diagnostic @validator('test.actual-stone') def actual_stone(scene, node, rule): for p in rule.cells: if scene.inspect(p)['state'] != 'minecraft:stone': yield Diagnostic('test.actual-stone', node.path, p, 'Need actual stone') s = Scene() s.place('rule', Assembly('rule', Box((0, 0, 0), (0, 0, 0)), (Child('stone', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))),), (Rule('test.actual-stone', ((0, 0, 0),)),))) with pytest.raises(ContractError, match='test.actual-stone'): s.remove('/rule/stone') with pytest.raises(ContractError, match='input-domain'): s.place('bad-wall', Wall(width=100)) def test_forwarded_interfaces_discharge_after_scope_construction(): from hearth.kernel import Choice later = Assembly('later', Box((0, 0, 0), (0, 0, 0)), (Child('solid', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))),), ports=(Port('access', 'access', Frame(), Box((0, 0, 0), (0, 0, 0))),)) choice = Choice('first', (Child('one', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))), Child('two', Volume(Box((1, 0, 0), (1, 0, 0)), state_of('stone')))), lambda v, p: 0) wrapper = Assembly('wrapper', Box((0, 0, 0), (3, 1, 1)), (choice, Child('later', later, frame=Frame((3, 0, 0)))), ports=(Port('access', 'access', Frame((3, 0, 0)), Box((3, 0, 0), (3, 0, 0)), delegate=('later', 'access')),)) s = Scene() s.place('root', wrapper) s.finalize() assert s.view.port('/root', 'access').frame.origin == (3, 0, 0) def test_dense_export_budget_is_explicit(work): s = Scene(limits=Limits(export_volume=10)) s.place('line', Volume(Box((0, 0, 0), (10, 0, 0)), state_of('stone'))) with pytest.raises(ContractError, match='export-volume'): export_scene(s, work / 'too large.litematic') assert not (work / 'too large.litematic').exists()
test/test_geometry_environment.py
# Actual-geometry damage tests, independent environment sampling and regeneration. from dataclasses import replace, dataclass from pathlib import Path import pytest from hearth import Scene, Box, Frame, Binding, ContractError from hearth.kernel import validate, Capability, Contract, Plan, Port, Grant, Child, Rule from hearth.kernel.scene import Cell from hearth.blocks import state_of, name_of, blockstates_equivalent, validate_state from hearth.environment import Terrain, constant, gradient, wave, radial from hearth.components.building import Building, Blueprint, RoomSpec from hearth.components.primitives import Pool, Volume from hearth.programs import PROGRAMS, building_scene, settlement_scene from hearth.assessment import adaptation_expression, principal_signature from hearth.persistence import export_scene, load_scene, semantic_digest, companion_path, _mcio def damage(scene, p, material=None): scene = scene._fork() old = scene.blocks.get(p) if old: scene.reverse[old.owner].discard(p) scene.blocks.pop(p) if material: owner = old.owner if old else next(n.path for n in scene.nodes.values() if n.type.startswith('room.')) operation = old.operation if old else next(iter(scene.operations)) scene.blocks[p] = Cell(material, owner, operation) scene.reverse[owner].add(p) return scene @pytest.fixture def house(): return building_scene(Blueprint((RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom'))), 7, gradient(.04, 0, 4), 6) def test_removed_support_blocked_stair_exit_and_paired_door(house): foundation = next(n for n in house.nodes.values() if n.type == 'adapter.foundation') p = foundation.contract.rules[0].cells[0] assert 'support' in {d.rule for d in validate(damage(house, p), True)} stair = next(n for n in house.nodes.values() if n.type == 'circulation.stair') p = next(r for r in stair.contract.rules if r.kind == 'clear').cells[4] assert 'clearance' in {d.rule for d in validate(damage(house, p, state_of('stone')), True)} door = next(p for p, c in house.blocks.items() if 'spruce_door' in c.state and 'half=lower' in c.state) issues = validate(damage(house, door, state_of('stone')), True) assert {'door-pair', 'reachability'} <= {d.rule for d in issues} assert all(d.component.startswith('/') and d.conditions for d in issues) def test_lights_furniture_seal_and_inventory_are_actual(house): room = '/building/room-0-0-0' s = house for p in house.cells(room, True): if name_of(house.blocks[p].state) == 'lantern': s = damage(s, p) assert 'lighting' in {d.rule for d in validate(s, True)} glass = next(p for p in house.cells(room, True) if name_of(house.blocks[p].state) == 'glass') assert 'enclosure' in {d.rule for d in validate(damage(house, glass), True)} bed = next(p for p, c in house.blocks.items() if name_of(c.state) == 'red_bed') assert 'bed-pair' in {d.rule for d in validate(damage(house, bed), True)} barrel = next(p for p, c in house.blocks.items() if c.nbt) s = house._fork() nbt = dict(s.blocks[barrel].nbt) nbt['Items'] = [{'Slot': 0, 'id': 'minecraft:bread', 'count': 100}] s.blocks[barrel] = replace(s.blocks[barrel], nbt=nbt) assert 'inventory' in {d.rule for d in validate(s, True)} def test_pool_boundary_damage_and_unsupported_substrate(): s = Scene(domain=Box((-3, -3, -3), (14, 20, 14))) s.place('land', Terrain(s.domain, constant(0))) s.place('pool', Pool(), bindings=(Binding('/land', 'construction', 'excavate'),)) assert 'pool-containment' in {d.rule for d in validate(damage(s, (0, 0, 2)), True)} def test_nbt_roundtrip_and_real_schematic_mismatch(house, work): path = work / 'inventory and spaces.litematic' export_scene(house, path) restored = load_scene(path) assert semantic_digest(restored) == semantic_digest(house) assert {p: c.nbt for p, c in restored.blocks.items() if c.nbt} == {p: c.nbt for p, c in house.blocks.items() if c.nbt} _, _, tag, nbtfile = _mcio() nbt = nbtfile.load_regardless_of_gzipped(filename=path) region = next(iter(nbt['Regions'].values())) region['TileEntities'][0]['Items'][0]['count'] = tag.Int(7) nbtfile(nbt).save(path) with pytest.raises(ContractError, match='geometry-mismatch'): load_scene(path) companion_path(path).unlink() with pytest.raises(ContractError, match='untrusted-structure'): load_scene(path) @pytest.mark.parametrize('environment_seed', range(16)) @pytest.mark.parametrize('building_seed', range(4)) def test_64_frozen_independent_pairings(environment_seed, building_seed): field, water = adaptation_expression(environment_seed) domain = Box((-8, -4, -18), (34, 64, 34)) s = Scene(building_seed, domain=domain) s.place('ground', Terrain(domain, field, water)) before = {p: c.state for p, c in s.blocks.items()} # An existing protected environmental observation outside all building edits. protected = (32, s.view.elevation(32, 32), 32) from hearth.components.primitives import Assembly s.place('preserved', Assembly('protected-soil', Box(protected, protected), (), (Rule('expected', (protected,), data={'names': [name_of(s.blocks[protected].state)]}),))) design = PROGRAMS['dwelling'](building_seed) s.place('house', Building(design, '/ground')) s.finalize() assert s.nodes['/house'].contract.decisions['rooms'] == [(r.x, r.z, r.level, r.purpose) for r in design.normalized()] allowed = set() for path, old in s.displaced.items(): if path.startswith('/house/'): allowed.update(old) assert all(s.nodes[path].contract.envelope.contains(p) for p in old) assert all(p in allowed or (p in s.blocks and s.blocks[p].state == material) for p, material in before.items()) assert s.blocks[protected].state == before[protected] assert s.nodes['/house/approach'].contract.decisions['rows'] assert all(s.view.supports(p) for p in s.nodes['/house/foundation'].contract.rules[0].cells) def test_environment_implementation_substitution_and_public_forwarding(): @dataclass(frozen=True) class IndependentField: def __call__(self, x, z): return 4 + 0.01 * x - 0.01 * z def expression(self): return {'polynomial': [4, .01, -.01]} @dataclass(frozen=True) class WrappedEnvironment: domain: Box def capability(self): return Capability('extension.environment', ('environment', 'composite')) def negotiate(self, c, p): ports = tuple(Port(key, key, Frame(self.domain.lo), self.domain, 100000, delegate=('strata', key)) for key in ('construction', 'planting')) return Contract(self.domain, ports=ports) def realize(self, c, b): return Plan(children=[Child('strata', Terrain(self.domain, IndependentField()))]) domain = Box((-8, -4, -18), (30, 50, 30)) s = Scene(2, domain=domain) s.place('world', WrappedEnvironment(domain)) s.place('house', Building(Blueprint((RoomSpec(0, 0, 0, 'living'),)), '/world')) s.finalize() assert s.view.port('/house', 'street').delegate == ('approach', 'street') assert any(d['source'] == '/world' for d in s.dependencies) def test_environment_dependency_regeneration_is_explicit_and_atomic(): domain = Box((-8, -4, -18), (28, 55, 28)) s = Scene(3, domain=domain) s.place('land', Terrain(domain, constant(3))) design = Blueprint((RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom'))) s.place('house', Building(design, '/land')) before = semantic_digest(s) with pytest.raises(ContractError): s.regenerate('/land', Terrain(domain, constant(4))) assert semantic_digest(s) == before old_floor = s.nodes['/house'].contract.decisions['floor'] s.regenerate('/land', Terrain(domain, constant(4)), dependents=('/house',)) assert s.nodes['/house'].contract.decisions['floor'] == old_floor + 1 assert not any(n.stale for n in s.nodes.values()) assert all(p in s.blocks for cells in s.reverse.values() for p in cells) @pytest.mark.parametrize('program', tuple(PROGRAMS)) @pytest.mark.parametrize('seed', range(8)) def test_three_composition_programs(program, seed): s = building_scene(PROGRAMS[program](seed), seed) assert s.completed and any(n.type.startswith('room.') for n in s.nodes.values()) @pytest.mark.parametrize('seed,count', [(i, None) for i in range(8)] + [(0, 3), (0, 6)]) def test_settlement_corpus_and_boundaries(seed, count): s = settlement_scene(seed, count) assert s.completed buildings = [n for n in s.nodes.values() if n.type == 'building.rooms'] assert len(buildings) == count if count else 3 <= len(buildings) <= 6 route = next(n for n in s.nodes.values() if n.type == 'settlement.connections') assert len(route.contract.rules[0].cells) == len(buildings) + 2 def test_blockstate_explicit_semantics_and_rotation(): assert blockstates_equivalent('minecraft:oak_log[axis=x]', 'minecraft:oak_log[axis=x]') assert not blockstates_equivalent('minecraft:oak_log', 'minecraft:oak_log[axis=y]') assert not blockstates_equivalent('minecraft:oak_log[axis=x]', 'minecraft:oak_log[axis=z]') assert not blockstates_equivalent('minecraft:oak_log[axis=x]', 'minecraft:spruce_log[axis=x]') with pytest.raises(ValueError): validate_state('minecraft:stone[facing=north]') for turn in range(4): validate_state(Frame(turn=turn).state('minecraft:rail[shape=north_east,waterlogged=false]')) def test_complete_settlement_transforms_and_public_gateway(): from hearth.programs import Settlement, dwelling, atelier local = Box((-49, -4, -23), (49, 64, 66)) frame = Frame((150, 2, 80), 1) s = Scene(0, domain=frame.box(local)) s.place('land', Terrain(s.domain, constant(4))) s.place('district', Settlement((dwelling(1), atelier(1), dwelling(4)), local, '/land'), frame=frame) s.finalize() ports = s.view.offers('/district', 'public-access') assert len(ports) == 1 and ports[0].frame.turn == 1 assert ports[0].frame.origin == frame.point((0, 3, -12)) assert s.view.capability('/district/plot-0').inputs['design.bay'].accepts(9) assert any(d['reason'] == 'observed-spatial-input' for d in s.dependencies) def test_actual_subsurface_support_not_just_height(): domain = Box((-8, -4, -18), (28, 55, 28)) s = Scene(0, domain=domain) s.place('ground', Terrain(domain, constant(4))) s.place('local-cavity', Volume(Box((2, 3, 2), (2, 3, 2)), state_of('air'), 'siteworks'), bindings=(Binding('/ground', 'construction', 'excavate'),)) assert s.view.elevation(2, 2) == 4 and s.view.sample(2, 2).support_depth == 1 before = semantic_digest(s) with pytest.raises(ContractError, match='substrate-depth'): s.place('house', Building(Blueprint((RoomSpec(0, 0, 0, 'living'),)), '/ground')) assert semantic_digest(s) == before def test_path_endpoint_respects_host_authority(): from hearth.components.landscape import PathNetwork from hearth.components.primitives import Assembly domain = Box((-4, -3, -4), (12, 20, 12)) s = Scene(0, domain=domain) s.place('ground', Terrain(domain, constant(0))) # An unrelated solid host behind the offered endpoint must survive path widening. s.place('behind', Volume(Box((-1, 1, -1), (-1, 1, 1)), state_of('stone'))) s.place('route', PathNetwork(((0, 1, 0), (8, 1, 0)), ((0, 1),)), bindings=(Binding('/ground', 'construction', 'surface'),)) assert s.cells('/behind') == {(-1, 1, -1), (-1, 1, 0), (-1, 1, 1)} s.finalize() def test_upper_room_bay_boundary_with_vertical_circulation(): design = Blueprint((RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom')), bay=13) s = building_scene(design, 5, gradient(base=4), 6) assert s.completed and s.nodes['/building'].contract.decisions['bay'] == 13 assert s.nodes['/building/room-0-0-0/stairs'].contract.rules
test/test_extension_protocol.py
# A read-only endpoint consumer must not need the host's mutation authority. import pytest from hearth import Scene, Box from hearth.kernel import Capability, Contract, Port, Grant, Plan from hearth.space import Frame from hearth.blocks import state_of from hearth_extensions import Endpoint, EndpointContact class Landing: def capability(self): return Capability('test.landing', ('landing',)) def negotiate(self, ctx, parameters): return Contract(Box((-1, 0, -1), (1, 0, 1)), ports=(Port('access', 'access', Frame((0, 1, 0)), Box((-1, 0, -1), (1, 2, 1)), 4, 'resurface'),), grants=(Grant('resurface', Box((-1, 0, -1), (1, 0, 1)), ('surface',), ('path',), 9),)) def realize(self, ctx, contract): p = Plan() p.fill(contract.envelope, state_of('stone_bricks')) return p def test_read_only_connection_to_mutable_port(): s = Scene() s.place('landing', Landing()) endpoint = Endpoint('/landing', 'access') before = dict(s.blocks) s.place('consumer', EndpointContact(endpoint), bindings=(endpoint.binding(),)) assert s.blocks == before assert ('/consumer', 'connected_to', '/landing') in s.relations s.finalize() def test_connection_does_not_acquire_write_authority(): from hearth.kernel import ContractError class Bad(EndpointContact): def realize(self, ctx, contract): p = Plan() p.block((0, 0, 0), state_of('gold_block')) return p s = Scene() s.place('landing', Landing()) endpoint = Endpoint('/landing', 'access') before = dict(s.blocks) with pytest.raises(ContractError, match='write-authority'): s.place('bad', Bad(endpoint), bindings=(endpoint.binding(),)) assert s.blocks == before and '/bad' not in s.nodes def test_atomic_multi_branch_replay_accepts_explicit_replacements(): from hearth.components.primitives import Volume s = Scene() s.place('a', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))) s.place('b', Volume(Box((3, 0, 0), (3, 0, 0)), state_of('stone'))) s.regenerate('/a', dependents=('/b',), replacements={'/b': Volume(Box((3, 0, 0), (4, 0, 0)), state_of('oak_planks'))}) assert len(s.cells('/b')) == 2 assert s.inspect((0, 0, 0))['state'] == state_of('stone') def test_multi_branch_replay_rejects_undeclared_target_and_rolls_back(): from hearth.components.primitives import Volume from hearth.kernel import ContractError from hearth.persistence import semantic_digest s = Scene() s.place('a', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))) before = semantic_digest(s) with pytest.raises(ContractError, match='replay-targets'): s.regenerate('/a', replacements={'/unknown': Landing()}) assert semantic_digest(s) == before and set(s.nodes) == {'/a'} def test_importable_generation_has_no_new_native_dependency(): import subprocess, sys from pathlib import Path code = ''' import sys,importlib.abc class NoNative(importlib.abc.MetaPathFinder): def find_spec(self, fullname, path=None, target=None): if fullname.split('.')[0] in ('numpy','mcio','scipy','shapely','ctypes'): raise RuntimeError('Unexpected native/transport dependency: '+fullname) sys.meta_path.insert(0,NoNative()) from hearth_extensions.assessment import hall_scene from hearth.persistence import semantic_digest scene=hall_scene(4,1) print(semantic_digest(scene)) ''' result = subprocess.run([sys.executable, '-c', code], cwd=Path(__file__).parents[1], capture_output=True, text=True) assert result.returncode == 0, result.stderr assert len(result.stdout.strip()) == 64
test/test_extension_geometry.py
# Extension-only probes for non-cardinal circulation and curve interfaces. from dataclasses import replace import pytest from hearth import Scene, Box, Frame, Binding, ContractError from hearth.kernel import validate, Child, Plan from hearth.components.primitives import Volume from hearth.environment import Terrain, gradient, wave from hearth.blocks import state_of from hearth.persistence import export_scene, load_scene, semantic_digest from hearth_extensions import Polyline, Endpoint, Link, Boundary, IlluminateBoundary, Platform def bridge_scene(seed=0, water=3, frame=Frame()): domain = Box((-8, -4, -8), (45, 42, 45)) s = Scene(seed, domain=frame.box(domain)) s.place('land', Terrain(domain, gradient(.02, .01, 1) + wave(.2, .1, .15, seed), water), frame=frame) s.place('a', Platform('/land'), frame=frame) s.place('b', Platform('/land'), frame=frame.compose(Frame((18, 0, 27)))) a, b = Endpoint('/a', 'south'), Endpoint('/b', 'north') s.place('link', Link(a, b, '/land', rise=1), frame=frame, bindings=(a.binding(), b.binding())) return s.finalize() def test_diagonal_bridge_actual_route_support_railings_and_reload(work): s = bridge_scene() assert any(n.type == 'extension.trestles' for n in s.nodes.values()) assert len(set(x for x, z in s.nodes['/link'].contract.decisions['center'])) > 5 assert not validate(s, True) p = next(iter(s.cells('/link/deck'))) q = s.inspect(p) assert any('connect' in str(r) for r in s.inspect(p)['related']) or ('/link', 'connects', '/a') in s.relations export_scene(s, work / 'diagonal bridge.litematic') t = load_scene(work / 'diagonal bridge.litematic') assert t.inspect(p) == q and semantic_digest(t) == semantic_digest(s) def test_curve_boundary_interfaces_and_external_attachment(): s = Scene(3, domain=Box((-5, -4, -5), (45, 35, 35))) s.place('land', Terrain(s.domain, gradient(.015, .01, 3))) curve = Polyline.bezier(((0, 0), (7, 25), (28, -3), (37, 20))) s.place('boundary', Boundary(curve)) s.place('lamps', IlluminateBoundary('/boundary')) s.finalize() ports = s.view.offers('/boundary', 'mount') assert len(ports) > 3 p = ports[0].frame.origin q = s.inspect(p) assert q['chain'][1]['id'] == '/boundary' assert p in s.cells('/boundary', descendants=True) @pytest.mark.parametrize('width,depth,corner,lantern', [(13, 17, 0, False), (17, 21, 3, True), (25, 13, 4, False)]) def test_polygon_hall_multiple_usable_ports(width, depth, corner, lantern, work): from hearth_extensions import Pavilion, Polygon s = Scene(2, domain=Box((-15, -4, -15), (42, 60, 42))) s.place('land', Terrain(s.domain, gradient(.025, -.018, 4))) s.place('hall', Pavilion(Polygon.chamfered(width, depth, corner), '/land', entrances=('north', 'east', 'south', 'west'), lantern=lantern)) s.finalize() assert len(s.view.offers('/hall', 'access')) == 4 glass = next(p for p, c in s.blocks.items() if c.state == 'minecraft:glass' and '/facade/' in c.owner) assert [n['type'] for n in s.inspect(glass)['chain']][:3] == ['window.shuttered', 'extension.polygon-shell', 'extension.pavilion'] export_scene(s, work / 'hall.litematic') assert load_scene(work / 'hall.litematic').inspect(glass) == s.inspect(glass) @pytest.mark.parametrize('turn', [0, 1, 2, 3]) def test_extension_transforms_geometry_interfaces_claims_and_queries(turn, work): from hearth.blocks import blockstates_equivalent frame = Frame((7, 3, -5), turn) base = bridge_scene() moved = bridge_scene(frame=frame) assert len(base.blocks) == len(moved.blocks) for point, cell in base.blocks.items(): q = frame.point(point) assert blockstates_equivalent(frame.state(cell.state), moved.inspect(q)['state']) assert moved.inspect(q)['instance'] == cell.owner assert moved.view.port('/a', 'south').frame == frame.compose(base.view.port('/a', 'south').frame) assert moved.nodes['/link'].contract.rules[0].cells == tuple(frame.point(p) for p in base.nodes['/link'].contract.rules[0].cells) export_scene(moved, work / 'rotated bridge.litematic') restored = load_scene(work / 'rotated bridge.litematic') q = next(iter(moved.cells('/link/deck'))) assert restored.inspect(q) == moved.inspect(q) def test_untried_kinked_ribbon_and_asymmetric_polygon(): from hearth_extensions import Polygon, Pavilion # Endpoints share Z; a global endpoint clipping plane would sever this route. curve = Polyline(((4, 8), (4, 12), (13, 16), (22, 12), (22, 8))) s = Scene(19, domain=Box((-8, -4, -8), (50, 60, 50))) s.place('land', Terrain(s.domain, gradient(base=2), water_level=3)) s.place('a', Platform('/land')) s.place('b', Platform('/land'), frame=Frame((18, 0, 0))) a, b = Endpoint('/a', 'south'), Endpoint('/b', 'south') s.place('link', Link(a, b, '/land', curve=curve, covered=True), bindings=(a.binding(), b.binding())) s.finalize() # A six-sided asymmetric footprint absent from the shipped clients. polygon = Polygon(((2, 0), (18, 0), (22, 4), (22, 16), (0, 16), (0, 3))) other = Scene(19, domain=Box((-10, -4, -10), (40, 60, 40))) other.place('land', Terrain(other.domain, gradient(.01, .02, 3))) other.place('hall', Pavilion(polygon, '/land', entrances=('north', 'south'), height=7, roof_run=3)) other.finalize() def test_graph_parent_substitutes_public_access_components(): from hearth_extensions.graphs import Campus, Vertex, Edge from hearth_extensions import Pavilion, Polygon domain = Box((-12, -4, -12), (55, 65, 60)) variants = [] for component in (Platform('/land', 13, 13), Pavilion(Polygon.chamfered(13, 13, 2), '/land', entrances=('north', 'south'))): s = Scene(6, domain=domain) s.place('land', Terrain(domain, gradient(base=3), water_level=3)) campus = Campus((Vertex('a', component, Frame()), Vertex('b', Platform('/land'), Frame((25, 0, 29)))), (Edge('a', 'south', 'b', 'north'),), '/land', domain, landscape=False) s.place('group', campus) s.finalize() assert len(s.view.offers('/group', 'access')) == 1 assert ('/group/circulation/link-0', 'connects', '/group/a') in s.relations variants.append(semantic_digest(s)) assert variants[0] != variants[1] @pytest.mark.parametrize('environment_seed,structure_seed', [(0, 0), (1, 5), (2, 3), (3, 2), (4, 1), (5, 4), (6, 0), (7, 5)]) def test_independent_extension_environment_structure_pairs(environment_seed, structure_seed): from hearth_extensions.assessment import freeze_probe, connector_scene frozen = freeze_probe(environment_seed) digest = semantic_digest(frozen) scene = connector_scene(frozen, structure_seed) assert semantic_digest(frozen) == digest assert not validate(scene, True)
test/test_extension_failures.py
# Deliberate input and geometry damage for extension contracts and atomicity. from dataclasses import replace import copy import pytest from hearth import Scene, Box, Frame, Binding, ContractError from hearth.kernel import validate, Child, Plan, Choice, Limits from hearth.blocks import state_of from hearth.components.primitives import Volume from hearth.environment import Terrain, gradient, wave from hearth.persistence import semantic_digest, export_scene, load_scene, encode from hearth_extensions import Polyline, Endpoint, Link, Boundary, IlluminateBoundary, Platform from hearth_extensions.boundaries import BoundaryChain from hearth_extensions.circulation import Trestles from test_extension_geometry import bridge_scene def snapshot(s): return (semantic_digest(s), copy.deepcopy(encode(s.nodes)), copy.deepcopy(encode(s.relations)), copy.deepcopy(encode(s.dependencies)), copy.deepcopy(encode(s.operations)), copy.deepcopy(s.reverse), copy.deepcopy(s.port_uses), copy.deepcopy(s.events)) def damage(s, p): record = s.blocks.pop(p) s.reverse[record.owner].remove(p) @pytest.mark.parametrize('kind', ['support', 'guard', 'endpoint', 'headroom']) def test_broken_bridge_geometry_is_diagnosed(kind): s = bridge_scene() if kind == 'support': p = s.nodes['/link/supports'].contract.rules[0].cells[0] damage(s, p) expected = 'support' elif kind == 'guard': p = next(iter(s.cells('/link/guards'))) damage(s, p) expected = 'bridge-guard' elif kind == 'endpoint': a = s.view.port('/a', 'south').frame.origin p = (a[0], a[1] - 1, a[2]) damage(s, p) expected = 'reachability' else: p = next(r for r in s.nodes['/link'].contract.rules if r.kind == 'clear').cells[len(s.nodes['/link'].contract.decisions['deck']) // 2] before = snapshot(s) with pytest.raises(ContractError, match='clearance'): s.place('blocked', Volume(Box(p, p), state_of('stone'))) assert snapshot(s) == before return errors = validate(s, True) assert any(d.rule == expected and d.position is not None for d in errors) @pytest.mark.parametrize('fault', ['endpoint', 'frame', 'kind']) def test_invalid_connections_rollback_every_index(fault): s = bridge_scene() s.remove('/link') a, b = Endpoint('/a', 'south'), Endpoint('/b', 'north') pa = s.view.port('/a', 'south').frame.origin pb = s.view.port('/b', 'north').frame.origin curve = Polyline(((pa[0], pa[2]), (pa[0] + 3, pa[2]), (pb[0], pb[2]))) expected = 'endpoint-frame' if fault == 'endpoint': curve = Polyline(((pa[0] + 1, pa[2]), (pb[0], pb[2]))) expected = 'endpoint-disconnected' if fault == 'kind': a = Endpoint('/land', 'construction') expected = 'endpoint-kind' before = snapshot(s) with pytest.raises(ContractError, match=expected): s.place('bad', Link(a, b, '/land', curve=curve), bindings=(a.binding(), b.binding())) assert snapshot(s) == before def test_connection_permission_overflow_is_atomic(): s = Scene(0, domain=Box((-3, -4, -3), (12, 20, 12))) s.place('land', Terrain(s.domain, gradient(base=0), water_level=5, edit_limit=1)) before = snapshot(s) columns = ((2, 0, 2, 4, True), (3, 0, 2, 4, True)) with pytest.raises(ContractError, match='edit-limit'): s.place('piers', Trestles(columns), bindings=(Binding('/land', 'construction', 'fill'),)) assert snapshot(s) == before def test_connection_remove_and_regenerate_restore_water_and_membership(): s = bridge_scene() s.remove('/link') before = snapshot(s) a, b = Endpoint('/a', 'south'), Endpoint('/b', 'north') comp = Link(a, b, '/land', rise=1) s.place('link', comp, bindings=(a.binding(), b.binding())) old = s.cells('/link', True) s.regenerate('/a', dependents=('/b', '/link'), replacements={'/link': replace(comp, covered=True, rise=0)}) new = s.cells('/link', True) assert old != new assert all(s.inspect(p)['instance'] in s.nodes for p in new) assert all(not s.inspect(p)['instance'] or not s.inspect(p)['instance'].startswith('/link') for p in old - new) s.remove('/link') assert semantic_digest(s) == before[0] assert not any('/link' in a or '/link' in c for a, b, c in s.relations) assert not any(k.startswith('/link') for k in s.nodes) def test_boundary_missing_coping_support_and_whole_removal(work): s = Scene(0, domain=Box((-5, -4, -5), (45, 24, 25))) s.place('land', Terrain(s.domain, gradient(base=3))) curve = Polyline.bezier(((0, 0), (9, 20), (26, 0), (37, 17))) s.place('boundary', BoundaryChain(curve)) s.place('lamps', IlluminateBoundary('/boundary')) before = snapshot(s) with pytest.raises(ContractError): s.remove('/boundary') assert snapshot(s) == before changed = Polyline.bezier(((0, 1), (9, 19), (26, 1), (37, 18))) s.regenerate('/boundary', BoundaryChain(changed), dependents=('/lamps',)) s.finalize() p = s.view.offers('/boundary', 'mount')[0].frame.origin assert p in s.cells('/boundary', True) export_scene(s, work / 'curve.litematic') t = load_scene(work / 'curve.litematic') assert t.inspect(p) == s.inspect(p) base = (p[0], p[1] - 1, p[2]) damage(t, base) assert any(d.rule in ('support', 'enclosure') and d.position == base for d in validate(t, True)) def test_curve_boundary_rejects_incompatible_installation_frame(): from hearth_extensions import BoundaryLantern s = Scene(0, domain=Box((-3, -4, -3), (25, 25, 25))) s.place('land', Terrain(s.domain, gradient(base=3))) s.place('wall', Boundary(Polyline(((0, 0), (20, 8))))) port = s.view.offers('/wall', 'mount')[0] before = snapshot(s) with pytest.raises(ContractError, match='port-alignment'): s.place('bad-lamp', BoundaryLantern(), frame=Frame(port.frame.origin, port.frame.turn + 1), bindings=(Binding('/wall', port.key),)) assert snapshot(s) == before def test_failed_choice_does_not_perturb_sibling_randomness(): s = bridge_scene() s.remove('/link') a, b = Endpoint('/a', 'south'), Endpoint('/b', 'north') before = snapshot(s) bad = Link(a, b, '/land', fill_limit=0) with pytest.raises(ContractError): s.compose_choice(Choice('link', (Child('attempt', bad, bindings=(a.binding(), b.binding())),), lambda v, p: 0)) assert snapshot(s) == before good = Link(a, b, '/land', rise=1) s.place('link', good, bindings=(a.binding(), b.binding())) assert semantic_digest(s) == semantic_digest(bridge_scene())
test/test_extension_interiors.py
# Functional bays must preserve their own access, room circulation, support and inventories. import pytest from hearth import Scene, Box, ContractError from hearth.environment import Terrain, gradient from hearth.kernel import validate from hearth.blocks import state_of, name_of from hearth.components.primitives import Volume from hearth.persistence import export_scene, load_scene, semantic_digest, encode from hearth_extensions import Pavilion, Polygon from hearth_extensions.interiors import FUNCTION_GROUPS from test_extension_failures import damage, snapshot def furnished_scene(purpose='library', width=13): scene = Scene(23, domain=Box((-12, -4, -12), (40, 60, 40))) scene.place('land', Terrain(scene.domain, gradient(base=3))) scene.place('hall', Pavilion(Polygon.chamfered(width, 17, 4), '/land', purpose, ('north', 'south', 'east', 'west'))) return scene.finalize() @pytest.mark.parametrize('purpose', tuple(FUNCTION_GROUPS)) def test_functional_bays_are_reachable_and_preserve_inventory(purpose, work): scene = furnished_scene(purpose) bays = [n for n in scene.nodes.values() if n.type == 'extension.work-bay'] assert len(bays) >= 2 assert not validate(scene, True) for bay in bays: port = scene.view.port(bay.path, 'use') assert scene.view.clear(port.region) assert any(scene.blocks[p].nbt for p in scene.cells(bay.path)) path = work / (purpose + '.litematic') export_scene(scene, path) restored = load_scene(path) assert encode(restored.nodes) == encode(scene.nodes) assert semantic_digest(restored) == semantic_digest(scene) def test_larger_hall_allocates_more_bays_and_protects_central_aisle(): small = furnished_scene(width=13) large = furnished_scene(width=25) small_decisions = small.nodes['/hall/furnishings'].contract.decisions large_decisions = large.nodes['/hall/furnishings'].contract.decisions assert large_decisions['placed_bays'] > small_decisions['placed_bays'] assert large_decisions['omitted_optional'] == 0 point = large.nodes['/hall/furnishings'].contract.rules[0].cells[20] before = snapshot(large) with pytest.raises(ContractError, match='clearance'): large.place('crate', Volume(Box(point, point), state_of('stone'))) assert snapshot(large) == before def test_damaged_station_furnishing_and_support_are_detected(): scene = furnished_scene('library') bay = next(n for n in scene.nodes.values() if n.type == 'extension.work-bay') lectern = next(p for p in scene.cells(bay.path) if name_of(scene.blocks[p].state) == 'lectern') damage(scene, lectern) assert any(d.rule == 'furnishing' and d.component == bay.path for d in validate(scene, True)) bed = bay.contract.rules[0].cells[0] damage(scene, bed) assert any(d.rule == 'support' and d.position == bed for d in validate(scene, True)) def test_interaction_clearance_remains_protected_after_completion(): scene = furnished_scene('bedroom') bay = next(n for n in scene.nodes.values() if n.type == 'extension.work-bay') at = scene.view.port(bay.path, 'use').frame.origin before = snapshot(scene) with pytest.raises(ContractError, match='clearance'): scene.place('block-user', Volume(Box(at, at), state_of('stone'))) assert snapshot(scene) == before
test/test_building_quality.py
# Building-craft contracts, actual damage, transforms, rollback and structural reload evidence. from dataclasses import dataclass, replace import copy import json import pytest from hearth import Scene, Box, Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Plan, validate from hearth.kernel.scene import Cell from hearth.environment import Terrain, constant from hearth.components.building import Building, Blueprint, RoomSpec from hearth.components.roofcraft import RoofDesign, Dormer, ProfileRoof from hearth.components.primitives import Volume from hearth.lodges import hillside_home, gabled_hall, high_house, lodge_scene from hearth.persistence import export_scene, load_scene, semantic_digest, encode from hearth.quality_assessment import principal_signature from hearth.blocks import state_of, name_of, parse def make_house(bay=11, rise=(1, 2), turn=0, porch_depth=4): frame = Frame((30, 0, -20), turn) domain = frame.box(Box((-8, -4, -18), (30, 64, 28))) s = Scene(17, domain=domain) s.place('land', Terrain(domain, constant(3))) design = Blueprint((RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom')), bay=bay, balcony=True, porch_depth=porch_depth, roof_design=RoofDesign(rise), chimney=True) s.place('house', Building(design, '/land'), frame=frame) return s.finalize(), design def damaged(scene, p, material=None): candidate = scene.fork() old = candidate.blocks.get(p) if old: candidate.reverse[old.owner].remove(p) del candidate.blocks[p] if material: candidate.blocks[p] = Cell(material, old.owner, old.operation, old.nbt) candidate.reverse[old.owner].add(p) return candidate def snapshot(scene): return semantic_digest(scene), copy.deepcopy(encode(scene.nodes)), copy.deepcopy(encode(scene.dependencies)), copy.deepcopy(encode(scene.relations)), copy.deepcopy(scene.reverse), copy.deepcopy(scene.port_uses), copy.deepcopy(encode(scene.operations)) @pytest.mark.parametrize('bay,rise,depth', [(9, (1,), 3), (11, (1, 2), 4), (13, (2,), 5)]) def test_profile_porch_and_bay_boundaries(bay, rise, depth): s, design = make_house(bay, rise, porch_depth=depth) assert not validate(s, True) assert s.view.contract('/house').decisions['rooms'] == [(r.x, r.z, r.level, r.purpose) for r in design.normalized()] assert any(n.type == 'roof.dormer' for n in s.nodes.values()) assert s.view.contract('/house/porch').decisions['balcony'] assert s.cells('/house/porch') @pytest.mark.parametrize('turn', range(4)) def test_rotated_dormer_ownership_and_complete_pair(turn, work): s, _ = make_house(turn=turn) for point in s.cells('/house/porch'): if name_of(s.blocks[point].state) != 'spruce_fence': continue _, properties = parse(s.blocks[point].state) for side, delta in {'north': (0, 0, -1), 'south': (0, 0, 1), 'east': (1, 0, 0), 'west': (-1, 0, 0)}.items(): neighbor = tuple(point[i] + delta[i] for i in range(3)) if properties[side] == 'true': assert s.view.state(neighbor) != 'minecraft:air' if name_of(s.view.state(neighbor)) == 'spruce_fence': assert properties[side] == 'true' windows = [n for n in s.nodes.values() if n.type == 'window.flush' and '/dormer-' in n.path] assert len(windows) >= 2 a, b = [min(s.cells(n.path)) for n in windows[:2]] assert s.inspect(a)['state'] == s.inspect(b)['state'] assert s.inspect(a)['instance'] != s.inspect(b)['instance'] query = s.inspect(a) assert [n['type'] for n in query['chain']][:4] == ['window.flush', 'wall.dormer-face', 'roof.dormer', 'roof.weather-cover'] assert query['chain'][-1]['id'] == '/house' assert any(kind == 'attached_to' for _, kind, _ in query['related']) path = work / 'crafted roof and balcony.litematic' export_scene(s, path) restored = load_scene(path) assert restored.inspect(a) == query assert encode(restored.nodes) == encode(s.nodes) assert restored.cells('/house', True) == s.cells('/house', True) assert {p: c.nbt for p, c in restored.blocks.items() if c.nbt} == {p: c.nbt for p, c in s.blocks.items() if c.nbt} def test_actual_roof_glass_guard_support_and_lighting_damage(): s, _ = make_house() roof = next(n for n in s.nodes.values() if n.type == 'roof.weather-cover') # A plain interior course outside the dormers, above every other solid cell. p = roof.frame.point((5, roof.contract.decisions['levels'][6], 1)) # The ridge above this column is also removed: no projected cap may remain. t = s for y in range(p[1], roof.contract.envelope.hi[1] + 1): t = damaged(t, (p[0], y, p[2])) assert 'roof-cover' in {d.rule for d in validate(t, True)} glass = next(min(s.cells(n.path)) for n in s.nodes.values() if n.type == 'window.flush') assert 'enclosure' in {d.rule for d in validate(damaged(s, glass), True)} porch = s.nodes['/house/porch'] railing = next(r.cells[0] for r in porch.contract.rules if r.kind == 'expected') assert 'expected-geometry' in {d.rule for d in validate(damaged(s, railing), True)} chimney = s.nodes['/house/chimney'] p = chimney.frame.point((0, 2, 0)) assert 'support' in {d.rule for d in validate(damaged(s, p), True)} room = '/house/room-0-0-0' t = s for p in s.cells(room, True): if name_of(s.blocks[p].state) == 'lantern': t = damaged(t, p) assert 'lighting' in {d.rule for d in validate(t, True)} def test_balcony_door_and_furniture_access_remain_usable(): s, _ = make_house() door = '/house/room-0-0-1/door-north' p = min(s.cells(door)) broken = damaged(s, p, state_of('stone')) assert {'door-pair', 'reachability'} <= {d.rule for d in validate(broken, True)} node = next(n for n in s.nodes.values() if n.type.startswith('furnishing.group.')) port = s.view.port(node.path, 'use') with pytest.raises(ContractError, match='clearance|reachability'): s.place('blocked-use', Volume(port.region, state_of('stone'))) assert '/blocked-use' not in s.nodes def test_misaligned_dormer_and_permission_overflow_rollback(): from hearth.components.roofcraft import RoofCover s = Scene(3, domain=Box((-3, -3, -3), (16, 30, 16))) s.place('land', Terrain(s.domain, constant(3))) s.place('cover', RoofCover(11, 11, 'deepslate_tile', RoofDesign(), populate=False), frame=Frame((0, 4, 0))) roof = s.nodes['/cover'] port = s.view.offers('/cover', 'roof-installation')[0] before = snapshot(s) with pytest.raises(ContractError, match='dormer-interface'): s.place('bad-frame', Dormer(), frame=Frame(port.frame.origin, (port.frame.turn + 1) % 4), bindings=(Binding(roof.path, port.key),)) assert snapshot(s) == before @dataclass class Spill: def capability(self): return Capability('probe.spill', ('dormer',)) def negotiate(self, c, params): return Contract(Box.enclosing(port.frame.inverse(q) for q in roof.contract.envelope.corners())) def realize(self, c, contract): plan = Plan() plan.block(port.frame.inverse(roof.frame.point((5, roof.contract.decisions['levels'][6], 1))), state_of('air')) return plan with pytest.raises(ContractError, match='write-authority'): s.place('overflow', Spill(), frame=port.frame, bindings=(Binding(roof.path, port.key),)) assert snapshot(s) == before # A separate facade program can discover a mount and install without private geometry. s.place('external-dormer', Dormer(), frame=port.frame, bindings=(Binding('/cover', port.key),)) s.finalize() window = '/external-dormer/face/window' point = min(s.cells(window)) chain = [n['id'] for n in s.inspect(point)['chain']] assert chain == [window, '/external-dormer/face', '/external-dormer', '/cover'] assert s.cells(window) <= s.cells('/cover', descendants=True) def test_regeneration_removes_old_dormer_cells_and_structure(): s, design = make_house() old = {p for p in s.nodes if '/dormer-' in p} assert old replacement = replace(design, roof_design=RoofDesign((1, 2), 0)) s.regenerate('/house', Building(replacement, '/land')) s.finalize() assert not old.intersection(s.nodes) assert all(c.owner not in old for c in s.blocks.values()) assert all(not {a, c}.intersection(old) for a, _, c in s.relations) assert all(p in s.blocks and s.blocks[p].owner == owner for owner, cells in s.reverse.items() for p in cells) def test_roof_policy_substitution_without_parent_change(): s, design = make_house() from hearth.components.roofs import Roof @dataclass(frozen=True) class IndependentPolicy: def heights(self, span): return (0, (span + 1) // 2) def component(self, width, depth, axis, material): return Roof(width, depth, axis, material) s.regenerate('/house', Building(replace(design, roof_design=IndependentPolicy()), '/land')) s.finalize() assert any(n.type == 'roof.gable' for n in s.nodes.values()) assert not any(n.type == 'roof.profile' for n in s.nodes.values()) assert s.nodes['/house'].contract.decisions['rooms'] == [(r.x, r.z, r.level, r.purpose) for r in design.normalized()] @pytest.mark.parametrize('client', (hillside_home, gabled_hall, high_house)) @pytest.mark.parametrize('seed', (0, 6)) def test_complete_new_compositions(client, seed): s = lodge_scene(client(seed), seed, seed) assert s.completed and not validate(s, True) assert len([n for n in s.nodes.values() if n.type == 'roof.dormer']) >= 1 assert len([n for n in s.nodes.values() if n.type == 'plant.conifer']) >= 3 def test_deterministic_architecture_and_unrelated_branch(): a, _ = make_house() b, _ = make_house() assert semantic_digest(a) == semantic_digest(b) signature = principal_signature(a) # A read-only addition outside the building changes neither blocks nor architectural decisions. a.place('marker', Volume(Box((50, 20, 4), (50, 20, 4)), state_of('stone'))) assert principal_signature(a) == signature assert a.cells('/house', True) == b.cells('/house', True) def test_heavy_shaft_on_piers_has_continuous_bounded_bearing(): from hearth.assessment import adaptation_expression field, water = adaptation_expression(0) s = lodge_scene(hillside_home(0), 0, 0, field, water, garden=False) course = s.nodes['/building/chimney-bearing'] assert course.contract.decisions['fill'] > 0 assert course.contract.decisions['span'] == 2 assert all(s.view.supports(p) for p in course.contract.rules[0].cells) p = course.contract.rules[0].cells[-1] assert 'support' in {d.rule for d in validate(damaged(s, p), True)} def test_bearing_rejects_missing_support_and_rolls_back(): from hearth.adapters.bearing import BearingCourse s = Scene() before = snapshot(s) with pytest.raises(ContractError, match='bearing-span'): s.place('floating', BearingCourse(3, 2)) assert snapshot(s) == before

程序结构说明 · 完整使用说明 · 模型的完整评估 · 接口改动。

原生测试、浏览器核对和开发者自己记录的评估,来自不同检查过程。它们共同支持这里列出的有限结论,但都不能证明所有随机结果合法、美观,或已经实现自动规划任意城市。