我正在使用 Python 语言和 win32com.client 库向绘图添加剖面线。
以下是实现阴影线创建的代码:
import win32com.client
import pythoncom
acad = win32com.client.Dispatch("AutoCAD.Application")
acadModel = acad.ActiveDocument.ModelSpace
def APoint(x, y, z = 0):
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))
def ADouble(xyz):
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (xyz))
def variants(object):
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, (object))
out_loop = [acadModel.AddPolyline(ADouble([0,0,0,1000,0,0,1000,1000,0,0,1000,0,0,0,0]))]
hatch = acadModel.AddHatch(0, "HEX", True)
hatch.PatternScale = 20
hatch.AppendOuterLoop(variants(out_loop))
hatch.Evaluate()
hatch = acadModel.AddHatch(0, "ANSI31", True)
hatch.PatternScale = 10
hatch.AppendOuterLoop(variants(out_loop))
hatch.Evaluate()
任务是找到一种解决阴影线相互重叠的方法,可以使用Python来实现。想要的结果如图片右侧所示。
我可以在 autocad 中使用“爆炸”命令手动执行此任务第一个剖面线,然后添加第二个剖面线。但我需要使用Python来实现这个。
我还建议了一种使用 WipeOut 和 SuperHatch 的方法,但我仍然没有弄清楚如何在代码中实现它。 (https://stackoverflow.com/a/77905739/23389658)
可能需要修改autocad脚本,用lisp或者Autolisp。我不知道。
不幸的是我还没有找到使用ActiveX(COM)的解决方案,主要是因为Hatch没有爆炸方法。我建议使用 PyRx - Object ARX 上的 Python 包装器。
简而言之:
import traceback
from itertools import pairwise
from typing import Iterable, Tuple
import numpy as np
import shapely
from pyrx_imp import Db, Ge
from PyRxDebug import startListener
from shapely.ops import linemerge
def PyRxCmd_doit():
try:
# HEX hatch
hex_hatch = Db.Hatch()
hex_hatch.setDatabaseDefaults()
hex_hatch.setPattern(Db.HatchPatternType.kPreDefined, "HEX")
outer_edges = (
((0.0, 0.0), (100.0, 0.0)),
((100.0, 0.0), (100.0, 100.0)),
((100.0, 100.0), (0.0, 100.0)),
((0.0, 100.0), (0.0, 0.0)),
)
outer_segments = [
Ge.LineSeg2d(Ge.Point2d(p1), Ge.Point2d(p2)) for p1, p2 in outer_edges
]
hex_hatch.appendLoopEdges(
Db.HatchLoopType.kExternal,
outer_segments,
[Db.HatchEdgeType.kLine for _ in outer_segments],
)
hex_hatch.evaluateHatch()
# explode hatch and get single lines
hex_lines_ents = hex_hatch.explode()
hex_lines = [Db.Line.cast(ent) for ent in hex_lines_ents]
# connect individual lines in a "polyline" so that you can
# create loops for cutting the target hatch; round the coordinates
# so that the lines connect properly
hex_lines_points = (
(
np.round(i.startPoint().toTuple()[:2], 6),
np.round(i.endPoint().toTuple()[:2], 6),
)
for i in hex_lines
)
plines = get_plines(hex_lines_points) # get_plines below
# Target hatch
hatch = Db.Hatch()
hatch.setPattern(Db.HatchPatternType.kPreDefined, "ANSI31")
hatch.appendLoopEdges(
Db.HatchLoopType.kExternal,
outer_segments,
[Db.HatchEdgeType.kLine for _ in outer_edges],
)
for pline in plines: # hex plines
# create a list of segments that make up the polylines of one hexagon
line_segments = [
Ge.LineSeg2d(Ge.Point2d(p1), Ge.Point2d(p2))
for p1, p2 in pairwise(pline)
]
hatch.appendLoopEdges(
Db.HatchLoopType.kDefault,
line_segments,
[Db.HatchEdgeType.kLine for _ in line_segments],
)
hatch.evaluateHatch()
db = Db.HostApplicationServices().workingDatabase()
model = Db.BlockTableRecord(db.modelSpaceId(), Db.OpenMode.kForWrite)
model.appendAcDbEntity(hatch) # add hatch to the model
model.appendAcDbEntities(hex_lines) # add hexagon lines if needed too
model.close()
except Exception:
traceback.print_exc()
Point_T = Tuple[float, float]
def get_plines(
line_points: Iterable[Tuple[Point_T, Point_T]]
) -> Iterable[Iterable[Point_T]]:
line_strings = linemerge(line_points)
if isinstance(line_strings, shapely.LineString):
line_strings = (line_strings,)
elif isinstance(line_strings, shapely.MultiLineString):
pass
else:
raise TypeError
for line_string in line_strings.geoms:
ch = line_string.convex_hull
if isinstance(ch, shapely.Polygon):
yield ch.exterior.coords
算法需要在孵化时进行细化;作为六边形一部分的折线的起点和终点直接向前连接,而不是沿着外部剖面线轮廓线连接;我建议使用
shapely
- 创建一个轮廓大于目标剖面线的六角形剖面线,并从目标剖面线的多边形 (get_plines()
) 中剪切该剖面线的折线(上面的shapely.Polygon
)。
PYLOAD
命令并选择包含代码的 python 模块,DOIT
命令 (PyRxCmd_doit)。PyRx 允许用户交互,对于用户指定外部填充轮廓,请使用
Ed
模块 (from pyrx_imp import Ed
)
您还可以将 ActiveX(Autocad 对象模型)与 PyRx 一起使用,请查看:
from pyrx_impx import Ax
doc = Ax.getDbx() # same as acad.ActiveDocument