明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1027|回复: 4

AutoCAD多段线坐标取整时关于坐标系的问题

[复制链接]
发表于 2023-2-28 18:43:34 | 显示全部楼层 |阅读模式
本帖最后由 箭头_Row 于 2023-2-28 18:48 编辑

先上代码:

代码逻辑如下:
STEP01:定义函数,在图中选择多段线(仅限模型空间操作,因为目前本人还不会判断选择正在操作的空间)

STEP02:获取多段线属性列表,顶点坐标列表,使用round函数取整。
STEP03:获取凸度列表,删除多段线。

STEP04:绘制多段线,添加凸度,赋值属性。


BUG:如果UCS坐标是旋转过的UCS,无法智能以自定义的UCS去取用户坐标点取整数,会依然以WCS世界坐标系中的坐标值取整。如何解决这个BUG,有么有大佬提供点思路,提供一些关于UCS用户坐标系相关的资料研究研究。

  1. # env Python = 3.11.1  pywin32 = 305
  2. # -*- coding: utf-8 -*-

  3. """
  4.     =============================
  5.     Author: Meditation/箭头
  6.     Email: 1191101855@qq.com
  7.     Last Update: 2023.02.14 20:22
  8.     =============================
  9. """
  10. import win32com.client as win32
  11. import pythoncom

  12.     # AutoCAD 2022的ProgramID
  13. ProgramID = "AutoCAD.Application.24.1"
  14.     # 获取CAD程序      
  15. Acadapp = win32.Dispatch(ProgramID)
  16.     # 指定当前活动文档
  17. doc = Acadapp.ActiveDocument
  18. AcadA = doc.Application
  19. msp = doc.ModelSpace
  20. print(doc.Path, '\\', doc.Name, sep='')

  21. # 数据转换
  22. def vtpnt(x, y, z=0):
  23.     """坐标点转化为浮点数"""
  24.     return win32.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))

  25. def vtobj(obj):
  26.     """转化为对象数组"""
  27.     return win32.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, obj)

  28. def vtlstf(lst):
  29.     """列表转化为浮点数"""
  30.     return win32.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, lst)
  31.    
  32. def vtlsti(lst):
  33.     """列表转化为整数"""
  34.     return win32.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, lst)

  35. def vtlstvariant(lst):
  36.     """列表转化为变体"""
  37.     return win32.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, lst)

  38. def My_Select():
  39.     # 新建选择集
  40.     try:
  41.         doc.SelectionSets.Item("SS1").Delete()
  42.     except:
  43.         print("Delete selection failed")
  44.         
  45.     slt = doc.SelectionSets.Add("SS1")

  46.     slt.SelectOnScreen()

  47.     return slt

  48. def Polyline_XY_Zero():

  49.     """注意如果坐标系与当前坐标系不一致,可能导致数据error"""
  50.     slt = My_Select()

  51.     count = 0
  52.     for Entity in slt:
  53.         Coor = []
  54.         if Entity.objectname == 'AcDbPolyline':
  55.             Entity_Properties = [Entity.Layer, Entity.Color, Entity.Linetype ,Entity.LinetypeScale ,Entity.Lineweight]
  56.             Entity_closed = Entity.closed
  57.             Entity_Coor = Entity.Coordinates
  58.             # print(Entity_Coor)

  59.             # 获取多线段的顶点数
  60.             Entity_count = int(len(Entity_Coor)/2)

  61.             # 获取凸度列表
  62.             Entity_Bulge = []
  63.             for i in range(Entity_count):
  64.                 RetVal = Entity.GetBulge(i)
  65.                 Entity_Bulge.append(RetVal)
  66.             # print(Entity_Bulge)

  67.             # 坐标值精度归0
  68.             for xy in Entity_Coor:
  69.                 Entity_Coor_round = round(xy,0)
  70.                 Coor.append(Entity_Coor_round)

  71.             Entity.Erase()

  72.             new_Coor = vtlstf(Coor)
  73.             Entity = doc.ModelSpace.AddLightWeightPolyline(new_Coor)

  74.             # 添加凸度
  75.             for i in range(len(Entity_Bulge)):
  76.                 Entity.SetBulge(i, Entity_Bulge[i])

  77.             [Entity.Layer, Entity.Color, Entity.Linetype ,Entity.LinetypeScale ,Entity.Lineweight] = Entity_Properties
  78.             Entity.closed = Entity_closed

  79.             Coor = []
  80.             count += 1
  81.     print(f'多段线Z轴归零: {count} 条!')
  82.     doc.Utility.Prompt(f'多段线Z轴归零: {count} 条!')

  83. if __name__ == "__main__":
  84.     a = Polyline_XY_Zero.__name__
  85.     b = Polyline_XY_Zero.__doc__
  86.     c = Polyline_XY_Zero.__init__
  87.     print(a, b, c,sep='\n')
  88.     Polyline_XY_Zero()
复制代码


 楼主| 发表于 2023-2-28 19:08:47 | 显示全部楼层
#  附上刚找到的判断提取当前操作空间的代码
可以整合進剛才的代碼中,修復STEP01只能在模型空間操作的小BUG

import win32com.client

#啟動AutoCAD應用程序
acad = win32com.client.Dispatch("AutoCAD.Application.24.1")

#獲取當前文檔
doc = acad.ActiveDocument

#獲取當前空間
space = doc.ActiveSpace

print(space)

#判斷當前空間是模型空間還是佈局空間
if space == 'acModelSpace':
    print("當前空間:模型空間")
else:
    print("當前空間:佈局空間")

#獲取當前空間名稱值
if space == 'acModelSpace':
    name = "Model"
else:
    layout = doc.ActiveLayout
    name = layout.Name
print("當前空間名稱:", name)

 楼主| 发表于 2023-2-28 21:16:44 | 显示全部楼层
剛找到了實現在活動的space畫圖的功能,先判斷當前是在模型還是佈局,然後再在相應space畫出圖元。
代碼如下:

import pythoncom
import win32com.client

# 創建AutoCAD程序的com對象
acad = win32com.client.Dispatch("AutoCAD.Application")

# 獲取文檔對象
doc = acad.ActiveDocument

# 獲取模型空間
ms = doc.ModelSpace

# 獲取佈局空間
layouts = doc.Layouts
layout = doc.ActiveLayout
ps = layout.Block

# 判斷當前空間
if doc.ActiveSpace == 0:  # 佈局空間
    # 在佈局空間中添加圓形
    center = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, [5.0, 5.0, 0.0])
    radius = 2.5
    circle = ps.AddCircle(center, radius)
else:  # 模型空間
    # 在模型空間中添加圓形
    center = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, [0.0, 0.0, 0.0])
    radius = 2.5
    circle = ms.AddCircle(center, radius)

# 調整視圖範圍
doc.Application.ZoomExtents()
发表于 2023-3-1 14:23:18 | 显示全部楼层
BUG:如果UCS坐标是旋转过的UCS,无法智能以自定义的UCS去取用户坐标点取整数,会依然以WCS世界坐标系中的坐标值取整。……

关于这个问题CADVBA提供的方法是否可解决呢?
TranslateCoordinates Method (ActiveX)
Translates a point from one coordinate system to another.
发表于 2023-3-1 14:25:56 | 显示全部楼层
TranslateCoordinates Method (ActiveX)
Translates a point from one coordinate system to another.
Supported platforms: Windows only
Signature
VBA:
RetVal = object.TranslateCoordinates(Point, FromCoordSystem, ToCoordSystem, Displacement, [OCSNormal])
object

    Type: Utility

    The object this method applies to.
Point
    Access: Input-only
    Type: Variant (three-element array of doubles)
    The 3D WCS coordinates specifying the original coordinates to be translated. This parameter can be treated as a point or a displacement vector depending on the value of Displacement.
FromCoordSystem
    Access: Input-only
    Type: AcCoordinateSystem enum
    The coordinate system from which the point originates.
        acWorld
        acUCS
        acOCS
        acDisplayDCS
        acPaperSpaceDCS

ToCoordSystem
    Access: Input-only
    Type: AcCoordinateSystem enum
    The coordinate system to which the point will be converted.
        acWorld
        acUCS
        acOCS
        acDisplayDCS
        acPaperSpaceDCS
Displacement
    Access: Input-only
    Type: Long
    A displacement vector flag.
        True: Point is treated as a displacement vector.
        False: Point is treated as a point.
OCSNormal
    Access: Input-only; optional
    Type: Variant (three-element array of doubles)
    The normal for the OCS.
Return Value (RetVal)
Type: Variant (three-element array of doubles)
The translated 3D coordinate.
Remarks
You cannot directly translate a coordinate from one OCS to another OCS. To do this, first translate the coordinate from one OCS to an intermediary coordinate system such as the WCS. Then translate that coordinate into the second OCS.
To translate a point on a Polyline or LWPolyline object from OCS to WCS:
    Get the X and Y coordinates of the OCS point from the Coordinate or Coordinates property.
    Get the Z coordinate of the OCS point from the Elevation property.
    Get the Normal for the polyline from the Normal property.
    Call TranslateCoordinates using the X, Y, Z coordinates and the Normal.

以上为桌子公司的帮助文件的说明。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-17 21:29 , Processed in 0.165523 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表