Как переопределить Viewport, чтобы его центр указывал на заданную точку в модели

Автор Тема: Как переопределить Viewport, чтобы его центр указывал на заданную точку в модели  (Прочитано 12985 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Не стал заводить новую тему, т.к. у меня похожий с ТС вопрос. Код по имени листа проводит итерацию во вхождениях блока в модели. Найдя блок с соответствующим атрибутом  считывает геометрию и обновляет видовой экран. Привожу код, координаты точки присваиваемой при выполнении к свойству ViewP.ViewCenter равен (2376722.36,5386680.23). После выполнения кода, я вижу что видовой экран показывает совсем другое место с центром вида (5100948.31,2940316.23) XY в обеих примерах соответствую друг другу. Что у меня не правильно?
Код - vb.net [Выбрать]
  1. ViewP.UpgradeOpen()
  2.             ViewP.SetUcsToWorld()
  3.             ViewP.ViewCenter = New Point2d(FstBlkData.CenterPoint.X, FstBlkData.CenterPoint.Y)
  4.             ViewP.ViewTarget = New Point3d(0, 0, 0)
  5.             ViewP.ViewDirection = New Vector3d(0, 0, 1)
  6.             ViewP.CustomScale = LGeomFactor
  7.             ViewP.TwistAngle = FstBlkData.TwistAngle

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
FstBlkData.CenterPoint
Это точка в координатах модели? Тогда её следует преобразовать в координаты листа.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Да, это координаты модели. Так, и что это за штука. Юзая просто AutoCAD даже не знал, что есть такая фигня фишка.

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Еще раз просмотрел ваш код приведенный выше и нашел строки выполняющий манипуляции с matrix3D. Начал искать инфу по нему и нашел такой код (не буду говорить чей он, вы и так знаете))).
Код - vb.net [Выбрать]
  1.   51:  '' Переводим систему координат WCS (международную систему координат) в DCS (систему координат отображения)
  2.   52:  Dim matWCS2DCS As Matrix3d
  3.   53:  matWCS2DCS = Matrix3d.PlaneToWorld(acView.ViewDirection)
  4.   54:  matWCS2DCS = Matrix3d.Displacement(acView.Target - Point3d.Origin) * matWCS2DCS
  5.   55:  matWCS2DCS = Matrix3d.Rotation(-acView.ViewTwist, _
  6.   56:  acView.ViewDirection, _
  7.   57:  acView.Target) * matWCS2DCS
По методам ничего не понятно, что делают и для чего. Все значения присваиваются одной переменной, что имхо должно перезаписывать предыдущее значение (ну если считать, что возвращаемый тип будет один и тот же). Методом научного копипаста с небольшой редакцией не хочется идти (да и не получится в моем случае наверняка). Читаю дальше насчет матриц, пока ничего не понятно.
Добавлено:
Возвращаемый тип как раз один и тот же, matrix3D, из этого следует, что происходит не перезапись, а дополнение информации матрицы новой информацией (лично мое умозаключение).

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Выложи фрагмент своего чертежа, укажи о какой вставке блока и каком видовом экране идёт речь.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Лист 1, блок тоже (его невозможно не увидеть). Код рассчитывает координаты центра блока, угол поворота, рассчитывает масштаб согласно отношения длины/ширины блока и видового экрана. Далее все это применяет в выше приведенном примере.

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Приведу некоторые свои умозаключения на этот момент. Посмотрим насколько они будут правильны.
С методами немного разорался (кстати я не доглядел, что во втором и третьем присваивании идет умножение на действующее значение матрицы и получаем значение матрицы с новым "действием"), но по порядку.
1. PlaneToWorld. Метод возвращает матрицу в мир.СК для текущей плоскости (не знаю как правильно написать, но в моем случае для плоскости "Вид сверху") видового экрана.
2. Displacement. Тут проще. Передаем значение вектора, куда переносить объект (значение центра видового экрана и вычисленный центр блока) и применяем это на существующую матрицу, получаем матрицу со смещением.
3. Rotation. Метод вращения. Угол на который надо повернуть и вокруг какого вектора. Тут ИМХО большое значение имеют значения координат, в моем случае
Код - vb.net [Выбрать]
  1. matWCS2DCS = Matrix3d.Rotation(Angle, New Point3d(0, 0, 0), New Vector3d(0, 0, 1)) * matWCS2DCS
не подойдут, надо
Код - vb.net [Выбрать]
  1. matWCS2DCS = Matrix3d.Rotation(Angle, New Point3d(FstBlkData.CenterPoint.X, FstBlkData.CenterPoint.Y, 0), _
  2. New Vector3d(FstBlkData.CenterPoint.X, FstBlkData.CenterPoint.Y, 1)) * matWCS2DCS
и наверное далее будет что то такое.
Код - vb.net [Выбрать]
  1. Dim pt As Point3d = FstBlkData.CenterPoint
  2. pt.TransformBy(matWCS2DCS)
Жду от вас тапок)))

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Давай полный архив с проектом. Буду править "по живому".
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Выкладываю.
Проект со ссылками на цивилские dll, лень было все чистить, поэтому только модули. Надеюсь это не сильно затруднит. Запускается метод Componovka_Listov_Sub.
Еще если будут замечания по коду, буду рад узнать про них.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
лень было все чистить
А мне лень разбираться с этими обрывками кода, в которых я даже не вижу команду запуска.
Так что с преобразованием WCS->DCS тебе придётся разбираться самостоятельно.
Поощрять лень я не буду.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Хорошо, я услышал. Исправлюсь и выложу, но так же не жду от вас, что вы поможете. Никакой обиды, все понимаю.

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Несколько полученных уроков.
1. Оказалось что проще не чистить, а создать новый и подгрузить туда необходимые модули и настроить проект.
2. Как ни внимательно ни смотрел модули перед загрузкой сюда, остались куча багов, вроде необъявленных переменных и ссылок на цивилские объекты.
3. Никогда не надо так больше делать.
Приношу извинения.

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Больше похоже на чудо, чем на осмысленные действия, но сработал такой код.

Код - vb.net [Выбрать]
  1. ViewP.SetUcsToWorld()
  2.         Dim Pt1 As Point2d = ViewP.ViewCenter
  3.         Dim Pt2 As Point3d = FstBlkData.CenterPoint 'вычисленные координаты центра в wcs
  4.         Dim ViewMoveVector As Vector3d = New Vector3d(Pt2.X - Pt1.X, Pt2.Y - Pt1.Y, 0) 'Вектор перемещения видового экрана
  5.  
  6.         Dim matWCS2DCS As Matrix3d
  7.         matWCS2DCS = Matrix3d.PlaneToWorld(ViewP.ViewDirection) 'Получаем матрицу плоскости видового экрана
  8.         'matWCS2DCS = Matrix3d.Displacement(ViewMoveVector) * matWCS2DCS 'Обновляем матрицу с вектором перемещения центра вида
  9.         matWCS2DCS = Matrix3d.Rotation(FstBlkData.TwistAngle, New Vector3d(0, 0, 1), New Point3d(0, 0, 0)) * matWCS2DCS
  10.  
  11.         Pt2 = FstBlkData.CenterPoint.TransformBy(matWCS2DCS)
  12.  
  13.         ViewP.UpgradeOpen()
  14.         ViewP.ViewCenter = New Point2d(Pt2.X, Pt2.Y)
  15.         ViewP.ViewTarget = New Point3d(0, 0, 0)
  16.         ViewP.ViewDirection = New Vector3d(0, 0, 1)
  17.         ViewP.CustomScale = LGeomFactor
  18.         ViewP.TwistAngle = FstBlkData.TwistAngle

Путем тестирования разных вариантов с методом Displacement и Rotation класса matrix3d и свойства TwistAngle видового экрана, пришел к данному коду. Не совсем уверен, но могу предположить, что так как в наших чертежах всегда вид сверху, но постоянно "вертится север" видового экрана, то при определении матрицы трансформации wcs2dcs, надо применять только метод Rotation. И обязательно обновлять угол TwistAngle видового экрана. Далеко не понял теорию трансформации, но метод научного копипаста, редактирования и тыка дал такой результат. Проверил на всех трех листах, сработал правильно, но не уверен что не будет багов в других чертежах.
ps/ При первом использовании свойство ViewP.ViewCenter выдает координаты в wcs. А при повторном в этой же сессии запуска кода  выдает координаты в dcs. Но почемуто результат работы кода все равно правильный, интересно почему?
Добавлено: Понял почему, потому что он вообще не участвует в вычислениях (точка pt1) ::)

Отмечено как Решение NurGeo 28-11-2015, 09:51:45

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Приношу извинения.
Принимается.
так как в наших чертежах всегда вид сверху, но постоянно "вертится север" видового экрана, то при определении матрицы трансформации wcs2dcs, надо применять только метод Rotation.
В этом случае можно еще упростить код:
Код - vb.net [Выбрать]
  1. Dim FstBlkData As SheetBlockGeometry = BlkGeomColl.Item(0)
  2.  
  3. Dim Pt2 As Point3d = FstBlkData.CenterPoint 'вычисленные координаты центра в wcs
  4.  
  5. Dim matWCS2DCS As Matrix3d
  6. matWCS2DCS = Matrix3d.Rotation(FstBlkData.TwistAngle, Vector3d.ZAxis, Point3d.Origin)
  7.  
  8. Pt2 = Pt2.TransformBy(matWCS2DCS)
  9.  
  10. ViewP.UpgradeOpen()
  11. ViewP.ViewCenter = Pt2.Convert2d(New Plane)
  12. ViewP.ViewTarget = Point3d.Origin
  13. ViewP.ViewDirection = Vector3d.ZAxis
  14. ViewP.CustomScale = LGeomFactor
  15. ViewP.TwistAngle = FstBlkData.TwistAngle

По коду есть еще несколько соображений. Например, количество видовых экранов в листе можно получить так:
Layout.GetViewports.Count и соотвественно ObjectId последнего из них Layout.GetViewports(Layout.GetViewports.Count-1)



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

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Просмотрел ваш код, любим мы усложнять некоторые очень простые вещи.
Вопрос:
Точка Point3d.Origin всегда возвращает Point3D (0,0,0) или может вернуть  другое значение (например какую нибудь системную переменную)?