AutoCAD多段线坐标取整时关于坐标系的问题
本帖最后由 箭头_Row 于 2023-2-28 18:48 编辑先上代码:
代码逻辑如下:
STEP01:定义函数,在图中选择多段线(仅限模型空间操作,因为目前本人还不会判断选择正在操作的空间)
STEP02:获取多段线属性列表,顶点坐标列表,使用round函数取整。
STEP03:获取凸度列表,删除多段线。
STEP04:绘制多段线,添加凸度,赋值属性。
BUG:如果UCS坐标是旋转过的UCS,无法智能以自定义的UCS去取用户坐标点取整数,会依然以WCS世界坐标系中的坐标值取整。如何解决这个BUG,有么有大佬提供点思路,提供一些关于UCS用户坐标系相关的资料研究研究。
# env Python = 3.11.1pywin32 = 305
# -*- coding: utf-8 -*-
"""
=============================
Author: Meditation/箭头
Email: 1191101855@qq.com
Last Update: 2023.02.14 20:22
=============================
"""
import win32com.client as win32
import pythoncom
# Autocad 2022的ProgramID
ProgramID = "AutoCAD.Application.24.1"
# 获取CAD程序
Acadapp = win32.Dispatch(ProgramID)
# 指定当前活动文档
doc = Acadapp.ActiveDocument
AcadA = doc.Application
msp = doc.ModelSpace
print(doc.Path, '\\', doc.Name, sep='')
# 数据转换
def vtpnt(x, y, z=0):
"""坐标点转化为浮点数"""
return win32.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))
def vtobj(obj):
"""转化为对象数组"""
return win32.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, obj)
def vtlstf(lst):
"""列表转化为浮点数"""
return win32.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, lst)
def vtlsti(lst):
"""列表转化为整数"""
return win32.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, lst)
def vtlstvariant(lst):
"""列表转化为变体"""
return win32.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, lst)
def My_Select():
# 新建选择集
try:
doc.SelectionSets.Item("SS1").Delete()
except:
print("Delete selection failed")
slt = doc.SelectionSets.Add("SS1")
slt.SelectOnScreen()
return slt
def Polyline_XY_Zero():
"""注意如果坐标系与当前坐标系不一致,可能导致数据error"""
slt = My_Select()
count = 0
for Entity in slt:
Coor = []
if Entity.objectname == 'AcDbPolyline':
Entity_Properties =
Entity_closed = Entity.closed
Entity_Coor = Entity.Coordinates
# print(Entity_Coor)
# 获取多线段的顶点数
Entity_count = int(len(Entity_Coor)/2)
# 获取凸度列表
Entity_Bulge = []
for i in range(Entity_count):
RetVal = Entity.GetBulge(i)
Entity_Bulge.append(RetVal)
# print(Entity_Bulge)
# 坐标值精度归0
for xy in Entity_Coor:
Entity_Coor_round = round(xy,0)
Coor.append(Entity_Coor_round)
Entity.Erase()
new_Coor = vtlstf(Coor)
Entity = doc.ModelSpace.AddLightWeightPolyline(new_Coor)
# 添加凸度
for i in range(len(Entity_Bulge)):
Entity.SetBulge(i, Entity_Bulge)
= Entity_Properties
Entity.closed = Entity_closed
Coor = []
count += 1
print(f'多段线Z轴归零: {count} 条!')
doc.Utility.Prompt(f'多段线Z轴归零: {count} 条!')
if __name__ == "__main__":
a = Polyline_XY_Zero.__name__
b = Polyline_XY_Zero.__doc__
c = Polyline_XY_Zero.__init__
print(a, b, c,sep='\n')
Polyline_XY_Zero()
#附上刚找到的判断提取当前操作空间的代码
可以整合進剛才的代碼中,修復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)
剛找到了實現在活動的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, )
radius = 2.5
circle = ps.AddCircle(center, radius)
else:# 模型空間
# 在模型空間中添加圓形
center = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, )
radius = 2.5
circle = ms.AddCircle(center, radius)
# 調整視圖範圍
doc.Application.ZoomExtents() BUG:如果UCS坐标是旋转过的UCS,无法智能以自定义的UCS去取用户坐标点取整数,会依然以WCS世界坐标系中的坐标值取整。……
关于这个问题CADVBA提供的方法是否可解决呢?
TranslateCoordinates Method (ActiveX)
Translates a point from one coordinate system to another. 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, )
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.
以上为桌子公司的帮助文件的说明。
页:
[1]