Спільнота програмістів autodesk в співдружність незалежних держав
Створення DWF-підкладки в AutoCAD Ліспі
Знадобилося мені тут вставити кілька dwf (або dwfx, не настільки суть важливо) в поточний документ dwg. Природно, що захотілося мені завдання вирішити Ліспі, та без застосування команд типу _.dwfattach. Ось про свої поневіряння і розповідаю трохи нижче :)
Нескладні колупання в dwg-файлі виявили, що записи про DWF (x) описах зберігаються в словнику ACAD_DWFDEFINITIONS. Ок, перевірити наявність словника і при необхідності створити його - не питання. А ось далі розпочалося вже не дуже зрозуміле і очевидне.
По-перше, мені ніяк не вдавалося коректно створити запис в цьому словнику. Природно, що dwf існує, природно, його ACAD знаходить. Але і все! Рішення, які мені вдалося знайти, рано чи пізно зводяться до коду, показаному на ADN DevBlog. Код наводити не буду, покажу краще, як я над ним знущався :)
По-перше, я з команди зробив LISP-функцію, і, по-друге, прибрав вставку DWF в простір моделі. Ну захотілося мені таке провернути;)
# 91; LispFunction # 40; "Kpblc_dwfinsert" # 41; # 93;
public static object lisp_dwfinsert # 40; ResultBuffer Args # 41;
ObjectId res = ObjectId. Null;
Array arguments = Args. AsArray # 40; # 41; ;
string sFileName = Convert. ToString # 40; # 40; # 40; TypedValue # 41; # 40; arguments. GetValue # 40; 0 # 41; # 41; # 41 ;. Value # 41; ;
if # 40; System. IO. File. Exists # 40; sFileName # 41; # 41;
Document doc = Application. DocumentManager. MdiActiveDocument;
Database db = doc. Database;
Editor ed = doc. Editor;
using # 40; Transaction tr = db. TransactionManager. StartTransaction # 40; # 41; # 41;
// first check for the required Layout
UnderlayFile layouts = UnderlayHost. DwfHost. GetFile # 40; sFileName, "" # 41; ;
UnderlayItem selectedItem = null;
Regex rxEng = new Regex # 40; "Model". RegexOptions. IgnoreCase # 41; ;
Regex rxRus = new Regex # 40; "Мо". RegexOptions. IgnoreCase # 41; ;
if # 40; layouts. Items. Count> 1 # 41;
foreach # 40; UnderlayItem item in layouts. Items # 41;
Match strMatchEng = rxEng. Match # 40; item. Name # 41; ;
Match strMatchRus = rxRus. Match # 40; item. Name # 41; ;
if # 40; # 40; String. Compare # 40; item. Name. ToUpper # 40; # 41 ;. "MODEL". false # 41; == 0 # 41; || strMatchEng. Success || strMatchRus. Success # 41;
# 123; selectedItem = item; break; # 125;
# 123; selectedItem = layouts. Items # 91; 0 # 93; ; # 125;
if # 40; selectedItem == null # 41;
# 123; ed. WriteMessage # 40; "Error, No page with name Model" # 41; ; return null; # 125;
DBDictionary nod = # 40; DBDictionary # 41; tr. GetObject # 40; db. NamedObjectsDictionaryId. OpenMode. ForRead # 41; ;
string defDictKey = UnderlayDefinition. GetDictionaryKey # 40; typeof # 40; DwfDefinition # 41; # 41; ;
ObjectId defId = ObjectId. Null;
if # 40 ;. nod. Contains # 40; defDictKey # 41; # 41;
using # 40; DBDictionary dict = new DBDictionary # 40; # 41; # 41;
nod. UpgradeOpen # 40; # 41; ;
defId = nod. SetAt # 40; defDictKey, dict # 41; ;
tr. AddNewlyCreatedDBObject # 40; dict, true # 41; ;
# 123; defId = nod. GetAt # 40; defDictKey # 41; ; # 125;
ObjectId idDef = ObjectId. Null;
DBDictionary dwfDict = # 40; DBDictionary # 41; tr. GetObject # 40; defId, OpenMode. ForRead # 41; ;
string sDwfName = Path. GetFileNameWithoutExtension # 40; sFileName # 41; ;
if # 40; dwfDict. Contains # 40; sDwfName # 41; # 41;
# 123; idDef = dwfDict. GetAt # 40; sDwfName # 41; ; # 125;
Так, код спрацював: повертає покажчик на створений примітив (

А ось в диспетчері посилань твориться щось дивне:

А якщо повестися як мавпа з гранатою і виконати "Detach" (відключити) посилання?

Я звернувся в ADN DevHelp, відповідь була приблизно наступним: "Створення DWF-підкладки, використовуючи механізм COM, на даний момент неможливо. Створення відповідних елементів через DXF є дуже громіздким і нестійким"
Підводячи підсумки, можна сказати наступне: якщо треба вставити DWF-підкладку в документ, то або використовувати командні методи, або повністю розробляти на .NET: Лісп з цим завданням не впорається.
