18/05/2016
Как обновить выбранные поля не выполняя регенерацию всего чертежа
Вопрос: Мне необходимо выполнить обновление некоторых полей в чертеже, но мне не хотелось бы выполнять полную регенерацию. Как это можно осуществить?
Ответ: В ObjectARX есть семейство функций acdbEvaluateFields, которые и позволяют обновить поля в чертеже. Пример использования функции acdbEvaluateFields смотрите ниже:
Код - C++: [Выделить]
- static void UPDFLD () {
- Acad::ErrorStatus es;
- ads_name en; ads_point p;
- if (acedEntSel(_T("\nВыберите примитив: "), en, p) == RTNORM) {
- AcDbObjectId eId; acdbGetObjectId(eId, en);
- AcDbEntityPointer pEnt(eId, AcDb::kForRead);
- if ((es = pEnt.openStatus()) != Acad::eOk) {
- acutPrintf(_T("\nОшибка открытия: %s"),
- acadErrorStatusText(pEnt.openStatus()));
- return;
- }
- int i1 = 0, i2 = 0;
- Acad::ErrorStatus es = acdbEvaluateFields(eId,
- AcDbField::EvalContext::kRegen, NULL, NULL, AcFd::kEvalRecursive, &i1, &i2);
- }
- }
Если использовать AutoCAD .NET API, то имеется возможность обновить все поля в чертеже при помощи метода Database.EvaluateFields. Чтобы обновить выбранные поля придётся воспользоваться P/Invoke для acdbEvaluateFields. Так как сигнатура у этой функции не очень тривиальная, то привожу пример:
Код - C#: [Выделить]
- using System;
- using Autodesk.AutoCAD.Runtime;
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.DatabaseServices;
- using Autodesk.AutoCAD.Geometry;
- using Autodesk.AutoCAD.EditorInput;
- using System.Runtime.InteropServices;
- [assembly: CommandClass(typeof(AutoCAD_CSharp_plug_in5.MyCommands))]
- namespace AutoCAD_CSharp_plug_in5
- {
- public class MyCommands
- {
- #region PInvoke acdbEvaluateFields
- // Acad::ErrorStatus acdbEvaluateFields (
- // const AcDbObjectId& objId,
- // int nContext,
- // const ACHAR* pszPropName = NULL,
- // AcDbDatabase* pDb = NULL,
- // AcFd::EvalFields nEvalFlag = AcFd::kEvalRecursive,
- // int* pNumFound = NULL,
- // int* pNumEvaluated = NULL
- // );
- // AutoCAD 2013 и 2014 x64
- const string acdbEvaluateFields_x64 =
- "?acdbEvaluateFields@@YA?AW4ErrorStatus@Acad@@AEBVAcDbObjectId@@HPEB_WPEAVAcDbDatabase@@W4EvalFields@AcFd@@PEAH4@Z";
- const string acdbEvaluateFields_x32 =
- "?acdbEvaluateFields@@YA?AW4ErrorStatus@Acad@@ABVAcDbObjectId@@HPB_WPAVAcDbDatabase@@W4EvalFields@AcFd@@PAH4@Z";
- [DllImport("acdb19.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, ExactSpelling = true,
- EntryPoint = acdbEvaluateFields_x64)]
- private static extern Int32 acdbEvaluateFields19x64(ref ObjectId id, Int32 context,
- IntPtr pszPropName, IntPtr db, Int32 eval, IntPtr i1, IntPtr i2);
- // AutoCAD 2013 и 2014 x86
- [DllImport("acdb19.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, ExactSpelling = true,
- EntryPoint = acdbEvaluateFields_x32)]
- private static extern Int32 acdbEvaluateFields19x32(ref ObjectId id, Int32 context,
- IntPtr pszPropName, IntPtr db, Int32 eval, IntPtr i1, IntPtr i2);
- // AutoCAD 2015 и 2016 x64
- [DllImport("acdb20.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, ExactSpelling = true,
- EntryPoint = acdbEvaluateFields_x64)]
- private static extern Int32 acdbEvaluateFields20x64(ref ObjectId id, Int32 context,
- IntPtr pszPropName, IntPtr db, Int32 eval, IntPtr i1, IntPtr i2);
- // AutoCAD 2015 и 2016 x86
- [DllImport("acdb20.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, ExactSpelling = true,
- EntryPoint = acdbEvaluateFields_x32)]
- private static extern Int32 acdbEvaluateFields20x32(ref ObjectId id, Int32 context,
- IntPtr pszPropName, IntPtr db, Int32 eval, IntPtr i1, IntPtr i2);
- // AutoCAD 2017 x64
- [DllImport("acdb21.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, ExactSpelling = true,
- EntryPoint = acdbEvaluateFields_x64)]
- private static extern Int32 acdbEvaluateFields21x64(ref ObjectId id, Int32 context,
- IntPtr pszPropName, IntPtr db, Int32 eval, IntPtr i1, IntPtr i2);
- // AutoCAD 2017x86
- [DllImport("acdb21.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, ExactSpelling = true,
- EntryPoint = acdbEvaluateFields_x32)]
- private static extern Int32 acdbEvaluateFields21x32(ref ObjectId id, Int32 context,
- IntPtr pszPropName, IntPtr db, Int32 eval, IntPtr i1, IntPtr i2);
- #endregion
- private Int32 acdbEvaluateFields(ref ObjectId id, Int32 context)
- {
- switch (Application.Version.Major)
- {
- case 21:
- if (IntPtr.Size == 8)
- return acdbEvaluateFields21x64(ref id, 16, IntPtr.Zero, IntPtr.Zero, 1, IntPtr.Zero, IntPtr.Zero);
- else
- return acdbEvaluateFields21x32(ref id, 16, IntPtr.Zero, IntPtr.Zero, 1, IntPtr.Zero, IntPtr.Zero);
- case 20:
- if (IntPtr.Size == 8)
- return acdbEvaluateFields20x64(ref id, 16, IntPtr.Zero, IntPtr.Zero, 1, IntPtr.Zero, IntPtr.Zero);
- else
- return acdbEvaluateFields20x32(ref id, 16, IntPtr.Zero, IntPtr.Zero, 1, IntPtr.Zero, IntPtr.Zero);
- case 19:
- if (IntPtr.Size == 8)
- return acdbEvaluateFields19x64(ref id, 16, IntPtr.Zero, IntPtr.Zero, 1, IntPtr.Zero, IntPtr.Zero);
- else
- return acdbEvaluateFields19x32(ref id, 16, IntPtr.Zero, IntPtr.Zero, 1, IntPtr.Zero, IntPtr.Zero);
- default:
- break;
- }
- return 0;
- }
- [CommandMethod("Test", "Test", CommandFlags.Modal)]
- public void Test()
- {
- // Обновление полей в блоке
- Document doc = Application.DocumentManager.MdiActiveDocument;
- Database db = doc.Database;
- Editor ed = doc.Editor;
- var sel = ed.GetEntity("Выбери блок для обновления полей в атрибутах: ");
- if (sel.Status == PromptStatus.OK)
- {
- ObjectId id = sel.ObjectId;
- acdbEvaluateFields(ref id, 16);
- }
- }
- }
- }
Автор: Александр Ривилис
Отредактировано 18.05.2016 в 19:47:43
Обсуждение: http://adn-cis.org/forum/index.php?topic=7092
Опубликовано 18.05.2016Отредактировано 18.05.2016 в 19:47:43