BIM360 Issue pushpin - в каких координатах?

Автор Тема: BIM360 Issue pushpin - в каких координатах?  (Прочитано 10995 раз)

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

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Если из BIM360 Docs получать Issues, "привязанные" к файлам (в основном это файлы Navisworks), то у Issue будут данные по булавке (pushpin):


Булавку, в свою очередь, можно "прикрепить" только к элементу модели. Например, используя плагин Coordination Issues for Autodesk® Navisworks®

Возникла задача - найти элемент в модели Navisworks по координатам pushpin. Но никакой справочной информации я не смог найти. Главный вопрос - что это за координаты location и как перевести их в координаты модели?

Отмечено как Решение Александр Пекшев aka Modis 28-09-2021, 16:35:19

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #1 : 27-09-2021, 13:06:44 »
На вскидку, нужно учесть globalOffset, как вот здесь:
https://adn-cis.org/map-forge-viewer-camera-back-to-navisworks.html

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #2 : 27-09-2021, 13:09:16 »
Я бы ещё посмотрел вот в эту сторону на всякий случай
Код - Javascript [Выбрать]
  1. NOP_VIEWER.model.getModelToViewerTransform()

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #3 : 27-09-2021, 14:33:17 »
Спасибо за ссылки, но вопрос-то в другом.
Из плагина я "вынул" кусок, который восстанавливает точку обзора:
Код - C# [Выбрать]
  1. public static void RestorePushPinViewpoint(Autodesk.Navisworks.Api.View view, PushPinData data)
  2. {
  3.     if (view == null)
  4.         return;
  5.  
  6.     var viewpoint = view.CreateViewpointCopy();
  7.     if (data.Target != null)
  8.     {
  9.         viewpoint.Position = LinearUtils.ArrayToPoint3D(data.Eye);
  10.         viewpoint.AspectRatio = data.AspectRatio;
  11.         viewpoint.WorldUpVector = new UnitVector3D(Autodesk.Navisworks.Api.Application.ActiveDocument.UpVector);
  12.         viewpoint.PointAt(LinearUtils.ArrayToPoint3D(data.Target));
  13.         viewpoint.AlignUp(LinearUtils.ArrayToVector3D(data.Up));
  14.         viewpoint.Projection = data.IsOrthographic ? ViewpointProjection.Orthographic : ViewpointProjection.Perspective;
  15.         if (data.IsOrthographic)
  16.         {
  17.             if (!data.OrthographicHeight.HasValue)
  18.             {
  19.                 throw new ArgumentException(
  20.                     @"Invalid viewpoint. Is orthographic but no orthographicHeight specified.",
  21.                     nameof(data.OrthographicHeight));
  22.             }
  23.            
  24.             viewpoint.HeightField = data.OrthographicHeight.Value;
  25.         }
  26.         else
  27.         {
  28.             if (!data.FieldOfView.HasValue)
  29.             {
  30.                 throw new ArgumentException(
  31.                     @"Invalid viewpoint. Is perspective but no fieldOfView specified.",
  32.                     nameof(data.FieldOfView));
  33.             }
  34.            
  35.             viewpoint.HeightField = LinearUtils.DegreesToRadians(data.FieldOfView.Value);
  36.         }
  37.     }
  38.     else
  39.     {
  40.         viewpoint.ZoomBox(Autodesk.Navisworks.Api.Application.MainDocument.GetBoundingBox(true));
  41.     }
  42.    
  43.     view.CopyViewpointFrom(viewpoint, ViewChange.JumpCut);
  44.     view.RequestDelayedRedraw(ViewRedrawRequests.OverlayRender);
  45. }

И перед этим еще производится трансформ:
Код - C# [Выбрать]
  1. public static bool TryTransformPushPinData(Pushpin data, Model model, out PushPinData transformedData)
  2. {
  3.     if (model != null)
  4.     {
  5.         transformedData = new PushPinData(data);
  6.        
  7.         if (!Path.GetExtension(new Uri(model.FileName).LocalPath)
  8.             .Equals(".nwd", StringComparison.OrdinalIgnoreCase))
  9.         {
  10.             Transform3D modelToWorldTransform = GetModelToWorldTransform(model);
  11.             transformedData.Location = TransformPoint(data.Location, modelToWorldTransform);
  12.             transformedData.Eye = TransformPoint(data.Eye, modelToWorldTransform);
  13.             transformedData.Target = TransformPoint(data.Target, modelToWorldTransform);
  14.         }
  15.  
  16.         if (transformedData.IsOrthographic && transformedData.OrthographicHeight.HasValue)
  17.         {
  18.             double num = Autodesk.Navisworks.Api.Interop.LcOaUnit.ScaleFactor(model.Units,
  19.                 Autodesk.Navisworks.Api.Application.MainDocument.Models.First.Units);
  20.             transformedData.OrthographicHeight *= num;
  21.         }
  22.        
  23.         return true;
  24.     }
  25.  
  26.     transformedData = null;
  27.     return false;
  28. }
  29.  
  30. private static Transform3D GetModelToWorldTransform(Model model)
  31. {
  32.     double value = Autodesk.Navisworks.Api.Interop.LcOaUnit.ScaleFactor(
  33.         model.Units,
  34.         Autodesk.Navisworks.Api.Application.MainDocument.Models.First.Units);
  35.     Transform3DComponents transform3DComponents = model.Transform.Factor();
  36.     transform3DComponents.Scale = transform3DComponents.Scale.Multiply(value);
  37.     return transform3DComponents.Combine();
  38. }
  39.  
  40. private static double[] TransformPoint(double[] pnt, Transform3D transform)
  41. {
  42.     return LinearUtils.Vector3DToArray(new Vector3D(pnt[0], pnt[1], pnt[2]).Multiply(transform.Linear).Add(transform.Translation));
  43. }
  44.  


Там есть некоторые неясные моменты, но в тестовом файле все работает - точка обзора восстанавливается как надо.
При создании булавок используется метод View.PickItemFromPoint. Как я понял - эта точка - PickItemResult.Point - это и есть точка location. Но скорее всего я ошибаюсь

А вопрос в том - как имея location найти элемент в модели? Какие обратные процедуры произвести?

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #4 : 27-09-2021, 15:21:25 »
А вопрос в том - как имея location найти элемент в модели? Какие обратные процедуры произвести?

Где ты ищешь элемент? В Navisworks или Forge Viewer?

Если в Navisworks, тогда нужно преобразовать координаты, pushpin имеет координаты в системе координат Viewer-а (логично, вроде), есть матрица перехода model-to-viewer, можно получить обратную viewer-to-model. Ну или ещё проще, вряд ли при трансформации модели будет назначен какой-то поворот или масштабирование, взять global offset как в статье предложено. С API Navisworks-а мало имел и совсем давно, возможно, там есть что-то для пространственного поиска.

Если речь про поиск в Forge Viewer, то преобразовывать координаты не нужно. Сам поиск можно реализовывать по разному в зависимости от задачи. Если одноразово, то можно простым перебором, если многоразово, то, наверное, стоит по boundingbox-ам построить R-Tree, искать уже в нём


Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #5 : 27-09-2021, 15:44:42 »
Где ты ищешь элемент? В Navisworks или Forge Viewer?
В Navisworks

можно получить обратную viewer-to-model
Как? Я не понимаю

В модели вот примерно такие координаты (центры BB):
Цитировать
Element 802034 bb center: (9952,5384326613802841, 70816,2968044955487130, 522,9658793952521592)
Element 802423 bb center: (10204,6086616059928929, 70569,3836395785911009, 523,2939633847535106)
Element 1340572 bb center: (9834,1697264512931724, 70497,0170252555108164, 520,3412074942601748)

Булавки вот с такими координатами:
Цитировать
Issue 495 pushpin: -168,621583508413, -100,020605428304, 7,31800306525327
Issue 494 pushpin: 201,793944775753, -27,6070030396659, 9,06755644286818
Issue 493 pushpin: -50,2509445499618, 220,224071918055, 15,971968234686

Видно, что координаты не особо коррелируют, что указывает на правдивость высказывания
Цитировать
pushpin имеет координаты в системе координат Viewer-а (логично, вроде)

Но что и как преобразовывать - я не понимаю

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #6 : 27-09-2021, 17:49:19 »
Набросал чуток кода:
Код - Javascript [Выбрать]
  1. function getLeafFragIds (model, leafId) {
  2.         const instanceTree = model.getInstanceTree();
  3.        
  4.         const fragIds = [];
  5.        
  6.         instanceTree.enumNodeFragments(leafId, (fragId) => {fragIds.push(fragId)});
  7.        
  8.         return fragIds;
  9. }
  10.  
  11. function getBoundingBox(fragIds, fragList) {
  12.     const fragbBox = new THREE.Box3();
  13.     const nodebBox = new THREE.Box3();
  14.     fragIds.forEach(function(fragId) {
  15.         fragList.getWorldBounds(fragId, fragbBox);
  16.         nodebBox.union(fragbBox);
  17.     });
  18.  
  19.     return nodebBox;
  20. }
  21.  
  22. const box = getBoundingBox(getLeafFragIds(NOP_VIEWER.model, NOP_VIEWER.getSelection()[0]), NOP_VIEWER.model.getFragmentList())
  23.  
  24. const offset = NOP_VIEWER.model.getGlobalOffset();
  25. console.log(new THREE.Vector3().copy(box.min).add(offset))
  26. console.log(new THREE.Vector3().copy(box.max).add(offset))

Revit:

Forge:



Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #7 : 27-09-2021, 18:01:40 »
А как код для форджа поможет мне решить проблему в нэвисе? При том, что с форждом я вообще не работаю

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #8 : 27-09-2021, 18:58:21 »
При том, что с форждом я вообще не работаю
Ну сорри, не понял, что Forge viewer не при делах.

Смотри, global offset - это центр bounding box-а всей модели, вот ссылка на дискуссию, где это обсуждается: https://stackoverflow.com/questions/42148538/aligning-coordinate-systems-in-autodesk-forge-viewer

Цитировать
What is this offset? the difference between (0,0,0) and where the model was placed originally?
Цитировать
Correct. The viewer will load the model by placing the center of its bounding box at the origin, so depending on the original file, this may add an offset which is returned by the property discussed above.

Philippe доверять можно :-)

А дальше по аналогии переходить от координат во вьювере к модельными координатам

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #9 : 28-09-2021, 10:28:54 »
Ну нет в нэвисе Viewer'а! И нет там свойства GlobalOffset...

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #10 : 28-09-2021, 10:41:13 »
И? я и не говорил, что тебе нужен viewer в navis. Я как бы показал, как считается GlobalOffset

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #11 : 28-09-2021, 10:57:43 »
Вот как работает плагин автодеска:
Юзер тыкает в элемент модели и плагин получает PickItemResult. У этого результат есть свойство Point, которое:
Цитировать
The picked point on the surface of the picked model item (in world space).
В мировой системе координат!

Дальше плагин делает вот так:



Если это nwd (а именно на таком случае я тестирую), то просто отправляет эту точку.

Значит, логично предположить, что из BIM360 я получаю эту точку в мировой системе координат и мне нужно трансформировать её в систему координат модели. В том-же плагине есть такие методы:



Я попробовал их оба (на всякий случай):
Код - C# [Выбрать]
  1. Transform3D modelToWorldTransform = GetModelToWorldTransform(model);
  2. var worldToModelTransform = GetWorldToModelTransform(model);
  3. Debug.Print($"Issue origin location: {data.Location[0]}, {data.Location[1]}, {data.Location[2]}");
  4. var d = TransformPoint(data.Location, modelToWorldTransform);
  5. Debug.Print($"Issue transformed model to world location: {d[0]}, {d[1]}, {d[2]}");
  6. d = TransformPoint(data.Location, worldToModelTransform);
  7. Debug.Print($"Issue transformed world to model location: {d[0]}, {d[1]}, {d[2]}");

и получил такой результат:
Цитировать
Issue origin location: 201,793944775753, -27,6070030396659, 9,06755644286818
Issue transformed model to world location: 201,793944775753, -27,6070030396659, 9,06755644286818
Issue transformed world to model location: 201,793944775753, -27,6070030396659, 9,06755644286818

А вот как выглядят свойства модели:


т.е. там нет никакого трансформа

Так что это за координаты и как их трансформировать? Где и как я тут могу использовать GlobalOffset?


Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #12 : 28-09-2021, 11:40:05 »
GlobalOffset - это вектор в центр bounding box-а модели

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #13 : 28-09-2021, 16:40:22 »
Александр Игнатович, да, ты был прав с самого начала. Я не заметил, что GlobalOffset тоже можно получить из Issue. Если банально сложить координаты булавки с координатами GlobalOffset, то получаются вроде нужные значения.
Правда, оказалось, что к Issue можно привязать несколько элементов, поэтому задачу реализовывать не стали и решили пойти другим путем. Спасибо за участие

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Re: BIM360 Issue pushpin - в каких координатах?
« Ответ #14 : 28-09-2021, 16:42:55 »
You are welcome