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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > C# .net переопределение динамического блока из внешнего файла

C# .net переопределение динамического блока из внешнего файла

Ответ
Поиск в этой теме
Непрочитано 05.10.2011, 11:17
C# .net переопределение динамического блока из внешнего файла
bargool
 
Санкт-Петербург
Регистрация: 16.08.2006
Сообщений: 508

Есть динамический блок с атрибутами и прочими извращениями в текущем файле и в неком эталонном постороннем файле.
Необходимо обновить блок в текущем файле в соответствии с изменившимся эталоном.
Я догадался до такого способа, но может, можно сделать всё проще?
Код:
[Выделить все]
[CommandMethod("blockRedefine", CommandFlags.Session)]
public void blockRedefine()
{
	// "Текущий" документ
	currDwg = Application.DocumentManager.MdiActiveDocument;
	currDatabase = currDwg.Database;
	DocumentCollection docManager = Application.DocumentManager;
	//открываем файл с эталонным блоком в режиме для чтения
	Document frameDoc = docManager.Open(@"Путь до файла.dwg", true);
	Database frameDb = frameDoc.Database;
	ObjectIdCollection frameCollection = new ObjectIdCollection();
	using (DocumentLock docLock = frameDoc.LockDocument())
	{
		using (Transaction transaction = frameDb.TransactionManager.StartTransaction())
		{
			BlockTable frameBlockTable = (BlockTable)transaction.GetObject(frameDb.BlockTableId, OpenMode.ForRead);
			// Пытаемся открыть эталонный блок
			BlockTableRecord frameBlock = transaction.GetObject(frameBlockTable["Frame"], OpenMode.ForRead) as BlockTableRecord;
			// если получилось - описание блока есть, добавляем в ObjectIdCollection для переноса в "текущий" документ
			if (frameBlock != null)
			{
				frameCollection.Add(frameBlock.ObjectId);
			}
		}

	}
	// Переключаемся на "текущий документ"
	docManager.MdiActiveDocument = currDwg;
	using (DocumentLock docLock = currDwg.LockDocument())
	{
		using (Transaction transaction = currDatabase.TransactionManager.StartTransaction())
		{
			BlockTable blockTable = (BlockTable)transaction.GetObject(currDatabase.BlockTableId, OpenMode.ForRead);
			IdMapping idmapping = new IdMapping();
			// пишем определение эталонного блока в "текущий" файл с заменой
			frameDb.WblockCloneObjects(frameCollection, blockTable.ObjectId, idmapping, DuplicateRecordCloning.Replace, false);
			transaction.Commit();
		}
	}
	// закрываем уже ненужный файл с эталонным блоком
	frameDoc.CloseAndDiscard();
	// Теперь надо обновить уже вставленные вхождения блока. Следующая конструкция работает, но мне крайне не нравится
	currDwg.SendStringToExecute("attsync\n", true, false, false);
	currDwg.SendStringToExecute("n\n", true, false, false);
	currDwg.SendStringToExecute("Frame\n", true, false, false);
}
Есть ли более корректный способ обновления описания блока, и самое главное, как более корректно и безгеморройно обновить вхождения блока?
Код тестовый, за отсутствие должных проверок не бить

Последний раз редактировалось bargool, 05.10.2011 в 13:27.
Просмотров: 16896
 
Непрочитано 05.10.2011, 20:37
#21
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от TararykovDG Посмотреть сообщение
Наверное Вы правы, но раз уж есть bool setAttDefValues и можно сбрасывать атрибуты в умолчательные значения, то почему бы не быть и bool setDynParamValue, а там как надо с такими значениями и вызывать static void AttSync
Ок, пусть будет static void AttSync(this BlockTableRecord btr, bool removeSuperfluous, bool setAttDefValues, bool setDynDefValues).
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
 
Автор темы   Непрочитано 09.10.2011, 13:01
#22
bargool


 
Регистрация: 16.08.2006
Санкт-Петербург
Сообщений: 508
<phrase 1=


Я сейчас поплотнее посмотрел, BlockTableRecord имеет метод UpdateAnonymousBlocks, который обновляет динамические свойства вхождений блоков
Этот код обновляет динамические свойства вхождений после изменения описания блока. Атрибуты не обновляются.
Код:
[Выделить все]
BlockTableRecord frame = transaction.GetObject(
	blockTable[blockname], OpenMode.ForRead) as BlockTableRecord;
if (frame != null)
{
	frame.UpdateAnonymousBlocks();
}
осталось только атрибуты обновлять.

Последний раз редактировалось bargool, 09.10.2011 в 13:05. Причина: нечаянно отправил сообщение
bargool вне форума  
 
Непрочитано 09.10.2011, 13:30
#23
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от bargool Посмотреть сообщение
Я сейчас поплотнее посмотрел, BlockTableRecord имеет метод UpdateAnonymousBlocks, который обновляет динамические свойства вхождений блоков
Этот код обновляет динамические свойства вхождений после изменения описания блока. Атрибуты не обновляются.
Код:
[Выделить все]
BlockTableRecord frame = transaction.GetObject(
	blockTable[blockname], OpenMode.ForRead) as BlockTableRecord;
if (frame != null)
{
	frame.UpdateAnonymousBlocks();
}
осталось только атрибуты обновлять.
я в курсе об этом методе
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
 
Автор темы   Непрочитано 09.10.2011, 20:18
#24
bargool


 
Регистрация: 16.08.2006
Санкт-Петербург
Сообщений: 508
<phrase 1=


static void AttSync(this BlockTableRecord btr, bool removeSuperfluous, bool setAttDefValues, bool setDynDefValues), мне кажется, не надо делать настолько универсальный метод , обычный аналог attsynca, и всё

Последний раз редактировалось bargool, 09.10.2011 в 20:49.
bargool вне форума  
 
Непрочитано 09.10.2011, 21:51 Моя реализация метода AttSynch
1 | #25
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от bargool Посмотреть сообщение
static void AttSync(this BlockTableRecord btr, bool removeSuperfluous, bool setAttDefValues, bool setDynDefValues), мне кажется, не надо делать настолько универсальный метод , обычный аналог attsynca, и всё
Я написал реализацию метода (последний параметр всё же убрал из сигнатуры). Реальная сигнатура такова:

static void AttSync(this BlockTableRecord btr, bool removeSuperfluous, bool setAttDefValues)

Код выложил здесь. Протестировал - работает как на обычных, так и на динамических блоках (тестировал в AutoCAD 2009).
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
 
Непрочитано 09.10.2011, 22:28
#26
TararykovDG

Программист-энтузиаст
 
Регистрация: 17.07.2009
Воронеж
Сообщений: 571


Цитата:
Сообщение от hwd Посмотреть сообщение
Я написал реализацию метода (последний параметр всё же убрал из сигнатуры). Реальная сигнатура такова:

static void AttSync(this BlockTableRecord btr, bool removeSuperfluous, bool setAttDefValues)

Код выложил здесь. Протестировал - работает как на обычных, так и на динамических блоках (тестировал в AutoCAD 2009).


hwd, спасибо за код . И все-таки в коде по ссылке сигнатура шире чем была изначально static void AttSync(this BlockTableRecord btr, bool directOnly, bool removeSuperfluous, bool setAttDefValues)
__________________
cadtools
TararykovDG вне форума  
 
Непрочитано 09.10.2011, 22:30
#27
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от TararykovDG Посмотреть сообщение
hwd, спасибо за код . И все-таки в коде по ссылке сигнатура шире чем была изначально static void AttSync(this BlockTableRecord btr, bool directOnly, bool removeSuperfluous, bool setAttDefValues)
А, ну да, забыл упомянуть... С помощью этого параметра я даю возможность управлять тем, стоит ли обрабатывать те вхождения блоков, которые входят в состав др. определения блока. Т.е. блок в блоке. Иными словами - параметр указывает, нужна ли рекурсивная проверка содержимого блоков.

п.с. Подправил код - добавил контроль над многими дополнительными свойствами атрибута (цвет/слой/ширина/и т.п.). В процессе тестирования обнаружил такой баг (я видимо где-то накосячил в коде): у меня в некоторых вхождениях блоков, один атрибут почему-то разместился в точке 0,0 (МСК) вместо того, чтобы находиться там, где положено. Разбираюсь с проблемой.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:

Последний раз редактировалось hwd, 10.10.2011 в 08:51.
hwd вне форума  
 
Автор темы   Непрочитано 10.10.2011, 10:17
#28
bargool


 
Регистрация: 16.08.2006
Санкт-Петербург
Сообщений: 508
<phrase 1=


hwd, у меня вопрос: ты обращаешься к свойству атрибута TextStyle, это в 2009 есть? просто в 2010 есть только TextStyleId и TextStyleName
bargool вне форума  
 
Непрочитано 10.10.2011, 11:10
#29
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от bargool Посмотреть сообщение
hwd, у меня вопрос: ты обращаешься к свойству атрибута TextStyle, это в 2009 есть? просто в 2010 есть только TextStyleId и TextStyleName
Не сложно догадаться, что если бы такого свойства не было, то я бы попросту не смог скомпилировать код.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
 
Непрочитано 10.10.2011, 11:57
#30
4ydik

Инженер
 
Регистрация: 08.10.2009
Красноярск
Сообщений: 16


Цитата:
Сообщение от hwd Посмотреть сообщение
Я написал реализацию метода (последний параметр всё же убрал из сигнатуры). Реальная сигнатура такова:

static void AttSync(this BlockTableRecord btr, bool removeSuperfluous, bool setAttDefValues)

Код выложил здесь. Протестировал - работает как на обычных, так и на динамических блоках (тестировал в AutoCAD 2009).
Извините меня. я в этом чайник, как этот код прикрутить к Autocad? И как его заставит работать?
4ydik вне форума  
 
Автор темы   Непрочитано 10.10.2011, 12:31
#31
bargool


 
Регистрация: 16.08.2006
Санкт-Петербург
Сообщений: 508
<phrase 1=


Цитата:
Сообщение от 4ydik Посмотреть сообщение
Извините меня. я в этом чайник, как этот код прикрутить к Autocad? И как его заставит работать?
конкретно этот код нужен для использования в других дотнетовских программах. Сам по себе он дублирует стандартную команду автокада attsync. Вам точно нужно объяснять как с ним работать?
bargool вне форума  
 
Непрочитано 10.10.2011, 12:40
#32
4ydik

Инженер
 
Регистрация: 08.10.2009
Красноярск
Сообщений: 16


Цитата:
Сообщение от bargool Посмотреть сообщение
конкретно этот код нужен для использования в других дотнетовских программах. Сам по себе он дублирует стандартную команду автокада attsync. Вам точно нужно объяснять как с ним работать?
У меня имеется куча динам. блоков во внешних файлах которые периодически надо обновлять в соответствии с исходником! Вот я подумал что эта программа спасет меня от того чтобы тыкать по палитре свойств и обновлять каждый блок отдельно!
4ydik вне форума  
 
Автор темы   Непрочитано 10.10.2011, 12:46
#33
bargool


 
Регистрация: 16.08.2006
Санкт-Петербург
Сообщений: 508
<phrase 1=


Цитата:
Сообщение от 4ydik Посмотреть сообщение
У меня имеется куча динам. блоков во внешних файлах которые периодически надо обновлять в соответствии с исходником! Вот я подумал что эта программа спасет меня от того чтобы тыкать по палитре свойств и обновлять каждый блок отдельно!
Это промежуточный результат. Я, сейчас как раз такую программку пишу (почему и создал топик). Предполагаю спрашивать пользователя, какой блок обновлять (ткнуть в примитив), затем спросить файл с эталонным блоком, затем спросить в каких ещё файлах обновлять блоки (это полезно если рамка, к примеру, обновилась..). Но пока я ещё в процессе. Код hwd, очень помог.
Какой у вас автокад?

Последний раз редактировалось bargool, 10.10.2011 в 13:46.
bargool вне форума  
 
Непрочитано 10.10.2011, 14:48
#34
4ydik

Инженер
 
Регистрация: 08.10.2009
Красноярск
Сообщений: 16


У меня 2012 64 bit!
4ydik вне форума  
 
Непрочитано 10.10.2011, 14:55
#35
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от 4ydik Посмотреть сообщение
У меня 2012 64 bit!
и что? я писал и тестил attsync как под 86, так и под 64. Небольшую разницу в API для версии 2012 те, кто пишет на .net, сами внесут.

п.п.с всё, код можно тестировать далее - все обнаруженные баги исправлены. В исходном коде я закомментировал проблемные строки и указал, какие именно проблемы они вызывали:
Цитата:
строки 90, 94 128 и 132 Сбивали позиционирование атрибута GGG
Строки 100 и 138 Вызывали обрушение AutoCAD при нажатии Ctrl + Z
p.s.2 Внёс изменение в код - реализовал корректное выравнивание атрибута.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:

Последний раз редактировалось hwd, 11.10.2011 в 11:56.
hwd вне форума  
 
Непрочитано 18.10.2011, 16:03
#36
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Для тех, кому тема интересна: обновил версию BlockSync + выложил исходники. Более подробно здесь.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > C# .net переопределение динамического блока из внешнего файла

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нужна функция импорта блока из файла Krieger Программирование 20 18.01.2017 07:19
Странное поведение динамического блока высотной отметки hwd Динамические блоки 12 08.09.2011 11:15
Повторное создание вхождения блока из внешнего файла hwd AutoCAD 6 02.04.2010 16:16
Как перенести в чертеж блок из файла библиотеки блоков Main Urod Программирование 8 03.02.2010 14:15
Обновление/замена блока с таким же именем из другого файла. Pesec AutoCAD 2 11.11.2009 19:33