Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: iskin от 04-03-2016, 00:11:11

Название: Код черчения массива объектов
Отправлено: iskin от 04-03-2016, 00:11:11
Код из справки автокада по созданию массива из объектов. Подскажите, что не так?
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. }
Название: Re: Код черчения массива объектов
Отправлено: Александр Ривилис от 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. }

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

Название: Re: Код черчения массива объектов
Отправлено: Александр Ривилис от 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. }


Название: Re: Код черчения массива объектов
Отправлено: iskin от 04-03-2016, 19:35:05
Спасибо большое. Просто не ожидал, что в официальной справке может быть код с ошибкой. Про using я догадался. А про пространство имен не до конца.
Название: Re: Код черчения массива объектов
Отправлено: Александр Ривилис от 04-03-2016, 20:08:08
Просто не ожидал, что в официальной справке может быть код с ошибкой.
Это не ошибка. Они часто публикуют код не полностью. Если бы не опубликовали using'и то наверное было бы очевиднее, что это только два метода класса.