Как добавить новый SubAssembly

Автор Тема: Как добавить новый SubAssembly  (Прочитано 211 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

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

  • ADN OPEN
  • Сообщений: 23
  • Карма: 0
Как добавить новый SubAssembly
« : 18-09-2019, 15:51:35 »
Создан новый SubAssembly (вернее изменен существующий BaseLane.vb под именем BaseLane2.vb)
Получен новый  C3DStockSubassemblies.dll , скопирован в C:\ProgramData\Autodesk\C3D 2018\enu\C3DStockSubassemblies.dll

при запуске программы на C# с файлом  BasicLane все нормально, если меняем на BasicLane2, выскакивает ошибка
Can't find subassembly with the className
что-то не так делаю, где-то нужно добавить имя, вопрос где?
код
Код - C# [Выбрать]
  1. [CommandMethod("CreateAssembly")]
  2.         public void CreateAssembly()
  3.         {
  4.             CivilDocument a_CivilDoc = CivilApplication.ActiveDocument;      
  5.             string saname = "C:\\ProgramData\\Autodesk\\C3D 2018\\enu\\C3DStockSubassemblies.dll";
  6.             string cname = "Subassembly.BasicLane2";
  7.             Autodesk.AutoCAD.Geometry.Point3d location = new Autodesk.AutoCAD.Geometry.Point3d(0, 0, 0);
  8.            
  9.           ObjectId q_SubassemblyId = a_CivilDoc.SubassemblyCollection.ImportStockSubassembly(saname, cname, location);
  10.         }

ошибка выскакивает после ImportStockSubassembly       
Спасибо заранее
« Последнее редактирование: 18-09-2019, 17:15:40 от alsh »

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

  • Administrator
  • *****
  • Сообщений: 10027
  • Карма: 1281
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как добавить новый SubAssembly
« Ответ #1 : 18-09-2019, 16:30:04 »
И класс поменяли на BaseLane2 ?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 23
  • Карма: 0
Re: Как добавить новый SubAssembly
« Ответ #2 : 18-09-2019, 17:13:58 »
В Vb
Код - vb.net [Выбрать]
  1. Option Explicit On
  2. Option Strict Off
  3.  
  4. Public Class BasicLane2
  5.     Inherits SATemplate
  6.  
  7.     '--------------------------------------------------------------------------
  8.     ' Default values for input parameters
  9.     Private Const SideDefault = 0 '"right"
  10.     Private Const LaneWidthDefault = 15.0#
  11.     Private Const LaneDepthDefault = 0.75
  12.     Private Const LaneSlopeDefault = -0.05
  13.  
  14.     Protected Overrides Sub GetInputParametersImplement(ByVal corridorState As CorridorState)
  15.         MyBase.GetInputParametersImplement(corridorState)
  16.  
  17.         Dim paramsLong As ParamLongCollection
  18.         paramsLong = corridorState.ParamsLong
  19.  
  20.         Dim paramsDouble As ParamDoubleCollection
  21.         paramsDouble = corridorState.ParamsDouble
  22.  
  23.         ' Add the input parameters we use in this script
  24.         paramsLong.Add(Utilities.Side, SideDefault)
  25.         paramsDouble.Add("Width", LaneWidthDefault)
  26.         paramsDouble.Add("Depth", LaneDepthDefault)
  27.         paramsDouble.Add("Slope", LaneSlopeDefault)
  28.     End Sub
Все в точности как BasicLane. В предыдущем посте ошибся, не BaseLane2, a BasicLane2 (стандартный файл BasicLane.vb).
Вообще файл vb добавил в список файлов в примере C:\Program Files\Autodesk\AutoCAD 2018\C3D\Sample\Civil 3D API\C3DStockSubassemblies,
dll добавил и туда в \bin тоже, в cs файле менял ссылку, не помогло ...

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2098
  • Карма: 543
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Re: Как добавить новый SubAssembly
« Ответ #3 : 18-09-2019, 18:27:36 »
У меня пока тоже не получилось. Пока понял, что в первом аргументе метода должен быть не путь к dll (civil его и так знает), а произвольное название конструкции: https://knowledge.autodesk.com/support/autocad-civil-3d/learn-explore/caas/CloudHelp/cloudhelp/2017/ENU/Civil3D-DevGuide/files/GUID-9A86FF91-547D-4843-8D5D-F28201EF836B-htm.html

Отмечено как Решение Александр Ривилис 19-09-2019, 13:37:15

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2098
  • Карма: 543
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Re: Как добавить новый SubAssembly
« Ответ #4 : 18-09-2019, 19:05:22 »
Судя по всему, для метода ImportStockSubassembly нужно чтобы конструкция содержалась в файле APC (Т.к. "под капотом" этот метод использует загрузку из файла методом ImportSubassembly, внимание на строки 32 и 36):
Код - C# [Выбрать]
  1. public unsafe ObjectId ImportStockSubassembly(string subassemblyName, string className, Point3d location)
  2. {
  3.         //IL_009a: Unknown result type (might be due to invalid IL or missing references)
  4.         //IL_009b: Unknown result type (might be due to invalid IL or missing references)
  5.         //IL_00a0: Unknown result type (might be due to invalid IL or missing references)
  6.         //IL_00cf: Unknown result type (might be due to invalid IL or missing references)
  7.         //IL_00fb: Unknown result type (might be due to invalid IL or missing references)
  8.         checkSubassemblyNameValid(subassemblyName);
  9.         string paramName = "className";
  10.         if (null == className)
  11.         {
  12.                 throw new ArgumentNullException(paramName);
  13.         }
  14.         byte b = (className.Trim().Length > 0) ? ((byte)1) : ((byte)0);
  15.         string message = "className should be at least one character.";
  16.         if (0 == b)
  17.         {
  18.                 throw new ArgumentException(message);
  19.         }
  20.         string stockSubassemblyFolder = getStockSubassemblyFolder();
  21.         AecRmCString aecRmCString;
  22.         ObjectId result;
  23.         if (stockSubassemblyFolder != (string)null && stockSubassemblyFolder.Length > 0)
  24.         {
  25.                 global::<Module>.AecRmCString.{ctor}(&aecRmCString);
  26.                 AecRmCString aecRmCString2;
  27.                 try
  28.                 {
  29.                         global::<Module>.AecRmCString.{ctor}(&aecRmCString2);
  30.                         try
  31.                         {
  32.                                 if (getAtcFilePathAndItemId(stockSubassemblyFolder, className, &aecRmCString, &aecRmCString2)) // <--- !!!!
  33.                                 {
  34.                                         char* value = global::<Module>.ATL.CSimpleStringT<wchar_t,1>.GetString((CSimpleStringT<wchar_t,1>*)(&aecRmCString2));
  35.                                         char* value2 = global::<Module>.ATL.CSimpleStringT<wchar_t,1>.GetString((CSimpleStringT<wchar_t,1>*)(&aecRmCString));
  36.                                         result = ImportSubassembly(subassemblyName, new string(value2), new string(value), location); // <--- !!!
  37.                                 // .... итд

У себя нашёл, что BasicLane описана тут: C:\ProgramData\Autodesk\C3D 2018\rus\Tool Catalogs\Road Catalog\C3D Metric Basic Subassembly Catalog.atc
Подозреваю, что надо туда внести и BasicLane2.
Если используются "имперские" единицы, то изменения надо вносить в этот файл: C:\ProgramData\Autodesk\C3D 2018\rus\Tool Catalogs\Road Catalog\C3D Imperial Basic Subassembly Catalog.atc
Код - C# [Выбрать]
  1. [return: MarshalAs(UnmanagedType.U1)]
  2. private unsafe bool getAtcFilePathAndItemId(string stockSubassemblyFolderPath, string className, AecRmCString* strActFilePath, AecRmCString* strItemId)
  3. {
  4.         AeccUnitBase.SettingsUnits settingsUnits = global::<Module>.AeccUnitBase.GetDrawingUnit(GetImpObj(), 0);
  5.         bool flag = global::<Module>.AeccUnitBase.IsMetric(settingsUnits);
  6.         bool flag2 = global::<Module>.AeccUnitBase.IsImperial(settingsUnits);
  7.         string[] files = Directory.GetFiles(stockSubassemblyFolderPath, "*.atc", SearchOption.TopDirectoryOnly);
  8.         int num = 0;
  9.         if (0L < (long)(IntPtr)(void*)files.LongLength)
  10.         {
  11.                 do
  12.                 {
  13.                         string text = files[num];
  14.                         string fileName = Path.GetFileName(text);
  15.                         if ((flag && fileName.StartsWith("C3D Metric")) || (flag2 && fileName.StartsWith("C3D Imperial"))) // <--- !!!!
  16.                         {
  17.                                 XmlDocument xmlDocument = global::<Module>.?A0x671e1822.loadXmlDocument(text);
  18.                                 if (xmlDocument != null)
  19.                                 {
  20.                                 // ... итд

Фрагмент файла ATC (Imperial):
Код - XML [Выбрать]
  1. <Tool>
  2.         <ItemID idValue="{32BCCC1B-5F68-4B1A-A0E6-B8CB9C37034D}"/>
  3.         <Properties>
  4.         <ItemName resource="501" src="AeccStockSubassemblyScriptsRC.dll"/>
  5.                 <Images>
  6.                         <Image cx="64" cy="64" src=".\Images\AeccBasicLane.png"/>
  7.                 </Images>
  8.         <Description resource="502" src="AeccStockSubassemblyScriptsRC.dll"/>
  9.                 <Keywords>_lane subassembly</Keywords>
  10.                 <Help>
  11.                         <HelpFile>WBH</HelpFile>
  12.                         <HelpCommand>HELP_HHWND_TOPIC</HelpCommand>
  13.                         <HelpData>SA_BasicLane</HelpData>
  14.                 </Help>
  15.                 <Time createdUniversalDateTime="2002-04-05T21:58:00" modifiedUniversalDateTime="2002-04-05T21:58:00"/>
  16.         </Properties>
  17.         <Source/>
  18.         <StockToolRef idValue="{7F55AAC0-0256-48D7-BFA5-914702663FDE}"/>
  19.         <Data>
  20.                 <AeccDbSubassembly>
  21.                         <GeometryGenerateMode>UseDotNet</GeometryGenerateMode>
  22.                 <DotNetClass Assembly="%AECCCONTENT_DIR%\C3DStockSubassemblies.dll">Subassembly.BasicLane</DotNetClass>
  23.             <Resource Module="AeccStockSubassemblyScriptsRC.dll"/>
  24.                         <Params>
  25.                                 <Version DataType="String" DisplayName="503" Description="504">R2017</Version>
  26.                                 <Side DataType="Long" DisplayName="505" Description="506">0
  27.                     <Enum>
  28.                                                 <Right DisplayName="507">0</Right>
  29.                                                 <Left DisplayName="508">1</Left>
  30.                                         </Enum>
  31.                                 </Side>
  32.                                 <Width DataType="Double" TypeInfo="16" DisplayName="509" Description="510">12.0</Width>
  33.                                 <Depth DataType="Double" TypeInfo="16" DisplayName="511" Description="512">0.67</Depth>
  34.                                 <Slope DataType="Double" TypeInfo="9"  DisplayName="513" Description="514">-0.02</Slope>
  35.                         </Params>
  36.                 </AeccDbSubassembly>
  37.                 <Units>foot</Units>
  38.         </Data>
  39. </Tool>
  40.  

Update 19.09.2019 11:40
Проверил идею. После того как я добавил данные о новом классе в ATC-файл, код отработал без ошибок и конструкция добавилась в чертёж.

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

  • ADN OPEN
  • Сообщений: 23
  • Карма: 0
Re: Как добавить новый SubAssembly
« Ответ #5 : 19-09-2019, 13:30:13 »
Дмитрий, спасибо большое!
Добавил всю конструкцию типа последнего кода, от <Tool> до </Tool> для нового класса.
Тоже отрабатывает без ошибок и рисует.
Вопрос что с IdValue в коде ATC и другие значения, можно ли просто копировать?

https://knowledge.autodesk.com/support/civil-3d/learn-explore/caas/CloudHelp/cloudhelp/2016/ENU/Civil3D-DevGuide/files/GUID-8F9A5C64-4EBE-433E-89B8-92F776DBACFD-htm.html
Здесь Аutodesk рекомендует скопировать ATC и другие файлы "to its destination directory". Непонятно, сюда? <AutoCAD Civil 3D Install Directory>\Sample\Civil 3D API\C3DstockSubAssemblies ?


Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2098
  • Карма: 543
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Re: Как добавить новый SubAssembly
« Ответ #6 : 19-09-2019, 14:17:01 »
Вопрос что с IdValue в коде ATC и другие значения, можно ли просто копировать?
ItemID-idValue однозначно надо генерировать новый (например, с помощью встроенного в VS инструмента генерации GUID). Иначе будут конфликты с другими конструкциями.
По остальным параметрам не подскажу, т.к. с конструкциями мало имел дело и не до конца понимаю что они обозначают. Но вот тут довольно толково про них всё расписано: https://knowledge.autodesk.com/support/civil-3d/learn-explore/caas/CloudHelp/cloudhelp/2016/ENU/Civil3D-DevGuide/files/GUID-1D0CC1CE-DB5E-427B-A2C2-485075145D5B-htm.html
Здесь Аutodesk рекомендует скопировать ATC и другие файлы "to its destination directory". Непонятно, сюда? <AutoCAD Civil 3D Install Directory>\Sample\Civil 3D API\C3DstockSubAssemblies ?
Autodesk похоже сам ещё не определился :) (Отсюда):
Цитировать
Save the .atc file to the location where your tool catalogs are stored. The default location is .
Насколько я помню, файлы конструкций могут лежать вообще в любом месте (при подгрузке просто надо указать полный путь к ним). А по умолчанию:
C:\ProgramData\Autodesk\C3D 2018\rus\Tool Catalogs\Road Catalog\C3D Metric Basic Subassembly Catalog.atc
C:\ProgramData\Autodesk\C3D 2018\rus\Tool Catalogs\Road Catalog\C3D Imperial Basic Subassembly Catalog.atc
По крайней мере, метод ImportStockSubassembly ищет их только там.

P.S.
Код - C# [Выбрать]
  1. [CommandMethod("GetDefaultCatalogTest")]
  2. public void GetDefaultCatalogCmd()
  3. {
  4.     Type subColType = CivilApplication.ActiveDocument.SubassemblyCollection.GetType();
  5.     MethodInfo dynMethod = subColType.GetMethod
  6.         ("getStockSubassemblyFolder", BindingFlags.NonPublic | BindingFlags.Static);
  7.     string defCatalogPath = dynMethod.Invoke(this, null)?.ToString();
  8.  
  9.     Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager
  10.         .MdiActiveDocument.Editor.WriteMessage("\nCatalog path: {0}", defCatalogPath ?? "*ERROR*");
  11. }
  12.  

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

  • ADN OPEN
  • Сообщений: 23
  • Карма: 0
Re: Как добавить новый SubAssembly
« Ответ #7 : 19-09-2019, 14:57:29 »
Еще раз спасибо