全局配置库与参数来源
爆破设计的很多输入参数(孔网、孔径、雷管类型、炸药、装药结构模板)在 Dimine 中属于全局配置, SDK 把它们做成三个可读可写的配置库管理器,用于「读入真实工程参数 / 把设计成果写回 GUI 配置」:
| 库 | 文件(相对 DIMINE_HOME) |
管理器 | 内容 |
|---|---|---|---|
| 布孔参数 | Parameter/CHoleParamDlg.xml |
HoleParam |
孔口/孔底标高、孔网、钻孔、超深、雷管与延时等 |
| 炸药数据库 | SysParameter/explosivedb.dmt |
ExplosiveDB |
炸药 名称 / 体重(线装药密度) / 单价 |
| 装药结构模板库 | SysParameter/explosivemodel.dmt |
ChargeTemplateDB |
装药模板(连续装药 / 间隔装药 …) |
三者共同约定:
- 定位基于环境变量
DIMINE_HOME;xxx_path(home=None)返回目标路径,未设置DIMINE_HOME时抛*PathError。 - 惰性加载:构造
xxx_db(file_path=None)后首次访问数据才解析文件;增删改直接作用于内存模型, 由显式save()写回(save(file_path=...)可另存)。 - 每个库配套一个上下文管理器(
hole_param_conn/explosive_db_conn/charge_template_conn), 进入自动加载、退出自动释放。 - 数值语义:长度 m、延时 ms、线装药密度 kg/m、单价 元/kg。
这些管理器都经 Dimine 原生数据表(
.dmt/ XML)读写,需要DIMINE_HOME指向含DmPyBindInterface.pyd的目录。纯设计计算不需要它们——不读配置也能用内置默认跑,见 爆破设计流程。
一、从全局配置读设计默认(推荐入口)
多数场景只想要「读全局配置 → 填进设计参数」,不必逐个字段操作。defaults 提供两个快捷函数,
读不到一律返回 None(不抛异常),由调用方回退内置默认,保证离线可用:
from dimine_python_sdk.lib.blasting import load_layout_params, load_explosives
layout = load_layout_params() # -> Optional[HoleLayoutParams](无 DIMINE_HOME / 解析失败 → None)
explosives = load_explosives() # -> Optional[List[Explosive]]
# 典型用法:读不到就用内置默认
if layout is None:
from dimine_python_sdk.lib.blasting import HoleLayoutParams
layout = HoleLayoutParams()
if explosives is None:
from dimine_python_sdk.lib.blasting import Explosive
explosives = [Explosive(name="乳化炸药", line_density=5.0, unit_price=8.0)]
load_layout_params() 读 CHoleParamDlg.xml 并映射到 HoleLayoutParams,关键映射:
| CHoleParamDlg 字段 | → HoleLayoutParams 字段 |
说明 |
|---|---|---|
hole_dist / row_dist |
hole_spacing / row_spacing |
孔间距 / 排间距 m |
hole_mode |
pattern |
0 → SQUARE,否则 CUSTOM |
safe_front_dist / back_break_dist / left_break_dist / right_break_dist |
front_distance / back_distance / left_distance / right_distance |
各向安全距离 m |
rotate_angle |
rotation_angle |
旋转角 ° |
diameter / direction / slope |
diameter(mm) / azimuth / inclination |
钻孔参数 |
front_subdrill / rear_subdrill |
front_overdrill / back_overdrill |
前排 / 后排超深 m |
mine_height |
bench_height |
回采高度 m |
detonator_type |
detonator |
含「数码」→ DIGITAL,否则 NONEL |
tube_burn_velocity / start_delay / isochrone_gap / hole_tolerance |
detonation_velocity / init_delay / isochrone_interval / tolerance |
燃速/起爆点延时/等时线间隔/容差 |
load_explosives() 读 explosivedb.dmt,逐行映射为 Explosive(name=名称, line_density=体重, unit_price=单价)。
二、布孔参数 HoleParam(CHoleParamDlg.xml)
对应 Dimine「布孔参数」对话框。文件是无声明的单行 UTF-8 XML,固定结构
<Parameter><DdefaultNode>…;读写直接作用于内存 XML 树,未知节点原样保留,
浮点字段按软件惯例 6 位小数写回。
from dimine_python_sdk.lib.blasting import HoleParam, hole_param_path, hole_param_conn
hp = HoleParam() # 自动定位 DIMINE_HOME/Parameter/CHoleParamDlg.xml
print(hp.diameter) # 220.0
hp.hole_dist = 6.0 # 孔间距改为 6 m
hp.update(row_dist=3.5, front_subdrill=2.5) # 批量修改
hp.save() # 写回原文件(无声明、单行、UTF-8)
# 或用上下文管理器(退出自动释放)
with hole_param_conn() as hp:
print(hp.to_dict()) # 全部字段 {属性: 值}
hp.detonator_type = "数码电子雷管"
hp.save()
常用字段(属性名 → 类型化 property,直读直写)
孔口 / 孔底设计标高
| 属性 | 默认 | 说明 |
|---|---|---|
top_z |
765.0 |
孔口设计标高-指定 Z 值 (m) |
top_source |
0 |
孔口标高来源(0=指定Z值 / 1=表面文件) |
top_surface_file |
"" |
孔口表面文件 |
bottom_z |
750.0 |
孔底设计标高-指定 Z 值 (m) |
bottom_depth |
15.0 |
孔底-指定孔深 (m) |
bottom_source |
0 |
孔底标高来源(0=Z值 / 1=底面文件 / 2=底面坡度) |
bottom_slope |
30.0 |
孔底-指定底面坡度 (°) |
bottom_default_mode |
0 |
孔底默认标高方式(0=Z值 / 1=孔深) |
钻孔参数
| 属性 | 默认 | 说明 |
|---|---|---|
diameter |
220.0 |
孔径 (mm) |
direction |
0.0 |
方位角 (°) |
slope |
-90.0 |
倾角 (°) |
孔网参数
| 属性 | 默认 | 说明 |
|---|---|---|
hole_dist |
5.0 |
孔间距 (m) |
row_dist |
3.0 |
排间距 (m) |
hole_mode |
0 |
布孔方式(0=方形布孔) |
safe_front_dist |
4.0 |
前排安全距离 (m) |
back_break_dist |
2.0 |
后冲距离 (m) |
left_break_dist / right_break_dist |
2.0 / 2.0 |
左侧 / 右侧冲距离 (m) |
rotate_angle |
0.0 |
旋转角度 (°) |
超深与数量限制
| 属性 | 默认 | 说明 |
|---|---|---|
front_subdrill / rear_subdrill |
2.0 / 1.0 |
前排 / 后排超深 (m) |
max_row_count |
7 |
最大排数 |
max_hole_count_per_row |
15 |
单排最大孔数 |
雷管与延时等
| 属性 | 默认 | 说明 |
|---|---|---|
mine_height |
15.0 |
平均回采高度 (m) |
detonator_type |
"导爆管雷管" |
雷管类型(含「数码」即数码电子) |
tube_burn_velocity |
2000 |
导爆管燃速 (m/s) |
start_delay |
110 |
起爆点延时 (ms) |
isochrone_gap |
10 |
等时线间隔 (ms) |
hole_tolerance |
1.0 |
布孔容差 (m) |
rock_density |
2.6 |
岩石密度 (t/m³) |
完整字段列表可用
HoleParam.field_names()获取;逐字段说明见各 property 的 docstring (形如「孔径 (mm)(XML:<m_dDiameter>)」)。属性名缺省值时返回对话框出厂默认。
三、炸药数据库 ExplosiveDB(explosivedb.dmt)
DMT 表固定三列,「体重」即线装药密度,与设计模型 Explosive.line_density 一一对应、无需换算:
| 列名 | 含义 | 单位 | → Explosive 字段 |
|---|---|---|---|
名称 |
炸药名称 | — | name |
体重 |
线装药密度 | kg/m | line_density |
单价 |
单价 | 元/kg | unit_price |
from dimine_python_sdk.lib.blasting import ExplosiveDB, explosive_db_conn
db = ExplosiveDB() # 自动定位 DIMINE_HOME/SysParameter/explosivedb.dmt
print(db.names()) # ['2#岩石炸药', '乳化炸药', ...]
db.to_explosives() # -> list[Explosive](逐行映射,体重非法抛 ExplosiveDBFormatError)
db.explosive("乳化炸药") # -> Explosive 或 None
# 读写模式:不存在则加、存在则改,返回 Explosive
db.ensure("乳化炸药", line_density=6.0, unit_price=8.0)
db.add("铵油炸药", line_density=1.05, unit_price=2.0) # 已存在/非法参数抛 ExplosiveDBError
db.update("乳化炸药", line_density=6.5) # -> bool(找到了?)
db.remove("铵油炸药") # -> bool
db.save() # 写回原文件
# 或用上下文管理器
with explosive_db_conn() as db:
for rec in db.records(): # 每行 {名称, 体重, 单价}
print(rec)
常用方法 / 容器协议:
- 读取:
names()、records()、get(name)(行 dict 或 None)、explosive(name)、to_explosives(); - 修改:
ensure(name, line_density, unit_price=0)(不存在加/存在改并返回)、add(...)、update(name, line_density=None, unit_price=None)、remove(name); - 容器:
len(db)、name in db、db[name](行 dict,缺失KeyError)、db[i]、迭代行 dict; - 保存:
save(file_path=None);load()链式加载 /reload()/close()。
校验(违反抛 ExplosiveDBError):名称非空、line_density > 0、unit_price >= 0;重复名称抛「已存在」。
四、装药结构模板库 ChargeTemplateDB(explosivemodel.dmt)
DMT 表固定四列;一个「模板」= 同名连续多行,行序即自孔口 → 孔底:
| 列名 | 含义 | 取值 |
|---|---|---|
模版名称 |
模板名 | 连续装药 / 间隔装药 … |
填充类型 |
分段填充类型 | 填塞物 / 炸药名(如 2#岩石炸药)/ 间隔器 / 空气 / 起爆药包 |
填充长度 |
分段长度 | m |
雷管延时 |
分段雷管延时 | 惰性段 -1、炸药段 >=0(ms;文件里为字符串字段) |
「雷管延时」列在文件里按字符串存储,SDK 写回时保持字符串形态以免类型漂移。模板与设计分段
ChargeSegment(fill_type, length, delay) 一一对应(文件不含重量,weight 恒为 0)。
from dimine_python_sdk.lib.blasting import ChargeTemplateDB, ChargeTemplateFormatError
db = ChargeTemplateDB() # 自动定位 DIMINE_HOME/SysParameter/explosivemodel.dmt
print(db.names()) # ['连续装药', '间隔装药', ...](文件顺序)
segs = db.segments("间隔装药") # -> list[ChargeSegment](自孔口→孔底;模板不存在 → [])
segs[0].fill_type # '填塞物'(孔口填塞段)
segs[0].delay # -1(惰性)
模板内每段 delay 语义与设计一致:填塞物/间隔器/空气惰性段为 -1;炸药 / 起爆药包 >=0。
读出的 ChargeSegment 可直接交给 装药模板套用 的
design_charge_from_template。
示例:真实模板结构(标定孔深 15 m)
| 模板 | 分段(自孔口 → 孔底) |
|---|---|
| 连续装药 | 填塞物 6.0 m (-1) → 2#岩石炸药 9.0 m (250ms) |
| 间隔装药 | 填塞物 6.0 m (-1) → 2#岩石炸药 3.5 m (350ms) → 间隔器 2.0 m (-1) → 2#岩石炸药 3.5 m (350ms) |
读写模板
from dimine_python_sdk.lib.blasting import ChargeSegment
# 新增模板:接受 ChargeSegment 或 dict(fill_type, length, delay)
db.add("三间隔装药", [
{"fill_type": "填塞物", "length": 6.0, "delay": -1},
{"fill_type": "2#岩石炸药", "length": 2.6, "delay": 350},
{"fill_type": "间隔器", "length": 2.0, "delay": -1},
{"fill_type": "2#岩石炸药", "length": 2.6, "delay": 380},
{"fill_type": "间隔器", "length": 2.0, "delay": -1},
{"fill_type": "2#岩石炸药", "length": 2.6, "delay": 410},
]) # 名已存在 / 空 / 非法分段抛 ChargeTemplateError
db.update("间隔装药", [ChargeSegment(fill_type="填塞物", length=5.0, delay=-1),
ChargeSegment(fill_type="乳化炸药", length=10.0, delay=300)])
# # -> bool:整段替换并保持原位(未找到 False)
db.remove("三间隔装药") # -> bool
db.save() # 写回原文件(delay 保持字符串形态)
# 读取 API
db.records() # 全表行 dict(含 '模版名称','填充类型','填充长度','雷管延时')
db.template("连续装药") # 该模板原始行 dict 列表(不存在 → [])
db["连续装药"] # 等价 db.segments(name)(缺失 KeyError);db[0]/db[0:2] 取模板名
len(db) # 模板数;name in db 判断存在
校验:segments() 遇到非数字 / 负长度 / 非法延时会抛 ChargeTemplateFormatError(消息含模板名);
add 要求名称非空且不重复、至少一个分段、分段含合法 fill_type 与非负长度。
异常层次汇总
三个库各自为 *Error(Exception) + 两个子类:
| 库 | 基类 | *PathError(找不到文件 / 未设 DIMINE_HOME) |
*FormatError(结构 / 值非法) |
|---|---|---|---|
| 布孔参数 | HoleParamError |
HoleParamPathError |
HoleParamFormatError |
| 炸药库 | ExplosiveDBError |
ExplosiveDBPathError |
ExplosiveDBFormatError |
| 装药模板库 | ChargeTemplateError |
ChargeTemplatePathError |
ChargeTemplateFormatError |
未设置 DIMINE_HOME 且未传 home 时,xxx_path() 与 xxx_db() 均抛 *PathError;
若只想「有配置就读、没有就用默认」,请用上文的 defaults.load_*(返回 None)。