【pyclipper+增材CAM】轮廓偏置

在增材打印CAM中,我们需要在切片得到的每层轮廓中规划生成打印路径。传统的三轴3D打印的常见填充方式有:轮廓平行填充方向平行填充。其中轮廓平行填充主要是通过轮廓偏置实现的。

pyclipper安装使用

Python下安装pyclipper库,命令行输入pip指令:

pip install pyclipper

通过 import pyclipper 导入使用。

pyclipper基础

pyclipper是Python环境下的Clipper库,主要用于平面闭合多边形或非闭合多线段的裁剪(clipping)和偏置(offsetting)。

重要术语:

  • 裁剪(Clipping): 指二维平面图形之间的四个布尔操作:交集(intersection)、并(union)、差(difference )和异或(exclusive-or))中的任何一个。

  • 路径(Path): 是一个有序的顶点集合,它定义一个单一的几何轮廓(contour),要么是一条线(一个开放的路径),要么是一个多边形(一个闭合的轮廓)。

  • 直线(Line): 或者多线段(polyline) 是一个包含两个或多个顶点的开放路径。

  • 多边形(Polygon): 通常是指一个二维的区域,其边界是一个外部不相交的闭合轮廓。

  • 轮廓(Contour): 同路径(path)。

  • 孔(Hole): 是一个多边形中不属于多边形的封闭区域。一个“孔多边形”是一个封闭的路径。

  • 多边形填充规则(Polygon Filling Rule): 填充规则,定义了平面封闭区域中的内部区域(即需要填充的区域)和外部的区域(即“孔”,不需要填充的区域)。

需要掌握的Clipper基础:

代码实现

import math
import vtk
from pyclipper import *

def numeric_scaling(digits: 'int > 0' = 7, *, pos: list):
    def decorate(func):
        def scaled(*_args):
            __args = list(_args)
            f = math.pow(10, digits)  # 数值精度,默认为7位小数
            for p in pos:
                if isinstance(_args[p], int) or isinstance(_args[p], float):
                    __args[p] *= f
                elif isinstance(_args[p], list):
                    __args[p] = [[tuple(map(lambda x: x * f, pt)) for pt in path] for path in _args[p]]
                else:
                    pass
            _result = func(*tuple(__args))  # _result is list of paths
            _result = [[tuple(map(lambda x: x / f, pt)) for pt in path] for path in _result]
            return _result

        return scaled

    return decorate


@numeric_scaling(digits = 7, pos = [0, 1])
def offset(polys, delta, jt = JT_SQUARE):  # 偏置函数,输人多边形:[[[pt1_x,pt2_y],...,[ptN_x,ptN_y]],[...],...]
    pco = PyclipperOffset()
    pco.AddPaths(polys, jt, ET_CLOSEDPOLYGON)
    sln = pco.Execute(delta)  # 偏置距离delta
    return sln  # 返回偏置曲线

# 轮廓平行路径填充
def genCpPath_clipper(boundaries, interval, shellThk):  # 输人:轮廓、偏置距离、填充带宽
    offsetPolyses = []  # 偏置曲线列表
    delta = interval / 2  # 首次偏置距离
    polys = offset(boundaries, -delta, JT_SQUARE)
    offsetPolyses.append(polys)  # 偏置曲线存放在offsetPolys中
    while math.fabs(delta) < shellThk:  # 循环直至偏置距离大于填充带宽
        delta += interval
        polys = offset(boundaries, -delta, JT_SQUARE)
        if polys is None or len(polys) == 0:
            break  # 已到偏置区域中心,则退出
        offsetPolyses.append(polys)
    return offsetPolyses

按理来讲装饰器定义和调用应该分开来,这里为了方便所以写在一个文件中。

测试结果

偏置轮廓填充结果如下图所示,其中黑色为切片得到的轮廓,红色为偏置填充的路径。

在这里插入图片描述

第24层偏置填充结果:

在这里插入图片描述

第27层偏置填充结果:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_39784672/article/details/128373234