窗边能种花,屋后不再空:第四轮自动建房


这次只给模型发了一个 continue。它继续补窗户、花箱、家具和绿化,并让房屋两翼围出一个后院。这里看真实成品、对照上轮变化,也可以直接运行 Python 自己生成。

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

230 / 230最终自动测试通过
129 / 140实际试建成功,另 11 次拒绝
26 / 3232 栋住宅里测得 26 种结构
0修改的共用内核文件

01 · 这轮到底做了什么

这是一套用 Python 自动搭 Minecraft 建筑的工具,叫 Hearth。用户用简短代码安排房间和零件,工具负责摆方块、检查支撑与通路,并记住每块玻璃属于哪扇窗、哪栋房子。我们想要的是可以不断扩充的“建筑积木库”,以及用这些积木拼出不同建筑的轻量代码。

第四轮只给原会话发了一个词:continue。 没有重写任务,没有换会话。模型自行接着第三轮的单栋建筑改进工作,重点放在后墙、窗下花箱、家具、天花木梁和房屋周边植物,还增加了两翼围出后院的 U 形住宅。

现在能看出进步:烟囱两边有窗,家具按用途布置,栏杆与地板更容易分辨,屋脚不再只有大片草地。但还没有做到参考木石住宅那样精致。房间仍沿规整网格排布,屋顶细节重复,阁楼不能居住;新住宅虽有后院,却没有直接从室内通向后院的门。

先把三个数字分清楚

哪一件事 本轮结果 大白话解释
自动测试 230 项通过,0 项失败 检查正常情况能工作,故意损坏或越界时也能被发现
最终实际试建 140 次,129 次建成,11 次拒绝 普通范围内 124 次全部建成;困难场景 16 次只建成 5 次
开发中首次跑完整测试 223 项通过,7 项失败 当时确实有错误,也有新测试写错的预期;修复后再跑,才得到最后的 230 项全通过

230 项全通过不等于任何输入都能造房子,更不等于已经好看。 最后的 11 次拒绝,都是地面高差超过现有 5 格上限。对检查器来说,拒绝符合规则;对使用者来说,那 11 次仍然没有拿到建筑。

02 · 第三轮到第四轮,具体变了什么

这一轮既有细节补全,也有一种真正改变房屋布局的新组合。不要把换深色木头和增加 U 形房间布局,算成同一种程度的进步。

对照项目 第三轮 第四轮 应该怎样理解
发给模型的新消息 第一轮完整任务,加单栋建筑要求 只有 continue 原会话接着做,并未重新发送整份任务
工具版本 1.3.0 1.4.0 在同一套积木库上继续改进
自动测试 200 项通过 230 项通过 新增 30 项,旧 200 项的测试源码未修改
共用内核、保存、第二轮扩展 已具备权限、归属、撤销和组合能力 这些模块内容保持不变 主要改部件和安排部件的规则,没有推翻底层机制
烟囱旁的后窗 烟囱会让整面墙的窗被取消 只避开烟囱实际占的范围,在两侧安排窗 改共享规则,其他符合条件的建筑也受益
窗下花箱 原来的植物和花床 新增带木框花箱,可以通过窗的公开安装位置挂上去 有独立归属、支撑和替换规则,不只是在截图上加装饰
家具 已有基本家具组合,较多重复桌子 增加会客、阅读、烹饪、制作、储物五类家具组 检查所需物件、站人位置、支撑和储物内容
天花木梁 没有这一套可独立安装的木梁 安装在楼板下方,避开楼梯头顶和灯 后装木梁也能正确归属到房间
栏杆和桌椅看不清 已发现问题,原因未定 对选定部件做网格、射线和临时着色检查,确认是颜色混在一起 正常成品换用更有对比的材料;没有修改渲染器
屋脚绿化 入口庭院、树、花床 增加沿房屋边界布置的植物,调整树冠层次 植物要找真正的土和空位,不能随意挖房子或填水
新房屋布局 阳台住宅、多翼大厅、三层高屋 再加一个 U 形庭院住宅 高层程序用公开房间、屋顶和立面接口拼成,库不限定只能选这四类
样本中的结构变化 原三种住宅 24 次,测得 18 种结构 原三种仍是 18/24;新庭院住宅 8 次测得 8 种 合计 26/32。增加主要来自新组合,不能说原三种突然变得更丰富
普通范围内试建 104/104 建成 124/124 建成 原 104 次重跑,加 8 次新住宅和 12 次新地形配对
困难地形 5/16 建成 仍为 5/16 建成 这一轮没有扩大高差支持范围
默认五栋村落 128,021 方块、908 部件 128,055 方块、1,005 部件 方块只多 34 个,部件多 97 个。部件有新增也有替换,不能简单看方块数评价细节
实际外观检查 20 张图 25 张图 多了一组 U 形住宅的五个视图;没有审美盲评或百分制评分
仍未完成 规整房间、重复屋顶、简单景观、非居住阁楼 这些限制仍存在 不能用“本轮正常结束”代替“目标全部实现”

统计第三轮第四轮
Python 文件数7886
Python 行数(含空行注释)74308149
原文件变化基线12 修改 / 0 删除
新增 Python 文件—8

文件与行数包含库、示例和测试,不包括网页与参考程序。代码长短不作为质量评分。按文件比较的原始记录。

展开查看新增和修改的文件

变化文件
新增examples/building_detail.py
新增examples/garden_house.py
新增hearth/components/borders.py
新增hearth/components/ceiling.py
新增hearth/components/domestic.py
新增hearth/components/facades.py
新增hearth/components/windowbox.py
新增test/test_building_detail.py
修改hearth/__init__.py
修改hearth/components/__init__.py
修改hearth/components/building.py
修改hearth/components/furnishing.py
修改hearth/components/grounds.py
修改hearth/components/interior.py
修改hearth/components/joinery.py
修改hearth/components/landscape.py
修改hearth/components/primitives.py
修改hearth/components/roofs.py
修改hearth/lodges.py
修改hearth/programs.py

03 · 自己动手生成建筑

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

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

下载本轮默认五栋房屋

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

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

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

轮换程序的完整 Python 代码
# Report-owned examples, composed through public interfaces. programs = ('court', 'home', 'hall', 'high', 'adaptation', 'settlement', 'courtyard', 'commons', 'atelier', 'dwelling', 'campus', 'perimeter', 'sample_hall', 'sample_connector', 'sample_boundary') program = programs[SEED % len(programs)] if program == 'court': from examples.garden_house import garden_house from hearth.lodges import lodge_scene scene = lodge_scene(garden_house(SEED), seed=SEED, environment_seed=int(ENV_SEED)) elif 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 生成。

本轮 U 形庭院住宅预览

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

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

这块方块属于哪里?

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

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

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

05 · 这次的积木接口是否更有用

这一轮的新增接口更接近“外层只需要看说明,就知道怎么使用零件”。例如,一个独立程序可以询问窗户哪里能挂花箱,随后安装;不用知道那扇窗内部如何逐格画出来。底层自动记录花箱属于窗,窗属于墙和房间。

新接口或部件 使用者知道什么就能用 必须遵守什么
窗户的花箱安装位置 方向、宽度、深度及可使用的范围 只能替换允许的窗台部分,必须有墙体支撑与种植土
房间的天花装饰位置 楼板下的位置与方向 不能拆原方块,避开楼梯头顶和已有灯;检查实际承托
房屋的占地边界 房屋在地上的轮廓 边界本身不授予改地权限;种植物还得另取地形许可
五类家具组合 用途与宽度 所需物件真实存在,有支撑,面前能站人,储物内容能保存
U 形住宅程序 房间如何相连、哪些位置加楼层 用公开部件搭建,不在高层逐块补墙,也不手写方块归属

共享内核没有改。 权限、失败撤销、依赖和归属机制继续沿用;新东西主要在部件实现与组合安排这一层。接口及限制说明。

“代码层级”和“部件大小层级”不是一回事:前者是内核、部件、高层程序的职责;后者是“花箱 → 窗 → 墙 → 房间 → 房子”。外部安装的花箱和后装的天花木梁,也应自动进入正确的部件关系。

手动调窗户、屋顶与房间时,实际运行的高层代码

from hearth.components.building import Blueprint, RoomSpec from hearth.components.facades import FacadeDesign 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, facade_design=FacadeDesign(width=WINDOW_WIDTH, height=WINDOW_HEIGHT, planters=WINDOW_BOXES), rail_material='dark_oak' if CONTRAST_RAILS else 'spruce') scene = lodge_scene(plan, seed=SEED, environment_seed=int(ENV_SEED), garden=GARDEN)

接口并不是无限能力。当前房间尺寸主要是 9、11、13 格,楼层间距固定为 6 格;屋顶和接地策略也有界限。找不到合适位置时,沿房屋边界的绿化允许为空。部件作者仍需要了解公开的坐标、权限和物理检查约定。保存后能恢复已生成的结构记录;要重新执行自定义 Python 策略,仍要提供那份代码。

06 · 230 项测试,具体在测什么

最终 230 项测试全部通过。 新增一个测试文件,11 个测试函数按方向、尺寸和用途展开后是 30 项。原 200 项测试保留且源码不变。这不是“发现了 30 个错误”,而是增加了 30 种检查情形。

新检查 项数 实际怎样检查 主要检查哪层
烟囱两边能否保留窗 3 三种房间尺寸,每层应有两扇后窗,玻璃不碰烟囱,房间布局不变 立面和房屋组合规则
外部程序挂花箱,转四个方向 4 查花箱归属,保存再读回,删除后无旧记录,换花后正确重建 花箱接口、内核归属、保存
故意把花箱装歪、越权或挖掉土 1 错误安装被拒绝且没有残留;破坏土后能发现支撑问题 部件规则与内核撤销
五种家具用途、两种宽度 10 堵住使用位置、挖掉支撑、拿走必需家具时都能报错;物品内容保存后相同 家具部件和通行、支撑检查
两格高植物和种植土 1 玫瑰上下两段完整;少一段、没土或悬空种植会被拦住 植物部件与撤销
沿房屋轮廓种植 1 读取公开边界,找到实际土层,保留已有方块,新增植物关联 绿化组合与公开接口
深色栏杆是否真的存在 1 护栏有足够实际方块;拆掉一格能被发现 门廊部件
天花木梁转四个方向 4 有实际支撑,避开楼梯头顶;归属到正确房间;错误安装不留残余 天花部件、安装关系与内核
增加绿化不应改房子 1 比较房屋的方块、归属和部件记录;新增景观关联允许变化 部件之间的隔离与归属
边界值和无效输入 1 密度为零可以不种;密度越界拒绝;被挡满的墙允许没有可选窗 参数范围与部件安排
不同窗宽、窗高和窗台高度 3 实际玻璃数量符合声明,花箱带框;拆掉框会被发现 立面与花箱部件

这些主要是对库的测试,其中一些会用高层程序造完整房屋。它们使用程序中的移动、支撑和照明规则,没有运行完整 Minecraft 游戏物理,也不是审美评分。它们不能保证任意用户代码都正确。把坏情况主动制造出来,再要求检查器识别它,是通过测试的一部分,不应列成“最终建筑仍有缺陷”。新增测试完整源码。

报告独立做的验收

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

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

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

网页检查包括原图建筑重现、室内和楼梯切面、真实方块归属、手动参数、相同输入复现、编辑 Python、15 个例子轮换、停止与恢复、错误提示和手机宽度显示。下载包还要回到原 Python 环境打开,比较方块、部件及关联记录。没有拿第三轮的网页测试成绩冒充本轮。

原实验的统一验收如下:

统一验收结果秒
default通过15.402
seed-0-a通过15.58
seed-0-b通过15.526
seed-1通过8.569
tests通过189.618

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

........................................................................ [ 31%] ........................................................................ [ 62%] ........................................................................ [ 93%] .............. [100%] 230 passed in 188.90s (0:03:08)

重跑使用原实验镜像和可写源码副本,不提供网络或账号凭证,原始归档不改。模型自己做过“禁止导入原生数组、图片和建筑文件库后仍能生成”的检查,但那不是浏览器实测;网页执行由报告另行验收。

07 · 生成了多少,又拒绝了多少

最终只统计 release、release-prior-holdout、release-new-composition 三组目录。其他名字带 first、final 或 new-composition 的目录是开发中途留下的记录,不能重复加进最终成绩。

试建内容 建成 / 尝试 这组说明什么
原三种住宅,各 8 个编号 24 / 24 旧住宅仍能用新的零件造出来
16 个旧地形,各放 4 种房屋要求 64 / 64 原接地案例重测
上轮额外准备的地形组 16 / 16 现在也是已见过的回归输入,不再称为全新检验
新 U 形住宅,8 个编号 8 / 8 新高层组合在这些编号上可用
6 个本轮地形,各放 2 种房屋要求 12 / 12 地形先独立生成,再放建筑;开发期间已使用,不能称为完全未见过的最终考题
困难地形 5 / 16 11 次高差为 6–19 格,超过现有 5 格上限
合计 129 / 140 普通范围内 124 次全部建成,另有 11 次困难输入拒绝
实际试建成功与拒绝次数,不能当作自动测试通过率。
每种住宅试建 8 次,测得不同结构数分别是 4、7、7、8。

32 次住宅样本中,测得 26 种主要结构。比较考虑房间、连接、屋顶、门廊等实际结构;换材料、植物或摆放位置不增加这个数。新 U 形住宅的 8 次各不相同,是有限样本结果,不等于随机一次就必定是新设计。

新增加的 20 次试建另测得 10 种家具布置、6 种窗户安排。这些是细节变化,没有另加到 26 种房屋结构里面。也没有估计所有参数相乘后的总组合数。

普通场景会在两个接地办法中选择,共检查 248 个备选方案,183 个可用;困难组检查 32 个备选,6 个可用,最终得到 5 次建成。备选方案数与试建次数不同。每个固定输入只跑一次,没有失败后暗中换随机编号重试。

逐条查看 140 次最终试建和拒绝原因
试建编号建造结果建筑编号地形编号方块数部件数原始记录
home-0建造成功0013449280
查看数据
{ "label": "home-0", "inputs": { "client": "home", "structure_seed": 0, "environment_seed": 0 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "a15a356fa58a935667596aa63ed12254d48f5c2c7e7c7a74135931800b46c691", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 13449, "nodes": 280, "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-detail/release/home-0.litematic", "audit": { "queries": 260, "inventories": 23, "nodes": 280, "digest": "a15a356fa58a935667596aa63ed12254d48f5c2c7e7c7a74135931800b46c691" }, "seconds": 3.0391 }
home-1建造成功1114480258
查看数据
{ "label": "home-1", "inputs": { "client": "home", "structure_seed": 1, "environment_seed": 1 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "ffb8fb6f4b3fcb169451784d715c2a063431da74cfc5b673d94b8015f7f50cf1", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 14480, "nodes": 258, "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-detail/release/home-1.litematic", "audit": { "queries": 234, "inventories": 23, "nodes": 258, "digest": "ffb8fb6f4b3fcb169451784d715c2a063431da74cfc5b673d94b8015f7f50cf1" }, "seconds": 2.7314 }
home-2建造成功2214240252
查看数据
{ "label": "home-2", "inputs": { "client": "home", "structure_seed": 2, "environment_seed": 2 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "de076e20da263782e18e7b3e479c33be69d08d1eb00f4ae121ffc07c13b16046", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 14240, "nodes": 252, "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.5646 }
home-3建造成功3312386229
查看数据
{ "label": "home-3", "inputs": { "client": "home", "structure_seed": 3, "environment_seed": 3 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "41451b0010477b11fe78baf46ffa92b935705a71127288d9959e9d5a2561e7eb", "principal_signature": "5880edf6b41329f9cbc752e64431e1e766b84fe677fd4c68c341e452fa8df42a", "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 ] }, "a3480f0598cf51c82b350c6c7326d70dd963fa31c16cee02e7dc93ad7e8e3a5c" ], [ "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": 12386, "nodes": 229, "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": 1.3352 }
home-4建造成功4414762299
查看数据
{ "label": "home-4", "inputs": { "client": "home", "structure_seed": 4, "environment_seed": 4 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "14613231801d32dd709d95c50a6ad0fcc98a729272ae0c159f897ea858d94381", "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": 14762, "nodes": 299, "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.6802 }
home-5建造成功5514694269
查看数据
{ "label": "home-5", "inputs": { "client": "home", "structure_seed": 5, "environment_seed": 5 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "1a2cbf1649bb6b884be1354fb6d76d1863f455ef51b654a24940d34e20c43f59", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 14694, "nodes": 269, "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.5293 }
home-6建造成功6611936232
查看数据
{ "label": "home-6", "inputs": { "client": "home", "structure_seed": 6, "environment_seed": 6 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "796bdec7a9ea407698ffbab3faaa025b233ec0728e59ced7a1b750034c0491fc", "principal_signature": "5880edf6b41329f9cbc752e64431e1e766b84fe677fd4c68c341e452fa8df42a", "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 ] }, "a3480f0598cf51c82b350c6c7326d70dd963fa31c16cee02e7dc93ad7e8e3a5c" ], [ "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": 11936, "nodes": 232, "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-detail/release/home-6.litematic", "audit": { "queries": 208, "inventories": 20, "nodes": 232, "digest": "796bdec7a9ea407698ffbab3faaa025b233ec0728e59ced7a1b750034c0491fc" }, "seconds": 2.1699 }
home-7建造成功7714211266
查看数据
{ "label": "home-7", "inputs": { "client": "home", "structure_seed": 7, "environment_seed": 7 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "234db477e5748c93b3b7d2ed79e31faecc0e2dc3bb75b43ebeeb3685d69c35ef", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 14211, "nodes": 266, "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.7151 }
hall-0建造成功0014318296
查看数据
{ "label": "hall-0", "inputs": { "client": "hall", "structure_seed": 0, "environment_seed": 0 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "b5b919ae4d8241e509380410b5150c501fd9d0b1e1be6a7b55cf879b9bf935fc", "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": 14318, "nodes": 296, "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-detail/release/hall-0.litematic", "audit": { "queries": 277, "inventories": 24, "nodes": 296, "digest": "b5b919ae4d8241e509380410b5150c501fd9d0b1e1be6a7b55cf879b9bf935fc" }, "seconds": 2.6985 }
hall-1建造成功1112311252
查看数据
{ "label": "hall-1", "inputs": { "client": "hall", "structure_seed": 1, "environment_seed": 1 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "2702f6da9944dcf4f9a4c79983a06075dbb1787cb4579960a7f60fabfce2749e", "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": 12311, "nodes": 252, "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-detail/release/hall-1.litematic", "audit": { "queries": 231, "inventories": 24, "nodes": 252, "digest": "2702f6da9944dcf4f9a4c79983a06075dbb1787cb4579960a7f60fabfce2749e" }, "seconds": 1.9728 }
hall-2建造成功2215709285
查看数据
{ "label": "hall-2", "inputs": { "client": "hall", "structure_seed": 2, "environment_seed": 2 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "2ea118fe5f5b04c6b760c9d843575c720e805233c73fca2fcc8206125a3c5f64", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 15709, "nodes": 285, "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.7801 }
hall-3建造成功3315677276
查看数据
{ "label": "hall-3", "inputs": { "client": "hall", "structure_seed": 3, "environment_seed": 3 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "10c7b32a6c7ef8f3a688c0f480417ac1d164d4a024b9304758a753353fa8dcc5", "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": 15677, "nodes": 276, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.1 ], [ 0, 1.3 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.4715 }
hall-4建造成功4412275264
查看数据
{ "label": "hall-4", "inputs": { "client": "hall", "structure_seed": 4, "environment_seed": 4 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "8fa4704f725717386fb7038b09f53c1e9bfba0bd6b63bec08071429fcdc76cf9", "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": 12275, "nodes": 264, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.35 ], [ 1, 0.64 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.226 }
hall-5建造成功5513007272
查看数据
{ "label": "hall-5", "inputs": { "client": "hall", "structure_seed": 5, "environment_seed": 5 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "7778c1c6f61b02519be5cd72aab38c5c365532a72f4b17a359b8492a67e81fdf", "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": 13007, "nodes": 272, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.35 ], [ 1, 0.73 ] ], "chosen": 1 } ], "optional_omissions": [], "seconds": 1.318 }
hall-6建造成功6613311285
查看数据
{ "label": "hall-6", "inputs": { "client": "hall", "structure_seed": 6, "environment_seed": 6 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "baf11599346542fa96220584c7d9d40d7845ca40c32b0012d5451b811a9f57db", "principal_signature": "f31c95b88f7eb2741d22b90e6ac6fab2826a5bed213b6bc84a42a11ce7e1aee1", "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 ] }, "7bfebfe833b865abe15fe1fc4319b4d7ca5aaee03b7d408b5c38e202d092d414" ], [ "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": 13311, "nodes": 285, "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-detail/release/hall-6.litematic", "audit": { "queries": 261, "inventories": 32, "nodes": 285, "digest": "baf11599346542fa96220584c7d9d40d7845ca40c32b0012d5451b811a9f57db" }, "seconds": 2.2996 }
hall-7建造成功7716009312
查看数据
{ "label": "hall-7", "inputs": { "client": "hall", "structure_seed": 7, "environment_seed": 7 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "8dc1a5f1c961a169824044de9c0e868b87fe15f565c2c787f4e3c2ffc5f567cb", "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": 16009, "nodes": 312, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.28 ], [ 1, 0.66 ] ], "chosen": 0 } ], "optional_omissions": [], "seconds": 1.7877 }
high-0建造成功0010111253
查看数据
{ "label": "high-0", "inputs": { "client": "high", "structure_seed": 0, "environment_seed": 0 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "b9077e6d387c2c9e69814a9ddf8f6d5b34b04eb8937df215d758ac38d4d19e5b", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 10111, "nodes": 253, "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-detail/release/high-0.litematic", "audit": { "queries": 235, "inventories": 18, "nodes": 253, "digest": "b9077e6d387c2c9e69814a9ddf8f6d5b34b04eb8937df215d758ac38d4d19e5b" }, "seconds": 1.781 }
high-1建造成功1113389303
查看数据
{ "label": "high-1", "inputs": { "client": "high", "structure_seed": 1, "environment_seed": 1 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "e2e8422df7b51a894951b1d115540041c6042f1a30be2abbcc7585785002f2c6", "principal_signature": "4e4e6cad6c5c1350050d8b292d507b4ab6a7daabb9bce14cc5a52a534612036c", "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 ] }, "03696bdf0ea9dd11f838ddb8446738180efcb69ddee39936c7b9c6ef54b9200a" ], [ "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": 13389, "nodes": 303, "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-detail/release/high-1.litematic", "audit": { "queries": 278, "inventories": 35, "nodes": 303, "digest": "e2e8422df7b51a894951b1d115540041c6042f1a30be2abbcc7585785002f2c6" }, "seconds": 2.5564 }
high-2建造成功2212704281
查看数据
{ "label": "high-2", "inputs": { "client": "high", "structure_seed": 2, "environment_seed": 2 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "02ab9dc58f7e53da421b001897c3a03b59f3d93866f8fb2c9a56139072f841be", "principal_signature": "1ffcd5de45c4a7fd31487b30c8a0617d1413a50d057ec60cc17d849864eafe80", "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 ] }, "03696bdf0ea9dd11f838ddb8446738180efcb69ddee39936c7b9c6ef54b9200a" ], [ "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": 12704, "nodes": 281, "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.3807 }
high-3建造成功3310827232
查看数据
{ "label": "high-3", "inputs": { "client": "high", "structure_seed": 3, "environment_seed": 3 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "c7e74fa886521dd42d8db3665b45b8da91bb4382ac3c4d7ca509ba14c3d28612", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 10827, "nodes": 232, "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.0239 }
high-4建造成功4410092236
查看数据
{ "label": "high-4", "inputs": { "client": "high", "structure_seed": 4, "environment_seed": 4 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "bf7cbe3e3793083a8618546312d4a9c3efc4271643f3e03bd00777c3a6fc5ed4", "principal_signature": "42a1aa878b972424a798b362465f407ad9e45ac26ad58c9764727356d71ff0f1", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 10092, "nodes": 236, "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": 0.9822 }
high-5建造成功5511056274
查看数据
{ "label": "high-5", "inputs": { "client": "high", "structure_seed": 5, "environment_seed": 5 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "19fefa97fa4dbf577137adda5e087067b6cff00f453a2258ca0f3443597be681", "principal_signature": "634ac8b29c460a433eb81e3d1ded862d287d4cba66d268630110f90144968dcb", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 11056, "nodes": 274, "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.2171 }
high-6建造成功6612641263
查看数据
{ "label": "high-6", "inputs": { "client": "high", "structure_seed": 6, "environment_seed": 6 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "761a1d5a038f5476562025a4e953d8545ace778d6d8844c95e51c56efa0b48b4", "principal_signature": "46cfd7ee5c84f3e4c2214b536bd92851d57866b64c38b16e3ff2e1ce1252e1b9", "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 ] }, "03696bdf0ea9dd11f838ddb8446738180efcb69ddee39936c7b9c6ef54b9200a" ], [ "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": 12641, "nodes": 263, "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-detail/release/high-6.litematic", "audit": { "queries": 238, "inventories": 22, "nodes": 263, "digest": "761a1d5a038f5476562025a4e953d8545ace778d6d8844c95e51c56efa0b48b4" }, "seconds": 2.4587 }
high-7建造成功7710829266
查看数据
{ "label": "high-7", "inputs": { "client": "high", "structure_seed": 7, "environment_seed": 7 }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "a80b80b4b6967c2d09313a7a039e464d53b81225ea6717867e1ba7fe28ef257e", "principal_signature": "742698f240c48157d4ddf2538f2a686c5c2444780f7841b3c0c9d2fee3e6bf0d", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 10829, "nodes": 266, "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.2531 }
adaptation-00建造成功0034816127
查看数据
{ "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": "01cb1728b02e59d5782a7cfc240bca677ab1b0748cd25c95c7cdfcbb81b77c28", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 34816, "nodes": 127, "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-detail/release/adaptation-00.litematic", "audit": { "queries": 118, "inventories": 23, "nodes": 127, "digest": "01cb1728b02e59d5782a7cfc240bca677ab1b0748cd25c95c7cdfcbb81b77c28" }, "seconds": 2.9567 }
adaptation-01建造成功1034722127
查看数据
{ "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": "1f798474e88c847a02e4847705c0155a13ed2547b96ac2262de4e641a8f497bd", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 34722, "nodes": 127, "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": 1.1193 }
adaptation-02建造成功2035076159
查看数据
{ "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": "91e786f03fd2d446208d572a01fc25e9f04061e20374d742813f3e9197a7966f", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 35076, "nodes": 159, "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": 1.1751 }
adaptation-03建造成功3033851135
查看数据
{ "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": "e7b441cf73e4a8bba59c33fde7f2b038aad3070319d9bf60fbac695241240a79", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 33851, "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, 2.25 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.7569 }
adaptation-04建造成功0130588127
查看数据
{ "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": "3674ac7faa0a0513fcf483fd016f42eeb6fe43bd2b375821b47091574f1fc619", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 30588, "nodes": 127, "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.4324 }
adaptation-05建造成功1130494127
查看数据
{ "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": "268bf28519756cc4ac4178263999d46faf23f60aecfbc4abc11e13e0bfd6f858", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 30494, "nodes": 127, "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.4064 }
adaptation-06建造成功2130871159
查看数据
{ "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": "fa6e8e50d2a58cd9fb5cd98e213e5e00a16a40acf9f9bc41d07caaf427713fbb", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 30871, "nodes": 159, "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.571 }
adaptation-07建造成功3129588135
查看数据
{ "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": "cb53e6d03fff107ffb11c5ed66a890824785be7c597616cf15f0752074257623", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 29588, "nodes": 135, "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.8898 }
adaptation-08建造成功0237965127
查看数据
{ "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": "06f2a9b6e3a079ea78c67ed6a69d77f2e12c07d6190f275f5d6945717455d68f", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 37965, "nodes": 127, "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-detail/release/adaptation-08.litematic", "audit": { "queries": 118, "inventories": 23, "nodes": 127, "digest": "06f2a9b6e3a079ea78c67ed6a69d77f2e12c07d6190f275f5d6945717455d68f" }, "seconds": 3.0665 }
adaptation-09建造成功1237871127
查看数据
{ "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": "bfcd6191c10cde27f677cd90edf06df07fe7ffd309e49128a1cf4dfcfd7dd9c5", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 37871, "nodes": 127, "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": 1.0436 }
adaptation-10建造成功2238225159
查看数据
{ "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": "5368ec14a5387552bf4afb2e25fc83f3134279de97b7b9776fc5e43eae83031d", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 38225, "nodes": 159, "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": 1.1796 }
adaptation-11建造成功3237000135
查看数据
{ "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": "ad2817f56c9cf455d178bb81be6b265c4696b3add6df496b3c8c584e57f08b67", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 37000, "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, 2.79 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.9728 }
adaptation-12建造成功0331705127
查看数据
{ "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": "50b54a45bd74efeb4b004b1b8728322c2e3ea645f7a0f427f8588648374e7401", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 31705, "nodes": 127, "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.8924 }
adaptation-13建造成功1331611127
查看数据
{ "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": "901fcc56f380b71be10bfc3c50cfb0b05b53933409175b9bd411f553f31fe869", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 31611, "nodes": 127, "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.8347 }
adaptation-14建造成功2331965159
查看数据
{ "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": "832a53599b98578bed337d55e9091ab4ecf9654cd3791bc82c1ec6b3c93469a9", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 31965, "nodes": 159, "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.9183 }
adaptation-15建造成功3330740135
查看数据
{ "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": "19f55c9e22b76d592086d50b0bea2225c8e3b5d4999fd80541a29f72720671af", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 30740, "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.3952 }
adaptation-16建造成功0434816127
查看数据
{ "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": "a22a65c9158a9a62c0354bc415888c7ef7139f830f94c3168caa04e77c4232aa", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 34816, "nodes": 127, "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": 1.3408 }
adaptation-17建造成功1434722127
查看数据
{ "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": "8cdb04f353a5d8796a794a3cfa06c9007193862579ecab9098e9eea9be14da11", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 34722, "nodes": 127, "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": 1.2974 }
adaptation-18建造成功2435076159
查看数据
{ "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": "8ff6184fcf17b17257de743e070855e0b498e94eac2e382a6466af4a1e14bda8", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 35076, "nodes": 159, "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": 1.3054 }
adaptation-19建造成功3433851135
查看数据
{ "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": "2e4f73ad97d0e2cbba8be4d1cf09113b3b79a47113eea8f9f5fcc63e4ec91246", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 33851, "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, 2.34 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.7755 }
adaptation-20建造成功0537927127
查看数据
{ "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": "1d5dbfa13ab8c44d0eacc89fb76443e363f79fab29d5cdbf21dd10d67d421388", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 37927, "nodes": 127, "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": 1.169 }
adaptation-21建造成功1537833127
查看数据
{ "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": "dd91d930fc38cc41cb2e2beb54e2c1eda726ced9e564d35694b5f85b98eb93c3", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 37833, "nodes": 127, "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": 1.403 }
adaptation-22建造成功2538187159
查看数据
{ "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": "e43c1c73453f4beb266f6c452bd3d1898c53a627482eaa2abed7d33293fab139", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 38187, "nodes": 159, "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": 1.2148 }
adaptation-23建造成功3536962135
查看数据
{ "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": "49deabca21ef77b31884ab46d59747d3c7164d948739608440a8eb3c5a251194", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 36962, "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.14 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.7435 }
adaptation-24建造成功0634816127
查看数据
{ "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": "a83eae3c1487efca38436c00b4b25f6e9045c026c113d644f44244b9133d3f82", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 34816, "nodes": 127, "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": 1.132 }
adaptation-25建造成功1634722127
查看数据
{ "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": "37475d209e43347e5d948f02a9faef9d46b0e4cfe4ff0106fb53c8d1f5da90ca", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 34722, "nodes": 127, "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": 1.0722 }
adaptation-26建造成功2635076159
查看数据
{ "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": "bbffb733fb9c47fe2b4000002c9a1c708e9b863eaa815df27c844245731529b4", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 35076, "nodes": 159, "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": 1.0987 }
adaptation-27建造成功3633851135
查看数据
{ "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": "b00f9e20838b930413f02f5609dcb2e97768248da9d64cfbb6a867b284b592db", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 33851, "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, 2.04 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.7039 }
adaptation-28建造成功0737927127
查看数据
{ "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": "c3395b04480a5a2d4c150984d0f74402c512e3a4fed64ab968ee10f6f1405d09", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 37927, "nodes": 127, "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": 1.0149 }
adaptation-29建造成功1737833127
查看数据
{ "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": "3872063be4ac805b9609db10b32f32aedd357a405408b089137ae34857252252", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 37833, "nodes": 127, "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.9695 }
adaptation-30建造成功2738187159
查看数据
{ "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": "16523ba21d98021742636e8d979f98fa0a8ea2bd3ee4c941e0f83625d9dc539c", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 38187, "nodes": 159, "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": 1.0576 }
adaptation-31建造成功3736962135
查看数据
{ "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": "8f916d4acaea37494f181932301aa57821d964e542c7558477c3fc05606a0b25", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 36962, "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.45 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.6732 }
adaptation-32建造成功0830312127
查看数据
{ "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": "4efe1c11684fb7e5ac3c31da7ddb339a773b2f9bb461a9e49b541725d54016d8", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 30312, "nodes": 127, "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.2516 }
adaptation-33建造成功1830218127
查看数据
{ "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": "7ce16f015562b41562d3c7c85ffed3a28106b3d5af425f78b0aefffeedbb2930", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 30218, "nodes": 127, "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.2309 }
adaptation-34建造成功2830616159
查看数据
{ "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": "41a382f85ff92876ec57e98b5cb0f5f898a8a8696305837027121df69c1f221a", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 30616, "nodes": 159, "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.3896 }
adaptation-35建造成功3829331135
查看数据
{ "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": "c4ee34574fa1b1d082fe1d04554260fbe1a48454d5c0040f6df401e7f7d25777", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 29331, "nodes": 135, "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-detail/release/adaptation-35.litematic", "audit": { "queries": 128, "inventories": 18, "nodes": 135, "digest": "c4ee34574fa1b1d082fe1d04554260fbe1a48454d5c0040f6df401e7f7d25777" }, "seconds": 2.365 }
adaptation-36建造成功0937927127
查看数据
{ "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": "b81e2edf059cc0ea41368bdbf4be3d0dcf2ad9a873c26ca477e6f8594cf1752f", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 37927, "nodes": 127, "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": 1.0344 }
adaptation-37建造成功1937833127
查看数据
{ "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": "badee8101480c4f1388f46e1f9ad9778360f6bbb80de06485da75e65d4bf22c6", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 37833, "nodes": 127, "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.9791 }
adaptation-38建造成功2938187159
查看数据
{ "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": "35862ddd9c7b1f5331bc512b7d76eb56315bd8b3b84e02bb97899a8daf97a6cf", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 38187, "nodes": 159, "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": 1.0549 }
adaptation-39建造成功3936962135
查看数据
{ "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": "3800ef983843e69243b9d3b63b2b5335039e62764f74e117597a6f5dd00b4b75", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 36962, "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.48 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.6777 }
adaptation-40建造成功01030680127
查看数据
{ "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": "5e3f40e3cdef7cc4db79571e09a401b1f64154d8a36b57ae02b9189ed940b8de", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 30680, "nodes": 127, "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.2594 }
adaptation-41建造成功11030586127
查看数据
{ "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": "3c44dc956ed510e26a99618321d4758d7098dde809bee231478304b29f8dd9f4", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 30586, "nodes": 127, "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.236 }
adaptation-42建造成功21030920159
查看数据
{ "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": "0b1761ef3ad680d8c2e5912f2eb024478c78cf1421f161cf306b6720bba4b13f", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 30920, "nodes": 159, "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.3654 }
adaptation-43建造成功31029678135
查看数据
{ "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": "9a45e17623a18bdb8dae7780e4ed8dba16d7de2245f82d128927ea40b982b252", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 29678, "nodes": 135, "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.8811 }
adaptation-44建造成功01134816127
查看数据
{ "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": "5bbf5376eb2c77545dcddc3f43feb9f2195ba2cf32fcea9136c38d2fd0abb694", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 34816, "nodes": 127, "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": 1.0189 }
adaptation-45建造成功11134722127
查看数据
{ "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": "9aebe3adff5b1542aaa22d8e3cf68468b8b2c8e5953e5a30a3bc0e5283d9519e", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 34722, "nodes": 127, "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.9462 }
adaptation-46建造成功21135076159
查看数据
{ "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": "77374e7aaf7be04c1c4572f66be87c88355e4067b16f03d9c2024f52b1e6173c", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 35076, "nodes": 159, "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": 1.0282 }
adaptation-47建造成功31133851135
查看数据
{ "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": "f115107a9b1a5b5d3b941bcaf26e0b30e8b2e7c4732b0dff92a7e953ab73dfa8", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 33851, "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, 2.31 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.6487 }
adaptation-48建造成功01234816127
查看数据
{ "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": "295e2a6776bcecacabc84ae05796f4aee2b9549c46c7f56ee71e0eed2c6170e3", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 34816, "nodes": 127, "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.9567 }
adaptation-49建造成功11234722127
查看数据
{ "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": "d37da1997ecbdbcd29a639f9046ee2f92486247667cc9614c60d83ec998c3e27", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 34722, "nodes": 127, "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.9451 }
adaptation-50建造成功21235076159
查看数据
{ "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": "cdb076fbc83be3a6ef88cf549748be2736728390df43b05ca07099f73c3e5b9d", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 35076, "nodes": 159, "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": 1.0193 }
adaptation-51建造成功31233851135
查看数据
{ "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": "b1c8003cd08424a3709d99151bd4f6b1b54c43e8c8b4c269a0345b589d4e800a", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 33851, "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, 2.16 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.6648 }
adaptation-52建造成功01332168127
查看数据
{ "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": "66a4962eaeeafd39b0a897f77c51c02d00da085e71c90372b7e2e9af8b9c52a0", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 32168, "nodes": 127, "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.2619 }
adaptation-53建造成功11332074127
查看数据
{ "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": "3d2fe1ed7a4a1cb7be95f3e848144f001322cf701cfff01debecbc6615ec5445", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 32074, "nodes": 127, "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.241 }
adaptation-54建造成功21332428159
查看数据
{ "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": "6ced58d89a1a233241c6f7b12fd7775454d0a3e30a729089847e3958dafc33d6", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 32428, "nodes": 159, "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.3797 }
adaptation-55建造成功31331203135
查看数据
{ "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": "df42c7128a90c5d2b0ebae98eb9edef409c1ff70ab78e39a22a511b83fc20279", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 31203, "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": 0.9577 }
adaptation-56建造成功01434816127
查看数据
{ "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": "a35eefc8888e37c45b0b81848051ff97df28108f7af5da2e73352dc6dc24cd46", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 34816, "nodes": 127, "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.9546 }
adaptation-57建造成功11434722127
查看数据
{ "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": "cc015f7a8554c1467e1bde3f351a86c2a47b343614e09da2909afcf99b8149a7", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 34722, "nodes": 127, "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.9565 }
adaptation-58建造成功21435076159
查看数据
{ "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": "5f353f653f538a82c7c73871fdba727d886071ec13a1b09cebd9315463631ee7", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 35076, "nodes": 159, "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": 1.0367 }
adaptation-59建造成功31433851135
查看数据
{ "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": "230cce8b6312503eea1fa5d8cc3fdaa969781a76c4e089b60e3406682a345af5", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 33851, "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, 2.28 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.647 }
adaptation-60建造成功01537927127
查看数据
{ "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": "88eb53481cd5ed81a2b5566824caafb8c0955b8f9d3ed2feab17a58fcd421719", "principal_signature": "de267ba03deef9f434df3bc82fc66bc4b4db8869c90b69b9e147db6787e42efa", "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 ] }, "5e0957cdcb8d60746d537709958cf09e4c84156d970247e9347d51bed51b92ac" ], [ "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": 37927, "nodes": 127, "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-detail/release/adaptation-60.litematic", "audit": { "queries": 118, "inventories": 23, "nodes": 127, "digest": "88eb53481cd5ed81a2b5566824caafb8c0955b8f9d3ed2feab17a58fcd421719" }, "seconds": 2.942 }
adaptation-61建造成功11537833127
查看数据
{ "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": "f1397c2adb7d7dd5f9fa6df2b12859bbc1b4f76b333ebc2864aa421226ada754", "principal_signature": "7ec3a0fc66387707bcd912412d76718a3c7a57e44e19e9cfa01eaf19e9ca2d8a", "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 ] }, "ab1c04a43bc78607854e25438c35f31f60b2723c410bd7108b422756f845bd16" ], [ "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": 37833, "nodes": 127, "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.9717 }
adaptation-62建造成功21538187159
查看数据
{ "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": "43f28eee17dae7eb1f708710b73871d5eb4e2c20d63f16806c023a7a6a1d9600", "principal_signature": "e08fe6798223614df7b423eb0bf2a76bb685fbf2ddae1b68d24499b4cc7e76a9", "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 ] }, "8f6c5eee98aba5ec0832da3c5366db4489ecba28f87e6f8a2511d1dcbdc0be60" ], [ "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": 38187, "nodes": 159, "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": 1.0449 }
adaptation-63建造成功31536962135
查看数据
{ "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": "99e329b415b31522f5eb879300d8b5a6be8593113f19d49b4ab70b3293232c05", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 36962, "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.21 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.6772 }
stress-00建造成功0200036498135
查看数据
{ "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": "61e93e3a236509f55a27d91772cd8b7bca3e2cb5fef453b55b6ffe33e67c67eb", "principal_signature": "49f0379c37ead3990d4170ad50fc24c282e33b7653ac497c3ceecb111ab7a06a", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 36498, "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, 2.5 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ] ] } ], "seconds": 0.7646 }
stress-01建造成功1200140998183
查看数据
{ "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": "6452ceb4af63da18db8348bae8d018e64f9df1fc1540cf49b5934ecd679f97d4", "principal_signature": "4e4e6cad6c5c1350050d8b292d507b4ab6a7daabb9bce14cc5a52a534612036c", "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 ] }, "03696bdf0ea9dd11f838ddb8446738180efcb69ddee39936c7b9c6ef54b9200a" ], [ "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": 40998, "nodes": 183, "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": 1.0182 }
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.3321 }
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.2347 }
stress-04建造成功4200436754134
查看数据
{ "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": "2da5bfc08b9e2b943996792981da540cca776f29fc0bb11f49bbe58562132652", "principal_signature": "42a1aa878b972424a798b362465f407ad9e45ac26ad58c9764727356d71ff0f1", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 36754, "nodes": 134, "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.6667 }
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.2271 }
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.3259 }
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.2271 }
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.2337 }
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.3296 }
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.3248 }
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.2326 }
stress-12建造成功4201236557134
查看数据
{ "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": "7f0d2ed678c3968143f3bd32d850eddf6220ab20f4ebd6614294a945eee05193", "principal_signature": "42a1aa878b972424a798b362465f407ad9e45ac26ad58c9764727356d71ff0f1", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 36557, "nodes": 134, "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.687 }
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.2327 }
stress-14建造成功6201435723152
查看数据
{ "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": "5abc44357a0dd135541d22eba4bf0eca239cc0fcf1c5ce2d145e6af4204f91f2", "principal_signature": "46cfd7ee5c84f3e4c2214b536bd92851d57866b64c38b16e3ff2e1ce1252e1b9", "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 ] }, "03696bdf0ea9dd11f838ddb8446738180efcb69ddee39936c7b9c6ef54b9200a" ], [ "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": 35723, "nodes": 152, "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.2249 }
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.2345 }
0-high_house-5建造成功5300034241162
查看数据
{ "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": "9b8b4478c19573f2b7e7657bdbe49e575ddb321218937e28684db03b0c21c59c", "principal_signature": "634ac8b29c460a433eb81e3d1ded862d287d4cba66d268630110f90144968dcb", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 34241, "nodes": 162, "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-detail/release-prior-holdout/0-high_house-5.litematic", "audit": { "queries": 154, "inventories": 26, "nodes": 162, "digest": "9b8b4478c19573f2b7e7657bdbe49e575ddb321218937e28684db03b0c21c59c" }, "seconds": 3.1947 }
0-gabled_hall-7建造成功7300035480173
查看数据
{ "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": "628d71a4a0e3b7f4a1e55c730d06b58ecee56e72616b0f3566da030865ce10e3", "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": 35480, "nodes": 173, "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-detail/release-prior-holdout/0-gabled_hall-7.litematic", "audit": { "queries": 163, "inventories": 37, "nodes": 173, "digest": "628d71a4a0e3b7f4a1e55c730d06b58ecee56e72616b0f3566da030865ce10e3" }, "seconds": 3.1843 }
1-high_house-5建造成功5300137352162
查看数据
{ "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": "45f3fb64632bc582e08143573ff87a395ced2d80fd1a875bcc3085019794fc4e", "principal_signature": "634ac8b29c460a433eb81e3d1ded862d287d4cba66d268630110f90144968dcb", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 37352, "nodes": 162, "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.7975 }
1-gabled_hall-7建造成功7300138591173
查看数据
{ "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": "eb5d2a825d714ee446b9fdc33e1e7dafcd71328dd7c58f0f059599ad3d7feeb4", "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": 38591, "nodes": 173, "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.3623 }
2-high_house-5建造成功5300234412162
查看数据
{ "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": "d9cd62e94c02d1151f5e3fb851a72cd9b0c84faaa9bb9d4f0cfe7310fb652d99", "principal_signature": "634ac8b29c460a433eb81e3d1ded862d287d4cba66d268630110f90144968dcb", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 34412, "nodes": 162, "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.7978 }
2-gabled_hall-7建造成功7300235651173
查看数据
{ "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": "f431cac76024440395cfc39c115620535593c3bb2e9ecce60880d87405639b4c", "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": 35651, "nodes": 173, "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.2177 }
3-high_house-5建造成功5300334241162
查看数据
{ "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": "5a3b95c04ae13a702e275957b54aed92fcdce5683499543dcab2807d04916f1a", "principal_signature": "634ac8b29c460a433eb81e3d1ded862d287d4cba66d268630110f90144968dcb", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 34241, "nodes": 162, "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.7671 }
3-gabled_hall-7建造成功7300335480173
查看数据
{ "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": "3be97303155473bc573e256ad23b4b1496c65931127a95bc49d2154d216e38bd", "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": 35480, "nodes": 173, "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.3172 }
4-high_house-5建造成功5300434241162
查看数据
{ "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": "72def37cc6d3c155d6b616bda097b8abe3845030ac03af44180c12a7c7d83325", "principal_signature": "634ac8b29c460a433eb81e3d1ded862d287d4cba66d268630110f90144968dcb", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 34241, "nodes": 162, "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.842 }
4-gabled_hall-7建造成功7300435480173
查看数据
{ "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": "71db80b4ee5867b25ea11ee5728aeab5c40100de16f8c6c7daea7c91e8192906", "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": 35480, "nodes": 173, "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.3943 }
5-high_house-5建造成功5300534241162
查看数据
{ "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": "0f4e8b75439e929c9b5a1985e711f2a9040a21b41cd075fd3d2afcfb64cf78dd", "principal_signature": "634ac8b29c460a433eb81e3d1ded862d287d4cba66d268630110f90144968dcb", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 34241, "nodes": 162, "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.8831 }
5-gabled_hall-7建造成功7300535480173
查看数据
{ "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": "d0b9da68ea6971c493b8bfffbcd711756ad7acbae96902019ca40fa6139396fc", "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": 35480, "nodes": 173, "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.365 }
6-high_house-5建造成功5300634241162
查看数据
{ "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": "71d18e30d79c238695b01722227b27815377ea39635044e90314741e7dc28780", "principal_signature": "634ac8b29c460a433eb81e3d1ded862d287d4cba66d268630110f90144968dcb", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 34241, "nodes": 162, "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.8238 }
6-gabled_hall-7建造成功7300635480173
查看数据
{ "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": "5c41b3a294b5d473ec8016bc1831d88565402eaa55b3651bfb0a637958142209", "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": 35480, "nodes": 173, "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.3056 }
7-high_house-5建造成功5300734241162
查看数据
{ "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": "39f91abd108cf30350c0609dc10a764035bcfb459769ad9f476163cfc6bce8ca", "principal_signature": "634ac8b29c460a433eb81e3d1ded862d287d4cba66d268630110f90144968dcb", "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 ] }, "bfa2fd7013208d1505ae9171ffc52c47e24613b5dcec3074e5915abdc3e9e6bc" ], [ "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": 34241, "nodes": 162, "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.8033 }
7-gabled_hall-7建造成功7300735480173
查看数据
{ "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": "2aa05418f57a5abcefc08d146f8966ecf132dd670c116fcfb28efdada4ef37c6", "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": 35480, "nodes": 173, "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.2538 }
court-0建造成功0410026228480
查看数据
{ "label": "court-0", "inputs": { "structure_seed": 0, "environment_seed": 4100, "garden": true }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "92eba50736e706f0b63870ed093b2c3f4f9a05383f08c4c3412ad512e583abc8", "principal_signature": "af9d862689350efe4ce39374953b42df82af6752a631d63986cfdedf524d1493", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": false, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 26 ], { "height": 21, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 24 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 11 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 20 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "9e0fbadaa825da6bd49f1860058d4ee2072b69221954bdca3c2fcf07f6f58532" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "de2b0548d8dc68dba6940c337d50478e4c6b039fccfcc3163b94bf748695c40e" ], [ "roof.profile", [ 26, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "884208ea66726cd7f143a73d68aab2cdf529bb0933c0044d9dc37ba738d1b961" ], [ "roof.profile", [ 26, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "fa6d3b312c2bad4b384c8bf71d324c87581769852a2d04780e510ff1c0c7d6fc" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 0, 13 ], "room.kitchen", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 13, 0, 0 ], "room.library", [ "west", "east" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 0 ], "room.workshop", [ "south", "west" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 13 ], "room.storage", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 6, 0 ], "room.bedroom", [], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ] ] ], "contact": { "fill": 158, "excavation": 0, "sitework_occupied_cells": 194, "replaced_cells": 30, "new_sitework_cells": 164, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "98da4571e1fc2464eb1c11be8301f666dcf3630c0c3305b019518adeebcccd24", "bearing_fill": 3 }, "blocks": 26228, "nodes": 480, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.76 ], [ 0, 1.98 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-1/cover", "dormers": [ [ "right", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-detail/release-new-composition/court-0.litematic", "audit": { "queries": 448, "inventories": 77, "nodes": 480, "digest": "92eba50736e706f0b63870ed093b2c3f4f9a05383f08c4c3412ad512e583abc8" }, "seconds": 6.3227, "details": { "stations": "0bc8be3eeb50ce841fa908bf68d68fe7839ab40d747a63486c9616969449e964", "facade_openings": "5cf0cdae896c3082d83ec0ae9f262e1c8a23e9c2fbbe4a3c060929f76ce410ea", "station_count": 12, "window_count": 45, "window_boxes": 28 } }
court-1建造成功1410026793493
查看数据
{ "label": "court-1", "inputs": { "structure_seed": 1, "environment_seed": 4100, "garden": true }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "e4332e7ffb3cb2929fd6aa5da3fea6d0fdc098c1efb15afa180f4af780039a46", "principal_signature": "b26caa9101006cc8e8a7654eac493613714054a3aa9dca9265d541fe18295aba", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 26 ], { "height": 21, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "884208ea66726cd7f143a73d68aab2cdf529bb0933c0044d9dc37ba738d1b961" ], [ "roof.profile", [ 0, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "bd9684f9c786190f4efc8b833b48d80b50826d3cfaeae3b5dd16634395ae28ce" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40886e1c5e1fa16bb82f0ddc7722566ddfc6a6fa47006ee26bb0038fc5c6b9f2" ], [ "roof.profile", [ 26, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "884208ea66726cd7f143a73d68aab2cdf529bb0933c0044d9dc37ba738d1b961" ], [ "roof.profile", [ 26, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "fa6d3b312c2bad4b384c8bf71d324c87581769852a2d04780e510ff1c0c7d6fc" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 0, 13 ], "room.kitchen", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.library", [ "west", "east" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 0 ], "room.workshop", [ "south", "west" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 13 ], "room.storage", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 6, 0 ], "room.bedroom", [], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ] ] ], "contact": { "fill": 158, "excavation": 0, "sitework_occupied_cells": 194, "replaced_cells": 30, "new_sitework_cells": 164, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "98da4571e1fc2464eb1c11be8301f666dcf3630c0c3305b019518adeebcccd24", "bearing_fill": 3 }, "blocks": 26793, "nodes": 493, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.76 ], [ 0, 1.98 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ], [ "right", 4, "existing upper volume" ] ] } ], "seconds": 4.1894, "details": { "stations": "8a6ab5a03a11254aff9af317e2a7406b45c499d11601ca723bebcbacc6abec73", "facade_openings": "4b225fbde16bfd5797b93bcb726718ecb0e058e58314a6f46e99a51b712f7086", "station_count": 14, "window_count": 49, "window_boxes": 30 } }
court-2建造成功2410021112407
查看数据
{ "label": "court-2", "inputs": { "structure_seed": 2, "environment_seed": 4100, "garden": true }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "a813e18ddf02bb89adc53fc33dca6fe5a7675e0b3ce0a08ede908826c3134d45", "principal_signature": "b15515d944aab39ad72b80dcfb8b7d8f7d7a840f65746964c917d3deb54a1241", "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, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 32, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c1a11f0f69059d517411ef5e7e60a41e467ab257ac61a4baef00a61de4f2486e" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "f077435e219f2885917fcc7f32ff74239a4d66c67ab33ea3d3a2140859ebf277" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "65a63520d3754a281ba3f181431ede58eaaf05dd18704d58ec8d47b0a371d9e2" ], [ "roof.profile", [ 22, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c517627449fef556818812285f34a7a967540385454012fad9fecd7b6eeef1e5" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.kitchen", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.library", [ "west", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 11 ], "room.storage", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 130, "excavation": 0, "sitework_occupied_cells": 166, "replaced_cells": 30, "new_sitework_cells": 136, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "7e864981ff2dd3b1ef1c295649a234f0d1513e02868d75127f432eb49588ecdb", "bearing_fill": 3 }, "blocks": 21112, "nodes": 407, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.48 ], [ 0, 1.74 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-3/cover", "dormers": [ [ "right", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-detail/release-new-composition/court-2.litematic", "audit": { "queries": 376, "inventories": 66, "nodes": 407, "digest": "a813e18ddf02bb89adc53fc33dca6fe5a7675e0b3ce0a08ede908826c3134d45" }, "seconds": 4.3381, "details": { "stations": "16785425ba8f8301abc9f1acb9e88aaaddfcf45a4ac6adef2e377d5d237a58b8", "facade_openings": "c1d4f5bdb65be2a10c45629adf7fc549459e2b123e6dc1002ee3c2bf7cda8506", "station_count": 12, "window_count": 40, "window_boxes": 22 } }
court-3建造成功3410021777452
查看数据
{ "label": "court-3", "inputs": { "structure_seed": 3, "environment_seed": 4100, "garden": true }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "75cd1fdc2c4725dc5a26c9875089f363377b253a5adadea66b36146617fd1a3d", "principal_signature": "62bd7bae9945ef64a1121315baa89d74658bcbc8a0064ee61e07179788152291", "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", [ 22, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 32, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 32, 8, 13 ], { "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 ] }, "c90ce1f7fb38c212933f3cf1d00a506d4d054c586f7edbc6284c3d744d0b1a1f" ], [ "roof.profile", [ 22, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "b4e204665a92f8c1e792f6c207f72e5630cc92784c22f952b738704a5a16c573" ], [ "roof.profile", [ 22, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "d8cbdd7f3ba160ae30c6c33c86ccfda503a93c2af004d69eb332d9e7e9f71010" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.kitchen", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.library", [ "west", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 0 ], "room.workshop", [ "south", "west" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 11 ], "room.storage", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 6, 0 ], "room.bedroom", [], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ] ] ], "contact": { "fill": 130, "excavation": 0, "sitework_occupied_cells": 166, "replaced_cells": 30, "new_sitework_cells": 136, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "7e864981ff2dd3b1ef1c295649a234f0d1513e02868d75127f432eb49588ecdb", "bearing_fill": 3 }, "blocks": 21777, "nodes": 452, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.48 ], [ 0, 1.74 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ], [ "right", 4, "existing upper volume" ] ] } ], "seconds": 3.4214, "details": { "stations": "ff08a415a324db40b078f927d514eaef060da539bccddf64c938abed7788ee2a", "facade_openings": "7a03a5da7601688ede0e21045f04893931e88f01f6b05cb533bb3a8facb0ed3d", "station_count": 14, "window_count": 49, "window_boxes": 26 } }
court-4建造成功4410032564583
查看数据
{ "label": "court-4", "inputs": { "structure_seed": 4, "environment_seed": 4100, "garden": true }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "97234db567e053b9b60aeb86f75e54274d231f89f253b6099f6c158e2528ba7f", "principal_signature": "6f8770fca0d60e3a59baacf660b425f1294fa4b2a56cfa3d4f9df20efbaebcf5", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 31, 0, 39 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 28 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 37 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 24 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 33 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 0, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "8a09a1b47cbef6c29c6a8c3c7b1c1da523fee4b0f3636f58f23f5014ff23dee9" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "a6f787436f38377ade78810d0cc70ce5c009268dafeca98b887d1b1291000357" ], [ "roof.profile", [ 26, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 26, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "c5edc055a7577d689a44fd692ccbd84320059f277fdd34be88097cf530558a29" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 0, 13 ], "room.kitchen", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.library", [ "west", "east" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 0 ], "room.workshop", [ "south", "west" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 13 ], "room.storage", [ "north", "south" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 26 ], "room.library", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 6, 0 ], "room.bedroom", [], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ] ] ], "contact": { "fill": 202, "excavation": 0, "sitework_occupied_cells": 238, "replaced_cells": 30, "new_sitework_cells": 208, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "734c9db84ed38a5507d88de742d111aea743428cf186f07213f1c67b02598f06", "bearing_fill": 1 }, "blocks": 32564, "nodes": 583, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.87 ], [ 0, 2.2 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ], [ "right", 4, "existing upper volume" ] ] } ], "seconds": 5.2823, "details": { "stations": "71cfc978cf88ac30db13a6c69d0b36a6c3cc4d10cfc3edeacaf204c9be11bfa9", "facade_openings": "fc96e5c4d00cea6bfca60e1ebd4eb7dacb8cb37dee551b49761fe4a5033b07db", "station_count": 16, "window_count": 57, "window_boxes": 34 } }
court-5建造成功5410032802578
查看数据
{ "label": "court-5", "inputs": { "structure_seed": 5, "environment_seed": 4100, "garden": true }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "5cc171e3b07746de4c274037d0276ee58934d87b0fa52b881e867098d30227ff", "principal_signature": "1fdc67a67100008747a7698ab1327be4e13c8185a825e2d6b62f833ecac9e4fb", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 31, 0, 39 ], { "height": 21, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 28 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 37 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 24 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 33 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "884208ea66726cd7f143a73d68aab2cdf529bb0933c0044d9dc37ba738d1b961" ], [ "roof.profile", [ 0, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "072cce6798df18e301f84f7a1fc866ddcba2897180aa7c210a703d3d41709939" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "40886e1c5e1fa16bb82f0ddc7722566ddfc6a6fa47006ee26bb0038fc5c6b9f2" ], [ "roof.profile", [ 26, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "884208ea66726cd7f143a73d68aab2cdf529bb0933c0044d9dc37ba738d1b961" ], [ "roof.profile", [ 26, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 2 ] }, "8ceb8c49931931ee9ef9e06e3d906d764293e6f24ddb382f06f25ba649fd2c9e" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 0, 13 ], "room.kitchen", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.library", [ "west", "east" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 0 ], "room.workshop", [ "south", "west" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 13 ], "room.storage", [ "north", "south" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 26 ], "room.library", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 6, 0 ], "room.bedroom", [], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ] ] ], "contact": { "fill": 202, "excavation": 0, "sitework_occupied_cells": 238, "replaced_cells": 30, "new_sitework_cells": 208, "strategies": [ "stepped", "stepped", "stepped", "stepped", "stepped" ], "signature": "734c9db84ed38a5507d88de742d111aea743428cf186f07213f1c67b02598f06", "bearing_fill": 1 }, "blocks": 32802, "nodes": 578, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.87 ], [ 0, 2.2 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ], [ "right", 4, "existing upper volume" ] ] } ], "seconds": 4.8666, "details": { "stations": "50671a67d3b1803cbc8e7f120d42546dc2ab9eede1e3d6e9510dfec1bc28e648", "facade_openings": "fc96e5c4d00cea6bfca60e1ebd4eb7dacb8cb37dee551b49761fe4a5033b07db", "station_count": 16, "window_count": 57, "window_boxes": 34 } }
court-6建造成功6410025358482
查看数据
{ "label": "court-6", "inputs": { "structure_seed": 6, "environment_seed": 4100, "garden": true }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "cea7e7534b3cd51d20ee8b8fd3e54a4c07b3d37d47733769856ee474790c6d78", "principal_signature": "3207fcac16745659c7e6e4e25c47140ad09051454d6146fdfc39fe88bb242d91", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 11 } ], [ "masonry.chimney", [ 26, 0, 33 ], { "height": 19, "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, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 26 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 32, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 32, 8, 22 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 1, 2 ] }, "b5960813c15baacc09e1bc1e1298e2ce8f4f79aac67b6f9b068fcbfc0c97a00f" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 1, 2 ] }, "0d9934de806de6d6d1021c253f73884b02238d04fadf3e8669c7f0468534ae0f" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 1, 2 ] }, "595466ba1966d36b0db7ff6ca2e37478802430fdbbf27b2afeff741fbbb30b7a" ], [ "roof.profile", [ 22, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 1, 2 ] }, "3d4abd3a0f589e729bafb3c5ac7b88499b16c259d0b03227d476955694a32a78" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.kitchen", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.library", [ "west", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 11 ], "room.storage", [ "north", "south" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 22 ], "room.library", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 142, "excavation": 0, "sitework_occupied_cells": 178, "replaced_cells": 30, "new_sitework_cells": 148, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "84fd456b345606cabad862c724a9c2e4053a932bc6f0769550d31910392b680b", "bearing_fill": 1 }, "blocks": 25358, "nodes": 482, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.6 ], [ 0, 1.94 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-3/cover", "dormers": [ [ "right", 4, "existing upper volume" ] ] } ], "seconds": 3.232, "details": { "stations": "9002d2cf5945b6f790ef0c9aaa9d0b580721e5a34ac9539ffabda82589208dd0", "facade_openings": "d4e84c6f7fa5732324242db12c6e6956afd82470c3484f07bd7598861f50d8ba", "station_count": 14, "window_count": 46, "window_boxes": 26 } }
court-7建造成功7410026587477
查看数据
{ "label": "court-7", "inputs": { "structure_seed": 7, "environment_seed": 4100, "garden": true }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "6ddb7ce446489efcc0d91f7ef848ba2efbde57d124b34f24b6b8ce4d29d1f8f4", "principal_signature": "c6355c35840d506d5a9b289a7de2ea16faeb40a24d0cfd8049d3fa357ab4de5f", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 26 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 0, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "ac58a23bade7310373b47f1e8f6e751c218827d6cb8b28d46e27b3f84563379a" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "a6f787436f38377ade78810d0cc70ce5c009268dafeca98b887d1b1291000357" ], [ "roof.profile", [ 26, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 26, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "99196cdad567087f649bc679b00253e86a6b19283e1079be2d3892e091e9d1a8" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 0, 13 ], "room.kitchen", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.library", [ "west", "east" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 0 ], "room.workshop", [ "south", "west" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 13 ], "room.storage", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 6, 0 ], "room.bedroom", [], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ] ] ], "contact": { "fill": 158, "excavation": 0, "sitework_occupied_cells": 194, "replaced_cells": 30, "new_sitework_cells": 164, "strategies": [ "piers", "stepped", "stepped", "stepped", "stepped" ], "signature": "98da4571e1fc2464eb1c11be8301f666dcf3630c0c3305b019518adeebcccd24", "bearing_fill": 3 }, "blocks": 26587, "nodes": 477, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 1, 1.76 ], [ 0, 1.98 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ], [ "right", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-detail/release-new-composition/court-7.litematic", "audit": { "queries": 442, "inventories": 83, "nodes": 477, "digest": "6ddb7ce446489efcc0d91f7ef848ba2efbde57d124b34f24b6b8ce4d29d1f8f4" }, "seconds": 5.6931, "details": { "stations": "2d185a0f0ccd9124f863de23c2599a41fb9e7dcdcb6fd5172a5dbd11e280624e", "facade_openings": "4b225fbde16bfd5797b93bcb726718ecb0e058e58314a6f46e99a51b712f7086", "station_count": 14, "window_count": 49, "window_boxes": 30 } }
new-pair-0-2建造成功2410043967231
查看数据
{ "label": "new-pair-0-2", "inputs": { "environment_seed": 4100, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, -0.02, 4 ] }, { "op": "wave", "args": [ 0.3, 0.13, 0.09, 1.9376801597532656 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.02, 4 ] }, { "op": "radial", "args": [ 18, 18, 36, 0.5 ] } ] }, { "op": "radial", "args": [ 8, 10, 44, 0.6 ] } ] }, 2, 6 ] }, "water": null, "digest": "a8c9e47c77a14eaa94764e1e104d6bf780e6135cd16dbf1a242602cc00f95e94", "structure_seed": 2, "garden": false }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "f866f095bc3e7b6d546f060fe3af12597aa52e3f9ccb419a7bc0a81266edcf0a", "principal_signature": "b15515d944aab39ad72b80dcfb8b7d8f7d7a840f65746964c917d3deb54a1241", "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, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 32, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c1a11f0f69059d517411ef5e7e60a41e467ab257ac61a4baef00a61de4f2486e" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "f077435e219f2885917fcc7f32ff74239a4d66c67ab33ea3d3a2140859ebf277" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "65a63520d3754a281ba3f181431ede58eaaf05dd18704d58ec8d47b0a371d9e2" ], [ "roof.profile", [ 22, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c517627449fef556818812285f34a7a967540385454012fad9fecd7b6eeef1e5" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.kitchen", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.library", [ "west", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 11 ], "room.storage", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 76, "excavation": 0, "sitework_occupied_cells": 82, "replaced_cells": 3, "new_sitework_cells": 79, "strategies": [ "stepped" ], "signature": "0f423edcc8b81cd4e92f3ff705d398d247a16ebe17a6bf0675b5a53bf2f19667", "bearing_fill": 1 }, "blocks": 43967, "nodes": 231, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.88 ], [ 1, 1.18 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-3/cover", "dormers": [ [ "right", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-detail/release-new-composition/new-pair-0-2.litematic", "audit": { "queries": 215, "inventories": 66, "nodes": 231, "digest": "f866f095bc3e7b6d546f060fe3af12597aa52e3f9ccb419a7bc0a81266edcf0a" }, "seconds": 4.6759, "details": { "stations": "cf868a3f22c811cc98cbd36963c80fda618d70fe73571b25c71b609cd82efb88", "facade_openings": "c1d4f5bdb65be2a10c45629adf7fc549459e2b123e6dc1002ee3c2bf7cda8506", "station_count": 12, "window_count": 40, "window_boxes": 22 } }
new-pair-0-7建造成功7410046146268
查看数据
{ "label": "new-pair-0-7", "inputs": { "environment_seed": 4100, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, -0.02, 4 ] }, { "op": "wave", "args": [ 0.3, 0.13, 0.09, 1.9376801597532656 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.02, 4 ] }, { "op": "radial", "args": [ 18, 18, 36, 0.5 ] } ] }, { "op": "radial", "args": [ 8, 10, 44, 0.6 ] } ] }, 2, 6 ] }, "water": null, "digest": "a8c9e47c77a14eaa94764e1e104d6bf780e6135cd16dbf1a242602cc00f95e94", "structure_seed": 7, "garden": false }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "25878ceebc3b92f885a6437b567786203a34d247126ce9dc6b29ea78b991812d", "principal_signature": "c6355c35840d506d5a9b289a7de2ea16faeb40a24d0cfd8049d3fa357ab4de5f", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 26 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 0, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "ac58a23bade7310373b47f1e8f6e751c218827d6cb8b28d46e27b3f84563379a" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "a6f787436f38377ade78810d0cc70ce5c009268dafeca98b887d1b1291000357" ], [ "roof.profile", [ 26, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 26, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "99196cdad567087f649bc679b00253e86a6b19283e1079be2d3892e091e9d1a8" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 0, 13 ], "room.kitchen", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.library", [ "west", "east" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 0 ], "room.workshop", [ "south", "west" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 13 ], "room.storage", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 6, 0 ], "room.bedroom", [], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ] ] ], "contact": { "fill": 127, "excavation": 0, "sitework_occupied_cells": 133, "replaced_cells": 3, "new_sitework_cells": 130, "strategies": [ "stepped" ], "signature": "9796e5b7166098e20609edfef2bbf2a44157030e212f649fba0aba9d75a4ad84", "bearing_fill": 1 }, "blocks": 46146, "nodes": 268, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 1.39 ], [ 1, 1.44 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ], [ "right", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-detail/release-new-composition/new-pair-0-7.litematic", "audit": { "queries": 248, "inventories": 83, "nodes": 268, "digest": "25878ceebc3b92f885a6437b567786203a34d247126ce9dc6b29ea78b991812d" }, "seconds": 6.4553, "details": { "stations": "8d685ea9888d15d1a68f7a096c2af8cfd3b966c43c599db9e7561c989a290cce", "facade_openings": "4b225fbde16bfd5797b93bcb726718ecb0e058e58314a6f46e99a51b712f7086", "station_count": 14, "window_count": 49, "window_boxes": 30 } }
new-pair-1-2建造成功2410147249231
查看数据
{ "label": "new-pair-1-2", "inputs": { "environment_seed": 4101, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, -0.02, 4 ] }, { "op": "wave", "args": [ 0.3, 0.13, 0.09, 1.6091962898701053 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.02, 4 ] }, { "op": "radial", "args": [ 18, 18, 36, 0.5 ] } ] }, { "op": "radial", "args": [ 8, 10, 44, 0.6 ] } ] }, 2, 6 ] }, "water": 4, "digest": "8f82df698da53194e6d29699c8a29bec3b44f5e47cbca0f1df6458325a0668b2", "structure_seed": 2, "garden": false }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "d394254e38bd536f1b9041787c677d83a1f215e80b4b14a0b4dbe93e4ecac74c", "principal_signature": "b15515d944aab39ad72b80dcfb8b7d8f7d7a840f65746964c917d3deb54a1241", "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, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 32, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c1a11f0f69059d517411ef5e7e60a41e467ab257ac61a4baef00a61de4f2486e" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "f077435e219f2885917fcc7f32ff74239a4d66c67ab33ea3d3a2140859ebf277" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "65a63520d3754a281ba3f181431ede58eaaf05dd18704d58ec8d47b0a371d9e2" ], [ "roof.profile", [ 22, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c517627449fef556818812285f34a7a967540385454012fad9fecd7b6eeef1e5" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.kitchen", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.library", [ "west", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 11 ], "room.storage", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 73, "excavation": 0, "sitework_occupied_cells": 79, "replaced_cells": 76, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "2b119f7acdc305f171f30421b9ff8882f5627572c13e57b8273b3bc25867beed", "bearing_fill": 3 }, "blocks": 47249, "nodes": 231, "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-3/cover", "dormers": [ [ "right", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-detail/release-new-composition/new-pair-1-2.litematic", "audit": { "queries": 215, "inventories": 66, "nodes": 231, "digest": "d394254e38bd536f1b9041787c677d83a1f215e80b4b14a0b4dbe93e4ecac74c" }, "seconds": 4.6561, "details": { "stations": "16785425ba8f8301abc9f1acb9e88aaaddfcf45a4ac6adef2e377d5d237a58b8", "facade_openings": "c1d4f5bdb65be2a10c45629adf7fc549459e2b123e6dc1002ee3c2bf7cda8506", "station_count": 12, "window_count": 40, "window_boxes": 22 } }
new-pair-1-7建造成功7410149377268
查看数据
{ "label": "new-pair-1-7", "inputs": { "environment_seed": 4101, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, -0.02, 4 ] }, { "op": "wave", "args": [ 0.3, 0.13, 0.09, 1.6091962898701053 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.02, 4 ] }, { "op": "radial", "args": [ 18, 18, 36, 0.5 ] } ] }, { "op": "radial", "args": [ 8, 10, 44, 0.6 ] } ] }, 2, 6 ] }, "water": 4, "digest": "8f82df698da53194e6d29699c8a29bec3b44f5e47cbca0f1df6458325a0668b2", "structure_seed": 7, "garden": false }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "86b18f7211fb67cb95da916788cb1e842ddeddba36c501a3762a3bace971be05", "principal_signature": "c6355c35840d506d5a9b289a7de2ea16faeb40a24d0cfd8049d3fa357ab4de5f", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 26 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 0, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "ac58a23bade7310373b47f1e8f6e751c218827d6cb8b28d46e27b3f84563379a" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "a6f787436f38377ade78810d0cc70ce5c009268dafeca98b887d1b1291000357" ], [ "roof.profile", [ 26, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 26, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "99196cdad567087f649bc679b00253e86a6b19283e1079be2d3892e091e9d1a8" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 0, 13 ], "room.kitchen", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.library", [ "west", "east" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 0 ], "room.workshop", [ "south", "west" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 13 ], "room.storage", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 6, 0 ], "room.bedroom", [], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ] ] ], "contact": { "fill": 100, "excavation": 0, "sitework_occupied_cells": 106, "replaced_cells": 103, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "910918d4fec0706daa067306e15b95ae3648602b9a5f1a6ae1ffccd5d6935cf8", "bearing_fill": 3 }, "blocks": 49377, "nodes": 268, "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.12 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ], [ "right", 4, "existing upper volume" ] ] } ], "artifact": "samples/building-detail/release-new-composition/new-pair-1-7.litematic", "audit": { "queries": 248, "inventories": 83, "nodes": 268, "digest": "86b18f7211fb67cb95da916788cb1e842ddeddba36c501a3762a3bace971be05" }, "seconds": 5.4439, "details": { "stations": "2d185a0f0ccd9124f863de23c2599a41fb9e7dcdcb6fd5172a5dbd11e280624e", "facade_openings": "4b225fbde16bfd5797b93bcb726718ecb0e058e58314a6f46e99a51b712f7086", "station_count": 14, "window_count": 49, "window_boxes": 30 } }
new-pair-2-2建造成功2410247249231
查看数据
{ "label": "new-pair-2-2", "inputs": { "environment_seed": 4102, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.3, 0.13, 0.09, 5.333154877072996 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.02, 4 ] }, { "op": "radial", "args": [ 18, 18, 36, 0.5 ] } ] }, { "op": "radial", "args": [ 8, 10, 44, 0.6 ] } ] }, 2, 6 ] }, "water": 4, "digest": "17a14b8b8ee4263f9c770f7b0dbb6ecb483dea3c0f72530310f28689db99427f", "structure_seed": 2, "garden": false }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "74ae26cd547f464abd4890341576ec8ef18be1034b806c87db17f7d6e4198fdb", "principal_signature": "b15515d944aab39ad72b80dcfb8b7d8f7d7a840f65746964c917d3deb54a1241", "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, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 32, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c1a11f0f69059d517411ef5e7e60a41e467ab257ac61a4baef00a61de4f2486e" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "f077435e219f2885917fcc7f32ff74239a4d66c67ab33ea3d3a2140859ebf277" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "65a63520d3754a281ba3f181431ede58eaaf05dd18704d58ec8d47b0a371d9e2" ], [ "roof.profile", [ 22, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c517627449fef556818812285f34a7a967540385454012fad9fecd7b6eeef1e5" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.kitchen", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.library", [ "west", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 11 ], "room.storage", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 31, "excavation": 0, "sitework_occupied_cells": 37, "replaced_cells": 34, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "4b8e9fb76e5bbdc6c5e699333a1dc632e291dcd2ab93acca990b4da019037df7", "bearing_fill": 0 }, "blocks": 47249, "nodes": 231, "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.05 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-3/cover", "dormers": [ [ "right", 4, "existing upper volume" ] ] } ], "seconds": 1.7999, "details": { "stations": "16785425ba8f8301abc9f1acb9e88aaaddfcf45a4ac6adef2e377d5d237a58b8", "facade_openings": "c1d4f5bdb65be2a10c45629adf7fc549459e2b123e6dc1002ee3c2bf7cda8506", "station_count": 12, "window_count": 40, "window_boxes": 22 } }
new-pair-2-7建造成功7410249377268
查看数据
{ "label": "new-pair-2-7", "inputs": { "environment_seed": 4102, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.3, 0.13, 0.09, 5.333154877072996 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.02, 4 ] }, { "op": "radial", "args": [ 18, 18, 36, 0.5 ] } ] }, { "op": "radial", "args": [ 8, 10, 44, 0.6 ] } ] }, 2, 6 ] }, "water": 4, "digest": "17a14b8b8ee4263f9c770f7b0dbb6ecb483dea3c0f72530310f28689db99427f", "structure_seed": 7, "garden": false }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "72e7d7e84c7821f60d48663490fe12ac0b55fb07f709e3b3bf93c632d8b46f12", "principal_signature": "c6355c35840d506d5a9b289a7de2ea16faeb40a24d0cfd8049d3fa357ab4de5f", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 26 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 0, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "ac58a23bade7310373b47f1e8f6e751c218827d6cb8b28d46e27b3f84563379a" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "a6f787436f38377ade78810d0cc70ce5c009268dafeca98b887d1b1291000357" ], [ "roof.profile", [ 26, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 26, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "99196cdad567087f649bc679b00253e86a6b19283e1079be2d3892e091e9d1a8" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 0, 13 ], "room.kitchen", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.library", [ "west", "east" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 0 ], "room.workshop", [ "south", "west" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 13 ], "room.storage", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 6, 0 ], "room.bedroom", [], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ] ] ], "contact": { "fill": 48, "excavation": 0, "sitework_occupied_cells": 54, "replaced_cells": 51, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "bdc923b5d979bd86ed3f7af7a273d914d4fd414e013d87dcc550f39c8af59d79", "bearing_fill": 0 }, "blocks": 49377, "nodes": 268, "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.56 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ], [ "right", 4, "existing upper volume" ] ] } ], "seconds": 3.2027, "details": { "stations": "2d185a0f0ccd9124f863de23c2599a41fb9e7dcdcb6fd5172a5dbd11e280624e", "facade_openings": "4b225fbde16bfd5797b93bcb726718ecb0e058e58314a6f46e99a51b712f7086", "station_count": 14, "window_count": 49, "window_boxes": 30 } }
new-pair-3-2建造成功2410345657231
查看数据
{ "label": "new-pair-3-2", "inputs": { "environment_seed": 4103, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.3, 0.13, 0.09, 0.5111599696578073 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.02, 4 ] }, { "op": "radial", "args": [ 18, 18, 36, 0.5 ] } ] }, { "op": "radial", "args": [ 8, 10, 44, 0.6 ] } ] }, 2, 6 ] }, "water": null, "digest": "8ac94e427f762dfd8328fba902c7e230565fc58407c48af9072dc64c3636dfed", "structure_seed": 2, "garden": false }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "c99e76f8fd3bac868e6ba5aa785b51b6d57db580b485d90dbe33036bcd0b33fe", "principal_signature": "b15515d944aab39ad72b80dcfb8b7d8f7d7a840f65746964c917d3deb54a1241", "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, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 32, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c1a11f0f69059d517411ef5e7e60a41e467ab257ac61a4baef00a61de4f2486e" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "f077435e219f2885917fcc7f32ff74239a4d66c67ab33ea3d3a2140859ebf277" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "65a63520d3754a281ba3f181431ede58eaaf05dd18704d58ec8d47b0a371d9e2" ], [ "roof.profile", [ 22, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c517627449fef556818812285f34a7a967540385454012fad9fecd7b6eeef1e5" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.kitchen", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.library", [ "west", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 11 ], "room.storage", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 32, "excavation": 0, "sitework_occupied_cells": 38, "replaced_cells": 3, "new_sitework_cells": 35, "strategies": [ "stepped" ], "signature": "5c7e2f17f4f56f9c6e465fb096bc01d0443407cffeb8b1e4a24d1c9321aaaac2", "bearing_fill": 0 }, "blocks": 45657, "nodes": 231, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.44 ], [ 1, 0.78 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-3/cover", "dormers": [ [ "right", 4, "existing upper volume" ] ] } ], "seconds": 3.3106, "details": { "stations": "cf868a3f22c811cc98cbd36963c80fda618d70fe73571b25c71b609cd82efb88", "facade_openings": "c1d4f5bdb65be2a10c45629adf7fc549459e2b123e6dc1002ee3c2bf7cda8506", "station_count": 12, "window_count": 40, "window_boxes": 22 } }
new-pair-3-7建造成功7410347799268
查看数据
{ "label": "new-pair-3-7", "inputs": { "environment_seed": 4103, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 4 ] }, { "op": "wave", "args": [ 0.3, 0.13, 0.09, 0.5111599696578073 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.02, 4 ] }, { "op": "radial", "args": [ 18, 18, 36, 0.5 ] } ] }, { "op": "radial", "args": [ 8, 10, 44, 0.6 ] } ] }, 2, 6 ] }, "water": null, "digest": "8ac94e427f762dfd8328fba902c7e230565fc58407c48af9072dc64c3636dfed", "structure_seed": 7, "garden": false }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "34af32119046a44835a45bd73ab6cb7435d50c0d61563fae5aa47ed328c27d72", "principal_signature": "c6355c35840d506d5a9b289a7de2ea16faeb40a24d0cfd8049d3fa357ab4de5f", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 26 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 0, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "ac58a23bade7310373b47f1e8f6e751c218827d6cb8b28d46e27b3f84563379a" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "a6f787436f38377ade78810d0cc70ce5c009268dafeca98b887d1b1291000357" ], [ "roof.profile", [ 26, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 26, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "99196cdad567087f649bc679b00253e86a6b19283e1079be2d3892e091e9d1a8" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 0, 13 ], "room.kitchen", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.library", [ "west", "east" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 0 ], "room.workshop", [ "south", "west" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 13 ], "room.storage", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 6, 0 ], "room.bedroom", [], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ] ] ], "contact": { "fill": 46, "excavation": 0, "sitework_occupied_cells": 52, "replaced_cells": 3, "new_sitework_cells": 49, "strategies": [ "stepped" ], "signature": "89f84ae2325499b0a1b5f9afea768966d694f939b28cad1fb8b0f8e089e9d849", "bearing_fill": 0 }, "blocks": 47799, "nodes": 268, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 0.58 ], [ 1, 0.88 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ], [ "right", 4, "existing upper volume" ] ] } ], "seconds": 4.7829, "details": { "stations": "8d685ea9888d15d1a68f7a096c2af8cfd3b966c43c599db9e7561c989a290cce", "facade_openings": "4b225fbde16bfd5797b93bcb726718ecb0e058e58314a6f46e99a51b712f7086", "station_count": 14, "window_count": 49, "window_boxes": 30 } }
new-pair-4-2建造成功2410447550231
查看数据
{ "label": "new-pair-4-2", "inputs": { "environment_seed": 4104, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.025, -0.02, 4 ] }, { "op": "wave", "args": [ 0.3, 0.13, 0.09, 0.1223935432842791 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.02, 4 ] }, { "op": "radial", "args": [ 18, 18, 36, 0.5 ] } ] }, { "op": "radial", "args": [ 8, 10, 44, 0.6 ] } ] }, 2, 6 ] }, "water": 4, "digest": "3396f0ea8e525372bb7569c27f0a869dadd2a85402d9b636f1db196662175966", "structure_seed": 2, "garden": false }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "a2565c2934d34f2839af2a360a635dbecce1ad020b65d09e4b4cfb507050a6ef", "principal_signature": "b15515d944aab39ad72b80dcfb8b7d8f7d7a840f65746964c917d3deb54a1241", "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, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 32, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c1a11f0f69059d517411ef5e7e60a41e467ab257ac61a4baef00a61de4f2486e" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "f077435e219f2885917fcc7f32ff74239a4d66c67ab33ea3d3a2140859ebf277" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "65a63520d3754a281ba3f181431ede58eaaf05dd18704d58ec8d47b0a371d9e2" ], [ "roof.profile", [ 22, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c517627449fef556818812285f34a7a967540385454012fad9fecd7b6eeef1e5" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.kitchen", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.library", [ "west", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 11 ], "room.storage", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 0, "excavation": 0, "sitework_occupied_cells": 6, "replaced_cells": 3, "new_sitework_cells": 3, "strategies": [ "stepped" ], "signature": "06ea11357cb8ebe51ce59a9fb3cc90529f7cb8ae0970b083ee967bea669e7676", "bearing_fill": 0 }, "blocks": 47550, "nodes": 231, "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-3/cover", "dormers": [ [ "right", 4, "existing upper volume" ] ] } ], "seconds": 2.9173, "details": { "stations": "cf868a3f22c811cc98cbd36963c80fda618d70fe73571b25c71b609cd82efb88", "facade_openings": "c1d4f5bdb65be2a10c45629adf7fc549459e2b123e6dc1002ee3c2bf7cda8506", "station_count": 12, "window_count": 40, "window_boxes": 22 } }
new-pair-4-7建造成功7410449678268
查看数据
{ "label": "new-pair-4-7", "inputs": { "environment_seed": 4104, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.025, -0.02, 4 ] }, { "op": "wave", "args": [ 0.3, 0.13, 0.09, 0.1223935432842791 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.02, 4 ] }, { "op": "radial", "args": [ 18, 18, 36, 0.5 ] } ] }, { "op": "radial", "args": [ 8, 10, 44, 0.6 ] } ] }, 2, 6 ] }, "water": 4, "digest": "3396f0ea8e525372bb7569c27f0a869dadd2a85402d9b636f1db196662175966", "structure_seed": 7, "garden": false }, "attempts": 2, "accepted_candidates": 1, "retries": 0, "status": "validated", "digest": "5e363e04215362581b38d9e8076c9d5bd55f5ee2ed3f4f800d0e9764730b3749", "principal_signature": "c6355c35840d506d5a9b289a7de2ea16faeb40a24d0cfd8049d3fa357ab4de5f", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 26 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 0, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "ac58a23bade7310373b47f1e8f6e751c218827d6cb8b28d46e27b3f84563379a" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "a6f787436f38377ade78810d0cc70ce5c009268dafeca98b887d1b1291000357" ], [ "roof.profile", [ 26, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 26, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "99196cdad567087f649bc679b00253e86a6b19283e1079be2d3892e091e9d1a8" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 0, 13 ], "room.kitchen", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.library", [ "west", "east" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 0 ], "room.workshop", [ "south", "west" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 13 ], "room.storage", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 6, 0 ], "room.bedroom", [], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ] ] ], "contact": { "fill": 14, "excavation": 0, "sitework_occupied_cells": 20, "replaced_cells": 17, "new_sitework_cells": 3, "strategies": [ "piers" ], "signature": "fb80c881bde38fa55e8c0941c1b873d9fa5ee92d53cf95840f36884843dad39c", "bearing_fill": 3 }, "blocks": 49678, "nodes": 268, "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, 0.54 ] ], "chosen": 1 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ], [ "right", 4, "existing upper volume" ] ] } ], "seconds": 2.9973, "details": { "stations": "2d185a0f0ccd9124f863de23c2599a41fb9e7dcdcb6fd5172a5dbd11e280624e", "facade_openings": "4b225fbde16bfd5797b93bcb726718ecb0e058e58314a6f46e99a51b712f7086", "station_count": 14, "window_count": 49, "window_boxes": 30 } }
new-pair-5-2建造成功2410543600231
查看数据
{ "label": "new-pair-5-2", "inputs": { "environment_seed": 4105, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.025, 0, 4 ] }, { "op": "wave", "args": [ 0.3, 0.13, 0.09, 1.299058974263774 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.02, 4 ] }, { "op": "radial", "args": [ 18, 18, 36, 0.5 ] } ] }, { "op": "radial", "args": [ 8, 10, 44, 0.6 ] } ] }, 2, 6 ] }, "water": null, "digest": "2f0f2680707f39505d74387868c1eebfe74f7a1a2a18e147ba8a18c1b206c553", "structure_seed": 2, "garden": false }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "9556c94f69f2aeb9d3f6110baa906714ce9051c7de62edf508aab79e2a67fe5f", "principal_signature": "b15515d944aab39ad72b80dcfb8b7d8f7d7a840f65746964c917d3deb54a1241", "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, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 13, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 17, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 0 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 22, 8, 17 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 10 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 32, 8, 13 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c1a11f0f69059d517411ef5e7e60a41e467ab257ac61a4baef00a61de4f2486e" ], [ "roof.profile", [ 0, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "f077435e219f2885917fcc7f32ff74239a4d66c67ab33ea3d3a2140859ebf277" ], [ "roof.profile", [ 11, 7, 0 ], { "axis": "x", "span": 11, "rise": [ 1, 2 ] }, "65a63520d3754a281ba3f181431ede58eaaf05dd18704d58ec8d47b0a371d9e2" ], [ "roof.profile", [ 22, 7, 11 ], { "axis": "z", "span": 11, "rise": [ 1, 2 ] }, "c517627449fef556818812285f34a7a967540385454012fad9fecd7b6eeef1e5" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 0, 11 ], "room.kitchen", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "892ab014ba1ce15bdcf3aeee00aa4f2ef05178ab6ed1bcecc15a72734df2513d" ], [ "room", [ 11, 0, 0 ], "room.library", [ "west", "east" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 0 ], "room.workshop", [ "south", "west" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ], [ "room", [ 22, 0, 11 ], "room.storage", [ "north" ], false, "d32081fa33421a8ea84c9b64181c3f6dcc8e44fc78b805693ea2aa0d1d417854" ] ] ], "contact": { "fill": 98, "excavation": 0, "sitework_occupied_cells": 105, "replaced_cells": 2, "new_sitework_cells": 103, "strategies": [ "stepped" ], "signature": "447d5e288aac00c23c2aafed1a9632056a239663a32e58d16fd41872eff9d521", "bearing_fill": 0 }, "blocks": 43600, "nodes": 231, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 1.09 ], [ 1, 1.23 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-3/cover", "dormers": [ [ "right", 4, "existing upper volume" ] ] } ], "seconds": 2.6457, "details": { "stations": "cf868a3f22c811cc98cbd36963c80fda618d70fe73571b25c71b609cd82efb88", "facade_openings": "c1d4f5bdb65be2a10c45629adf7fc549459e2b123e6dc1002ee3c2bf7cda8506", "station_count": 12, "window_count": 40, "window_boxes": 22 } }
new-pair-5-7建造成功7410545757268
查看数据
{ "label": "new-pair-5-7", "inputs": { "environment_seed": 4105, "expression": { "op": "clamp", "args": [ { "op": "blend", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.025, 0, 4 ] }, { "op": "wave", "args": [ 0.3, 0.13, 0.09, 1.299058974263774 ] } ] }, { "op": "add", "args": [ { "op": "gradient", "args": [ -0.02, 0.02, 4 ] }, { "op": "radial", "args": [ 18, 18, 36, 0.5 ] } ] }, { "op": "radial", "args": [ 8, 10, 44, 0.6 ] } ] }, 2, 6 ] }, "water": null, "digest": "2f0f2680707f39505d74387868c1eebfe74f7a1a2a18e147ba8a18c1b206c553", "structure_seed": 7, "garden": false }, "attempts": 2, "accepted_candidates": 2, "retries": 0, "status": "validated", "digest": "3510b77293f6ee7b3a3180e1ad3069d7a9cee61c0d24fdc8163fdd4697ea3cc3", "principal_signature": "c6355c35840d506d5a9b289a7de2ea16faeb40a24d0cfd8049d3fa357ab4de5f", "architecture": [ [ [ "attachment.porch", [ 0, 0, 0 ], { "balcony": true, "depth": 4, "width": 13 } ], [ "masonry.chimney", [ 5, 0, 26 ], { "height": 20, "function": "exterior flue; no simulated indoor heating" } ], [ "roof.dormer", [ 0, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 0, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 12, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 14, 6 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 26, 8, 19 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 14, 2 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.dormer", [ 38, 8, 15 ], { "tops": [ 4, 4, 4 ] }, "dd9c85cd0d20647f0444db8c76bad9c20e46e7a2f6ca3657bab7a188021b66fc" ], [ "roof.profile", [ 0, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 0, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "ac58a23bade7310373b47f1e8f6e751c218827d6cb8b28d46e27b3f84563379a" ], [ "roof.profile", [ 13, 7, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "a6f787436f38377ade78810d0cc70ce5c009268dafeca98b887d1b1291000357" ], [ "roof.profile", [ 26, 13, 0 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "1cbf65e26cd44a39e28bb245d5b836218b74556c6053e0fa2dc3b159ab48f8a7" ], [ "roof.profile", [ 26, 7, 13 ], { "axis": "z", "span": 13, "rise": [ 1, 1, 2 ] }, "99196cdad567087f649bc679b00253e86a6b19283e1079be2d3892e091e9d1a8" ], [ "room", [ 0, 0, 0 ], "room.living", [ "north", "south", "east" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 0, 13 ], "room.kitchen", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 0, 6, 0 ], "room.bedroom", [ "north" ], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ], [ "room", [ 13, 0, 0 ], "room.library", [ "west", "east" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 0 ], "room.workshop", [ "south", "west" ], true, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 0, 13 ], "room.storage", [ "north" ], false, "7c20fb3ec0b0e97b6766d63bba6e816ae797e2daf8b22eb6bdab41cbda0319b1" ], [ "room", [ 26, 6, 0 ], "room.bedroom", [], false, "e6a1b2f4b7cc518b62b00c9003fe72b80b3ad927b612e3997ba5f526adb421eb" ] ] ], "contact": { "fill": 125, "excavation": 0, "sitework_occupied_cells": 133, "replaced_cells": 1, "new_sitework_cells": 132, "strategies": [ "stepped" ], "signature": "f631de76958ac2167b4090eed37db52b886e7acfb6527b4dcf5cd5aaff9874d7", "bearing_fill": 0 }, "blocks": 45757, "nodes": 268, "candidates": [ { "kind": "candidate-selection", "component": "/building", "attempts": 2, "accepted": 2, "rejected": [], "scores": [ [ 0, 1.35 ], [ 1, 1.41 ] ], "chosen": 0 } ], "optional_omissions": [ { "component": "/building/roof-0/cover", "dormers": [ [ "left", 4, "existing upper volume" ], [ "right", 4, "existing upper volume" ] ] } ], "seconds": 3.6262, "details": { "stations": "8d685ea9888d15d1a68f7a096c2af8cfd3b966c43c599db9e7561c989a290cce", "facade_openings": "4b225fbde16bfd5797b93bcb726718ecb0e058e58314a6f46e99a51b712f7086", "station_count": 14, "window_count": 49, "window_boxes": 30 } }

选了 22 对建筑文件与配套记录做完整保存检查,涉及 5,635 个部件、5,213 次非空部件查询、895 个带物品数据的方块。默认命令和编号 1 的村落另做检查,共比较 1,663 个部件的下属方块集合。不是说所有可能随机结果都已检查。文件检查统计 · 两个命令输出的检查。

08 · 开发中错在哪里,哪些还没解决

第一次完整测试有 7 项失败,后来完整重跑 230 项全部通过。7 是失败的测试用例数,不是 7 种建筑都坏了。 其中四项来自同一个天花木梁归属问题,两项是新测试自己的错误预期,另一项是真正的屋顶碰花箱问题。

问题或限制 哪一层负责 最后怎样处理
一根烟囱让整面后墙不开窗 立面和房屋组合规则 只给烟囱保留必要空间,在两侧安排窗。属于过于粗糙的旧规则
天花木梁未归属到房间,四个方向的测试都失败 部件安装方式 原本用“连接”关系,改成“安装到房间”,且不允许替换已有方块。内核不需要改
新测试认为加整个庭院后,入口连接点归属也必须完全不变 新测试代码 庭院接路会合理地改变连接点;改用只种边界植物的案例验证房子不被改动
新测试期待错误在后面的阶段才报出 新测试代码 非法参数在更早的输入检查阶段就会被拒绝;修正新测试的预期,没有放松库的检查
村落编号 4:低处陡屋顶碰到高两层的花箱 共享房屋布局规则 原规则只看下一层,现在检查所有更低楼层的屋顶,必要时省略会相撞的可选窗,并记录原因;保留必需房间与屋顶意图。补完后重跑旧案例、全套测试和全部最终试建
早期花箱边框、门廊与高窗发生投影冲突 部件尺寸声明和相邻部件协调 明确花箱实际伸出范围,统一窗、墙和房屋声明的边界,避开门廊与屋顶
家具和栏杆在图中像是没画出来 材料与显示对比,针对检查过的样本 几何存在;临时染色定位后,正常成品改用对比更清楚的材料。不是删方块或改渲染器来过验收
最终 11 次困难输入没造出来 当前接地能力范围 高差超限,两个现有方案都拒绝。没有扩大支持范围,仍是实际限制
水边房子没有通向岸边的连接 高层场景尚未安排外部交通 局部房子通过不等于整片场景能到达岸边,报告明确保留这一点
U 形后院没有屋内直达门,阁楼不能住 当前高层设计与房屋能力 未实现;不能因房屋通过已有检查就假定具备这些功能

这些错误集中在部件如何摆放、如何绑定和新测试的预期,没有证据表明本轮必须推翻原架构。模型也未触发“发现严重架构问题就停工报告”的条件。但不改内核,只能说明本轮这些改进能做,不能证明任意复杂城市都能靠现有接口完成。

第一次完整测试日志 · 最终完整测试日志 · 模型的详细评估。离参考图还有距离的原因,不全是渲染:房间比例、屋顶变化、花园层次和建筑与环境的整体安排,都还需要继续设计。

09 · 运行时间和用量

第四轮从启动到验收与归档结束,共 67.19 分钟。仍使用原会话、gpt-6-astra、max 设置、kokemeow 账号、4 个 CPU 和 8 GiB 内存。这不是在网页里生成一栋房子的时间。

本轮新增用量数值
模型请求97
输入 Token(含缓存)15,314,141
其中缓存输入14,914,944
输出 Token(含推理)98,585
其中推理输出34,804
输入与输出合计15,412,726
命令记录125
命令非零退出码9

以上只算第四轮新增的模型用量。Token 是处理文字的计量单位,不等于汉字数;缓存输入包含在输入总量里,推理输出也包含在输出总量里,不能重复相加。原用量记录。

非零退出的命令可能是发现真实缺陷,也可能是故意测试错误输入,不能拿它的数量当作最终失败建筑数。本轮命令记录。报告制作时另跑的测试和浏览器操作,不计入实验的这些用量。

10 · 这次实际发了什么任务

本轮发送的完整文本只有:

continue

它通过原会话续跑,没有把第一轮任务再次贴进去。第三轮曾完整重申第一轮任务,并追加“优先打磨单栋建筑,严重架构问题先报告并停工”。从第四轮的实际行动和最终回复看,它继续围绕这些要求工作。

这不表示模型永远记得历史中每个字;会话仍可能经过上下文压缩。这里能确认的是使用同一个保存的会话,并且本轮输入严格只有 continue。

本轮输入 · 第一轮完整任务 · 第三轮实际发送的任务 · 两组原参考文件来源与校验值。参考用于审美结果,不要求照搬参考程序的实现结构。

11 · 模型结束时的原话

以下是原始会话中标为最终回复的消息,与结束事件保存的消息核对一致。不是报告作者替它拟的总结。英文原文下载 · 来源和时间记录。

中文翻译

已完成建筑改进:适配烟囱的后窗、带框花箱、不同用途的家具、天花木梁、沿房屋布置的植物,以及可用随机编号变化的 U 形庭院住宅组合。

新的公开接口包括窗边种植、天花装饰和占地边界。内核、保存协议、命令行入口,以及此前全部 200 项测试都保持不变;使用者无需了解内部几何细节。

已验证:

建筑的丰富程度仍低于 lodge 参考图:规整的房间模数、重复的屋顶、不能居住的阁楼,以及较简单的景观,仍是限制。没有发现严重的架构缺陷。

末尾附了评估、预览、默认建筑文件和配套记录的路径。

英文完整原文

Implemented the building improvements: fitted rear windows, framed flower boxes, distinct furnishings, ceiling timbers, planted borders, and a seeded U-shaped garden-house composition. New public interfaces cover window gardens, ceiling decoration, and footprint boundaries. The kernel, persistence, CLI, and all 200 earlier tests remain unchanged; clients need no private geometry knowledge. Verified: - **230 tests passed** - **124/124 supported inputs validated** - **5/16 stress inputs succeeded**, with all 11 limit failures retained - **25 exterior and cutaway renders inspected** - Paired reload and hash-seed replay passed Buildings remain below the lodge references in richness: regular bays, repetitive roofs, nonhabitable attics, and simpler landscaping remain constraints. No serious architectural flaw was found. [Assessment](/work/generator/workspace/reports/building-detail/ASSESSMENT.md) · [Previews](/work/generator/workspace/previews/building-detail/README.md) · [Default schematic](/work/generator/workspace/output.litematic) · [Companion](/work/generator/workspace/output.litematic.structure.json)

英文中的 /work/generator/workspace/... 是原容器路径,按原样保留。对应网页内容可看评估、图片和默认建筑下载。本轮模型没有交付新的浏览器执行记录;上面的在线验证由报告另做。

12 · 代码、下载和原始证据

本轮工具、示例和测试共 86 个 Python 文件、8149 行。报告中的控件、Python 运行桥接和查看器不算模型交付的库代码。网页执行的是这一轮归档中的原程序,文件有校验值,报告没有替模型修库。

自己的在线生成结果,可以下载完整建筑、部件关系、调用代码和参数。请一起保存;只有建筑文件,无法恢复这套实验中的部件归属关系。

全部源码文件列表

源码行数
generate.py21
hearth/space.py109
hearth/blocks.py83
hearth/randomness.py21
hearth/__init__.py8
hearth/persistence.py194
hearth/composition.py61
hearth/programs.py185
hearth/assessment.py163
hearth/lodges.py54
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.py205
hearth/components/__init__.py9
hearth/components/interior.py223
hearth/components/roofs.py161
hearth/components/building.py228
hearth/components/constraints.py19
hearth/components/landscape.py259
hearth/components/roofcraft.py261
hearth/components/joinery.py39
hearth/components/furnishing.py127
hearth/components/masonry.py32
hearth/components/grounds.py108
hearth/components/facades.py45
hearth/components/domestic.py70
hearth/components/borders.py99
hearth/components/windowbox.py46
hearth/components/ceiling.py42
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/garden_house.py33
examples/building_detail.py94
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_detail.py221
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.4.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.components.facades import FacadeDesign 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)), facade_design=FacadeDesign(), rail_material='dark_oak')) 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.facades import FacadeDesign 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, facade_design=FacadeDesign(), rail_material='dark_oak') 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, facade_design=FacadeDesign(), rail_material='dark_oak') 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, facade_design=FacadeDesign(), rail_material='dark_oak') 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',), version='2') 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()) from math import ceil # Each branch tier tapers over two layers, separated by exposed trunk. # Radius follows remaining crown height, preserving a pointed silhouette. layers = {h: 0, h - 1: 1} for base in range(3, h, 3): r = min(radius, ceil(radius * (h - base) / max(1, h - 3))) layers[base] = r if base + 1 < h: layers[base + 1] = max(0, r - 1) for y, r in sorted(layers.items()): for x in range(-r, r + 1): for z in range(-r, r + 1): if abs(x) + abs(z) > r 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' planter: bool = False garden_depth: int = 1 def capability(self): return Capability('window.shuttered' if self.shutters else 'window.lattice', ('window', 'sealed-opening'), offers=('daylight', 'window-garden'), adaptations=('depth reveal',), guarantees=('sealed opening', 'frame margins'), version='2') 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) if self.garden_depth not in (1, 2): raise ContractError('window-garden-depth', ctx.path) depth = port.facts['thickness'] box = Box((-1, -1, -self.garden_depth), (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') garden = Box((-1 if self.garden_depth == 2 else 0, -1, -self.garden_depth), (self.width if self.garden_depth == 2 else self.width - 1, 0, -1)) port = Port('garden', 'window-garden', Frame((0, -1, -1)), garden, 1, 'planting', facts={'width': self.width, 'depth': self.garden_depth}) grant = Grant('planting', garden, ('install',), ('planter',), (self.width + 2) * 4) return Contract(box, ports=(port,), grants=(grant,), rules=(Rule('sealed', tuple(inner.cells())),), decisions={'depth': depth, 'planter': self.planter}) 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') if self.planter: from .windowbox import WindowBox p.children.append(Child('box', WindowBox(), frame=Frame((0, -1, -1)), bindings=(Binding(ctx.path, 'garden'),))) 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 from .facades import FacadeDesign from .domestic import DomesticSuite from .windowbox import WindowBox from .borders import GardenPlant, BoundaryPlanting from .ceiling import CeilingTimbers
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, ...] = () facade_exclusions: tuple[Box, ...] = () facade_design: object = None occluded_sides: tuple[str, ...] = () def capability(self): return Capability('room.' + self.purpose, ('room', 'habitable', 'composite'), offers=('access', 'ceiling-decoration'), 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'), version='2') 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) ceiling = Box((0, 5, 0), (w - 1, 5, d - 1)) ports += (Port('ceiling', 'ceiling-decoration', Frame((0, 5, 0)), ceiling, 4, 'ceiling-mount', facts={'width': w, 'depth': d, 'projection': 1, 'replace_limit': 0}),) grants = (Grant('ceiling-mount', ceiling, ('install',), ('ceiling-trim',), 0),) projection = 2 if self.facade_design and self.facade_design.planters else 1 return Contract(Box((-projection, 0, -projection), (w - 1 + projection, 9, d - 1 + projection)), ports=ports, grants=grants, 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, 'facade_exclusions': [(b.lo, b.hi) for b in self.facade_exclusions], 'facade_projection': projection, 'omitted_optional_facades': {s: 'conservative lower roof envelope' for s in self.occluded_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: from .facades import FacadeDesign layout = self.facade_design or FacadeDesign(height=2, sill=2, planters=False) for i, opening in enumerate(layout.openings(length, frame, side in self.doors, self.facade_exclusions)): at = frame.compose(Frame(opening['at'])) flush = opening['flush'] or side in self.flush_sides window = self.window_component or (FlushWindow(opening['width'], opening['height']) if flush else Window(opening['width'], opening['height'], planter=layout.planters, garden_depth=2 if layout.planters else 1)) p.children.append(Child(f'window-{side}-{i}', 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: from .facades import local_exclusions p.children.append(Child('joinery-' + side, FacadeRelief(length, access=side in self.doors, exclusions=local_exclusions(self.facade_exclusions, frame)), 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), self.facade_exclusions))) 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 rail_material: str = 'spruce' 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 or self.rail_material not in ('spruce', 'dark_oak'): 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': [self.rail_material + '_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(self.rail_material + '_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 facade_design: object = None rail_material: str = 'spruce' 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.rail_material not in ('spruce', 'dark_oak'): raise ValueError('Rail material must be spruce or dark_oak') 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', 'footprint-boundary'), 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'), version='2') 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) projection = 2 if self.design.facade_design and self.design.facade_design.planters else 1 box = Box((-projection, min(minimum - self.site_limits.bed_thickness + 1, 0), -front), (width - 1 + projection, floor + height + b + 16, depth + (3 if self.design.chimney else projection - 1))) 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')) footprint = set(self.design.contact_footprint) edge = tuple((x, 0, z) for x, z in sorted(footprint) if any((x + dx, z + dz) not in footprint for dx, dz in ((1, 0), (-1, 0), (0, 1), (0, -1)))) boundary = Port('garden-edge', 'footprint-boundary', Frame(), Box.enclosing(edge), 100, facts={'outline': edge, 'coordinate_space': 'port-local', 'planting_authority': 'requires terrain planting binding'}) return Contract(box, ports=(port, street, boundary), 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)} peak = max(self.design.roof_design.heights(b)) if self.design.roof_design else ((b + 1) // 2 if self.design.steep else ((b + 1) // 2 + 1) // 2) 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)}))) # A steep roof can reach more than one storey of its neighbor. Use # every lower roof's public height profile, not a level-1 shortcut. contacts = {side: [(lower, axis) for (rx, rz, lower), axis in roof_axes.items() if (rx, rz) == (x, z) and lower < r.level and lower * 6 + 7 + peak >= r.level * 6 + 1] for side, (x, z, _) in adjacent.items()} abutments = {side for side, roofs in contacts.items() if any(axis == ('z' if side in ('north', 'south') else 'x') for _, axis in roofs)} windows = tuple(side for side, q in adjacent.items() if q not in cells and side not in abutments) exclusions = () if self.design.chimney: cx, cz = self.design.chimney_anchor exclusions = (Box((cx - r.x * b, 0, cz - r.z * b - 1), (cx - r.x * b + 2, 9, cz - r.z * b + 1)),) key = f'room-{r.x}-{r.z}-{r.level}' flush = tuple(side for side, roofs in contacts.items() if roofs) if self.design.porch and (r.x, r.z, r.level) == (0, 0, 1): flush = tuple(sorted(set(flush) | {'north'})) room = Room(r.purpose, b, b, doors=doors, windows=windows, upper_open=(r.x, r.z, r.level + 1) in cells, stair_up=(r.x, r.z, r.level) in stair_columns, stair_down=(r.x, r.z, r.level - 1) in stair_columns, window_component=self.design.window_component, light_component=self.design.light_component, sheltered_sides=('north',) if self.design.porch and r.x == 0 and r.z == 0 and r.level <= 1 else (), flush_sides=flush, facade_exclusions=exclusions, facade_design=self.design.facade_design, occluded_sides=tuple(sorted(abutments))) p.children.append(Child(key, room, frame=Frame((r.x * b, floor + r.level * 6, r.z * b)))) from .ceiling import CeilingTimbers for r in rooms: key = f'room-{r.x}-{r.z}-{r.level}' p.children.append(Child('ceiling-' + key, CeilingTimbers(), frame=Frame((r.x * b, floor + r.level * 6 + 5, r.z * b)), bindings=(Binding(ctx.path + '/' + key, 'ceiling'),))) if self.design.porch: p.children.append(Child('porch', Porch(b, self.design.porch_depth, self.design.balcony, self.design.rail_material), 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, ...] exclusions: tuple[Box, ...] = () 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' and not any(b.contains(q) for b in self.exclusions): 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' and not any(b.contains(q) or b.contains(above) for b in self.exclusions): 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 exclusions: tuple[Box, ...] = () 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' and not any(b.contains(q) for b in self.exclusions)] 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)) suites = {'living': ('gathering', 'study'), 'bedroom': ('study', 'cabinet'), 'library': ('study', 'gathering'), 'kitchen': ('cooking', 'gathering'), 'workshop': ('craft', 'cabinet'), 'storage': ('cabinet', 'craft')} station_order = list(suites[self.purpose]) if ctx.rng('station-arrangement').choice((False, True)): station_order.reverse() 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], 'stations': station_order if table_frames else []}) 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']): from .domestic import DomesticSuite p.children.append(Child('station-' + str(i), DomesticSuite(contract.decisions['stations'][i], 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)))) from .borders import BoundaryPlanting p.children.append(Child('borders', BoundaryPlanting(self.building, self.terrain))) return p
hearth/components/facades.py
# Shared facade planning against explicit local service and framing exclusions. from dataclasses import dataclass from hearth import Box, Frame @dataclass(frozen=True) class FacadeDesign: """Arrange aligned openings while preserving local reserved volumes. Exclusions use room coordinates. They reserve design space for later children; they never grant write permission. The enclosing composition still validates all actual writes and affected contracts transactionally. """ height: int = 3 sill: int = 1 width: int = 2 planters: bool = True def openings(self, length, frame=Frame(), access=False, exclusions=()): if self.height not in (2, 3) or self.width not in (1, 2) or self.sill < 1 or self.sill + self.height > 4: raise ValueError('Facade openings require width 1..2, height 2..3, sill >=1 and top <=3') door = Box((length // 2 - 1, 0, -1), (length // 2 + 1, 1, 0)) if access else None candidates = [] for x in range(1, length - self.width): inner = Box((x, self.sill, 0), (x + self.width - 1, self.sill + self.height - 1, 0)) exterior = Box((x - 1, self.sill - 1, -2 if self.planters else -1), (x + self.width, self.sill + self.height - 1, 0)) if any(frame.box(inner).intersection(b) for b in exclusions) or (door and inner.intersection(door)): continue flush = any(frame.box(exterior).intersection(b) for b in exclusions) or bool(door and exterior.intersection(door)) candidates.append({'at': (x, self.sill, 0), 'width': self.width, 'height': self.height, 'flush': flush}) desired = 2 if length >= 9 else 1 targets = (2 if length >= 11 else 1, length - self.width - (2 if length >= 11 else 1)) if desired == 2 else ((length - self.width) // 2,) chosen = [] for target in targets: feasible = [c for c in candidates if all(abs(c['at'][0] - q['at'][0]) >= self.width + 1 for q in chosen)] if not feasible: continue c = min(feasible, key=lambda q: (abs(q['at'][0] - target), q['flush'], q['at'][0])) chosen.append(c) return tuple(sorted(chosen, key=lambda q: q['at'][0])) def local_exclusions(exclusions, frame): """Convert enclosing design reservations into a child's local coordinates.""" return tuple(Box.enclosing(frame.inverse(p) for p in b.corners()) for b in exclusions)
hearth/components/domestic.py
# Purpose-specific interior stations with explicit, protected interaction aprons. from dataclasses import dataclass from hearth import Box, Frame, ContractError from hearth.kernel import Capability, Contract, Domain, Port, Rule, Plan from hearth.blocks import state_of, slab, stairs from .furnishing import supplies @dataclass(frozen=True) class DomesticSuite: """A compact room station substitutable through its interaction interface.""" purpose: str width: int = 3 def capability(self): return Capability('furnishing.suite.' + self.purpose, ('furniture', 'station'), inputs={'width': Domain(choices=(2, 3)), 'purpose': Domain(choices=('gathering', 'study', 'cooking', 'craft', 'cabinet'))}, offers=('interaction',), guarantees=('supported station', 'two-block interaction apron', 'actual function')) def negotiate(self, ctx, parameters): if self.width not in (2, 3) or self.purpose not in ('gathering', 'study', 'cooking', 'craft', 'cabinet'): raise ContractError('domestic-suite-domain', ctx.path) apron = Box((0, 0, 2), (self.width - 1, 1, 2)) area = Box((0, 0, 0), (self.width - 1, 2, 2)) function = {'gathering': [['dark_oak_stairs'], ['birch_pressure_plate']], 'study': [['bookshelf'], ['lectern']], 'cooking': [['smoker'], ['water_cauldron']], 'craft': [['crafting_table'], ['anvil']], 'cabinet': [['barrel']]} return Contract(area, ports=(Port('use', 'interaction', Frame((0, 0, 2)), apron, 4),), rules=(Rule('support', tuple((x, -1, z) for x in range(self.width) for z in range(3))), Rule('clear', tuple(apron.cells())), Rule('furnishing', box=area, data={'groups': function[self.purpose]}, phase='complete')), decisions={'purpose': self.purpose, 'width': self.width}, atomic_object=True) def realize(self, ctx, contract): p, w = Plan(), self.width barrel = state_of('barrel', facing='south', open='false') if self.purpose == 'gathering': for x in range(w): p.block((x, 0, 0), stairs('dark_oak', 'north'), 'settee') if x != w // 2: p.block((x, 0, 1), state_of('yellow_carpet'), 'hearth-rug') p.block((w // 2, 0, 1), state_of('dark_oak_fence', north='false', south='false', east='false', west='false', waterlogged='false'), 'table-base') p.block((w // 2, 1, 1), state_of('birch_pressure_plate', powered='false'), 'tabletop') elif self.purpose == 'study': for x in range(w): p.block((x, 0, 0), state_of('bookshelf'), 'bookcase') if x in (0, w - 1): p.block((x, 1, 0), state_of('bookshelf'), 'bookcase') p.block((x, 2, 0), slab('dark_oak'), 'bookcase-cornice') p.block((0, 0, 1), state_of('lectern', facing='south', has_book='false', powered='false'), 'reading-desk') p.block((w - 1, 0, 1), stairs('dark_oak', 'north'), 'reading-seat') elif self.purpose == 'cooking': for x in range(w): material = state_of('smoker', facing='south', lit='false') if x == 0 else state_of('water_cauldron', level='3') if x == w - 1 else barrel p.block((x, 0, 0), material, 'cooking-counter', nbt=supplies() if x not in (0, w - 1) else None) p.block((x, 2, 0), slab('dark_oak', 'top'), 'pot-shelf') p.block((0, 1, 0), state_of('iron_trapdoor', facing='north', half='top', open='false', powered='false', waterlogged='false'), 'stove-hood') p.block((0, 0, 1), state_of('crafting_table'), 'preparation') p.block((w - 1, 0, 1), state_of('brown_carpet'), 'work-mat') elif self.purpose == 'craft': for x in range(w): p.block((x, 0, 0), state_of('crafting_table' if x == 0 else 'smithing_table'), 'workbench') p.block((x, 2, 0), slab('dark_oak', 'top'), 'tool-shelf') p.block((0, 0, 1), state_of('anvil', facing='north'), 'anvil') p.block((w - 1, 0, 1), barrel, 'supplies', nbt=supplies()) else: for x in range(w): for y in range(2): p.block((x, y, 0), barrel, 'cabinet', nbt=supplies()) p.block((x, 2, 0), slab('dark_oak'), 'cabinet-cornice') p.block((x, 0, 1), state_of('brown_carpet'), 'storage-runner') return p
hearth/components/borders.py
# Ground-supported planting from public boundary geometry and measured free space. from dataclasses import dataclass from hearth import Box, Frame, ContractError from hearth.kernel import Capability, Contract, Domain, Rule, Port, Plan, Child, Binding from hearth.blocks import name_of, state_of @dataclass(frozen=True) class GardenPlant: species: str = 'fern' def capability(self): return Capability('plant.garden.' + self.species, ('plant', 'garden'), inputs={'species': Domain(choices=('fern', 'azalea', 'flowering_azalea', 'poppy', 'allium', 'rose_bush'))}, assumptions=('actual soil support',), guarantees=('whole plant', 'supported')) def negotiate(self, ctx, parameters): if self.species not in ('fern', 'azalea', 'flowering_azalea', 'poppy', 'allium', 'rose_bush'): raise ContractError('garden-plant-domain', ctx.path) if name_of(ctx.state((0, -1, 0))) not in ('grass_block', 'dirt', 'coarse_dirt', 'podzol', 'rooted_dirt', 'moss_block'): raise ContractError('planting-substrate', ctx.path, ctx.world((0, -1, 0))) height = 2 if self.species == 'rose_bush' else 1 return Contract(Box((0, 0, 0), (0, height - 1, 0)), rules=(Rule('support', ((0, -1, 0),)), Rule('expected', tuple((0, y, 0) for y in range(height)), data={'names': [self.species]})), atomic_object=True) def realize(self, ctx, contract): p = Plan() if self.species == 'rose_bush': for y, half in enumerate(('lower', 'upper')): p.block((0, y, 0), state_of(self.species, half=half), 'plant') else: p.block((0, 0, 0), state_of(self.species), 'plant') return p @dataclass(frozen=True) class BoundaryPlanting: """Plant a soft border near a discovered footprint; never excavate or fill.""" host: str terrain: str density: float = .55 minimum_distance: int = 2 maximum_distance: int = 4 def capability(self): return Capability('garden.boundary-border', ('garden', 'composite'), assumptions=('footprint-boundary interface',), adaptations=('actual soil and clearance', 'cluster density'), inputs={'density': Domain(0, 1), 'minimum_distance': Domain(1, 6), 'maximum_distance': Domain(1, 6)}, guarantees=('no terrain edits', 'retained paths and existing consumers')) def negotiate(self, ctx, parameters): if not 0 <= self.density <= 1 or not 1 <= self.minimum_distance <= self.maximum_distance <= 6: raise ContractError('border-domain', ctx.path) ports = ctx.view.offers(self.host, 'footprint-boundary') if not ports: raise ContractError('planting-boundary-interface', ctx.path, conditions='Host must expose a footprint-boundary port') port = ports[0] points = tuple(ctx.local(port.frame.point(tuple(q))) for q in port.facts['outline']) radius = self.maximum_distance box = Box.enclosing(points).expand(radius) # Surface observations determine height, not the boundary's nominal Y. candidates, rejected = [], {'unknown': 0, 'substrate': 0, 'occupied_or_protected': 0} edge = {(x, z) for x, _, z in points} for x in range(box.lo[0], box.hi[0] + 1): for z in range(box.lo[2], box.hi[2] + 1): distance = min(abs(x - a) + abs(z - b) for a, b in edge) if not self.minimum_distance <= distance <= radius: continue # A stable field creates patches instead of a uniform perimeter hedge. patch = ctx.scope.child(f'patch-{x // 3}-{z // 3}').stream('density').uniform(.2, 1) rng = ctx.scope.child(f'cell-{x}-{z}').stream('planting') if rng.random() > self.density * patch: continue wp = ctx.world((x, 0, z)) if ctx.view.domain and not (ctx.view.domain.lo[0] <= wp[0] <= ctx.view.domain.hi[0] and ctx.view.domain.lo[2] <= wp[2] <= ctx.view.domain.hi[2]): rejected['unknown'] += 1 continue y = ctx.elevation(x, z) + 1 if name_of(ctx.state((x, y - 1, z))) not in ('grass_block', 'podzol', 'dirt'): rejected['substrate'] += 1 continue area = Box((x, y, z), (x, y + 1, z)) if not all(ctx.view.domain.contains(ctx.world(q)) for q in area.corners()): rejected['unknown'] += 1 continue if any(name_of(ctx.state(q)) != 'air' for q in area.cells()) or ctx.view.protected(ctx.frame.box(area)): rejected['occupied_or_protected'] += 1 continue species = rng.choice(('fern', 'fern', 'azalea', 'flowering_azalea', 'poppy', 'allium', 'rose_bush')) candidates.append(((x, y, z), species)) bounds = Box.enclosing([*points, *(p for p, _ in candidates), *((p[0], p[1] + 1, p[2]) for p, _ in candidates)]) return Contract(bounds, decisions={'plants': candidates, 'rejected': rejected, 'optional_minimum': 0, 'outline': points}) def realize(self, ctx, contract): p = Plan() for q, species in contract.decisions['plants']: p.children.append(Child(f'plant-{q[0]}-{q[2]}', GardenPlant(species), frame=Frame(tuple(q)), bindings=(Binding(self.terrain, 'planting', 'plant'),))) p.relations.append((ctx.path, 'landscapes', self.host)) return p
hearth/components/windowbox.py
# Window-mounted planting with scoped sill replacement and actual masonry anchors. from dataclasses import dataclass from hearth import Box, ContractError from hearth.kernel import Capability, Contract, Plan, Rule from hearth.blocks import state_of @dataclass(frozen=True) class WindowBox: flowers: tuple[str, ...] = ('poppy', 'cornflower', 'oxeye_daisy') def capability(self): return Capability('garden.window-box', ('planter', 'plant', 'attachment'), assumptions=('window garden mounting interface',), guarantees=('soil supports flowers', 'wall anchors', 'within negotiated facade projection')) def negotiate(self, ctx, parameters): if len(ctx.bindings) != 1: raise ContractError('window-box-host', ctx.path) port = ctx.view.port(ctx.bindings[0].host, ctx.bindings[0].port) if port.kind != 'window-garden' or port.frame != ctx.frame: raise ContractError('window-box-interface', ctx.path, ctx.frame.origin) if not self.flowers or any(f not in ('poppy', 'cornflower', 'oxeye_daisy', 'allium', 'azure_bluet') for f in self.flowers): raise ContractError('window-box-flower-domain', ctx.path) width = port.facts['width'] framed = port.facts.get('depth', 1) == 2 box = Box((-1 if framed else 0, 0, -1 if framed else 0), (width if framed else width - 1, 1, 0)) if not all(port.region.contains(ctx.world(p)) for p in box.corners()): raise ContractError('window-box-region', ctx.path) boards = tuple((x, 0, -1) for x in range(width)) + ((-1, 0, 0), (width, 0, 0)) if framed else () return Contract(box, rules=(Rule('support', tuple((x, 0, 1) for x in range(width)) + tuple((x, 0, 0) for x in range(width))), Rule('expected', tuple((x, 1, 0) for x in range(width)), data={'names': list(self.flowers)}), Rule('expected', boards, data={'names': ['spruce_trapdoor']})), decisions={'width': width, 'framed': framed}, atomic_object=True) def realize(self, ctx, contract): p = Plan() rng = ctx.rng('flowers') for x in range(contract.decisions['width']): p.block((x, 0, 0), state_of('rooted_dirt'), 'planting-soil') p.block((x, 1, 0), state_of(rng.choice(self.flowers)), 'flower') if contract.decisions['framed']: p.block((x, 0, -1), state_of('spruce_trapdoor', facing='north', half='bottom', open='true', powered='false', waterlogged='false'), 'front-board') if contract.decisions['framed']: for x, side in ((-1, 'west'), (contract.decisions['width'], 'east')): p.block((x, 0, 0), state_of('spruce_trapdoor', facing=side, half='bottom', open='true', powered='false', waterlogged='false'), 'end-board') return p
hearth/components/ceiling.py
# Shallow ceiling timbers fitted to public room interfaces and actual clearances. from dataclasses import dataclass from hearth import Box, ContractError from hearth.kernel import Capability, Contract, Rule, Plan from hearth.blocks import name_of, log @dataclass(frozen=True) class CeilingTimbers: def capability(self): return Capability('interior.ceiling-timbers', ('decoration', 'timber-frame', 'ceiling-trim'), assumptions=('ceiling-decoration interface with actual overhead support',), adaptations=('omit cells at stair voids, lights and protected headroom',), guarantees=('one-cell projection', 'retained headroom', 'overhead bearing')) def negotiate(self, ctx, parameters): if len(ctx.bindings) != 1: raise ContractError('ceiling-host', ctx.path) port = ctx.view.port(ctx.bindings[0].host, ctx.bindings[0].port) if port.kind != 'ceiling-decoration' or port.frame != ctx.frame: raise ContractError('ceiling-interface', ctx.path, ctx.frame.origin) w, d = port.facts['width'], port.facts['depth'] points = {(x, 0, z): 'x' for z in (2, d - 3) for x in range(1, w - 1)} points.update({(w // 2, 0, z): 'z' for z in range(1, d - 1)}) members = [] for q, axis in sorted(points.items()): area = ctx.frame.box(Box(q, q)) above = (q[0], q[1] + 1, q[2]) if name_of(ctx.state(q)) == 'air' and ctx.view.supports(ctx.world(above)) and not ctx.view.protected(area): members.append((q, axis)) anchors = tuple((q[0], 1, q[2]) for q, _ in members) box = Box((1, 0, 1), (w - 2, 0, d - 2)) if not all(port.region.contains(ctx.world(q)) for q in box.corners()): raise ContractError('ceiling-region', ctx.path) return Contract(box, rules=(Rule('support', anchors), Rule('expected', tuple(q for q, _ in members), data={'names': ['stripped_dark_oak_log']})), decisions={'members': members, 'omitted_for_structure_or_clearance': len(points) - len(members)}) def realize(self, ctx, contract): p = Plan() for q, axis in contract.decisions['members']: p.block(q, log('stripped_dark_oak', axis), 'ceiling-member') 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/garden_house.py
# A new lightweight room-graph composition: inhabited wings around an open garden. import argparse from pathlib import Path from hearth.randomness import Scope from hearth.components import Blueprint, RoomSpec, FacadeDesign from hearth.components.roofcraft import RoofDesign from hearth.lodges import lodge_scene from hearth.persistence import export_scene def garden_house(seed): rng = Scope(seed).stream('garden-house-plan') rooms = [RoomSpec(0, 0, 0, 'living'), RoomSpec(1, 0, 0, 'library'), RoomSpec(2, 0, 0, 'workshop'), RoomSpec(0, 1, 0, 'kitchen'), RoomSpec(2, 1, 0, 'storage')] for x in rng.sample((0, 2), rng.choice((1, 2))): rooms.append(RoomSpec(x, 0, 1, 'bedroom')) if rng.choice((False, True)): rooms.append(RoomSpec(2, 2, 0, 'library')) balcony = any((r.x, r.z, r.level) == (0, 0, 1) for r in rooms) return Blueprint(tuple(rooms), bay=rng.choice((11, 13)), roof_axis=rng.choice(('auto', 'z')), roof_design=RoofDesign(rng.choice(((1, 2), (1, 1, 2))), 9), porch_depth=4, balcony=balcony, chimney=True, facade_design=FacadeDesign(), rail_material='dark_oak') 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('garden-house.litematic')) args = parser.parse_args() export_scene(lodge_scene(garden_house(args.seed), args.seed, args.environment_seed), args.output)
examples/building_detail.py
# Retained assessment of the new garden-house client and independently frozen environments. import argparse import json from pathlib import Path from hearth import Scene, Box from hearth.environment import Terrain, gradient, wave, radial from hearth.randomness import Scope from hearth.components import adapted from hearth.lodges import lodge_scene from hearth.persistence import semantic_digest from hearth.quality_assessment import evaluate, summary, fingerprint from examples.garden_house import garden_house def detail_signature(scene): """Measure functional stations and actual facade openings separately from massing.""" stations, openings = [], [] building = scene.nodes['/building'] floor = building.contract.decisions['floor'] for n in scene.nodes.values(): if n.type.startswith('furnishing.suite.') or n.type.startswith('window.'): local = building.frame.inverse(n.frame.origin) place = (local[0], local[1] - floor, local[2]) shape = sorted(n.frame.inverse(p) for p in scene.cells(n.path)) record = (n.type, place, shape) (stations if n.type.startswith('furnishing.suite.') else openings).append(record) return {'stations': fingerprint(sorted(stations)), 'facade_openings': fingerprint(sorted(openings)), 'station_count': len(stations), 'window_count': len(openings), 'window_boxes': sum(n.type == 'garden.window-box' for n in scene.nodes.values())} def run(seed, output, artifacts): output.mkdir(parents=True, exist_ok=True) artifacts.mkdir(parents=True, exist_ok=True) domain = Box((-10, -4, -20), (52, 72, 52)) environments, inputs, rows, details = [], [], [], {} # Freeze all six environments before any of their structure seeds are used. for index in range(6): es = 4100 + seed * 100 + index rng = Scope(es).stream('detail-environment') field = (gradient(rng.choice((-.025, 0, .025)), rng.choice((-.02, 0, .02)), 4) + wave(.3, .13, .09, rng.random() * 6)).blend( gradient(-.02, .02, 4) + radial(18, 18, 36, .5), radial(8, 10, 44, .6)).clamp(2, 6) water = rng.choice((None, 4, 5)) scene = Scene(es, domain=domain) scene.place('land', Terrain(domain, field, water)) scene.finalize() environments.append(scene) inputs.append({'environment_seed': es, 'expression': field.expression(), 'water': water, 'digest': semantic_digest(scene)}) (output / 'frozen-inputs.json').write_text(json.dumps(inputs, indent=2)) def retain(label, specification, recipe, artifact=None): def measured(): scene = recipe() details[label] = detail_signature(scene) return scene row = evaluate(label, specification, measured, artifact) if label in details: row['details'] = details[label] rows.append(row) (output / 'results.json').write_text(json.dumps(rows, indent=2)) print(label, row['status'], flush=True) for bs in range(8): label = f'court-{bs}' artifact = artifacts / (label + '.litematic') if bs in (0, 2, 7) else None retain(label, {'structure_seed': bs, 'environment_seed': 4100 + seed * 100, 'garden': True}, lambda b=bs: lodge_scene(garden_house(b), b, 4100 + seed * 100), artifact) for index, environment in enumerate(environments): for bs in (2, 7): def place(e=environment, b=bs): scene = e.fork(seed=b) scene.compose_choice(adapted('building', garden_house(b), '/land')) return scene.finalize() label = f'new-pair-{index}-{bs}' artifact = artifacts / (label + '.litematic') if index in (0, 1) else None retain(label, {**inputs[index], 'structure_seed': bs, 'garden': False}, place, artifact) if semantic_digest(environment) != inputs[index]['digest']: raise AssertionError('Frozen environmental input changed') result = {'client': summary(rows[:8]), 'independent_pairs': summary(rows[8:]), 'interior_signatures': len({d['stations'] for d in details.values()}), 'opening_signatures': len({d['facade_openings'] for d in details.values()})} (output / 'summary.json').write_text(json.dumps(result, indent=2)) (artifacts / 'manifest.json').write_text(json.dumps([r for r in rows if 'artifact' in r], indent=2)) return result if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--seed', type=int, default=0) parser.add_argument('--output', type=Path, default=Path('reports/building-detail/new-composition')) parser.add_argument('--artifacts', type=Path, default=Path('samples/building-detail/new-composition')) 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_detail.py
# Domestic components, facade exclusions and planted boundaries through public contracts. from dataclasses import dataclass, replace import pytest from hearth import Scene, Box, Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Plan, validate from hearth.environment import Terrain, constant, gradient, wave from hearth.components import Wall, Window, WindowBox, DomesticSuite, GardenPlant, BoundaryPlanting, Blueprint, RoomSpec, Building, FacadeDesign from hearth.components.primitives import Volume from hearth.lodges import lodge_scene, hillside_home from hearth.blocks import name_of, state_of, parse from hearth.persistence import export_scene, load_scene, encode from test.test_building_quality import snapshot, damaged @pytest.mark.parametrize('bay', (9, 11, 13)) def test_service_exclusion_retains_rear_daylight_and_locked_rooms(bay): design = Blueprint((RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom')), bay=bay, chimney=True, balcony=True, facade_design=FacadeDesign(), rail_material='dark_oak') scene = lodge_scene(design, 71, garden=False) for level in (0, 1): room = f'/building/room-0-0-{level}' windows = [n for n in scene.nodes.values() if n.path.startswith(room + '/window-south') and n.type.startswith('window.')] assert len(windows) == 2 glass = {p for n in windows for p in scene.cells(n.path) if name_of(scene.view.state(p)) == 'glass'} assert len(glass) == 12 stack = scene.cells('/building/chimney') assert not glass.intersection(stack) assert scene.nodes['/building'].contract.decisions['rooms'] == [(r.x, r.z, r.level, r.purpose) for r in design.normalized()] assert not validate(scene, True) @pytest.mark.parametrize('turn', range(4)) def test_external_window_box_attachment_roundtrip_and_regeneration(turn, work): frame = Frame((15, 0, -12), turn) scene = Scene(52, domain=frame.box(Box((-4, -2, -5), (16, 20, 8)))) scene.place('land', Terrain(scene.domain, constant(0))) scene.place('wall', Wall(11), frame=frame.compose(Frame((0, 1, 0)))) scene.place('window', Window(2, 3), frame=frame.compose(Frame((2, 2, 0))), bindings=(Binding('/wall', 'infill'),)) mount = scene.view.offers('/window', 'window-garden')[0] scene.place('flowers', WindowBox(), frame=mount.frame, bindings=(Binding('/window', mount.key),)) scene.finalize() point = next(p for p in scene.cells('/flowers') if name_of(scene.view.state(p)) == 'rooted_dirt') assert [n['id'] for n in scene.inspect(point)['chain']][:3] == ['/flowers', '/window', '/wall'] assert scene.inspect(point)['instance'] == '/flowers' assert scene.cells('/flowers').isdisjoint(scene.cells('/window')) path = work / 'window garden.litematic' export_scene(scene, path) restored = load_scene(path) assert restored.inspect(point) == scene.inspect(point) assert encode(restored.nodes) == encode(scene.nodes) original = scene.cells('/flowers') scene.remove('/flowers') assert '/flowers' not in scene.nodes and '/flowers' not in scene.reverse assert all(scene.inspect(q).get('instance') != '/flowers' for q in original) scene.place('flowers', WindowBox(('allium',)), frame=mount.frame, bindings=(Binding('/window', mount.key),)) assert scene.cells('/flowers') == original assert not validate(scene.finalize(), True) def test_window_box_missing_anchor_bad_frame_and_overflow_are_rejected(): scene = Scene(2, domain=Box((-4, -2, -5), (15, 20, 8))) scene.place('land', Terrain(scene.domain, constant(0))) scene.place('wall', Wall(11), frame=Frame((0, 1, 0))) scene.place('window', Window(2, 3), frame=Frame((2, 2, 0)), bindings=(Binding('/wall', 'infill'),)) port = scene.view.port('/window', 'garden') before = snapshot(scene) with pytest.raises(ContractError, match='window-box-interface'): scene.place('misaligned', WindowBox(), frame=Frame(port.frame.origin, 1), bindings=(Binding('/window', 'garden'),)) assert snapshot(scene) == before @dataclass(frozen=True) class Overflow: def capability(self): return Capability('test.planter-overflow', ('planter',)) def negotiate(self, ctx, parameters): return Contract(Box((0, 0, 0), (2, 1, 1))) def realize(self, ctx, contract): p = Plan() p.fill(contract.envelope, state_of('dirt')) return p with pytest.raises(ContractError, match='write-authority|permission'): scene.place('overflow', Overflow(), frame=port.frame, bindings=(Binding('/window', 'garden'),)) assert snapshot(scene) == before scene.place('flowers', WindowBox(), frame=port.frame, bindings=(Binding('/window', 'garden'),)) scene.finalize() soil = next(p for p in scene.cells('/flowers') if name_of(scene.view.state(p)) == 'rooted_dirt') assert any(d.rule == 'support' and d.component == '/flowers' for d in validate(damaged(scene, soil), True)) @pytest.mark.parametrize('purpose', ('gathering', 'study', 'cooking', 'craft', 'cabinet')) @pytest.mark.parametrize('width', (2, 3)) def test_domestic_station_function_apron_support_and_nbt(purpose, width, work): scene = Scene(6, domain=Box((-2, -2, -2), (8, 12, 8))) scene.place('land', Terrain(scene.domain, constant(0))) scene.place('station', DomesticSuite(purpose, width), frame=Frame((1, 1, 1))) scene.finalize() port = scene.view.offers('/station', 'interaction')[0] before = snapshot(scene) with pytest.raises(ContractError, match='clearance'): scene.place('obstruction', Volume(port.region, state_of('stone'))) assert snapshot(scene) == before support = (1, 0, 1) assert 'support' in {d.rule for d in validate(damaged(scene, support), True)} required = next(r for r in scene.nodes['/station'].contract.rules if r.kind == 'furnishing').data['groups'][0] broken = scene for p in scene.cells('/station'): if name_of(scene.view.state(p)) in required: broken = damaged(broken, p) assert 'furnishing' in {d.rule for d in validate(broken, True)} path = work / 'station.litematic' export_scene(scene, path) restored = load_scene(path) assert {p: c.nbt for p, c in restored.blocks.items() if c.nbt} == {p: c.nbt for p, c in scene.blocks.items() if c.nbt} def test_whole_tall_garden_plant_and_missing_substrate(): scene = Scene(5, domain=Box((-2, -2, -2), (8, 12, 8))) scene.place('land', Terrain(scene.domain, constant(0))) scene.place('rose', GardenPlant('rose_bush'), frame=Frame((2, 1, 2)), bindings=(Binding('/land', 'planting', 'plant'),)) scene.finalize() assert len(scene.cells('/rose')) == 2 assert 'plant-pair' in {d.rule for d in validate(damaged(scene, (2, 2, 2)), True)} assert 'support' in {d.rule for d in validate(damaged(scene, (2, 0, 2)), True)} before = snapshot(scene) with pytest.raises(ContractError): scene.place('unsupported', GardenPlant(), frame=Frame((4, 3, 4)), bindings=(Binding('/land', 'planting', 'plant'),)) assert snapshot(scene) == before def test_border_uses_public_transformed_boundary_and_preserves_scene(): design = replace(hillside_home(0), bay=11) scene = lodge_scene(design, 19, field=gradient(.06, -.02, 2) + wave(.35, .2, .1, 1), garden=False) before = dict(scene.blocks) scene.place('border', BoundaryPlanting('/building', '/land', density=1)) scene.finalize() assert scene.cells('/border', True) assert all(scene.blocks[p] == cell for p, cell in before.items()) assert scene.view.offers('/building', 'footprint-boundary') assert ('/border', 'landscapes', '/building') in scene.relations assert all(name_of(scene.view.state((p[0], p[1] - 1, p[2]))) != 'water' for n in scene.nodes.values() if n.type.startswith('plant.garden') for p in (n.frame.origin,)) def test_contrasting_balcony_guards_are_actual_and_damage_checked(): scene = lodge_scene(hillside_home(0), 0, garden=False) guards = [r for r in scene.nodes['/building/porch'].contract.rules if r.kind == 'expected'][0] assert len(guards.cells) > 10 assert all(name_of(scene.view.state(p)) == 'dark_oak_fence' for p in guards.cells) assert 'expected-geometry' in {d.rule for d in validate(damaged(scene, guards.cells[0]), True)} @pytest.mark.parametrize('turn', range(4)) def test_ceiling_members_preserve_actual_stair_headroom_and_rotate(turn): from hearth.components import CeilingTimbers frame = Frame((20, 0, -15), turn) domain = frame.box(Box((-8, -3, -18), (35, 64, 35))) scene = Scene(13, domain=domain) scene.place('land', Terrain(domain, constant(2))) design = Blueprint((RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom')), chimney=True, facade_design=FacadeDesign()) scene.place('house', Building(design, '/land'), frame=frame) scene.finalize() beams = [n for n in scene.nodes.values() if n.type == 'interior.ceiling-timbers'] assert len(beams) == 2 and all(scene.cells(n.path) for n in beams) stairs = scene.nodes['/house/room-0-0-0/stairs'] clear = {p for r in stairs.contract.rules if r.kind == 'clear' for p in r.cells} assert not clear.intersection(set().union(*(scene.cells(n.path) for n in beams))) point = min(scene.cells(beams[0].path)) assert [n['id'] for n in scene.inspect(point)['chain']][1] == '/house/room-0-0-0' assert 'expected-geometry' in {d.rule for d in validate(damaged(scene, point), True)} anchor = next(r.cells[0] for r in beams[0].contract.rules if r.kind == 'support') assert 'support' in {d.rule for d in validate(damaged(scene, anchor), True)} before = snapshot(scene) mount = scene.view.port('/house/room-0-0-0', 'ceiling') with pytest.raises(ContractError, match='ceiling-interface'): scene.place('bad-mount', CeilingTimbers(), frame=Frame(mount.frame.origin, (turn + 1) % 4), bindings=(Binding('/house/room-0-0-0', 'ceiling', 'connect'),)) assert snapshot(scene) == before def test_optional_planting_does_not_change_unrelated_building_branch(): a = lodge_scene(hillside_home(0), 8, garden=False) b = a.fork() # The border has no ground-edit authority. GardenCourt as a whole intentionally # replaces the building's street endpoint when it joins its path to the approach. b.place('border', BoundaryPlanting('/building', '/land')) b.finalize() cells = a.cells('/building', True) assert cells == b.cells('/building', True) keys = ('state', 'instance', 'chain', 'operation', 'nbt', 'shared') assert {p: {k: a.inspect(p)[k] for k in keys} for p in cells} == {p: {k: b.inspect(p)[k] for k in keys} for p in cells} # A new typed "landscapes" association is expected; principal structure is stable. assert encode({k: n for k, n in a.nodes.items() if k.startswith('/building')}) == encode({k: n for k, n in b.nodes.items() if k.startswith('/building')}) def test_boundary_and_facade_degenerate_domains_are_explicit(): with pytest.raises(ValueError, match='Facade'): FacadeDesign(height=3, sill=2).openings(11) assert not FacadeDesign().openings(11, exclusions=(Box((0, 0, -1), (10, 4, 0)),)) scene = lodge_scene(hillside_home(0), 12, garden=False) old = dict(scene.blocks) scene.place('empty-border', BoundaryPlanting('/building', '/land', density=0)) assert scene.blocks == old and not scene.cells('/empty-border', True) before = snapshot(scene) with pytest.raises(ContractError, match='input-domain'): scene.place('invalid-density', BoundaryPlanting('/building', '/land', density=1.1)) assert snapshot(scene) == before @pytest.mark.parametrize('width,height,sill', ((1, 2, 1), (1, 3, 1), (2, 2, 2))) def test_public_facade_dimensions_and_framed_boxes(width, height, sill): design = Blueprint((RoomSpec(0, 0, 0, 'library'),), bay=13, porch=False, facade_design=FacadeDesign(height=height, sill=sill, width=width)) scene = lodge_scene(design, 31, garden=False) boxes = [n for n in scene.nodes.values() if n.type == 'garden.window-box'] assert boxes and all(n.contract.decisions['framed'] for n in boxes) assert scene.nodes['/building/room-0-0-0'].contract.decisions['facade_projection'] == 2 front = next(p for p in scene.cells(boxes[0].path) if name_of(scene.view.state(p)) == 'spruce_trapdoor') assert 'expected-geometry' in {d.rule for d in validate(damaged(scene, front), True)} for n in scene.nodes.values(): if n.type == 'window.shuttered': assert sum(name_of(scene.view.state(p)) == 'glass' for p in scene.cells(n.path)) == width * height
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

结构设计说明 · 使用说明与需求完成记录 · 模型评估 · 接口改动。所有结论都有范围:有限样本和自动测试,不能证明任意输入都合法、美观,更不能证明已经能自动设计任何城市。