使用犀牛软件python自动化绘制大量坐标点,怎么减少绘制时间

背景介绍:.需要绘制的图是半径为0.0075-0.010的随机圆,大概需要30亿个圆
出现的问题:绘制相同规格的圆,使用批处理绘制,比一块一块绘制的时间长的多
绘制代码:

import os
import math
import Rhino
import scriptcontext as sc
import csv
# import rand_v4  # 确保 rand_v4 模块在同级目录下并可用
import time


# 定义画布大小、半径偏移量
canvas_size = (20, 20)
r_offset = 0.005
# r_offset = 0

# 计算最终行数和列数
# final_rows = math.ceil(rand_v4.final_canvas_size[1] / rand_v4.canvas_size[1])
# final_cols = math.ceil(rand_v4.final_canvas_size[0] / rand_v4.canvas_size[0])

def draw_circles_in_rhino(points):
    for point in points:
        # 提取点和半径
        x, y, radius = point
        # 在指定的点处绘制一个指定半径的圆
        center_point = Rhino.Geometry.Point3d(x, y, 0)
        circle = Rhino.Geometry.Circle(center_point, radius)
        sc.doc.Objects.AddCircle(circle)

def draw_line(start_point, end_point):
    line = Rhino.Geometry.Line(start_point, end_point)
    sc.doc.Objects.AddLine(line)

def save_as_dwg(file_path):
    save_script = f"-_Export \"{file_path}\" _Enter"
    Rhino.RhinoApp.RunScript(save_script, True)



def main():
    time_start = time.time()

    # 获取脚本所在目录
    script_directory = os.path.dirname(__file__)
    # 定义数据目录
    save_directory = os.path.join(script_directory, 'data')

    # 确保目录存在
    if not os.path.exists(save_directory):
        print("数据目录不存在")
        return

    # 绘制圆点
    for row in range(2):
        for col in range(2):
            # 指定 CSV 文件的文件名
            file_points_all = 'points_all%dx%d.csv' % (row, col)
            # 从 CSV 文件读取points_all数据
            file_path = os.path.join(save_directory, file_points_all)
            if not os.path.exists(file_path):
                print(f"文件 {file_path} 不存在")
                continue
            
            with open(file_path, mode='r') as file:
                reader = csv.reader(file)
                next(reader)  # 跳过标题行(如果有)
                points_all = [[float(x), float(y), float(r)] for x, y, r in reader]
            draw_circles_in_rhino(points_all)

            # 绘制画布边界
            draw_line(Rhino.Geometry.Point3d(0, 0, 0), Rhino.Geometry.Point3d(canvas_size[0] * (1 + col), 0, 0))
            draw_line(Rhino.Geometry.Point3d(0, 0, 0), Rhino.Geometry.Point3d(0, canvas_size[1] * (1 + row), 0))
            draw_line(Rhino.Geometry.Point3d(canvas_size[0] * (1 + col), 0, 0), Rhino.Geometry.Point3d(canvas_size[0] * (1 + col), canvas_size[1] * (1 + row), 0))
            draw_line(Rhino.Geometry.Point3d(0, canvas_size[1] * (1 + row), 0), Rhino.Geometry.Point3d(canvas_size[0] * (1 + col), canvas_size[1] * (1 + row), 0))

    sc.doc.Views.Redraw()  # 重绘视图

    # 保存为 DWG 文件
    dwg_file_path = os.path.join(script_directory, '500x200.dwg')
    save_as_dwg(dwg_file_path)

    time_end = time.time()
    print(f"绘制时间为:({time_end - time_start})")

if __name__ == "__main__":
    main()

30亿的圆画完之后需要做什么呢

画完之后需要保存成dwg文件,后期用于下游任务

你的一个板材上需要开30亿个洞吗?
这是什么板材?
几百米的板材,有这样的加工机器吗
如果有的话,加工厂的机器能载入30亿圆圈的单个dwg文件吗

1 个赞

已经看到了你的代码,如果总量30亿,分布在N个板材,每个板材一个csv生成一个dwg,每个板材的圆圈数量不那么大。那么个步骤可行
否则就是无稽之谈了。。

https://ezdxf.readthedocs.io/en/stable/
建议你下载pycharm单独处理,用上面的第三方库ezdxf
这个事情完全没必要在rhino内跑python,生成一大堆rhino圆形,然后再用rhino的3dm-dwg模块写成dwg
这个过程里面单纯数据的计算量可能只有1%,剩下99%都是几何层面和文件协议层面的API

注意:这个库只能生成dxf
你可以继续使用其他第三方工具将dxf转化为dwg,甚至如果下游直接支持dxf,你可以不转化。

借助AI帮你生成一下代码,大约在20行以内,生成代码+修改调试运行理论上不会超过10分钟
其他应该有的辅助库装好,numpy必须,pandas看情况
文件量巨大,考虑你的原始文件优化一下。
例如本来用方案A生成的csv
试试看用方案B生成更加高效的文件,常见的bin格式(numpy的),或者主流大数据格式hdf5,parquet等等都行。
csv实在是太粗暴了

3 个赞

半径是微米级别的,实际上一米五的正方形就能放30亿个点

非常感谢您的回答,ezdxf库我已经试过了,生成速度远远慢于犀牛绘制,所以现在也找不到合适的技术加快绘制

这是不可能的
读取csv文件后,使用ezdxf和numpy直接写入dxf文件
速度远远超过rhino内的读取csv+生成圆圈+创建dwg

如果一个dwg文件就需要承担30亿的圆
你可以计算一下他们总计需要的数据量
就不说这一个csv文件用的字符串需要多大,哪怕单纯用二进制来记录这些数据
30亿是什么概念?
3000000000个float的储存大小是(float=32位,4Bytes)
3000000000*4/1024/1024/1024 (三个1024表示GB)

11GB的DWG
这个大小的DWG文件,这个密度的圆圈,是光刻机吗?

csv可能轻松达到几百个GB

你的整个需求都来自于一个伪需求

4 个赞

绘制确实很困难,30亿的数据点是最终希望能做到的,目前能做到的是1.32亿个数据点(通过外部参照,再合并dwg的方式,最终也是一个dwg文件),我目前也不清楚下游是怎么做到读取这些dwg的,正常来说,不调用这些cad的api会更快,但实际实验使用ezdxf比autocad和犀牛都慢,这个我得再研究研究,非常感谢您的回答,对我后续的研究非常有帮助

我目前也不清楚下游是怎么做到读取这些dwg的

其实这种需求就属于伪需求
你应该做的是对下游的工艺做一些基本了解
其中任何一种可能性都会导致你的30亿圆圈cad的需求不存在:

1:这个密度的板材压根就找不到任何一个供应商能加工,是不是这个情况需要反馈到你的甲方?
如果这个操作是业界常规操作,你请教过同行的经验吗?
2:供应商本身就不一定要用dwg格式,可以是其他格式,甚至直接读取csv,这个你确认过吗?
3:一个板材上面的圆圈是否可以按照批次分成多个dwg文件,以达到加工机器的内存范围,然后使用流式读取的方式一个个dwg读取后加工,这个你有找过厂家咨询吗?

这些从你的回答来看完全不了解

在这个情况下容易诞生伪需求
“我觉得就这么做,我觉得下游就是要这个dwg图纸”
可能从一开始你的努力方向就错了呢
一直不进行深度的贯穿上下游的思考,只用自己有限的经验去揣测需求,那么最终只会让自己陷入到一个死循环。

3 个赞

明白了,非常感谢您的回答,我会重新梳理一遍整个程序开发和工艺制作的逻辑