Skip to content

巷道建模

井巷工程模块提供断面轮廓生成与三维巷道建模功能,基于本地 C++ 扩展 DmPyBindInterface 实现高性能计算,无需连接数采软件即可使用。

1. 断面轮廓生成

根据断面类型和尺寸参数,生成二维断面轮廓点列表。

import numpy as np
from dimine_python_sdk.lib.exploitation import Laneway, SectionParam

# 构造断面参数
section = SectionParam(
    type=0,          # 0=矩形拱
    width=2.0,       # 下宽度
    width_up=2.0,    # 上宽度
    wall_height=1.0, # 墙高
    wide_arch_ratio=3,
    offset_x=0.0,
    offset_y=0.0,
    point_count=20,  # 轮廓采集点数
)

# 获取断面轮廓(返回 numpy.ndarray)
contour = Laneway.get_section(section)
print(contour.shape)  # (N, 2) 或 (N, 3)

断面类型说明

type 断面类型
0 矩形拱
1 梯形拱
2 圆形拱
3 圆弧拱
4 三心拱
5 六边形拱
6 自定义断面

SectionParam 参数

参数名 类型 必填 默认值 约束 说明
type int 0~6 断面类型
width float > 0 下宽度
width_up float 0.0 上宽度
wall_height float 0.0 墙高
wide_arch_ratio int 2 >= 1 宽度/拱高比
offset_x float 0.0 X 轴偏移
offset_y float 0.0 Y 轴偏移
point_count int 20 > 0 轮廓采集点数

2. 巷道三维建模

根据断面参数和中心线集合,生成三维巷道模型,返回 List[TINGeometry] 三角网列表。每个 TINGeometry 包含 points(顶点坐标,shape=(N,3))和 faces(三角面片索引,shape=(M,3))。

from dimine_python_sdk.lib.exploitation import Laneway, LanewayParam, SectionParam
from dimine_python_sdk.models import TINGeometry

section = SectionParam(type=0, width=2.0, wall_height=1.0)

param = LanewayParam(
    section=section,
    polylines_set=[
        [[0.0, 0.0, 0.0], [10.0, 0.0, 0.0], [20.0, 5.0, 0.0]],
        [[5.0, 10.0, 0.0], [15.0, 10.0, 0.0]],
    ],
    close=False,       # 巷道尽头不封口
    connectivity=False,# 交叉口不自动联通
    method=0,          # 0=整体连接
    bottom_contour=False,
)

models = Laneway.get_lane_way_model(param)
print(type(models))        # <class 'list'>
print(type(models[0]))     # <class 'TINGeometry'>
print(models[0].points.shape)  # (N, 3)
print(models[0].faces.shape)   # (M, 3)

支持 Line 对象作为中心线

polylines_set 除了接受三维顶点列表,还支持直接传入 dimine_python_sdk.models.types.Line 对象,模型会在验证阶段自动提取 Line.geometry 转换为列表。

import numpy as np
from dimine_python_sdk.models.types import Line
from dimine_python_sdk.lib.exploitation import LanewayParam, SectionParam

line1 = Line(geometry=np.array([[0.0, 0.0, 0.0], [10.0, 0.0, 0.0]], dtype=np.float32))
line2 = Line(geometry=np.array([[5.0, 10.0, 0.0], [15.0, 10.0, 0.0]], dtype=np.float32))

section = SectionParam(type=0, width=2.0)
param = LanewayParam(
    section=section,
    polylines_set=[line1, line2],  # 直接传入 Line 对象
)

Line 对象与纯列表可以混合使用: python polylines_set=[line1, [[0.0, 0.0, 0.0], [5.0, 5.0, 5.0]]]

LanewayParam 参数

参数名 类型 必填 默认值 约束 说明
section SectionParam 断面参数
polylines_set list[list[list[float]] | Line [] 中心线集合
close bool False 巷道尽头是否封口
connectivity bool False 交叉口是否自动联通
method int 0 0~2 0=整体连接 1=拐点分离 2=顶墙分离
bottom_contour bool False 是否为底部轮廓线(联通时用)
shaft bool False 是否为竖井,true=竖井,false=巷道
angle float 0.0 [0, 360) 竖井水平旋转角度(度)

3. 联通巷道建模

当多条巷道的中心线在空间相交时,启用 connectivity=True 可让 C++ 底层自动处理交叉口,生成平滑的联通三维模型。此模式常用于井底车场、巷道交叉口等场景。

from dimine_python_sdk.lib.exploitation import Laneway, LanewayParam, SectionParam

# 三心拱断面
section = SectionParam(
    type=4,              # 三心拱
    width=3.0,
    width_up=3.0,
    wall_height=2.0,
    wide_arch_ratio=3,
    point_count=27,      # 三心拱建议 27 点
)

# 两条十字交叉的中心线
center_line_a = [
    [-20.0, 0.0, 0.0],
    [-10.0, 0.0, 0.0],
    [0.0, 0.0, 0.0],     # 交叉口中心
    [10.0, 0.0, 0.0],
    [20.0, 0.0, 0.0],
]
center_line_b = [
    [0.0, -20.0, 0.0],
    [0.0, -10.0, 0.0],
    [0.0, 0.0, 0.0],     # 交叉口中心(与 A 共享)
    [0.0, 10.0, 0.0],
    [0.0, 20.0, 0.0],
]

param = LanewayParam(
    section=section,
    polylines_set=[center_line_a, center_line_b],
    close=False,         # 巷道两头不封口
    connectivity=True,   # 启用联通建模,交叉口自动处理
    method=0,            # 整体连接
    bottom_contour=False,
)

models = Laneway.get_lane_way_model(param)
print(f"生成模型数量: {len(models)}")
for i, tin in enumerate(models):
    print(f"  模型[{i}] 顶点数: {tin.points.shape[0]}, 三角面片数: {tin.faces.shape[0]}")

联通建模关键参数

参数名 推荐值 说明
connectivity True 必须启用,否则交叉口处各自独立生成
close False 联通巷道一般两头不封口
method 0 整体连接,保证交叉口连续性
bottom_contour False 非底部轮廓线模式

提示:三心拱断面在生成时会自动将 point_count 修正为 27,若传入其他值会被覆盖。

4. 竖井建模

shaft=True 切换为竖井建模模式,配合 angle 控制水平旋转角度。竖井中心线通常沿 Z 轴方向(垂直向下)。

from dimine_python_sdk.lib.exploitation import Laneway, LanewayParam, SectionParam

# 矩形断面
section = SectionParam(
    type=0,              # 矩形断面
    width=3.0,           # 竖井净宽
    width_up=3.0,
    wall_height=2.0,
    wide_arch_ratio=2,
    point_count=20,
)

# 竖井中心线:沿 Z 轴垂直向下
center_line = [
    [0.0, 0.0, 0.0],     # 井口
    [0.0, 0.0, -30.0],   # 井底
]

param = LanewayParam(
    section=section,
    polylines_set=[center_line],
    close=True,          # 竖井顶部和底部封口
    connectivity=False,
    method=0,
    shaft=True,          # 启用竖井建模
    angle=45.0,          # 水平旋转 45°
)

models = Laneway.get_lane_way_model(param)
tin = models[0]
print(f"顶点数: {tin.points.shape[0]}")
print(f"三角面片数: {tin.faces.shape[0]}")

竖井建模关键参数

参数名 推荐值 说明
shaft True 必须启用,切换为竖井建模
angle 0.0 ~ 360 水平旋转角度(度),范围 [0, 360)
close True 竖井通常需要封口(顶部和底部)
connectivity False 竖井一般不需要联通建模

5. 异常处理

井巷工程模块定义了层次化异常,建议调用时捕获具体异常:

from dimine_python_sdk.lib.exploitation import (
    Laneway,
    LanewayError,
    SectionGenerateError,
    LanewayModelingError,
    SectionParam,
)

try:
    contour = Laneway.get_section(SectionParam(type=0, width=2.0))
except SectionGenerateError as e:
    print(f"断面生成失败: {e}")
except LanewayError as e:
    print(f"井巷工程错误: {e}")

异常继承关系:

RuntimeError
 └── LanewayError
      ├── SectionGenerateError  (断面生成失败)
      └── LanewayModelingError  (巷道建模失败)

6. 向后兼容

旧代码使用裸 dict 传递参数仍然可用,但会触发 DeprecationWarning,建议迁移到 Pydantic 模型:

import warnings

contour = Laneway.get_section(SectionParam(type=0, width=2.0, wide_arch_ratio=3))

7. 完整示例

7.1 基础巷道建模

import numpy as np
from dimine_python_sdk.lib.exploitation import (
    Laneway,
    LanewayParam,
    SectionParam,
)
from dimine_python_sdk.models.types import Line


def main():
    # 1. 定义断面
    section = SectionParam(
        type=0,
        width=2.0,
        width_up=2.0,
        wall_height=1.0,
        wide_arch_ratio=3,
        point_count=20,
    )

    # 2. 获取断面轮廓
    contour = Laneway.get_section(section)
    print(f"断面轮廓点数: {len(contour)}")

    # 3. 定义中心线(混合使用 Line 对象和列表)
    center_line = Line(geometry=np.array([
        [0.0, 0.0, 0.0],
        [10.0, 0.0, 0.0],
        [20.0, 5.0, 0.0],
    ], dtype=np.float32))

    # 4. 巷道建模
    param = LanewayParam(
        section=section,
        polylines_set=[
            center_line,
            [[5.0, 10.0, 0.0], [15.0, 10.0, 0.0]],
        ],
        close=False,
        connectivity=False,
        method=0,
    )

    models = Laneway.get_lane_way_model(param)
    print(f"巷道模型数量: {len(models)}")
    print(f"三角网顶点数: {models[0].points.shape[0]}")
    print(f"三角网面片数: {models[0].faces.shape[0]}")


if __name__ == "__main__":
    main()

7.2 联通巷道并提交到场景

import asyncio
import numpy as np
from dimine_python_sdk.conn import open_client
from dimine_python_sdk.lib.exploitation import Laneway, LanewayParam, SectionParam
from dimine_python_sdk.models.types import Shell, TINGeometry


async def main():
    section = SectionParam(type=4, width=3.0, wall_height=2.0, wide_arch_ratio=3)

    center_line_a = [[-20, 0, 0], [-10, 0, 0], [0, 0, 0], [10, 0, 0], [20, 0, 0]]
    center_line_b = [[0, -20, 0], [0, -10, 0], [0, 0, 0], [0, 10, 0], [0, 20, 0]]

    param = LanewayParam(
        section=section,
        polylines_set=[center_line_a, center_line_b],
        close=False,
        connectivity=True,   # 关键:启用联通建模
        method=0,
    )

    models = Laneway.get_lane_way_model(param)

    async with open_client() as client:
        files = await client.get_files()
        layers = await client.get_layers(file_id=files[0].id)

        shells = [
            Shell(
                file=files[0].id,
                layer=layers[0].id,
                feature="0",
                geometry=tin,
                color=[139, 90, 43],  # 赭石色
            )
            for tin in models
        ]
        await client.create_geometry(shells)


if __name__ == "__main__":
    asyncio.run(main())

7.3 竖井建模并提交到场景

import asyncio
from dimine_python_sdk.conn import open_client
from dimine_python_sdk.lib.exploitation import Laneway, LanewayParam, SectionParam
from dimine_python_sdk.models.types import Shell


async def main():
    section = SectionParam(type=0, width=3.0, wall_height=2.0)

    center_line = [[0, 0, 0], [0, 0, -30]]  # 垂直向下 30m

    param = LanewayParam(
        section=section,
        polylines_set=[center_line],
        close=True,          # 封口
        shaft=True,          # 关键:启用竖井建模
        angle=45.0,          # 水平旋转 45°
    )

    models = Laneway.get_lane_way_model(param)
    tin = models[0]

    async with open_client() as client:
        files = await client.get_files()
        layers = await client.get_layers(file_id=files[0].id)

        shell = Shell(
            file=files[0].id,
            layer=layers[0].id,
            feature="0",
            geometry=tin,
            color=[100, 149, 237],  # 钢蓝色
        )
        await client.create_geometry([shell])


if __name__ == "__main__":
    asyncio.run(main())