当前位置: 首页 > news >正文

Python_occ 学习记录 | 阵列

occ没有内置的阵列方法,用户可以在几何变换(平移、旋转)的基础上实现阵列操作,本质上计算出物体的位置,然后进行位置变换,复制出一个新的物体的过程。

线性阵列

def linear_array(shape: TopoDS_Shape,count: int,delta: Tuple[float, float, float],include_original: bool = True,
) -> Tuple[List[TopoDS_Shape], TopoDS_Compound]:"""线性阵列:沿 (dx, dy, dz) 方向等距平移复制。:param shape: 基准 shape:param count: 实例个数(>=1):param delta: 相邻两实例的位移 (dx, dy, dz):param include_original: 是否包含原件:return: (instances, compound)"""if count < 1:raise ValueError("count must be >= 1")instances: List[TopoDS_Shape] = []start_idx = 0if include_original:instances.append(shape)start_idx = 1# 逐个生成副本,循环+平移for i in range(start_idx, count):vec = (delta[0] * i, delta[1] * i, delta[2] * i)inst = transform_shape(shape, "translate", {"vec": vec})instances.append(inst)comp = _make_compound(instances)print(f"[LinearArray] Generated {len(instances)} instances.")return instances, comp

网格阵列

def grid_array(shape: TopoDS_Shape,rows: int,cols: int,dx: float,dy: float,include_original: bool = True,
) -> Tuple[List[TopoDS_Shape], TopoDS_Compound]:"""网格阵列(Grid Array):在 XY 平面内排布 rows × cols 个实例:param shape: 基准 shape:param rows: 行数 (>=1):param cols: 列数 (>=1):param dx: X 方向间距:param dy: Y 方向间距:param include_original: 是否包含原件 (默认 True):return: (instances, compound)"""if rows < 1 or cols < 1:raise ValueError("rows and cols must be >= 1")instances: List[TopoDS_Shape] = []# 按行、列双重循环+平移for i in range(rows):for j in range(cols):if i == 0 and j == 0 and include_original:instances.append(shape)continuevec = (dx * j, dy * i, 0.0)inst = transform_shape(shape, "translate", {"vec": vec})instances.append(inst)comp = _make_compound(instances)print(f"[GridArray] Generated {len(instances)} instances "f"({rows} rows × {cols} cols).")return instances, comp

环形阵列

def circular_array(shape: TopoDS_Shape,count: int,axis_point: Tuple[float, float, float],axis_dir: Tuple[float, float, float],total_angle_deg: float = 360.0,include_original: bool = True,start_angle_deg: float = 0.0,
) -> Tuple[List[TopoDS_Shape], TopoDS_Compound]:"""圆形阵列:绕指定轴等角度旋转复制。:param shape: 基准 shape:param count: 实例个数(>=1):param axis_point: 旋转轴上一点 (x, y, z):param axis_dir: 旋转轴方向 (dx, dy, dz),将会单位化:param total_angle_deg: 总旋转角度,默认 360°:param include_original: 是否包含原件:param start_angle_deg: 起始角(度),默认 0°:return: (instances, compound)"""if count < 1:raise ValueError("count must be >= 1")instances: List[TopoDS_Shape] = []step = total_angle_deg / (count if include_original else max(count, 1))if include_original:# 起始角度的一个实例(可选)if abs(start_angle_deg) > 1e-12:inst0 = transform_shape(shape,"rotate",{"axis_point": axis_point,"axis_dir": axis_dir,"angle": start_angle_deg,},)instances.append(inst0)else:instances.append(shape)start_index = 1else:start_index = 0# 生成其余实例(循环+旋转)for i in range(start_index, count):ang = start_angle_deg + step * iinst = transform_shape(shape,"rotate",{"axis_point": axis_point,"axis_dir": axis_dir,"angle": ang,},)instances.append(inst)comp = _make_compound(instances)print(f"[CircularArray] Generated {len(instances)} instances, step={step:.6f} deg.")return instances, comp

完整代码

需要结合之前的几何变换代码from transform_shape import transform_shape

arrays.py

"""
阵列工具:线性阵列、圆形阵列、矩形阵列
"""
from typing import Iterable, List, Tuple
from OCC.Core.TopoDS import TopoDS_Shape
from OCC.Core.BRep import BRep_Builder
from OCC.Core.TopoDS import TopoDS_Compoundfrom transform_shape import transform_shapedef _make_compound(shapes: Iterable[TopoDS_Shape]) -> TopoDS_Compound:"""把一组形体打包成复合体,便于一次性显示或导出。"""# 装配comp = TopoDS_Compound()builder = BRep_Builder()builder.MakeCompound(comp)for s in shapes:builder.Add(comp, s)return compdef linear_array(shape: TopoDS_Shape,count: int,delta: Tuple[float, float, float],include_original: bool = True,
) -> Tuple[List[TopoDS_Shape], TopoDS_Compound]:"""线性阵列:沿 (dx, dy, dz) 方向等距平移复制。:param shape: 基准 shape:param count: 实例个数(>=1):param delta: 相邻两实例的位移 (dx, dy, dz):param include_original: 是否包含原件:return: (instances, compound)"""if count < 1:raise ValueError("count must be >= 1")instances: List[TopoDS_Shape] = []start_idx = 0if include_original:instances.append(shape)start_idx = 1# 逐个生成副本for i in range(start_idx, count):vec = (delta[0] * i, delta[1] * i, delta[2] * i)inst = transform_shape(shape, "translate", {"vec": vec})instances.append(inst)comp = _make_compound(instances)print(f"[LinearArray] Generated {len(instances)} instances.")return instances, compdef circular_array(shape: TopoDS_Shape,count: int,axis_point: Tuple[float, float, float],axis_dir: Tuple[float, float, float],total_angle_deg: float = 360.0,include_original: bool = True,start_angle_deg: float = 0.0,
) -> Tuple[List[TopoDS_Shape], TopoDS_Compound]:"""圆形阵列:绕指定轴等角度旋转复制。:param shape: 基准 shape:param count: 实例个数(>=1):param axis_point: 旋转轴上一点 (x, y, z):param axis_dir: 旋转轴方向 (dx, dy, dz),将会单位化:param total_angle_deg: 总旋转角度,默认 360°:param include_original: 是否包含原件:param start_angle_deg: 起始角(度),默认 0°:return: (instances, compound)"""if count < 1:raise ValueError("count must be >= 1")instances: List[TopoDS_Shape] = []step = total_angle_deg / (count if include_original else max(count, 1))if include_original:# 起始角度的一个实例(可选)if abs(start_angle_deg) > 1e-12:inst0 = transform_shape(shape,"rotate",{"axis_point": axis_point,"axis_dir": axis_dir,"angle": start_angle_deg,},)instances.append(inst0)else:instances.append(shape)start_index = 1else:start_index = 0# 生成其余实例for i in range(start_index, count):ang = start_angle_deg + step * iinst = transform_shape(shape,"rotate",{"axis_point": axis_point,"axis_dir": axis_dir,"angle": ang,},)instances.append(inst)comp = _make_compound(instances)print(f"[CircularArray] Generated {len(instances)} instances, step={step:.6f} deg.")return instances, compdef grid_array(shape: TopoDS_Shape,rows: int,cols: int,dx: float,dy: float,include_original: bool = True,
) -> Tuple[List[TopoDS_Shape], TopoDS_Compound]:"""网格阵列(Grid Array):在 XY 平面内排布 rows × cols 个实例:param shape: 基准 shape:param rows: 行数 (>=1):param cols: 列数 (>=1):param dx: X 方向间距:param dy: Y 方向间距:param include_original: 是否包含原件 (默认 True):return: (instances, compound)"""if rows < 1 or cols < 1:raise ValueError("rows and cols must be >= 1")instances: List[TopoDS_Shape] = []for i in range(rows):for j in range(cols):if i == 0 and j == 0 and include_original:instances.append(shape)continuevec = (dx * j, dy * i, 0.0)inst = transform_shape(shape, "translate", {"vec": vec})instances.append(inst)comp = _make_compound(instances)print(f"[GridArray] Generated {len(instances)} instances "f"({rows} rows × {cols} cols).")return instances, comp

主程序调用:

from OCC.Display.SimpleGui import init_display
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox, BRepPrimAPI_MakeCylinder
from OCC.Core.gp import gp_Ax2, gp_Pnt, gp_Dir
import OCC.Core.Quantity as Qfrom arrays import linear_array, circular_array, grid_arraybox = BRepPrimAPI_MakeBox(6, 4, 3).Shape()ax2 = gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1))
cyl = BRepPrimAPI_MakeCylinder(ax2, 2.0, 6.0).Shape()# ---------- 线性阵列----------
box_list, box_comp = linear_array(box,                           # 阵列对象count=6,                       # 数量delta=(8.0, 0.0, 0.0),         # 移动方向和增量include_original=True          # 包含原对象
)# ---------- 圆形阵列 ----------
cyl_list, cyl_comp = circular_array(cyl,                           # 阵列对象count=8,                       # 数量axis_point=(30.0, 0.0, 0.0),   # 旋转轴过此点axis_dir=(0.0, 0.0, 1.0),      # 朝向 Z+total_angle_deg=360.0,         # 旋转角度include_original=True,         # 包含原对象start_angle_deg=0.0            # 起始相位
)# ---------- 网格阵列 ----------
_, grid_comp = grid_array(box,                           # 阵列对象rows=3,                        # 行数cols=4,                        # 列数dx=10,                         # 水平间距dy=8                           # 垂直间距
)display, start_display, *_ = init_display()# 线性阵列
display.DisplayShape(box_comp, color=Q.Quantity_NOC_BLUE3, transparency=0.35, update=False)# 圆形阵列
display.DisplayShape(cyl_comp, color=Q.Quantity_NOC_CORAL, transparency=0.45, update=False)# 网格阵列
display.DisplayShape(grid_comp, color=Q.Quantity_NOC_RED, transparency=0.55, update=True)display.FitAll()
start_display()

其中返回的instances, comp,分别是不同层次的结果:

  • instancesList[TopoDS_Shape]阵列中每一个独立的 shape 副本(单个零件/几何体),可以后续单独对阵列中某个零件进行操作
  • comp:把阵列里的所有副本组合成一个复合体
http://www.dtcms.com/a/349387.html

相关文章:

  • 李沐-第十章-训练Seq2SeqAttentionDecoder报错
  • 十九、云原生分布式存储 CubeFS
  • 剧本杀APP系统开发:打造多元化娱乐生态的先锋力量
  • Go编写的轻量文件监控器. 可以监控终端上指定文件夹内的变化, 阻止删除,修改,新增操作. 可以用于AWD比赛或者终端应急响应
  • TensorFlow深度学习实战(34)——TensorFlow Probability
  • GO学习记录八——多文件封装功能+redis使用
  • Node.js(2)—— Buffer
  • 安卓Android低功耗蓝牙BLE连接异常报错133
  • Docker Compose 部署 Elasticsearch 8.12.2 集成 IK 中文分词器完整指南
  • Go初级三
  • 上海AI实验室突破扩散模型!GetMesh融合点云与三平面,重塑3D内容创作
  • 少儿舞蹈小程序需求规格说明书
  • AutoCAD Electrical缺少驱动程序“AceRedist“解决方法
  • 【STM32】G030单片机的独立看门狗
  • ELKB日志分析平台 部署
  • 完美世界招数据仓库工程师咯
  • ArcGIS JSAPI 高级教程 - 创建渐变色材质的自定义几何体
  • three.js+WebGL踩坑经验合集(8.3):合理设置camera.near和camera.far缓解实际场景中的z-fighting叠面问题
  • 大数据平台ETL任务导入分库分表数据
  • Jenkins+docker 微服务实现自动化部署安装和部署过程
  • TDengine IDMP 应用场景:电动汽车
  • AI测试工具midsence和browse_use的使用场景和差异
  • react+taro打包到不同小程序
  • Flutter旧版本升级-> Android 配置、iOS配置
  • 机器视觉的3C玻璃盖板丝印应用
  • KeepAlived+Haproxy实现负载均衡(SLB)
  • window显示驱动开发—混合系统 DDI 和 dList DLL 支持
  • Shell 循环编程:for 与 select 轻松入门
  • HTTP 与 HTTPS 深度解析:从原理到实际应用
  • Kubernetes (K8s)入门指南:Docker之后,为什么需要容器编排?