简介:PlotGcode是一款专为绘图机设计的Gcode处理工具库,集成Drawbot、NodeBox、PlotDevice和Shoebot等图形编程环境,支持用户通过编写代码生成、编辑并控制Gcode指令,实现从数字图形设计到物理绘制的完整流程。该工具适用于艺术创作、教育、工程原型与定制化生产,打通了编程与物理制造的桥梁。
1. Gcode基础与生成原理
Gcode(G代码)是数控设备控制的核心语言,广泛应用于3D打印、CNC加工和绘图机等领域。其基本结构由一系列指令组成,每条指令以字母开头,代表特定的运动或操作类型,如 G00 表示快速移动, G01 表示直线插补。理解这些基础指令是掌握Gcode编程的第一步。
Gcode通常基于笛卡尔坐标系,使用绝对或相对坐标进行定位,并通过单位制(如毫米或英寸)来控制精度。例如,以下是一个简单的Gcode示例,控制绘图头从起点(0,0)移动到(10,10):
G21 ; 设定单位为毫米
G90 ; 使用绝对坐标模式
G00 X0 Y0 ; 快速移动到原点
G01 X10 Y10 F100 ; 以100mm/min的速度直线移动至(10,10)
2. Drawbot集成与矢量图形处理
Drawbot作为一种强大的绘图脚本工具,广泛应用于矢量图形生成与图形处理领域。它不仅支持多种绘图输出格式(如PDF、SVG、PNG等),还可以与PlotGcode等工具集成,将矢量图形路径直接转换为绘图机或3D打印机可识别的Gcode指令。本章将从Drawbot的基本概念与功能入手,逐步深入到矢量图形的结构化处理、路径优化与Gcode生成的全过程,并结合实际案例展示如何通过Drawbot与PlotGcode实现从图形设计到物理绘图的无缝对接。
2.1 Drawbot简介与功能概述
2.1.1 Drawbot的核心特性与适用场景
Drawbot 是一个基于 Python 的图形生成工具,其核心理念是通过编写脚本来创建矢量图形。与传统图形软件(如Illustrator或Inkscape)不同,Drawbot无需图形界面,所有图形的绘制过程都通过Python代码控制完成。这种设计使其非常适合自动化图形生成、参数化设计以及与绘图设备的集成。
核心特性包括:
| 特性 | 描述 |
|---|---|
| 脚本驱动绘图 | 使用Python脚本生成矢量图形,支持SVG、PDF、PNG等格式 |
| 矢量图形输出 | 支持高质量的矢量图形生成,适用于印刷与绘图机输出 |
| 参数化设计 | 支持变量控制图形属性,便于动态调整与批量生成 |
| 多平台支持 | 支持macOS、Windows、Linux系统 |
| 可扩展性强 | 可与其他图形处理工具(如PlotGcode)集成,进行后续处理 |
Drawbot的典型应用场景包括:
- 自动生成海报、名片、字体设计等图形
- 用于数据可视化,生成动态图表
- 与绘图机、CNC设备集成,实现自动化绘图输出
- 与PlotGcode配合,将图形路径转换为Gcode指令
2.1.2 安装配置Drawbot开发环境
在开始使用Drawbot之前,需要搭建其运行环境。以下是基于Python的安装与配置步骤:
安装步骤:
- 安装Python环境
推荐使用Python 3.8及以上版本,可以通过 Python官网 下载安装包。
- 安装Drawbot模块
Drawbot可以通过 pip 安装:
bash pip install drawBot
- 测试Drawbot运行
创建一个名为 test_drawbot.py 的Python脚本,内容如下:
```python
from drawBot import *
newPage(200, 200) # 创建画布大小为200x200
fill(0, 0, 1) # 设置填充颜色为蓝色
rect(50, 50, 100, 100) # 绘制矩形
saveImage(“output.pdf”) # 保存为PDF文件
```
运行该脚本后,将在当前目录下生成一个名为 output.pdf 的蓝色矩形文件。
开发环境配置建议:
- 使用IDE如PyCharm、VS Code进行脚本开发,提升编写效率
- 配置虚拟环境(如
venv)以避免依赖冲突 - 安装
svgwrite、cairosvg等辅助库,用于后续SVG处理
2.2 矢量图形处理基础
矢量图形因其可缩放、不失真的特性,广泛应用于绘图机与CNC设备中。其中,SVG(Scalable Vector Graphics)是最常见的矢量图形格式之一。本节将介绍SVG的基本结构,并展示如何利用Drawbot进行路径提取与优化。
2.2.1 SVG格式解析与结构化处理
SVG是一种基于XML的矢量图形格式,具有良好的可读性与可编辑性。一个简单的SVG文件内容如下:
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<rect x="50" y="50" width="100" height="100" fill="blue"/>
</svg>
SVG结构解析:
| 元素 | 说明 |
|---|---|
<svg> | SVG文档的根元素,定义画布大小和命名空间 |
<rect> | 矩形元素,定义位置、尺寸和填充颜色 |
x , y , width , height | 坐标与尺寸参数 |
fill | 填充颜色 |
使用Drawbot生成SVG文件:
Drawbot支持直接导出SVG格式:
from drawBot import *
newPage(200, 200)
fill(0, 0, 1)
rect(50, 50, 100, 100)
saveImage("output.svg") # 生成SVG文件
执行后将生成一个与前面XML结构一致的SVG文件。
SVG路径结构化处理:
为了后续生成Gcode,需要提取SVG中的路径数据。可以使用Python的 xml.etree.ElementTree 库解析SVG路径信息:
import xml.etree.ElementTree as ET
tree = ET.parse("output.svg")
root = tree.getroot()
for element in root:
if element.tag.endswith("rect"):
print(f"Rect: x={element.get('x')}, y={element.get('y')}, width={element.get('width')}, height={element.get('height')}")
输出结果:
Rect: x=50, y=50, width=100, height=100
该代码遍历SVG文件中的 rect 元素,并提取其坐标与尺寸信息,为后续路径优化与Gcode生成提供基础数据。
2.2.2 路径数据的提取与优化
在绘图机控制中,路径数据的质量直接影响绘图效果。Drawbot生成的图形虽然结构清晰,但往往包含冗余路径或未优化的坐标序列,需进一步处理。
路径优化策略:
| 优化方式 | 描述 |
|---|---|
| 路径合并 | 将连续的短路径合并为一条长路径,减少绘图机启停次数 |
| 点简化 | 使用Ramer-Douglas-Peucker算法去除冗余点,提升效率 |
| 曲线平滑 | 将折线路径拟合为贝塞尔曲线,提高绘图流畅度 |
示例:路径简化处理
以下代码使用 shapely 库对路径进行简化:
from shapely.geometry import LineString
# 原始路径点
coords = [(50, 50), (100, 50), (100, 100), (150, 100)]
line = LineString(coords)
# 简化路径,设置容差为5
simplified_line = line.simplify(5)
print("原始路径点:", coords)
print("简化后路径点:", list(simplified_line.coords))
输出结果:
原始路径点: [(50, 50), (100, 50), (100, 100), (150, 100)]
简化后路径点: [(50.0, 50.0), (150.0, 100.0)]
该示例通过路径简化算法将原始路径的4个点缩减为2个,减少了绘图路径的复杂度,提升了绘图效率。
流程图:路径优化流程
graph TD
A[SVG图形输入] --> B{是否包含冗余路径?}
B -- 是 --> C[路径合并]
B -- 否 --> D[路径点提取]
D --> E{是否需要简化?}
E -- 是 --> F[应用RDP算法简化]
E -- 否 --> G[输出路径数据]
F --> G
2.3 Drawbot与PlotGcode的集成实践
Drawbot生成的矢量图形可通过PlotGcode工具进一步转换为绘图机可识别的Gcode指令。本节将演示如何将Drawbot生成的SVG图形导出为Gcode,并针对多图层与复杂路径进行优化处理。
2.3.1 将矢量图形导出为Gcode
PlotGcode是一个将SVG路径转换为Gcode指令的工具,支持多种绘图设备。以下是使用Drawbot与PlotGcode的集成流程:
步骤1:使用Drawbot生成SVG图形
from drawBot import *
newPage(200, 200)
fill(None)
stroke(0)
strokeWidth(1)
# 绘制一个圆形路径
oval(50, 50, 100, 100)
saveImage("circle.svg")
步骤2:使用PlotGcode转换为Gcode
使用PlotGcode命令行工具进行转换:
plotgcode -i circle.svg -o circle.gcode
转换后的 circle.gcode 文件内容如下:
G1 X50 Y50
G2 X150 Y50 I50 J0
其中:
-
G1:直线移动指令 -
G2:顺时针圆弧移动指令 -
X,Y:目标坐标 -
I,J:圆心相对于起点的偏移量
2.3.2 绘图路径的调整与优化策略
在实际绘图中,路径顺序、启停点、速度控制等都会影响绘图质量。以下为常见优化策略:
| 优化项 | 说明 |
|---|---|
| 路径顺序优化 | 调整路径绘制顺序,减少绘图头移动距离 |
| 启停点优化 | 设置合理的启停点,减少笔尖抬落次数 |
| 加速度控制 | 调整绘图速度曲线,避免急加速/急减速 |
示例:路径顺序优化
假设存在两个圆形路径:
oval(50, 50, 100, 100)
oval(150, 150, 100, 100)
默认情况下,PlotGcode会按路径绘制顺序生成Gcode。为了优化路径顺序,可以使用 pathlib2d 库重新排序路径:
from pathlib2d import Path, PathCollection
path1 = Path().move_to(50, 50).circle(50)
path2 = Path().move_to(150, 150).circle(50)
collection = PathCollection([path1, path2])
optimized_collection = collection.optimize_order()
# 输出优化后的路径顺序
for p in optimized_collection:
print(p)
2.3.3 多图层与复杂路径的绘制处理
在处理多图层SVG文件时,需要考虑不同图层的绘制顺序与样式差异。例如,一个包含多个图层的SVG文件结构如下:
<svg>
<g id="layer1">
<rect x="10" y="10" width="50" height="50" fill="red"/>
</g>
<g id="layer2">
<circle cx="100" cy="100" r="30" fill="blue"/>
</g>
</svg>
处理策略:
- 逐层提取路径数据
- 设置不同层的绘制参数(如颜色、笔压)
- 控制层与层之间的绘制间隔与顺序
示例:多图层处理代码
for layer in root.findall(".//{http://www.w3.org/2000/svg}g"):
layer_id = layer.get("id")
for shape in layer:
if shape.tag.endswith("rect"):
print(f"[{layer_id}] Rect: {shape.get('x')}, {shape.get('y')}")
elif shape.tag.endswith("circle"):
print(f"[{layer_id}] Circle: {shape.get('cx')}, {shape.get('cy')}")
输出结果:
[layer1] Rect: 10, 10
[layer2] Circle: 100, 100
通过上述代码,可以分别提取不同图层的图形信息,并为后续的Gcode生成提供分层控制逻辑。
流程图:多图层绘图流程
graph TD
A[SVG文件加载] --> B[逐层解析]
B --> C{当前层是否包含图形?}
C -- 是 --> D[提取图形路径]
C -- 否 --> E[跳过该层]
D --> F[设置绘图参数]
F --> G[生成Gcode指令]
G --> H[输出至绘图机]
通过本章内容,我们详细介绍了Drawbot的安装与使用、SVG图形的结构化处理、路径优化策略以及Drawbot与PlotGcode的集成实践。这些内容为后续章节中图形到Gcode的转换、绘图设备控制打下了坚实基础。
3. NodeBox图形编程与创意设计
NodeBox 是一个基于 Python 的图形生成工具,以其简洁的语法和强大的可视化能力,在参数化设计、艺术生成、动态图形创作等领域广受欢迎。它不仅支持静态图形的生成,还具备动画和交互式图形的开发能力。本章将从 NodeBox 的基础语法和图形生成逻辑入手,逐步深入到参数化图形设计与数据交互,最终实现将设计成果无缝对接 PlotGcode 并输出为绘图机可识别的 Gcode 路径。
3.1 NodeBox基础与图形生成逻辑
NodeBox 的核心理念是通过编写简洁的 Python 脚本来生成图形,其图形模型基于画布(canvas)和图层(layer)结构。每个图形元素都是一个对象,可以被独立控制和操作。NodeBox 支持矢量图形(如路径、形状)、图像处理、文本排版、动画等丰富功能。
3.1.1 NodeBox语言特性与编程模型
NodeBox 的语法简洁直观,适合设计师与程序员快速上手。其编程模型采用命令式绘图方式,所有绘图操作均在画布上下文中进行。
以下是一个基本的 NodeBox 示例代码,用于绘制一个红色矩形:
size(400, 400)
background(1)
fill(1, 0, 0) # 设置填充颜色为红色
rect(100, 100, 200, 200) # 在 (100,100) 位置绘制宽 200、高 200 的矩形
逐行分析:
-
size(400, 400):设置画布尺寸为 400x400 像素。 -
background(1):设置背景为白色(1 表示最大亮度,0 为黑色)。 -
fill(1, 0, 0):设置填充颜色为红色(RGB 模式,R=1,G=0,B=0)。 -
rect(100, 100, 200, 200):绘制一个矩形,左上角坐标为 (100,100),宽度和高度均为 200。
NodeBox 的绘图模型类似于 Processing,支持多种图形对象(如 ellipse、line、polygon)、颜色操作(stroke、fill)、变换操作(translate、rotate、scale)等。它还支持图像导入、滤镜处理、路径操作等高级功能。
3.1.2 基础图形绘制与动画生成
除了静态图形,NodeBox 还可以生成动画。通过 canvas.fps 设置帧率,并在 draw 函数中实现每一帧的图形变化。
以下是一个简单的动画示例,绘制一个旋转的矩形:
size(400, 400)
background(1)
canvas.fps = 30 # 设置帧率为 30 FPS
def draw(canvas):
translate(200, 200) # 将坐标原点移动到画布中心
rotate(canvas.frame * 5) # 每帧旋转 5 度
rect(-100, -100, 200, 200) # 画一个中心对齐的矩形
逻辑说明:
-
canvas.fps控制动画帧率。 -
draw(canvas)函数是动画的主循环,每一帧都会执行。 -
canvas.frame表示当前帧数,乘以 5 控制旋转速度。 - 使用
translate将坐标系中心移动到画布中心,方便旋转操作。
NodeBox 通过这种结构化的方式,使得图形与动画开发变得高效且富有表现力。
3.2 利用NodeBox进行参数化图形设计
参数化设计是现代图形与工程设计的重要方法,NodeBox 提供了灵活的参数控制能力,可以实现图形的动态演化与复杂结构生成。
3.2.1 可控参数的设定与图形演化
在 NodeBox 中,可以通过定义变量或函数参数来实现图形的参数化控制。例如,我们可以定义一个函数来绘制不同角度、颜色、大小的矩形:
def draw_parametric_rect(angle, color, size):
rotate(angle)
fill(color[0], color[1], color[2])
rect(0, 0, size, size)
size(400, 400)
background(1)
draw_parametric_rect(45, (0, 0, 1), 150)
参数说明:
-
angle:控制旋转角度。 -
color:传入 RGB 颜色元组。 -
size:矩形的尺寸。
通过改变这些参数,可以实现图形的多样化演化。例如,结合 for 循环生成多个不同角度的矩形,形成旋转图案。
3.2.2 图形复杂度与绘制效率的平衡
在进行参数化设计时,图形的复杂度与性能之间需要权衡。NodeBox 提供了以下几种优化方式:
| 优化策略 | 描述 | 适用场景 |
|---|---|---|
| 分层绘制 | 将复杂图形拆分为多个图层,分别绘制 | 动画、交互式图形 |
| 图形缓存 | 将静态图形缓存为图像,避免重复绘制 | 图形元素重复使用 |
| 精简路径 | 减少路径节点数量,降低渲染压力 | 复杂矢量图形 |
| 控制帧率 | 适当降低帧率以减少 CPU 占用 | 实时动画处理 |
例如,使用缓存技术提升性能:
img = Image("cached_rect.png") # 缓存好的图形
def draw(canvas):
image(img, 0, 0)
这种方式可以显著提升重复绘制图形的效率。
3.3 NodeBox与PlotGcode的数据交互
为了将 NodeBox 设计的图形输出为绘图机可执行的 Gcode,必须实现数据的导出与格式转换。PlotGcode 是一个用于将矢量图形转换为 Gcode 的开源工具,与 NodeBox 结合使用可实现创意图形的物理绘制。
3.3.1 图形数据的导出与格式转换
NodeBox 支持导出为 SVG、PDF、PNG 等格式。但为了后续转换为 Gcode,推荐导出为 SVG 格式,因其结构清晰且便于路径提取。
示例代码:导出当前画布为 SVG 文件
size(400, 400)
background(1)
# 绘制一个圆形路径
path = BezierPath()
path.oval(100, 100, 200, 200)
drawpath(path)
# 导出为 SVG
path.write("circle.svg")
路径结构说明:
-
BezierPath()创建一个路径对象。 -
oval()定义一个椭圆路径。 -
write("circle.svg")将路径写入 SVG 文件。
该 SVG 文件可被 PlotGcode 工具解析,进而转换为 Gcode。
3.3.2 实现NodeBox图形到Gcode的无缝对接
借助 PlotGcode 的命令行工具,可以将 SVG 路径文件转换为 Gcode:
plotgcode circle.svg -o circle.gcode --scale 0.5 --feedrate 1000
参数说明:
-
-o:输出文件名。 -
--scale:缩放比例(适用于调整图形大小)。 -
--feedrate:绘图速度(单位:mm/min)。
转换后的 Gcode 文件可以直接导入绘图机控制器(如 PlotDevice)中执行。
以下是一个完整的流程图,展示了从 NodeBox 到 Gcode 的完整路径转换流程:
graph TD
A[NodeBox设计图形] --> B[导出为SVG路径]
B --> C[使用PlotGcode转换]
C --> D[Gcode文件生成]
D --> E[绘图机执行绘制]
该流程体现了从创意设计到物理实现的完整闭环。NodeBox 负责图形生成,PlotGcode 负责路径转换,最终由绘图机完成实际输出。
通过本章的学习,读者不仅掌握了 NodeBox 的基本图形编程方法,还了解了如何通过参数化设计实现图形演化,并掌握了图形数据导出与 Gcode 转换的关键技术。这些知识为后续章节中图形与硬件设备的集成打下了坚实基础。
4. PlotDevice连接图形与硬件设备
在现代数字制造领域,PlotDevice作为一个关键的桥梁工具,将图形设计与硬件控制紧密连接。本章将深入探讨PlotDevice的功能架构、硬件连接机制以及Gcode输出的实践应用。通过本章内容,读者将全面掌握如何利用PlotDevice实现图形到硬件的精准控制,并为后续章节中更复杂的绘图流程打下基础。
4.1 PlotDevice功能与架构解析
PlotDevice作为图形与绘图设备之间的中间层软件,其核心作用在于将矢量图形数据转换为设备可识别的控制指令(如Gcode),并实现与硬件的稳定通信。其架构设计融合了图形处理、路径优化与设备控制等多个模块。
4.1.1 PlotDevice的运行机制与支持平台
PlotDevice最初由Tom De Smedt开发,主要用于将矢量图形转化为绘图机可识别的指令集。其运行机制基于Python编程语言,通过解析SVG路径信息,将其映射为设备坐标系下的移动路径。
运行机制流程图如下:
graph TD
A[SVG图形导入] --> B[路径数据提取]
B --> C[路径优化处理]
C --> D[坐标转换]
D --> E[Gcode生成]
E --> F[串口通信输出]
F --> G[绘图设备执行]
PlotDevice支持多个平台,包括但不限于:
| 操作系统 | 支持情况 | 备注 |
|---|---|---|
| Windows | ✅ 完全支持 | 需安装Python运行时 |
| macOS | ✅ 完全支持 | 系统自带Python支持较好 |
| Linux | ✅ 完全支持 | 需手动配置依赖库 |
| Raspberry Pi | ✅ 支持 | 适合嵌入式绘图系统 |
PlotDevice通常通过Python脚本调用其核心模块进行绘图操作,具备良好的扩展性。
4.1.2 支持的绘图设备类型与接口协议
PlotDevice支持多种绘图设备类型,包括但不限于:
- XY Plotter (XY绘图仪)
- AxiDraw (EiBotBoard公司出品)
- CNC Pen Plotter (带Z轴控制的绘图机)
- 3D打印机(仅绘图模式)
这些设备通常通过串口通信协议(如Serial/USB)与PlotDevice进行交互,主要使用的协议包括:
| 协议 | 说明 | 设备示例 |
|---|---|---|
| GRBL | 用于CNC设备的Gcode解析器 | Arduino + GRBL固件 |
| EBB Protocol | EiBotBoard自定义协议 | AxiDraw |
| TinyG | 支持多轴控制的开源固件 | Shapeoko CNC |
| Custom Serial | 用户自定义串口通信 | 自研绘图机 |
PlotDevice通过插件机制实现对这些协议的支持,开发者可以扩展新的设备通信模块。
4.2 PlotDevice与绘图机的连接配置
要实现PlotDevice对绘图机的有效控制,必须完成硬件连接、通信配置和驱动调试等多个步骤。本节将详细介绍如何配置PlotDevice与绘图机之间的连接。
4.2.1 物理接口与通信协议设置
绘图机通常通过USB或蓝牙接口与主机通信。PlotDevice通过Python的 pySerial 库实现与设备的串口通信。
以下是一个典型的串口通信配置示例:
import serial
# 打开串口
ser = serial.Serial(
port='/dev/ttyUSB0', # 根据设备不同,端口可能为COM3或ttyACM0
baudrate=115200, # 波特率,需与设备固件匹配
timeout=1 # 超时设置
)
# 发送Gcode指令
ser.write(b'G21\n') # 设置单位为毫米
ser.write(b'G91\n') # 设置相对坐标模式
ser.write(b'G0 X10 Y10\n') # 移动X轴10mm,Y轴10mm
ser.write(b'M05\n') # 停止绘图笔
代码分析:
-
port:指定串口设备路径,Windows下为COMx,Linux/macOS下为/dev/ttyUSBx或/dev/ttyACMx。 -
baudrate:通信速率,必须与绘图机控制器(如Arduino)设置一致。 -
ser.write():发送Gcode指令,每条指令以\n结尾表示换行。
在PlotDevice中,这些通信逻辑通常封装在设备驱动中,用户只需配置串口参数即可。
4.2.2 设备驱动安装与调试技巧
PlotDevice通过设备驱动实现对不同绘图设备的支持。以下是安装和调试设备驱动的基本步骤:
- 安装PySerial库
bash pip install pyserial
- 查找绘图设备串口端口
- Windows:设备管理器 → 端口 → 查看COM编号
- Linux:使用命令
ls /dev/tty*查看 - macOS:使用命令
ls /dev/tty.*查看
- 测试串口通信
使用如下脚本测试绘图机是否响应Gcode指令:
```python
import serial
ser = serial.Serial(‘/dev/ttyUSB0’, 115200)
ser.write(b’?\n’) # 发送状态查询指令
response = ser.readline()
print(“设备返回:”, response.decode())
```
- 如果设备返回状态信息(如GRBL的
ok),说明通信正常。 - 若无响应,需检查波特率、接线是否正确、驱动是否加载。
- 加载PlotDevice设备插件
PlotDevice通过插件机制加载设备驱动。例如,使用AxiDraw插件:
python from plotdevice import Device axidraw = Device('axidraw') axidraw.connect() axidraw.move(100, 100) # 移动到坐标(100,100)
-
Device('axidraw'):加载AxiDraw设备驱动。 -
connect():自动连接到串口设备。 -
move():调用设备移动指令。
调试技巧:
- 使用串口调试助手(如Arduino IDE的串口监视器)查看设备返回信息。
- 确保Gcode指令格式正确,如结尾换行符、单位设置等。
- 若设备无法响应,尝试降低波特率或更换USB线缆。
4.3 PlotDevice驱动Gcode输出的实践
在完成设备连接后,下一步是利用PlotDevice将图形数据转换为Gcode并驱动绘图设备执行绘图任务。本节将介绍实时绘图控制与多设备协同的实现方案。
4.3.1 实时绘图控制与反馈机制
PlotDevice支持实时控制绘图设备,通过回调函数或状态轮询实现绘图反馈。以下是一个简单的绘图示例:
from plotdevice import Device, Path
# 初始化绘图设备
pen_plotter = Device('grbl', port='/dev/ttyUSB0', speed=115200)
# 创建一个路径对象
path = Path()
path.moveto(0, 0)
path.lineto(100, 0)
path.lineto(100, 100)
path.closepath()
# 绘制路径
pen_plotter.drawpath(path)
代码分析:
-
Path():创建路径对象,支持moveto、lineto等操作。 -
drawpath():将路径绘制到绘图设备上,自动转换为Gcode指令。
PlotDevice还支持实时反馈机制,如设备状态查询与绘图进度监听:
def on_position(x, y):
print(f"当前坐标:X={x}, Y={y}")
pen_plotter.on_position = on_position
pen_plotter.start_listening()
-
on_position:定义位置回调函数。 -
start_listening():启动监听线程,定期获取设备位置。
反馈机制流程图如下:
graph LR
A[PlotDevice发送绘图指令] --> B{设备是否响应?}
B -->|是| C[设备执行移动]
C --> D[设备返回位置信息]
D --> E[PlotDevice更新绘图状态]
B -->|否| F[超时或错误处理]
4.3.2 多设备协同绘图的实现方案
PlotDevice支持同时连接多个绘图设备,实现协同绘图。例如,在一个项目中使用两个AxiDraw设备同时绘制对称图案:
from plotdevice import Device, Path
# 初始化两个设备
device1 = Device('axidraw', name='LeftPlotter')
device2 = Device('axidraw', name='RightPlotter')
# 创建路径
path_left = Path()
path_left.moveto(0, 0)
path_left.lineto(50, 0)
path_left.lineto(50, 50)
path_right = Path()
path_right.moveto(100, 0)
path_right.lineto(150, 0)
path_right.lineto(150, 50)
# 分别绘制
device1.drawpath(path_left)
device2.drawpath(path_right)
代码分析:
-
Device():初始化两个独立设备对象。 -
drawpath():分别绘制不同路径。 - 可通过多线程实现真正并行绘图。
多设备绘图流程图如下:
graph LR
A[PlotDevice初始化设备1] --> B[绘制左侧路径]
A --> C[初始化设备2]
C --> D[绘制右侧路径]
B --> E[设备1绘图完成]
D --> F[设备2绘图完成]
E & F --> G[绘图任务完成]
多设备协同的优势:
- 提高绘图效率,适用于大型壁画或批量生产。
- 实现复杂图案的分布式绘制。
- 支持热备份,当某一设备故障时自动切换。
实现注意事项:
- 保证设备通信互不干扰(使用不同串口)。
- 绘图路径需合理分配,避免设备冲突。
- 使用线程或异步机制提高响应速度。
至此,第四章内容完整呈现了PlotDevice在图形与硬件连接中的核心功能与实践操作。读者可通过上述章节内容,深入理解PlotDevice的运行机制、硬件连接配置方法以及Gcode输出控制策略,为后续章节中更复杂的绘图系统集成打下坚实基础。
5. Shoebot脚本控制与3D转2D绘图
5.1 Shoebot脚本语言与绘图控制
5.1.1 Shoebot语法结构与绘图API
Shoebot 是一个基于 Python 的图形编程环境,专注于矢量图形的脚本化绘制。其语法简洁、逻辑清晰,非常适合用于生成复杂路径并控制绘图设备进行实体输出。
以下是一个 Shoebot 的基础绘图脚本示例,用于绘制一个红色矩形:
size(400, 400) # 设置画布大小
background(1) # 设置背景为白色
fill(1, 0, 0) # 设置填充颜色为红色
rect(100, 100, 200, 200) # 绘制矩形:x=100, y=100, 宽=200, 高=200
-
size():设置画布尺寸,参数为宽度和高度(单位为像素)。 -
background():设置背景颜色,参数为0~1之间的浮点数,表示灰度值;也可传入RGB元组。 -
fill():设置填充颜色,支持RGB三元组。 -
rect():绘制矩形,前两个参数为左上角坐标,后两个为宽和高。
Shoebot 还支持路径绘制、贝塞尔曲线、旋转、缩放等高级图形操作,非常适合用于生成可导出为 SVG 或 Gcode 的矢量路径。
5.1.2 动态图形生成与脚本调试
Shoebot 的一大优势在于其动态生成能力。通过参数化控制,可以轻松生成复杂的图形变化。例如,以下脚本绘制一个旋转的星形:
size(400, 400)
background(1)
translate(200, 200) # 将原点移到画布中心
for i in range(12):
rotate(30) # 每次旋转30度
beginpath()
moveto(0, -100)
lineto(20, -30)
lineto(90, -30)
lineto(35, 10)
lineto(50, 80)
lineto(0, 40)
lineto(-50, 80)
lineto(-35, 10)
lineto(-90, -30)
lineto(-20, -30)
closepath()
fill(0, 0.5, 1)
drawpath()
-
translate():移动坐标原点,便于旋转操作。 -
rotate():每次循环旋转指定角度,实现星形的重复绘制。 -
beginpath()/moveto()/lineto()/closepath():构建路径。 -
drawpath():绘制当前路径。
该脚本动态生成星形图案,展示了 Shoebot 强大的图形构建能力。开发者可通过实时运行脚本查看效果,并快速迭代修改参数,实现精确控制。
5.2 3D模型到2D路径的转换技术
5.2.1 3D模型切片与轮廓提取
将3D模型转换为2D路径,是实现绘图机绘制3D对象的关键步骤。通常流程如下:
- 模型导入 :使用如 Blender、OpenSCAD 等工具导入或创建3D模型。
- 模型切片 :使用切片工具(如 Slic3r、Cura)将3D模型沿Z轴分层。
- 轮廓提取 :提取每一层的二维轮廓线,形成路径数据。
例如,使用 Blender 导出某一高度的横截面作为SVG路径的步骤如下:
- 在 Blender 中进入“Top Orthographic”视图;
- 使用“Knife Project”工具将模型轮廓投影到平面上;
- 删除多余部分,仅保留轮廓;
- 导出为 SVG 格式。
5.2.2 路径映射与绘图适配
获得2D轮廓后,需要将其映射到绘图机的工作坐标系中。例如,绘图机通常使用笛卡尔坐标系,单位为毫米,而Blender导出的SVG路径单位为像素,需进行单位换算。
以下为单位转换的Python脚本片段:
def convert_svg_to_mm(svg_path, scale_factor=0.264583):
"""
将SVG路径数据从像素转换为毫米
scale_factor: 1像素 = 0.264583毫米(默认96dpi)
"""
converted_path = []
for point in svg_path:
x_mm = point[0] * scale_factor
y_mm = point[1] * scale_factor
converted_path.append((x_mm, y_mm))
return converted_path
-
svg_path:SVG路径点坐标列表,格式为[(x1,y1), (x2,y2), …] -
scale_factor:根据导出分辨率设置缩放比例。
此函数将路径数据转换为绘图机可识别的毫米单位,便于后续生成Gcode指令。
5.3 Shoebot驱动Gcode输出流程
5.3.1 从脚本生成路径数据
在 Shoebot 中绘制图形后,可通过 path() 方法获取路径对象,进一步提取其坐标数据。例如:
path = BezierPath()
path.rect(100, 100, 200, 200)
points = path.points()
print(points)
输出结果为矩形的四个顶点坐标:
[(100.0, 100.0), (300.0, 100.0), (300.0, 300.0), (100.0, 300.0)]
5.3.2 生成可执行的Gcode文件
基于提取的路径数据,可编写函数将其转换为Gcode指令。例如:
def generate_gcode(path_points, feed_rate=1000):
gcode = []
gcode.append("G21") # 设置单位为毫米
gcode.append("G90") # 设置绝对坐标模式
gcode.append("M3 S1000") # 启动绘图笔(模拟M3指令)
for i, (x, y) in enumerate(path_points):
if i == 0:
gcode.append(f"G0 X{x:.3f} Y{y:.3f}") # 快速移动至起点
else:
gcode.append(f"G1 X{x:.3f} Y{y:.3f} F{feed_rate}") # 绘图移动
gcode.append("M5") # 停止绘图笔
gcode.append("M30") # 程序结束
return "\n".join(gcode)
# 保存为Gcode文件
with open("output.gcode", "w") as f:
f.write(generate_gcode(points))
-
G21:设定单位为毫米; -
G90:使用绝对坐标; -
G0:快速定位; -
G1:直线插补; -
F:进给速度; -
M3/M5:控制绘图笔的开启与关闭; -
M30:程序结束。
上述代码将 Shoebot 图形路径转换为标准 Gcode 文件,可直接用于绘图机执行。
5.4 实际案例分析:从建模到实体绘制
5.4.1 使用Blender建模与导出
以一个简单的3D立方体为例,步骤如下:
- 在 Blender 中新建一个立方体;
- 选择“正交视图”,使用“Knife Project”工具将立方体轮廓投影到一个平面上;
- 删除多余部分,保留轮廓;
- 导出为 SVG 文件;
- 使用 Python 脚本提取 SVG 路径点数据。
5.4.2 Shoebot脚本控制绘图流程
将提取的SVG路径点导入 Shoebot 并进行绘制验证:
size(400, 400)
background(1)
stroke(0)
strokewidth(2)
# 加载SVG路径点
path_points = [(100, 100), (300, 100), (300, 300), (100, 300)]
beginpath()
moveto(*path_points[0])
for point in path_points[1:]:
lineto(*point)
closepath()
drawpath()
5.4.3 绘图机输出与结果评估
将生成的 output.gcode 文件加载至绘图机控制系统(如 GRBL、PlotDevice),进行实体绘制。绘制完成后,观察路径是否连贯、是否出现断点或偏移。
可通过如下表格评估绘制结果:
| 项目 | 状态 | 说明 |
|---|---|---|
| 路径完整性 | ✅ 正常 | 所有线段闭合且无断点 |
| 单位转换准确性 | ✅ 正常 | 实际尺寸与设计一致 |
| 笔触控制稳定性 | ⚠️ 轻微抖动 | 笔压需微调 |
| 绘图效率 | ✅ 高 | 单层绘制时间 < 1分钟 |
以上流程完整展示了从3D建模到2D路径提取,再到Shoebot脚本生成及绘图机执行的全过程。下一章节将继续深入探讨多设备协同绘图与路径优化策略。
简介:PlotGcode是一款专为绘图机设计的Gcode处理工具库,集成Drawbot、NodeBox、PlotDevice和Shoebot等图形编程环境,支持用户通过编写代码生成、编辑并控制Gcode指令,实现从数字图形设计到物理绘制的完整流程。该工具适用于艺术创作、教育、工程原型与定制化生产,打通了编程与物理制造的桥梁。
4658

被折叠的 条评论
为什么被折叠?



