Код черчения массива объектов

Автор Тема: Код черчения массива объектов  (Прочитано 6007 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн iskinАвтор темы

  • ADN OPEN
  • Сообщений: 2
  • Карма: 0
Код из справки автокада по созданию массива из объектов. Подскажите, что не так?
http://help.autodesk.com/view/ACD/2016/RUS/?guid=GUID-EB4639C2-4BCB-46DA-A00D-07FB443BBF0A отказывается работать:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.Geometry;
  5.  
  6. static Point2d PolarPoints(Point2d pPt, double dAng, double dDist)
  7. {
  8.   return new Point2d(pPt.X + dDist * Math.Cos(dAng),
  9.                      pPt.Y + dDist * Math.Sin(dAng));
  10. }
  11.  
  12. [CommandMethod("RectangularArrayObject")]
  13. public static void RectangularArrayObject()
  14. {
  15.     // Get the current document and database
  16.     Document acDoc = Application.DocumentManager.MdiActiveDocument;
  17.     Database acCurDb = acDoc.Database;
  18.  
  19.     // Start a transaction
  20.     using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  21.     {
  22.         // Open the Block table record for read
  23.         BlockTable acBlkTbl;
  24.         acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
  25.                                         OpenMode.ForRead) as BlockTable;
  26.  
  27.         // Open the Block table record Model space for write
  28.         BlockTableRecord acBlkTblRec;
  29.         acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
  30.                                         OpenMode.ForWrite) as BlockTableRecord;
  31.  
  32.         // Create a circle that is at 2,2 with a radius of 0.5
  33.         using (Circle acCirc = new Circle())
  34.         {
  35.             acCirc.Center = new Point3d(2, 2, 0);
  36.             acCirc.Radius = 0.5;
  37.  
  38.             // Add the new object to the block table record and the transaction
  39.             acBlkTblRec.AppendEntity(acCirc);
  40.             acTrans.AddNewlyCreatedDBObject(acCirc, true);
  41.  
  42.             // Create a rectangular array with 5 rows and 5 columns
  43.             int nRows = 5;
  44.             int nColumns = 5;
  45.  
  46.             // Set the row and column offsets along with the base array angle
  47.             double dRowOffset = 1;
  48.             double dColumnOffset = 1;
  49.             double dArrayAng = 0;
  50.  
  51.             // Get the angle from X for the current UCS
  52.             Matrix3d curUCSMatrix = acDoc.Editor.CurrentUserCoordinateSystem;
  53.             CoordinateSystem3d curUCS = curUCSMatrix.CoordinateSystem3d;
  54.             Vector2d acVec2dAng = new Vector2d(curUCS.Xaxis.X,
  55.                                                 curUCS.Xaxis.Y);
  56.  
  57.             // If the UCS is rotated, adjust the array angle accordingly
  58.             dArrayAng = dArrayAng + acVec2dAng.Angle;
  59.  
  60.             // Use the upper-left corner of the objects extents for the array base point
  61.             Extents3d acExts = acCirc.Bounds.GetValueOrDefault();
  62.             Point2d acPt2dArrayBase = new Point2d(acExts.MinPoint.X,
  63.                                                     acExts.MaxPoint.Y);
  64.  
  65.             // Track the objects created for each column
  66.             DBObjectCollection acDBObjCollCols = new DBObjectCollection();
  67.             acDBObjCollCols.Add(acCirc);
  68.  
  69.             // Create the number of objects for the first column
  70.             int nColumnsCount = 1;
  71.             while (nColumns > nColumnsCount)
  72.             {
  73.                 Entity acEntClone = acCirc.Clone() as Entity;
  74.                 acDBObjCollCols.Add(acEntClone);
  75.  
  76.                 // Caclucate the new point for the copied object (move)
  77.                 Point2d acPt2dTo = PolarPoints(acPt2dArrayBase,
  78.                                                 dArrayAng,
  79.                                                 dColumnOffset * nColumnsCount);
  80.  
  81.                 Vector2d acVec2d = acPt2dArrayBase.GetVectorTo(acPt2dTo);
  82.                 Vector3d acVec3d = new Vector3d(acVec2d.X, acVec2d.Y, 0);
  83.                 acEntClone.TransformBy(Matrix3d.Displacement(acVec3d));
  84.  
  85.                 acBlkTblRec.AppendEntity(acEntClone);
  86.                 acTrans.AddNewlyCreatedDBObject(acEntClone, true);
  87.  
  88.                 nColumnsCount = nColumnsCount + 1;
  89.             }
  90.  
  91.             // Set a value in radians for 90 degrees
  92.             double dAng = Math.PI / 2;
  93.  
  94.             // Track the objects created for each row and column
  95.             DBObjectCollection acDBObjCollLvls = new DBObjectCollection();
  96.  
  97.             foreach (DBObject acObj in acDBObjCollCols)
  98.             {
  99.                 acDBObjCollLvls.Add(acObj);
  100.             }
  101.  
  102.             // Create the number of objects for each row
  103.             foreach (Entity acEnt in acDBObjCollCols)
  104.             {
  105.                 int nRowsCount = 1;
  106.  
  107.                 while (nRows > nRowsCount)
  108.                 {
  109.                     Entity acEntClone = acEnt.Clone() as Entity;
  110.                     acDBObjCollLvls.Add(acEntClone);
  111.  
  112.                     // Caclucate the new point for the copied object (move)
  113.                     Point2d acPt2dTo = PolarPoints(acPt2dArrayBase,
  114.                                                     dArrayAng + dAng,
  115.                                                     dRowOffset * nRowsCount);
  116.  
  117.                     Vector2d acVec2d = acPt2dArrayBase.GetVectorTo(acPt2dTo);
  118.                     Vector3d acVec3d = new Vector3d(acVec2d.X, acVec2d.Y, 0);
  119.                     acEntClone.TransformBy(Matrix3d.Displacement(acVec3d));
  120.  
  121.                     acBlkTblRec.AppendEntity(acEntClone);
  122.                     acTrans.AddNewlyCreatedDBObject(acEntClone, true);
  123.  
  124.                     nRowsCount = nRowsCount + 1;
  125.                 }
  126.             }
  127.         }
  128.  
  129.         // Save the new objects to the database
  130.         acTrans.Commit();
  131.     }
  132. }
« Последнее редактирование: 04-03-2016, 00:40:14 от Александр Ривилис »

Отмечено как Решение iskin 04-03-2016, 19:35:17

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13880
  • Карма: 1786
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Код черчения массива объектов
« Ответ #1 : 04-03-2016, 00:41:00 »
Приветствую на форуме. Что не так с кодом? Я его чуть-чуть подредактировал, так как в нём не хватало описания namespace'а и class'а
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7.  
  8. // This line is not mandatory, but improves loading performances
  9. [assembly: CommandClass(typeof(ArrayClassic.MyCommands))]
  10.  
  11. namespace ArrayClassic
  12. {
  13.   public class MyCommands
  14.   {
  15.     static Point2d PolarPoints(Point2d pPt, double dAng, double dDist)
  16.     {
  17.       return new Point2d(pPt.X + dDist * Math.Cos(dAng),
  18.                          pPt.Y + dDist * Math.Sin(dAng));
  19.     }
  20.  
  21.     [CommandMethod("RectangularArrayObject")]
  22.     public static void RectangularArrayObject()
  23.     {
  24.       // Get the current document and database
  25.       Document acDoc = Application.DocumentManager.MdiActiveDocument;
  26.       Database acCurDb = acDoc.Database;
  27.  
  28.       // Start a transaction
  29.       using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  30.       {
  31.         // Open the Block table record for read
  32.         BlockTable acBlkTbl;
  33.         acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
  34.                                         OpenMode.ForRead) as BlockTable;
  35.  
  36.         // Open the Block table record Model space for write
  37.         BlockTableRecord acBlkTblRec;
  38.         acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
  39.                                         OpenMode.ForWrite) as BlockTableRecord;
  40.  
  41.         // Create a circle that is at 2,2 with a radius of 0.5
  42.         using (Circle acCirc = new Circle())
  43.         {
  44.           acCirc.Center = new Point3d(2, 2, 0);
  45.           acCirc.Radius = 0.5;
  46.  
  47.           // Add the new object to the block table record and the transaction
  48.           acBlkTblRec.AppendEntity(acCirc);
  49.           acTrans.AddNewlyCreatedDBObject(acCirc, true);
  50.  
  51.           // Create a rectangular array with 5 rows and 5 columns
  52.           int nRows = 5;
  53.           int nColumns = 5;
  54.  
  55.           // Set the row and column offsets along with the base array angle
  56.           double dRowOffset = 1;
  57.           double dColumnOffset = 1;
  58.           double dArrayAng = 0;
  59.  
  60.           // Get the angle from X for the current UCS
  61.           Matrix3d curUCSMatrix = acDoc.Editor.CurrentUserCoordinateSystem;
  62.           CoordinateSystem3d curUCS = curUCSMatrix.CoordinateSystem3d;
  63.           Vector2d acVec2dAng = new Vector2d(curUCS.Xaxis.X,
  64.                                               curUCS.Xaxis.Y);
  65.  
  66.           // If the UCS is rotated, adjust the array angle accordingly
  67.           dArrayAng = dArrayAng + acVec2dAng.Angle;
  68.  
  69.           // Use the upper-left corner of the objects extents for the array base point
  70.           Extents3d acExts = acCirc.Bounds.GetValueOrDefault();
  71.           Point2d acPt2dArrayBase = new Point2d(acExts.MinPoint.X,
  72.                                                   acExts.MaxPoint.Y);
  73.  
  74.           // Track the objects created for each column
  75.           DBObjectCollection acDBObjCollCols = new DBObjectCollection();
  76.           acDBObjCollCols.Add(acCirc);
  77.  
  78.           // Create the number of objects for the first column
  79.           int nColumnsCount = 1;
  80.           while (nColumns > nColumnsCount)
  81.           {
  82.             Entity acEntClone = acCirc.Clone() as Entity;
  83.             acDBObjCollCols.Add(acEntClone);
  84.  
  85.             // Caclucate the new point for the copied object (move)
  86.             Point2d acPt2dTo = PolarPoints(acPt2dArrayBase,
  87.                                             dArrayAng,
  88.                                             dColumnOffset * nColumnsCount);
  89.  
  90.             Vector2d acVec2d = acPt2dArrayBase.GetVectorTo(acPt2dTo);
  91.             Vector3d acVec3d = new Vector3d(acVec2d.X, acVec2d.Y, 0);
  92.             acEntClone.TransformBy(Matrix3d.Displacement(acVec3d));
  93.  
  94.             acBlkTblRec.AppendEntity(acEntClone);
  95.             acTrans.AddNewlyCreatedDBObject(acEntClone, true);
  96.  
  97.             nColumnsCount = nColumnsCount + 1;
  98.           }
  99.  
  100.           // Set a value in radians for 90 degrees
  101.           double dAng = Math.PI / 2;
  102.  
  103.           // Track the objects created for each row and column
  104.           DBObjectCollection acDBObjCollLvls = new DBObjectCollection();
  105.  
  106.           foreach (DBObject acObj in acDBObjCollCols)
  107.           {
  108.             acDBObjCollLvls.Add(acObj);
  109.           }
  110.  
  111.           // Create the number of objects for each row
  112.           foreach (Entity acEnt in acDBObjCollCols)
  113.           {
  114.             int nRowsCount = 1;
  115.  
  116.             while (nRows > nRowsCount)
  117.             {
  118.               Entity acEntClone = acEnt.Clone() as Entity;
  119.               acDBObjCollLvls.Add(acEntClone);
  120.  
  121.               // Caclucate the new point for the copied object (move)
  122.               Point2d acPt2dTo = PolarPoints(acPt2dArrayBase,
  123.                                               dArrayAng + dAng,
  124.                                               dRowOffset * nRowsCount);
  125.  
  126.               Vector2d acVec2d = acPt2dArrayBase.GetVectorTo(acPt2dTo);
  127.               Vector3d acVec3d = new Vector3d(acVec2d.X, acVec2d.Y, 0);
  128.               acEntClone.TransformBy(Matrix3d.Displacement(acVec3d));
  129.  
  130.               acBlkTblRec.AppendEntity(acEntClone);
  131.               acTrans.AddNewlyCreatedDBObject(acEntClone, true);
  132.  
  133.               nRowsCount = nRowsCount + 1;
  134.             }
  135.           }
  136.         }
  137.  
  138.         // Save the new objects to the database
  139.         acTrans.Commit();
  140.       }
  141.     }
  142.   }
  143. }

И он вполне работает:

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13880
  • Карма: 1786
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Код черчения массива объектов
« Ответ #2 : 04-03-2016, 01:34:54 »
Если же тебя не устраивает обычный массив, а нужен ассоциативный, то я немного переделал код отсюда: http://adn-cis.org/assocziativnyij-massiv-i-ego-api.html


Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7.  
  8. // This line is not mandatory, but improves loading performances
  9. [assembly: CommandClass(typeof(ArrayClassic.MyCommands))]
  10.  
  11. namespace ArrayClassic
  12. {
  13.   public class MyCommands
  14.   {
  15.     /////////////////////////////////////////////////////////////////////////////////////////////////////////
  16.     // Использование: Создание Прямоугольного Ассоциативного Массива
  17.     /////////////////////////////////////////////////////////////////////////////////////////////////////////
  18.     [CommandMethod("CreateAssocArrayRect")]
  19.     public void CreateAssocArrayRect()
  20.     {
  21.       Document doc = Application.DocumentManager.MdiActiveDocument;
  22.       Database db = doc.Database;
  23.       Editor ed = doc.Editor;
  24.       int nRows = 5;
  25.       int nColumns = 5;
  26.  
  27.       double dRowOffset = 1;
  28.       double dColumnOffset = 1;
  29.  
  30.  
  31.       using (Transaction Tx = db.TransactionManager.StartTransaction())
  32.       {
  33.  
  34.         // Создаем исходный примитив - здесь простой круг (Circle)
  35.         Circle circle = new Circle(new Point3d(2, 2, 0), new Vector3d(0, 0, 1), 0.5);
  36.         circle.ColorIndex = 1;
  37.         ObjectIdCollection sourceEntities = new ObjectIdCollection();
  38.  
  39.         // Исходный примитив должен быть в базе
  40.         AcHelper.PostToDatabase(circle);
  41.  
  42.         sourceEntities.Add(circle.ObjectId);
  43.  
  44.         // Базовая точка массива в  VertexRef
  45.         VertexRef basePoint = new VertexRef(new Point3d(2, 2, 0));
  46.  
  47.         // Параметры прямоугольного массива
  48.         double columnSpacing = dRowOffset;
  49.         double rowSpacing = dColumnOffset;
  50.         double levelSpacing = dColumnOffset;
  51.         int columnCount = 5;
  52.         int rowCount = 5;
  53.         int levelCount = 1;
  54.         double rowElevation = 0;
  55.         double axesAngle = 0;
  56.  
  57.         Matrix3d curUCSMatrix = ed.CurrentUserCoordinateSystem;
  58.         CoordinateSystem3d curUCS = curUCSMatrix.CoordinateSystem3d;
  59.         Vector2d acVec2dAng = new Vector2d(curUCS.Xaxis.X, curUCS.Xaxis.Y);
  60.         axesAngle += acVec2dAng.Angle;
  61.  
  62.         AssocArrayRectangularParameters parameters = new AssocArrayRectangularParameters(columnSpacing,
  63.             rowSpacing,
  64.             levelSpacing,
  65.             columnCount,
  66.             rowCount,
  67.             levelCount,
  68.             rowElevation,
  69.             axesAngle);
  70.  
  71.         parameters.AxesAngle = acVec2dAng.Angle;
  72.         parameters.XAxisDirection = curUCS.Xaxis;
  73.         parameters.YAxisDirection = curUCS.Yaxis;
  74.  
  75.         // Как показано ниже, параметры могут быть связаны с выражениями, включающими переменные
  76.         AcHelper.AddOrModifVariable("RowCount", rowCount.ToString());
  77.         AcHelper.AddOrModifVariable("RowSpacing", rowSpacing.ToString());
  78.  
  79.         parameters.SetRowCount(rowCount, "RowCount", "");
  80.         parameters.SetRowSpacing(rowSpacing, "RowSpacing", "");
  81.  
  82.         // Создаем массив. Возвращается AssocArray помещенный в базу
  83.         AssocArray array = Autodesk.AutoCAD.DatabaseServices.AssocArray.CreateArray(sourceEntities,
  84.             basePoint,
  85.             parameters);
  86.  
  87.         // Если нужно переместить массив, то имея его свойство EntityId
  88.         // можно применить трансформацию как показано ниже
  89.         Entity arrayEnt = Tx.GetObject(array.EntityId, OpenMode.ForWrite) as Entity;
  90.  
  91.         arrayEnt.TransformBy(Matrix3d.Displacement(new Vector3d(5, 5, 5)));
  92.  
  93.         // Заставляем обновится все связи
  94.         AssocManager.EvaluateTopLevelNetwork(db, null, 0);
  95.  
  96.         // Так как массив уже создан, то исходный круг можно удалить.
  97.         // Он уже содержится в массиве (фактически в анонимном блоке)
  98.         circle.Erase(true);
  99.  
  100.         Tx.Commit();
  101.       }
  102.     }
  103.  
  104.   }
  105.  
  106.   public class AcHelper
  107.   {
  108.     /////////////////////////////////////////////////////////////////////////////////////////////////////////
  109.     // Helper method: Добавление примитива в пространство модели указанной базы данных
  110.     //
  111.     /////////////////////////////////////////////////////////////////////////////////////////////////////////
  112.     public static ObjectId PostToDatabase(Database db, Entity entity)
  113.     {
  114.       using (Transaction Tx = db.TransactionManager.StartTransaction())
  115.       {
  116.         BlockTable bt = Tx.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  117.  
  118.         BlockTableRecord model = Tx.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  119.  
  120.         ObjectId newId = model.AppendEntity(entity);
  121.  
  122.         Tx.AddNewlyCreatedDBObject(entity, true);
  123.  
  124.         Tx.Commit();
  125.  
  126.         return newId;
  127.       }
  128.     }
  129.     /////////////////////////////////////////////////////////////////////////////////////////////////////////
  130.     // Helper method: Добавление примитива в пространство модели текущей базы данных
  131.     //
  132.     /////////////////////////////////////////////////////////////////////////////////////////////////////////
  133.     public static ObjectId PostToDatabase(Entity entity)
  134.     {
  135.       Database db = Application.DocumentManager.MdiActiveDocument.Database;
  136.       return PostToDatabase(db, entity);
  137.     }
  138.  
  139.     /////////////////////////////////////////////////////////////////////////////////////////////////////////
  140.     // Добавление новой переменной в ассоциативную сеть или модификация существующей
  141.     //
  142.     /////////////////////////////////////////////////////////////////////////////////////////////////////////
  143.     public static ObjectId AddOrModifVariable(string varName, string varExpression)
  144.     {
  145.       Document doc = Application.DocumentManager.MdiActiveDocument;
  146.       Database db = doc.Database;
  147.  
  148.       ObjectId varid = ObjectId.Null;
  149.  
  150.       using (Transaction Tx = db.TransactionManager.StartTransaction())
  151.       {
  152.         ObjectId networkId = AssocNetwork.GetInstanceFromObject(db.CurrentSpaceId, true, true, "ACAD_ASSOCNETWORK");
  153.         AssocNetwork network = Tx.GetObject(networkId, OpenMode.ForWrite) as AssocNetwork;
  154.  
  155.         ObjectIdCollection actionIds = network.GetActions;
  156.  
  157.         for (int i = 0; i < actionIds.Count; ++i)
  158.         {
  159.           try
  160.           {
  161.             AssocVariable var1 = Tx.GetObject(actionIds[i], OpenMode.ForWrite) as AssocVariable;
  162.  
  163.             if (var1 != null)
  164.             {
  165.               if (var1.Name == varName)
  166.               {
  167.                 String errMsg = "";
  168.                 var1.SetExpression(varExpression, "", true, true, ref errMsg, false);
  169.  
  170.                 ResultBuffer rb = new ResultBuffer();
  171.                 errMsg = var1.EvaluateExpression(ref rb);
  172.                 var1.Value = rb;
  173.  
  174.                 Tx.Commit();
  175.  
  176.                 return var1.ObjectId;
  177.               }
  178.             }
  179.           }
  180.           catch
  181.           {
  182.  
  183.           }
  184.         }
  185.  
  186.         AssocVariable var = new AssocVariable();
  187.         varid = network.Database.AddDBObject(var);
  188.         network.AddAction(var.ObjectId, true);
  189.         Tx.AddNewlyCreatedDBObject(var, true);
  190.         Tx.Commit();
  191.       }
  192.  
  193.       using (Transaction Tx = db.TransactionManager.StartTransaction())
  194.       {
  195.         AssocVariable var = (AssocVariable)Tx.GetObject(varid, OpenMode.ForWrite);
  196.         var.SetName(varName, true);
  197.         var.Value = new ResultBuffer(new TypedValue(1001, 5));
  198.         String errMsg = "";
  199.         var.SetExpression(varExpression, "", true, true, ref errMsg, false);
  200.         ResultBuffer rb = new ResultBuffer();
  201.         errMsg = var.EvaluateExpression(ref rb);
  202.         var.Value = rb;
  203.         Tx.Commit();
  204.       }
  205.  
  206.       return varid;
  207.     }
  208.  
  209.   }
  210. }


Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн iskinАвтор темы

  • ADN OPEN
  • Сообщений: 2
  • Карма: 0
Re: Код черчения массива объектов
« Ответ #3 : 04-03-2016, 19:35:05 »
Спасибо большое. Просто не ожидал, что в официальной справке может быть код с ошибкой. Про using я догадался. А про пространство имен не до конца.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13880
  • Карма: 1786
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Код черчения массива объектов
« Ответ #4 : 04-03-2016, 20:08:08 »
Просто не ожидал, что в официальной справке может быть код с ошибкой.
Это не ошибка. Они часто публикуют код не полностью. Если бы не опубликовали using'и то наверное было бы очевиднее, что это только два метода класса.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение