Тема: Можно ли редактировать 3dSolid через AutoLISP?
Всем привет! Подскажите, можно ли и каким образом редактировать 3dSolid через AutoLISP? И каким образом здесь замешан ACIS. Заранее благодарен...
Информационный портал для профессионалов в области САПР
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Форумы CADUser → Программирование → LISP → Можно ли редактировать 3dSolid через AutoLISP?
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Всем привет! Подскажите, можно ли и каким образом редактировать 3dSolid через AutoLISP? И каким образом здесь замешан ACIS. Заранее благодарен...
когда-то где-то находил информацию как шируется эта билиберда - все довольно просто что-то типа обычного XOR но вот не могу найти и вспомнить какой ключ. может кто вспомнит?
Если не трудно, объясните плиз что такое XOR ?
А может отправить acisout
И отредактировать .sat файл.
XOR - логическая функция "Исключающее ИЛИ", которая принимает значение "истина" только в том случае когда ТОЛЬКО ОДИН из ее аргументов "истинен". В Автолиспе реализуется функцией BOOLE:
(boole 6 6 5) -> 3
первая 6 - как раз признак операции XOR.
Не ужели ни кто так и не встречал как кодированы эти данные, ведь где-то я видел, не может быть что бы кроме меня никто больше не встречал!!!
(boole 6 x 95) для каждого элемента списка, полученного из строки посредством vl-string->list.
Вот спасибо!!! А то ни как не могу ни вспомнить где читал, ни найти текст функции которую на которой разбирался. Еще раз спасибо! А нельзя ли еще источник напомнить - а то ведь буду мучится, вспоминая...
> vk
(17.06.2003 в 17:26:09)
И какую информацию получаем в результате?
Если можно небольшой пример.
ей богу проще самому посмотреть...
Напомнить источник... Не помню, где видел, а вот что сам набросал, когда возникло желание вытянуть геометрию. Конечно, это совершенно черновой вариант, над которым работать, да работать... Вывод непосредственно на экран, а там есть над чем подумать.
;; выбор объекта (while (/= "3DSOLID" (cdr (assoc 0 (setq edat (entget (car (entsel)))))))) ;; выделение данных 3DSOLID'а (setq n (1- (length edat))) (setq dat '()) (while (>= n 0) (if (= 1 (car (nth n edat))) (setq dat (cons (vl-string->list (cdr (nth n edat))) dat)) ) ;_ if (setq n (1- n)) ) ;_ while (setq n (1- (length dat))) (setq points '()) (setq plane-surfaces '()) (setq cone-surfaces '()) (setq straight-curves '()) (setq ellipse-curves '()) (while (>= n 0) (setq d (nth n (reverse dat))) (setq p '()) (foreach x (reverse d) (setq p (cons (boole 6 x 95) p))) ; декодирование строки (setq str (vl-list->string p)) ;; разбивка строкИ на отдельные стрОки (setq poss 0) ; начальная позиция (setq strl '()) ; список строк (while (setq pose (vl-string-search "\177" str poss)) (setq strpart (substr str (1+ poss) (- pose poss))) (setq strl (cons (if (distof strpart) (distof strpart) strpart ) ;_ if strl ) ;_ cons ) ;_ setq (setq poss (1+ pose)) ) (setq strl (reverse strl)) ; список строк готов (princ "\n") (princ strl) ;; сортировка в списки-группы (cond ((= (car strl) "point") (setq points (cons (vl-remove "$-1" strl) points))) ((= (car strl) "plane-surface") (setq plane-surfaces (cons (vl-remove "$-1" strl) plane-surfaces))) ((= (car strl) "cone-surface") (setq cone-surfaces (cons (vl-remove "$-1" strl) cone-surfaces))) ((= (car strl) "straight-curve") (setq straight-curves (cons (vl-remove "$-1" strl) straight-curves))) ((= (car strl) "ellipse-curve") (setq ellipse-curves (cons (vl-remove "$-1" strl) ellipse-curves))) ) ;_ cond (setq n (1- n)) ) ;_ while (princ "\n") (princ points) (princ "\n") (princ plane-surfaces) (princ "\n") (princ cone-surfaces) (princ "\n") (princ straight-curves) (princ "\n") (princ ellipse-curves) (princ)
возможно я слегка погорячился и как получить желаемый результат из данной переписки не совсем очевидно -решил исправиться, привожу текст наскоро склепаной функции
(defun 3d-entget (ent) (mapcar '3d-decode (entget ent)) ) (defun 3d-decode (lst) (if (/= (car lst) 1) lst (cons 1 (mapstr '(lambda(x)(chr (boole 6 (ascii x) 95))) (cdr lst))) ) ) (defun MapStr (fun str / str1 len i ) (setq str1 "" len (if (= (type str) 'STR) (strlen str) 0) fun (if (member (type fun) '(SYM LIST USUBR)) (eval fun) fun) i 1) (while (<= i len) (setq str1 (strcat str1 (fun (substr str i 1))) i (1+ i))) str1)
вызывать (3d-entget <имя 3d-примитива>)
еще раз прошу прощения - торопливость не лучший партнер программиста... конечно-же vk был прав и лучше использовать vl-string->list:
(defun 3d-decode (lst) (if (/= (car lst) 1) lst (cons 1 (vl-list->string (mapcar '(lambda(x)(boole 6 x 95)) (vl-string->list (cdr lst))))) ) )
а третья функция вообще не нужна...
но у vk все проработано получше, особенно разбивка на строки и сортировки - я этого не делал по двум причинам
1. не было необходимой информации;
2. после того как увидел результат - интерес к структуре пропал, тем более что появились возможности ActiveX
тем не менее большое спасибо еще раз Vk!!!
В первом случае результат напоминает стуктуру .sat
файла. А она не совсем понятна.Тем более как
это редактировать?
Через activX-
(vlax-dump-object(vlax-ename->vla-object(car(entsel))))
что-то маловато информации.
> Сергей
Попадьин (18.06.2003 в 14:40:58)
У меня был интерес вытянуть из 3Dsolid (детали из листового материала) геометрию. Что касается прямоугольных деталей, там все достаточно просто, но как "выковырять" геометрию на сплайновых участках... не совсем понятно.
Через ActiveX не пробовал, может подскажете куда копать.
И еще заметил такой момент (это про точность): имеется точка (в вершине 3Dsolid'а) с координатой например X=1500. Так я ее задавал (), так она и отображается по команде ID. Но в строке после декодирования вижу что-то вроде 1499.999999999989.
Вторая строка содержит текущее время. Зачем???
Эдуарду:
1. никто ведь не обещал что будет все понятно - пробовать надо...
2. насчет ActiveX - можно сделать далеко не все это то же правда (печальная), хотя возможно и есть какие-нибудь недокументированные возможности... так глубоко я не копал, правда и проблема для меня больше "академический" интерес представляла...
Vk:
что касается точности, то на подобные моменты я уже неоднократо обращал внимание - там где присутствует перевод из формата int или fix во float - везде в АвтоКАДе присутствует потеря точности (так вроде и должно быть, но в некоторых ситуациях от этого не легче). А грешат этим в оcновном ActiveX (просто так API-написаны)...
Немного подправил программку. Теперь читается почти по-человечески.
(defun 3d_geom (/ edat n dat points plane-surfaces cone-surfaces straight-curves ellipse-curves d p s str poss strl pose strpart part) ;; выбор объекта (while (not (member (cdr (assoc 0 (setq edat (entget (car (entsel)))))) '("3DSOLID" "REGION" "BODY")))) ;; выделение данных 3DSOLID'а (setq n (1- (length edat))) (while (>= n 0) (if (= 1 (car (nth n edat))) (setq dat (cons (vl-string->list (cdr (nth n edat))) dat)) ) ;_ if (setq n (1- n)) ) ;_ while (setq n (1- (length dat))) (while (>= n 0) (setq d (nth n (reverse dat))) ;; декодирование строки (setq p '()) (foreach x (reverse d) (if (< (setq s (boole 6 x 95)) 33) (setq s (+ s 64)) ) ;_ if (setq p (cons s p)) ) ;_ foreach (setq str (vl-list->string p)) ;; разбивка строки на элементы (setq poss 0) ; начальная позиция (setq strl '()) ; список элементов (while (setq pose (vl-string-search "\177" str poss)) (setq strpart (substr str (1+ poss) (- pose poss))) (cond ((distof strpart) (setq part (atof strpart)) (if (not (vl-string-search "." strpart)) (setq part (atoi strpart)) ) ;_ if ) (t (setq part strpart)) ) ;_ cond (setq strl (cons part strl)) (setq poss (1+ pose)) ) ;_ while (setq strl (reverse strl)) ; список элементов готов (princ "\n") (princ strl) ;; сортировка в списки-группы (cond ((= (car strl) "point") (setq points (cons (vl-remove "$-1" strl) points))) ; и так далее для других групп ) ;_ cond (setq n (1- n)) ) ;_ while (princ "\n") (princ points) ; и так далее (princ) ) ;_ defun (3d_geom)
Получается почти точная копия *.sat .
По поводу структуры *.sat догадываюсь, что ее описание найти проблематично, однако, есть одно предположение (не более): строки - это элементы и признаки элементов объекта, а параметры $ (за исключением $-1 - разделителя) являются связями между строками. Это определяет форму объекта. Но как к форме привязаны координаты - совсем не понятно.
Есть идеи?
ну не так чтобы совсем..., кое о чем все же можно догадываться - point, cone-surface, plane-surface, straight-curve, ellipse-curve - очень похоже содержат координаты, правда формат не так прост... тем не менее, кое-что вычислить все же можно. Как я понимаю первые три значащих значения в ...-surface начальная точка (по крайней мере для конуса и шара). Пробовал менять - получается, только надо перед entmod опять шифровать (а раньше вроде бы не обязательно было, если я правильно помню). При должной усидчивости, думаю можно и остальные моменты вычислить... а вообще задрали все эти копирайтщики, честное слово!!!
вчера было немного свободного времени - посидел вечерком поковырял... разобраться вообщем-то пожалуй можно, по крайней мере шар, цилиндр и конус (оказывается описываются почти одинаково) научился модифицировать - правда, как работать с этими дебильными данными автоматизировано пока даже не могу себе представить... очень удивил ящичек - на его описание уходит более 120 (!!!) групп - там похоже есть и точки (все 8 нашел) и ребра (зачем то заданы точки средины) и грани и еще много чего не понятного... к сожалению объемы информации слишком велики для форума... дам лишь маленький совет
1. рисуйте по координатам (задавая циферками с клавы), а затем ищите в декодированном примитиве знакомые числа...
2. 3d-decode при повторном вызове даст закодированный вариант - это понадобится для entmod. А вызывать примерно так: (mapcar '3d-decode <декодированный список примитива>)
надыбал одну ссылочку там кое-что про SAT-формат есть, кажется не плохо...
http://www.cad.bmstu.ru/project/researc … ky/sat.htm
> Сергей Попадьин
Большое спасибо за ссылочку! Кое-что эта статья расставила по местам, но понятно одно, что механизм описания объекта в формате sat довольно сложный. Тоесть, редактировать, непосредственно само описание конечно можно, но не кажется ли, что в этом случае придется заново создать уже существующий механизм? Может быть, можно получить к нему доступ?
Что касается "точек середины" на ребрах и плоскостях, так здесь просто: заданы точка и вектор (для плоскости - нормаль) и действительно нет никакой разницы, в каком месте прямой или плоскости лежит точка. Может быть, это проекция центра тяжести на ребро\плоскость... проверю для более сложных тел...
за ссылочку спасибо Google и Opera...
ну а что касается sat - он не столько сложный, сколько не удобный в работе с Лиспом (да и с другими языками едва ли...). насчет получить доступ к существующему механизму думаю едва ли реально - насколько мне известно это разработка не Автодеска, а какой-то фирмы (сейчас не помню точно, не хочу врать) и используется по лицензии (эта же разработка используется и в некоторых других программах САПР, кажется даже в какой-то российской, если не ошибаюсь, кажется bCAD).
что касаемо ребер после прочтения статьи этот, как и многие другие вопросы исчезли...
но представить себе реальную работу с этими объектами почти не могу(не то чтобы сложно - но уж очень муторно), хотя конечно зависит от того что с ними надо делать... слава богу что у меня еще не было такой необходимости...
а ведь представь ту же структуру в виде списка насколько бы проше стало бы... и формат текстовым остался бы...
А нельзя ли еще источник напомнить - а то ведь буду мучится, вспоминая...
Можно. Вот опять на него наткнулся http://xarch.tu-graz.ac.at/autocad/wiki/DecodeAcis
раньше описание SAT можно было взять прямо на сайте Spatial, сейчас жмотятся :(
но в инете его найти запросто, правда может старые версии
а их viewer (http://www.spatial.com/products/visuali … viewer.htm) также может помочь, например, там есть topology browser
Немного оптимизировал вышеизложенную функцию ,
однако практического применения информации
не нахожу. :)
(defun 3ddecode (/ obj) (if (and (setq obj (car (entsel))) (member (cdr (assoc 0 (setq obj (entget obj)))) '("3DSOLID" "REGION" "BODY") ) ) (mapcar '(lambda (b) (read (strcat "(" b ")")) ) (mapcar 'vl-list->string (mapcar '(lambda (y) (subst 10 127 (mapcar '(lambda (z / s) (if (< (setq s (boole 6 z 95)) 33) (+ s 64) s ) ) y ) ) ) (mapcar 'vl-string->list (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 1)) obj) ) ) ) ) ) ) )
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Форумы CADUser → Программирование → LISP → Можно ли редактировать 3dSolid через AutoLISP?
Форум работает на PunBB, при поддержке Informer Technologies, Inc