轮廓线建模
轮廓线建模模块提供基于轮廓线的三维表面重建功能,支持两轮廓线生成三角网和单轮廓线封闭为面两种模式。基于本地 C++ 扩展 DmPyBindInterface 实现高性能计算,无需连接数采软件即可使用。
1. 两轮廓线建模
根据两条轮廓线(上下对应的点集)生成三角网模型,返回 List[TINGeometry]。每个 TINGeometry 包含 points(顶点坐标,shape=(N,3))和 faces(三角面片索引,shape=(M,3))。
基础用法
import numpy as np
from dimine_python_sdk.lib.exploitation import ContourModeling, ContourAlgorithm
from dimine_python_sdk.models import TINGeometry
# 两条轮廓线点集
contour1 = [[-52.28, 13.95, 0], [-52.28, -25.46, 0], [2.37, -25.46, 0],
[2.37, 13.95, 0], [-52.28, 13.95, 0]]
contour2 = [[-52.28, 13.95, 50], [-52.28, -25.46, 50], [2.37, -25.46, 50],
[2.37, 13.95, 50], [-52.28, 13.95, 50]]
# 两轮廓线建模
models = ContourModeling.two_contour_modeling(
ContourAlgorithm.MIN_PERIMETER, contour1, contour2
)
print(f"生成模型数量: {len(models)}")
for i, tin in enumerate(models):
print(f" 模型[{i}] 顶点数: {tin.points.shape[0]}, 三角面片数: {tin.faces.shape[0]}")
支持的输入格式
two_contour_modeling(method, line1, line2) 的 line1、line2 支持三种输入格式:
import numpy as np
from dimine_python_sdk.models.types import Line
from dimine_python_sdk.lib.exploitation import ContourModeling, ContourAlgorithm
# 方式一:List[List[float]] 纯列表
result = ContourModeling.two_contour_modeling(
ContourAlgorithm.MIN_PERIMETER,
[[0, 0, 0], [10, 0, 0], [10, 10, 0], [0, 10, 0]],
[[0, 0, 20], [10, 0, 20], [10, 10, 20], [0, 10, 20]],
)
# 方式二:np.ndarray
arr1 = np.array([[0, 0, 0], [10, 0, 0], [10, 10, 0], [0, 10, 0]])
arr2 = np.array([[0, 0, 20], [10, 0, 20], [10, 10, 20], [0, 10, 20]])
result = ContourModeling.two_contour_modeling(
ContourAlgorithm.MIN_PERIMETER, arr1, arr2
)
# 方式三:Line Pydantic 模型
line1 = Line(geometry=[[0, 0, 0], [10, 0, 0], [10, 10, 0], [0, 10, 0]])
line2 = Line(geometry=[[0, 0, 20], [10, 0, 20], [10, 10, 20], [0, 10, 20]])
result = ContourModeling.two_contour_modeling(
ContourAlgorithm.MIN_PERIMETER, line1, line2
)
2. 单轮廓线封闭为面
将一条封闭的轮廓线封闭为三角网平面。
from dimine_python_sdk.lib.exploitation import ContourModeling, ContourAlgorithm
# 封闭轮廓线
contour = [[-52.28, 13.95, 0], [-52.28, -25.46, 0], [2.37, -25.46, 0],
[2.37, 13.95, 0], [-52.28, 13.95, 0]]
# 单轮廓线封闭为面
models = ContourModeling.single_contour_modeling(
ContourAlgorithm.MIN_PERIMETER, contour
)
tin = models[0]
print(f"顶点数: {tin.points.shape[0]}")
print(f"三角面片数: {tin.faces.shape[0]}")
同样支持三种输入格式(List[List[float]]、np.ndarray、Line)。
3. 轮廓线外推建模
将一条轮廓线沿指定方向按外推模式生成三角网模型,用于矿体尖推/楔推/平推等场景。
基础用法
from dimine_python_sdk.lib.exploitation import (
ContourModeling,
ContourAlgorithm,
ExtrapolateMode,
ExtrapolateDirection,
)
# 轮廓线点集
contour = [[-52.28, 13.95, 0], [-52.28, -25.46, 0], [2.37, -25.46, 0],
[2.37, 13.95, 0], [-52.28, 13.95, 0]]
# 尖推(TIP)方式外推
models = ContourModeling.contour_extrapolate_modeling(
model=ExtrapolateMode.TIP,
point_set=contour,
extra_dir=ExtrapolateDirection.BOTH,
forward_distance=25.0,
backward_distance=25.0,
)
print(f"外推生成模型数量: {len(models)}")
for i, tin in enumerate(models):
print(f" 模型[{i}] 顶点数: {tin.points.shape[0]}, 三角面片数: {tin.faces.shape[0]}")
外推模式
通过 ExtrapolateMode 枚举指定外推方式:
| 枚举值 | 数值 | 说明 |
|---|---|---|
ExtrapolateMode.TIP |
0 | 尖推 — 外推端尖灭为一条线 |
ExtrapolateMode.WEDGE |
1 | 楔推 — 外推端形成楔形过渡 |
ExtrapolateMode.FLAT |
2 | 平推 — 外推端平直封闭 |
外推方向
通过 ExtrapolateDirection 枚举指定外推方向:
| 枚举值 | 数值 | 说明 |
|---|---|---|
ExtrapolateDirection.BOTH |
0 | 两端外推 |
ExtrapolateDirection.FRONT |
1 | 正侧(前向)外推 |
ExtrapolateDirection.BACK |
2 | 反侧(后向)外推 |
完整参数说明
models = ContourModeling.contour_extrapolate_modeling(
model=ExtrapolateMode.WEDGE, # 外推模式:TIP / WEDGE / FLAT
point_set=contour, # 轮廓线点集
extra_dir=ExtrapolateDirection.BOTH, # 外推方向
forward_distance=25.0, # 正侧外推距离
backward_distance=25.0, # 反侧外推距离
auto_calc=True, # 自动计算外推法向量
normal=None, # 手动指定法向量(auto_calc=False 时需提供)
zoom=70.0, # 缩放比例,楔推和平推时使用,范围 (0, 100]
pinchout_point_count=2, # 楔推尖灭点数
close=True, # 平推时是否封闭外推端
taper_line_verical=False, # 楔推时是否按短轴尖灭
)
三种外推模式效果对比
from dimine_python_sdk.lib.exploitation import (
ContourModeling, ExtrapolateMode, ExtrapolateDirection,
)
contour = [[0, 0, 0], [10, 0, 0], [10, 5, 0], [0, 5, 0], [0, 0, 0]]
# 尖推 — 外推端收缩为一条线
tip_result = ContourModeling.contour_extrapolate_modeling(
ExtrapolateMode.TIP, contour, forward_distance=15.0,
)
# 楔推 — 外推端楔形过渡
wedge_result = ContourModeling.contour_extrapolate_modeling(
ExtrapolateMode.WEDGE, contour, forward_distance=15.0,
)
# 平推 — 外推端平直封闭
flat_result = ContourModeling.contour_extrapolate_modeling(
ExtrapolateMode.FLAT, contour, forward_distance=15.0,
)
print(f"尖推: {len(tip_result)} 模型, 楔推: {len(wedge_result)} 模型, 平推: {len(flat_result)} 模型")
4. 多平行轮廓线建模
将多条平行的轮廓线(如多层水平断面)生成三角网模型。适用于多层矿体或地层的分层建模场景。
基础用法
from dimine_python_sdk.lib.exploitation import ContourModeling
# 三条平行轮廓线(例如三个不同高程的断面)
contour1 = [[-52.28, 13.95, 0], [-52.28, -25.46, 0], [2.37, -25.46, 0],
[2.37, 13.95, 0], [-52.28, 13.95, 0]]
contour2 = [[-52.28, 13.95, 50], [-52.28, -25.46, 50], [2.37, -25.46, 50],
[2.37, 13.95, 50], [-52.28, 13.95, 50]]
contour3 = [[-52.28, 13.95, 100], [-52.28, -25.46, 100], [2.37, -25.46, 100],
[2.37, 13.95, 100], [-52.28, 13.95, 100]]
# 多平行轮廓线建模
models = ContourModeling.multi_parallel_contour_modeling(
polylines_set=[contour1, contour2, contour3],
space_x=1.0,
space_y=1.0,
vertical_tol=0.5,
close_end=True,
)
print(f"生成模型数量: {len(models)}")
for i, tin in enumerate(models):
print(f" 模型[{i}] 顶点数: {tin.points.shape[0]}, 三角面片数: {tin.faces.shape[0]}")
参数说明
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
polylines_set |
List[Line] / List[np.ndarray] / List[List[List[float]]] |
— | 多条轮廓线数据集。每个元素为一条轮廓线,支持三种输入格式 |
space_x |
float |
1.0 |
X 方向网格大小 |
space_y |
float |
1.0 |
Y 方向网格大小 |
vertical_tol |
float |
0.5 |
垂直方向间隔容差 |
close_end |
bool |
True |
是否封闭端部 |
支持的输入格式
polylines_set 的每个元素支持三种格式,与两轮廓线建模一致:
import numpy as np
from dimine_python_sdk.models.types import Line
from dimine_python_sdk.lib.exploitation import ContourModeling
# 方式一:List[List[List[float]]]
set1 = [
[[0, 0, 0], [10, 0, 0], [10, 10, 0], [0, 10, 0], [0, 0, 0]],
[[0, 0, 20], [10, 0, 20], [10, 10, 20], [0, 10, 20], [0, 0, 20]],
[[0, 0, 40], [10, 0, 40], [10, 10, 40], [0, 10, 40], [0, 0, 40]],
]
models = ContourModeling.multi_parallel_contour_modeling(set1)
# 方式二:List[np.ndarray]
set2 = [
np.array([[0, 0, 0], [10, 0, 0], [10, 10, 0], [0, 10, 0], [0, 0, 0]]),
np.array([[0, 0, 20], [10, 0, 20], [10, 10, 20], [0, 10, 20], [0, 0, 20]]),
np.array([[0, 0, 40], [10, 0, 40], [10, 10, 40], [0, 10, 40], [0, 0, 40]]),
]
models = ContourModeling.multi_parallel_contour_modeling(set2)
# 方式三:List[Line Pydantic 模型]
set3 = [
Line(geometry=[[0, 0, 0], [10, 0, 0], [10, 10, 0], [0, 10, 0], [0, 0, 0]]),
Line(geometry=[[0, 0, 20], [10, 0, 20], [10, 10, 20], [0, 10, 20], [0, 0, 20]]),
Line(geometry=[[0, 0, 40], [10, 0, 40], [10, 10, 40], [0, 10, 40], [0, 0, 40]]),
]
models = ContourModeling.multi_parallel_contour_modeling(set3)
5. 实体合并
将多个 TINGeometry 三角网模型合并为一个实体。可用于将分段建模的结果合并为完整实体。
基础用法
import numpy as np
from dimine_python_sdk.models import TINGeometry
from dimine_python_sdk.lib.exploitation import ContourModeling
# 构建第一个四面体(TINGeometry 直接构造)
pts1 = np.array([
[0, 0, 0],
[10, 0, 0],
[5, 10, 0],
[5, 5, 10],
], dtype=np.float32)
faces1 = np.array([
[0, 1, 2], # 底面
[0, 1, 3], # 侧面1
[1, 2, 3], # 侧面2
[2, 0, 3], # 侧面3
], dtype=np.int32)
tin1 = TINGeometry(points=pts1, faces=faces1)
print(f"四面体A: 顶点数={tin1.points.shape[0]}, 面片数={tin1.faces.shape[0]}")
# 构建第二个四面体(与第一个相邻)
pts2 = np.array([
[10, 0, 0],
[20, 0, 0],
[15, 10, 0],
[15, 5, 10],
], dtype=np.float32)
faces2 = np.array([
[0, 1, 2],
[0, 1, 3],
[1, 2, 3],
[2, 0, 3],
], dtype=np.int32)
tin2 = TINGeometry(points=pts2, faces=faces2)
print(f"四面体B: 顶点数={tin2.points.shape[0]}, 面片数={tin2.faces.shape[0]}")
# 合并两个实体(传入 TINGeometry 列表)
results = ContourModeling.unite_polydata([tin1, tin2])
print(f"合并结果: {len(results)} 个三角网模型")
for i, merged in enumerate(results):
print(f" 结果[{i}]: 顶点数={merged.points.shape[0]}, 面片数={merged.faces.shape[0]}")
配合轮廓线建模使用
from dimine_python_sdk.lib.exploitation import ContourModeling, ContourAlgorithm
# 1. 对相邻轮廓线分别建模
contour1 = [[0, 0, 0], [10, 0, 0], [10, 8, 0], [0, 8, 0], [0, 0, 0]]
contour2 = [[0, 0, 15], [10, 0, 15], [10, 8, 15], [0, 8, 15], [0, 0, 15]]
contour3 = [[0, 0, 30], [10, 0, 30], [10, 8, 30], [0, 8, 30], [0, 0, 30]]
# 两段分别建模
models_1 = ContourModeling.two_contour_modeling(
ContourAlgorithm.MIN_PERIMETER, contour1, contour2
)
models_2 = ContourModeling.two_contour_modeling(
ContourAlgorithm.MIN_PERIMETER, contour2, contour3
)
# 2. 将 TINGeometry 直接传给 unite_polydata
merged_results = ContourModeling.unite_polydata(models_1 + models_2)
print(f"合并后共 {len(merged_results)} 个实体")
for i, merged in enumerate(merged_results):
print(f" 实体[{i}]: 顶点={merged.points.shape[0]}, 面片={merged.faces.shape[0]}")
6. 算法类型
通过 ContourAlgorithm 枚举指定两轮廓线之间的连接算法:
| 枚举值 | 数值 | 说明 |
|---|---|---|
ContourAlgorithm.MIN_PERIMETER |
0 | 最小周长法 — 选择使三角网总周长最小的连接方式 |
ContourAlgorithm.MIN_SURFACE_AREA |
1 | 最小表面积法 — 选择使三角网总表面积最小的连接方式 |
ContourAlgorithm.SYNC_ADVANCE |
2 | 同步前进法 — 两条轮廓线同步推进连接 |
ContourAlgorithm.MIN_DISTANCE |
3 | 最小距离法 — 选择距离最小的对应点连接 |
from dimine_python_sdk.lib.exploitation import ContourModeling, ContourAlgorithm
contour1 = [[0, 0, 0], [10, 0, 0], [10, 10, 0], [0, 10, 0]]
contour2 = [[0, 0, 20], [10, 0, 20], [10, 10, 20], [0, 10, 20]]
# 尝试不同算法对比效果
models = ContourModeling.two_contour_modeling(
ContourAlgorithm.MIN_SURFACE_AREA, contour1, contour2
)
7. 异常处理
轮廓线建模定义了层次化异常,建议调用时捕获具体异常:
from dimine_python_sdk.lib.exploitation import (
ContourModeling,
ContourAlgorithm,
ModelingError,
TwoContourModelingError,
SingleContourModelingError,
ContourExtrapolateModelingError,
ParallelContourModelingError,
)
try:
models = ContourModeling.two_contour_modeling(
ContourAlgorithm.MIN_PERIMETER, contour1, contour2
)
except TwoContourModelingError as e:
print(f"两轮廓线建模失败: {e}")
except ModelingError as e:
print(f"轮廓线建模错误: {e}")
异常继承关系:
RuntimeError
└── ModelingError
├── TwoContourModelingError (两轮廓线建模失败)
├── SingleContourModelingError (单轮廓线封闭为面失败)
├── ContourExtrapolateModelingError (轮廓线外推建模失败)
└── ParallelContourModelingError (多平行轮廓线建模失败)
8. 提交到 Dimine 场景
生成的三角网模型可以通过 conn 模块提交到 Dimine 场景中显示:
import asyncio
import numpy as np
from dimine_python_sdk.conn import open_client
from dimine_python_sdk.lib.exploitation import ContourModeling, ContourAlgorithm
from dimine_python_sdk.models.types import Shell
async def main():
# 轮廓线点集
contour1 = [[-52.28, 13.95, 0], [-52.28, -25.46, 0], [2.37, -25.46, 0],
[2.37, 13.95, 0], [-52.28, 13.95, 0]]
contour2 = [[-52.28, 13.95, 50], [-52.28, -25.46, 50], [2.37, -25.46, 50],
[2.37, 13.95, 50], [-52.28, 13.95, 50]]
# 两轮廓线建模
models = ContourModeling.two_contour_modeling(
ContourAlgorithm.MIN_PERIMETER, contour1, contour2
)
# 提交到场景
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)
print(f"已提交 {len(shells)} 个模型到场景")
if __name__ == "__main__":
asyncio.run(main())
9. 完整示例
import numpy as np
from dimine_python_sdk.lib.exploitation import (
ContourModeling,
ContourAlgorithm,
ModelingError,
)
from dimine_python_sdk.models.types import Line
def main():
# 示例一:两轮廓线建模(list 输入,最小距离法)
contour1 = [
[0.0, 0.0, 0.0],
[10.0, 0.0, 0.0],
[10.0, 8.0, 0.0],
[0.0, 8.0, 0.0],
[0.0, 0.0, 0.0],
]
contour2 = [
[0.0, 0.0, 15.0],
[10.0, 0.0, 15.0],
[10.0, 8.0, 15.0],
[0.0, 8.0, 15.0],
[0.0, 0.0, 15.0],
]
try:
models = ContourModeling.two_contour_modeling(
ContourAlgorithm.MIN_DISTANCE, contour1, contour2
)
print(f"两轮廓线建模: {len(models)} 个模型")
for i, tin in enumerate(models):
print(f" 模型[{i}] 顶点: {tin.points.shape[0]}, 面片: {tin.faces.shape[0]}")
except ModelingError as e:
print(f"建模失败: {e}")
# 示例二:单轮廓线封闭为面(ndarray 输入)
points = np.array([
[0.0, 0.0, 0.0],
[5.0, 0.0, 0.0],
[5.0, 5.0, 0.0],
[0.0, 5.0, 0.0],
[0.0, 0.0, 0.0],
])
try:
models = ContourModeling.single_contour_modeling(
ContourAlgorithm.MIN_PERIMETER, points
)
print(f"\n单轮廓线封闭: {len(models)} 个模型")
tin = models[0]
print(f" 顶点: {tin.points.shape[0]}, 面片: {tin.faces.shape[0]}")
except ModelingError as e:
print(f"封闭失败: {e}")
# 示例三:Line 模型输入
line1 = Line(geometry=[
[0.0, 0.0, 0.0], [3.0, 0.0, 0.0], [3.0, 3.0, 0.0], [0.0, 3.0, 0.0]
])
line2 = Line(geometry=[
[0.0, 0.0, 10.0], [3.0, 0.0, 10.0], [3.0, 3.0, 10.0], [0.0, 3.0, 10.0]
])
try:
models = ContourModeling.two_contour_modeling(
ContourAlgorithm.MIN_SURFACE_AREA, line1, line2
)
print(f"\nLine 输入两轮廓线建模: {len(models)} 个模型")
except ModelingError as e:
print(f"建模失败: {e}")
if __name__ == "__main__":
main()