Реклама i
Стань нашим партнером - зарабатывай с нами!
| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Конвертировать сплайн в полилинию

Конвертировать сплайн в полилинию

Ответ
Поиск в этой теме
Непрочитано 17.08.2018, 11:34 #1
Конвертировать сплайн в полилинию
Maestro GIS
 
Регистрация: 17.08.2018
Сообщений: 7

Есть такая команда "SSSegs" - "Конвертировать сплайн в полилинию"

При работе с коммандой приходится в ручном режим смотреть количество узлов в полилинии, например 25000.

Потом в уме делить на 2, запускать SSSegs и указывать ей значение 12500.

Потом еще раз делим в уме на 2, запускаем SSSegs и указываем 6250.

Если результат устраивает, завершаем, если нет, то еще раз делим в уме на 2, запускаем SSSegs и указываем 3125.

Подскажите пожалуйста, студенту, как грамотно это оформить, чтобы оставалось выделить полилинии и нажать на пиктограмму комманды (а онапринимала бы значение в два раза меньшее, чем количество узлов)

БлагоДарствую
Просмотров: 2219
 
Непрочитано 17.08.2018, 12:06
#2
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


Код команды показывай
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 17.08.2018, 14:16
#3
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,004


И какое приложение либо надстройку используете - Акад сказал, что он команды SSSegs не знает)
Сергей812 вне форума  
 
Автор темы   Непрочитано 17.08.2018, 19:12
#4
Maestro GIS


 
Регистрация: 17.08.2018
Сообщений: 7


Код программы где смотреть?

В адаптации, в строке макросы указано: "^C^C^P(if (not C:SSSegsl)(load "SSSegs"));^PSSSegs;"

Последний раз редактировалось Maestro GIS, 20.08.2018 в 11:12.
Maestro GIS вне форума  
 
Непрочитано 17.08.2018, 19:32
#5
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,004


Offtop:
Цитата:
Сообщение от Maestro GIS Посмотреть сообщение
GSTARCAD
немного у нас людей на форуме на ней сидит, наверно)


Цитата:
Сообщение от Maestro GIS Посмотреть сообщение
Код программы где смотреть?
В руководстве разработчика надстроек - на сайте программы в открытом доступе не вижу руководств.

Ну и исходный код команды можно попытаться в SSSegs.lsp (скорее всего) подглядеть.
Сергей812 вне форума  
 
Автор темы   Непрочитано 17.08.2018, 20:12
#6
Maestro GIS


 
Регистрация: 17.08.2018
Сообщений: 7


Нашел, родимую!)
она в составе менюгео находится

Код:
[Выделить все]
 (defun c:SSSegs ( / *error* doc ss undo )
  (vl-load-com) 

  (defun *error* ( msg )
    (and undo (vla-EndUndomark doc))
    (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
        (princ (strcat "\n** Error: " msg " **")))
    (princ)
  )

  (setq doc   (vla-get-ActiveDocument (vlax-get-acad-object))
        *segs (cond (*segs) (10)))

  (if (and (setq ss (ssget "_:L" '((0 . "ARC,CIRCLE,*POLYLINE,SPLINE,LINE,ELLIPSE"))))
           (not (initget 6))
           (setq *segs (cond ((getint (strcat "\n”кажите колличество сигментов <"
                                              (itoa *segs) "> : "))) (*segs))))
    (
      (lambda ( j / ent inc i pts )
        (setq undo (not (vla-StartUndoMark doc)))
        (while (setq ent (ssname ss (setq j (1+ j))))

          (setq inc (/ (vlax-curve-getDistatParam ent
                         (vlax-curve-getEndParam ent)) (float *segs)) i -1)
          
          (repeat (1+ *segs)
            (setq pts (cons (vlax-curve-getPointatDist ent (* (setq i (1+ i)) inc)) pts))
          )          
          (entmake (append (list (cons 0   "LWPOLYLINE")
                                 (cons 100 "AcDbEntity")
                                 (cons 100 "AcDbPolyline")
                                 (cons 90 (length pts))
                                 (cons 70 0))
                           (vl-remove 'nil
                             (mapcar
                               '(lambda ( d ) (assoc d (entget ent))) '(6 8 39 48 62)
                             )
                           )                     
                           (mapcar (function (lambda ( a ) (cons 10 a))) pts)))
          
          (entdel ent) (setq pts nil)
        )
        (setq undo (vla-EndUndoMark doc))
      )
      -1
    )
  )
  (princ)
)
Maestro GIS вне форума  
 
Непрочитано 17.08.2018, 20:28
| 1 #7
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,665


Цитата:
Сообщение от Maestro GIS Посмотреть сообщение
колличество сигментов
это сильно!
koMon вне форума  
 
Непрочитано 17.08.2018, 20:41
#8
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


Цитата:
Сообщение от Maestro GIS Посмотреть сообщение
чтобы оставалось выделить полилинии и нажать на пиктограмму комманды (а онапринимала бы значение в два раза меньшее, чем количество узлов)
Чем какое количество узлов? Если будет выбрано 2 полилинии - в одной 10 000 узлов, во второй - 3, что должно быть по умолчанию?
А если выбрана всего одна полилиния с количеством вершин 2?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 17.08.2018, 20:52
#9
Maestro GIS


 
Регистрация: 17.08.2018
Сообщений: 7


Вот к примеру простой dwg, где количество точек небольшое, 2711 в объекте в виде зигзагообразной линии - событии находящимся в слое "1%000"

Вариант А - "точный"
Количество точек задается кратно прогрессии, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2
до 2-4 раз последовательно (в зависимости от результата, если устраивает, останавливаемся),
первый раз берется из ближайшего ряда прогрессии

1 раз прогоняем через конвертацию сплайна, указываем количество точек ближайшее из ряда = 2048 точек
2 раз = 1024 точки
3 раз = 512 точек


Вариант Б - "альтернативный"
Количество точек уменьшается после каждого раза в 2 раза от исходного количества узлов в полилинии
(берется ближайшее нечетное число, но пойдет и просто целое)
до 2-4 раза последовательно (в зависимости от результата, если устраивает, останавливаемся),
первый раз берется от количества узлов в полилинии деленное на 2.

1 раз прогоняем через конвертацию сплайна, указываем количество точек 2711/2=1155
2 раз = 1155/2=577 точки
3 раз = 577/2= 288 точек
Вложения
Тип файла: dwg
DWG 2010
Пример.dwg (245.3 Кб, 15 просмотров)

Последний раз редактировалось Maestro GIS, 20.08.2018 в 11:14.
Maestro GIS вне форума  
 
Непрочитано 17.08.2018, 20:55
| 1 #10
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


Maestro GIS, у тебя в коде не заблокирована возможность выбора нескольких объектов!
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 17.08.2018, 21:00
#11
Maestro GIS


 
Регистрация: 17.08.2018
Сообщений: 7


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Чем какое количество узлов? Если будет выбрано 2 полилинии - в одной 10 000 узлов, во второй - 3, что должно быть по умолчанию?
готов по одной выбирать, лишь бы работало.
в теории, конечно, для каждой полилинии плясать от своего значения узлов

Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
А если выбрана всего одна полилиния с количеством вершин 2?
)) таких нет, минимум 4 точки, крайне редко, не больше статистической погрешности; в основном исходное количество узлов >10 тыс.
Maestro GIS вне форума  
 
Автор темы   Непрочитано 17.08.2018, 21:08
#12
Maestro GIS


 
Регистрация: 17.08.2018
Сообщений: 7


да, согласен, что нет блокировки и это очень хорошо, но для нашего случая количество узлов ко всем объектам применить одинаковое не подойдет.

Просто таких полилиний у меня около 2 тыс. штук, в 53 файлах.
это уровни подъёма воды.
соответственно цель - добиться, чтобы они не пересекались, красиво выглядели, и количество характерных узлов было минимальным.
т.е. функционал исходного лиспа - устраивает,
но нужен частный, упрощенный, описанный выше случай, для быстрой обработки данных

Последний раз редактировалось Maestro GIS, 17.08.2018 в 21:17.
Maestro GIS вне форума  
 
Непрочитано 17.08.2018, 21:26
1 | 1 #13
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


Программа никогда не поймет, что означает "красиво выглядит". Честно говоря, я как-то подустал за неделю, и заниматься мозголомством вечером в пятницу ну совсем не тянет.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 17.08.2018, 22:10
1 | #14
trir


 
Регистрация: 18.12.2010
Сообщений: 5,047


просто нужно прочитать The NURBS Book - и тогда поймёшь, что нужно использовать первую производную! а может и вторую
trir вне форума  
 
Непрочитано 18.08.2018, 15:31
1 | 1 #15
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,990
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Количество вершин берется как количество вершин полилинии и просто делится на два. Остаток отбрасывается. Без проверки, вроде нигде не напортачил. Переделка минимальная. В алгоритм расчета шага не вникал
Код:
[Выделить все]
 
 (defun c:SSSegs1 ( / *error* doc ss undo *segs)
  (vl-load-com) 

  (defun *error* ( msg )
    (and undo (vla-EndUndomark doc))
    (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
        (princ (strcat "\n** Error: " msg " **")))
    (princ)
  )

  (setq doc   (vla-get-ActiveDocument (vlax-get-acad-object))
        *segs (cond (*segs) (10)))

  (if (setq ss (ssget "_:L" '((0 . "*POLYLINE"))))
    (
      (lambda ( j / ent inc i pts )
        (setq undo (not (vla-StartUndoMark doc)))
        (while (setq ent (ssname ss (setq j (1+ j))))
          (princ (strcat "\nОбрабатываю полилинию - " (itoa (1+ j))))
          (princ "  вершин ")(princ (setq *segs (fix(vlax-curve-getEndParam ent))))
          (princ " пересчитанное - ")(princ (setq *segs (fix(/ *segs 2.0))))
          (setq inc (/ (vlax-curve-getDistatParam ent
                         (vlax-curve-getEndParam ent)) (float *segs)) i -1)
          
          (repeat (1+ *segs)
            (setq pts (cons (vlax-curve-getPointatDist ent (* (setq i (1+ i)) inc)) pts))
          )          
          (entmake (append (list (cons 0   "LWPOLYLINE")
                                 (cons 100 "AcDbEntity")
                                 (cons 100 "AcDbPolyline")
                                 (cons 90 (length pts))
                                 (cons 70 0))
                           (vl-remove 'nil
                             (mapcar
                               '(lambda ( d ) (assoc d (entget ent))) '(6 8 39 48 62)
                             )
                           )                     
                           (mapcar (function (lambda ( a ) (cons 10 a))) pts)))
          
          (entdel ent) (setq pts nil)
        )
        (setq undo (vla-EndUndoMark doc))
      )
      -1
    )
  )
  (princ)
)
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 20.08.2018, 11:40
#16
Maestro GIS


 
Регистрация: 17.08.2018
Сообщений: 7


Кулик Алексей aka kpblc
VVA

Всех благ! БлагоДарствую!
Maestro GIS вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Конвертировать сплайн в полилинию

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как преобразовать полилинию в сплайн Kotsar AutoCAD 20 02.08.2015 14:09
Помогите, пожалуйста, не могу объединить сплайн и полилинию Светлана21 AutoCAD 8 16.01.2013 09:57
можно ли преобразовать сплайн в полилинию? Petrovichhh AutoCAD 14 19.10.2012 10:57
сплайн в 3D полилинию Xela AutoCAD 2 02.12.2009 12:22
Как сконвертировать сплайн в полилинию OXOTHUK AutoCAD 4 18.12.2006 13:52