Как добавить штриховки в Автокад, чтобы они перекрывали друг друга?

Я использую язык 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. Я не знаю.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
121
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

К сожалению, я не нашел решения с использованием ActiveX (COM), главным образом потому, что в Hatch нет метода разнесения. Я предлагаю использовать PyRx — обертку Python над Object ARX.

В двух словах:

  • создать HEX-люк,
  • разбить на отдельные строки,
  • соедините линии в шестиугольники,
  • добавьте штриховку цели, вырезав шестиугольники.
import traceback
from itertools import pairwise
from typing import Iterable, Tuple

import numpy as np
import shapely
from pyrx_imp import Db, Ge
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 — создайте HEX-штриховку, контур которой больше целевой штриховки, и вырежьте полилинии (get_plines() выше) этой штриховки из многоугольника (shapely.Polygon) целевой штриховки.


PyRx

  • Установите последнюю версию,
  • Запустите AutoCAD и разрешите загрузку надстройки PyRx.arx.
  • В командной строке запустите команду 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

Почему Pyrx и PyRxDebug отображаются в vscode как неоткрытые библиотеки? И когда я запускаю команду DOIT, я получаю ошибку — pastebin.com/263bwv6e .

Bobby Lith 17.04.2024 06:08

Мой код Python создает штриховки в разных областях. В одной области может быть более одного люка. Как создать каждую новую штриховку, чтобы ее острова были элементами предыдущих штриховок? Вот мой код - pastebin.com/n36JBs2W Если нужно - откроем чат для обсуждения. Я буду очень рад вашей помощи

Bobby Lith 17.04.2024 06:50

Я отредактировал ответ, в hex_lines_points была ошибка, я изменил понимание генератора на понимание списка.

Grzegorz Świtek 17.04.2024 07:02

неоткрытые библиотеки — проверьте это github.com/CEXT-Dan/PyRx/issues/3

Grzegorz Świtek 17.04.2024 07:04

Спасибо, проверьте мой комментарий выше, пожалуйста

Bobby Lith 17.04.2024 07:53

Пожалуйста, покажите примеры данных и ожидаемый эффект, а также текущий код (весь).

Grzegorz Świtek 17.04.2024 07:57

Давайте продолжим обсуждение в чате.

Grzegorz Świtek 17.04.2024 08:19

Другие вопросы по теме