用python批量获取cad中线段点组成的凸包 + 面积

用python批量获取cad中线段点组成的凸包 + 面积

效率实在太低,还是用c# 吧

import win32com.client
import pythoncom
import tubao
import gelin
from tkinter import filedialog
import time
import numpy

def list_change(old_list, step=4, stop=None):  # 列表,步长,保留元素到第几个索引位置
    new_list = [old_list[x:x + step][:stop] for x in range( 0, len( old_list ), step )]
    return new_list


def vtpnt(x, y, z=0):
    """坐标点转化为浮点数"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))


def vtobj(obj):
    """转化为对象数组"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, obj)


def vtFloat(list):
    """列表转化为浮点数"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, list)


def vtInt(list):
    """列表转化为整数"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, list)


def vtVariant(list):
    """列表转化为变体"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, list)

start =time.clock()
f = open( "are.txt", "a+" )
acad = win32com.client.Dispatch( "AutoCAD.Application" )
# doc = acad.ActiveDocument
docs = acad.Documents  # AutoCAD图形的集合
paths = filedialog.askopenfilenames( filetypes=[("文本", "dwg")], title="选择数据" )
for path in paths:
    doc = docs.Open( path, False )  # 打开现有图形文件(DWG)并将其设为活动的文档,Document 对象
    # count = docs.Count #获取图形集合个数

    # doc.AuditInfo(False) # T修复所有图形错误,F不修复所有图形错误


    doc.ActiveSelectionSet.Clear()
    mp = doc.ModelSpace
    # sd1 = doc.Layers.Add("new_layer") # 添加图层
    #
    # doc.ActiveLayer = sd1 # 激活添加的图层
    try:
        doc.SelectionSets.Item( "ss1" ).Delete()  # 删除指定的选择集
    except:
        doc.Utility.Prompt( "\n醉后不知天在水\n满船清梦压星河\n" )

    v = doc.SelectionSets.Add( "ss1" )  # 添加名字为sd的选择集
    FilterType = vtInt([0])
    FData = vtVariant(["TEXT"])
    v.Select( 5 ,"","",FilterType,FData)
    '''
    https://blog.csdn.net/zhd18/article/details/78726469/
    全选 acSelectionSetAll = 5  ,tmd AcSelect 常数第五个
    FilterType  0 图元类型 8 图层
    FDdata 图元类型: 图层名称:
    '''

    # s = v.name #选择集的名称
    # point_1  = vtpnt(0,10,0)
    # point_2  = vtpnt(500,1000,0)
    # mp.Polyline(point_1,point_2) #添加直线

    point_3 = sum( [list_change(  x.InsertionPoint , step=3,stop=2 ) for x in v ],
                   [] )  # 所有的coordinates

    print(point_3)

    new_poinit_3 = list(dict.fromkeys(point_3))

    result = tubao.graham_scan( new_poinit_3 )

    #多段线
    points = numpy.array([m for n in result for m in n], dtype=numpy.float) # 格式转换
    polyline_points = vtFloat(points)

    retVal = mp.AddLightweightPolyline(polyline_points) #绘制多段线

    retVal.Closed = True #多段线闭合


    are = gelin.compute_polygon_area( result )

    f.writelines( [path, ":", str(are),"\n"] )
    # doc.SendCommand("PL ") #想cad命令行输入命令,命令后加空格结束命令

    # doc.SaveAs(r"C:\Users\Administrator\Desktop\Drawing3.dwg") #另存
    # doc.Save() # 保存
    doc.Close( False, path )  # 关闭文档
    time.sleep( 5 )
f.close()
end = time.clock()
print('Running time: %s Seconds'%(end-start))
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
如果不使用,也可以通过计算每个点的法向量,判断其是否为边界点。具体步骤如下: 1. 计算点云法向量 可以使用 `o3d.geometry.estimate_normals()` 函数来计算点云的法向量。该函数会根据点云每个点的邻域点计算其法向量,并将法向量信息存储在点云的 `normal` 属性。 示例代码: ```python import open3d as o3d # 读取点云数据 pcd = o3d.io.read_point_cloud("your_point_cloud.pcd") # 估计点云法向量 pcd.estimate_normals() ``` 2. 判断点是否为边界点 对于每个点,可以通过计算其与邻域点的法向量夹角来判断其是否为边界点。如果夹角大于某个阈值,则认为该点为边界点。 示例代码: ```python import open3d as o3d import numpy as np # 读取点云数据 pcd = o3d.io.read_point_cloud("your_point_cloud.pcd") # 估计点云法向量 pcd.estimate_normals() # 计算点是否为边界点 boundary_points = [] for i in range(len(pcd.points)): normal = np.asarray(pcd.normals[i]) indices, distances = pcd.tree.query_radius([pcd.points[i]], r=0.1, return_distance=True) is_boundary_point = True for j in range(indices.shape[0]): if j == 0: continue neighbor_normal = np.asarray(pcd.normals[indices[j]]) angle = np.arccos(np.dot(normal, neighbor_normal)) if angle < np.pi / 2: is_boundary_point = False break if is_boundary_point: boundary_points.append(pcd.points[i]) boundary_points = o3d.geometry.PointCloud() boundary_points.points = o3d.utility.Vector3dVector(np.asarray(boundary_points)) boundary_points.paint_uniform_color([0, 1.0, 0]) # 可视化 o3d.visualization.draw_geometries([pcd, boundary_points]) ``` 在上面的代码,首先使用 `estimate_normals()` 函数计算点云的法向量。然后,对于每个点,计算其与邻域点的法向量夹角,如果夹角都大于90度,则认为该点是边界点。最后,将边界点可视化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值