Некорректная отрисовка детали при повороте на 90 и 270 градусов

Автор Тема: Некорректная отрисовка детали при повороте на 90 и 270 градусов  (Прочитано 4745 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Добрый день.
Среда: MSVS 2015, Autocad 2017, Platform х64
Проект находится в архиве MyProject-Bolt-Rotate.rar

Проблема в отрисовке болта при задании угла в 90 или 270 градусов, деталь превращается в линию, пожалуйста помогите  :-[




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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Я чувствую, что тебе уже пора начать самостоятельно искать ошибки в твоей программе. Для этой цели есть отладчик в Visual Studio. Ну и как минимум ты должен начать понимать в каких методах твоего кода может возникать ошибка. Для начала наводящая информация:
1. Отрисовка происходит в методе Bolt::subWorldDraw. В этот момент посчитаны уже все все точки. Значит произошла ошибка на этапе  их расчета.
2. Расчет точек производится в методе Bolt::storePoints. В нём вроде бы всё чисто.
3. При повороте у тебя работает класс BoltJig. Изменение характеристик болта происходит в методе BoltJig::update(). Так как речь идёт о повороте то это mPromptCounter равен или 1 или 2.
Теперь следим за пальцами. Ты задаёшь вектор оси болта (m_vecU) при помощи вызова m_pBoltObj->setOrient(m_vec);  А кто за тебя будет задавать вектор m_vecV? В случае 90 и 270 градусов у тебя m_vecU совпадает с m_vecV и соответственно векторное произведение m_vecU.crossProduct(m_vecV) даёт нулевой вектор. Вот у тебя болт и "схлопывается". Так что не поленись в BoltJig::update() устанавливать и m_vecV.
А еще правильнее будет переписать Bolt::setOrient так, чтобы этот метод менял и m_vecU и m_vecV соотвествующим образом.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Пересмотрел это код:
Код - C++ [Выбрать]
  1. AcEdJig::DragStatus BoltJig::sampler()
  2. {
  3.   DragStatus stat = DragStatus::kCancel;
  4.   setUserInputControls((UserInputControls)
  5.     (AcEdJig::kAccept3dCoordinates));
  6.  
  7.   if (mPromptCounter == 0)
  8.   {
  9.     static double rezbaDiam;
  10.     stat = acquireDist(m_RezbaDiameter, m_pt0);
  11.     if (rezbaDiam != m_RezbaDiameter)
  12.       rezbaDiam = m_RezbaDiameter;
  13.     else if (stat == AcEdJig::kNormal)
  14.       return AcEdJig::kNoChange;
  15.   }
  16.   else if (mPromptCounter == 1)
  17.   {
  18. // Начало полного бреда
  19.     static double rezbaLen;
  20.         stat = acquireDist(m_RezbaDlina, m_pt0);
  21.     if (rezbaLen != m_RezbaDlina)
  22.       rezbaLen = m_RezbaDlina;
  23.     else if (stat == AcEdJig::kNormal)
  24.       return AcEdJig::kNoChange;
  25.         static double angle;
  26.         stat = acquireAngle(m_Angle, m_pt0);
  27.         if (angle != m_Angle)
  28.                 angle = m_Angle;
  29.         else if (stat == AcEdJig::kNormal)
  30.                 return AcEdJig::kNoChange;
  31. // Конец полного бреда - исправлять будешь сам
  32.   }
  33.   else if (mPromptCounter == 2)
  34.   {
  35.         static double angle;
  36.     stat = acquireAngle(m_Angle, m_pt0);
  37.     if (angle != m_Angle)
  38.       angle = m_Angle;
  39.     else if (stat == AcEdJig::kNormal)
  40.       return AcEdJig::kNoChange;
  41.   }
  42.  
  43.  
  44.   return stat;
  45. }
Кто тебе сказал что одновременно можно запрашивать и угол и расстояние???? Для этой цели обычно используют запрос точки (с указанием базовой точки). А так как сделал ты - так делать нельзя.
« Последнее редактирование: 11-07-2018, 20:12:22 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение knightrocker 12-07-2018, 22:59:28

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Я сделал еще чуть-чуть косметических преобразований, но код нужно переделывать с начала и до конца. Чем больше я в него углубляюсь, тем больше понимаю, что там очень много "плохого кода". Минимальные изменения в нём приводят к тому, что код перестаёт работать, так как он очень нелогично построен. Реши для себя какой минимум параметров описывает твой болт и всё остальное вычисляй по мере необходимости. Зачем хранить все точки болта, записывать их в методе Bolt::dwgOutFields и считывать их в Bolt::dwgInFields, если ты их всё-равно каждый раз пересчитываешь? Максимально упрости и почисть код.
 

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

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1

Я чувствую, что тебе уже пора начать самостоятельно искать ошибки в твоей программе. Для этой цели есть отладчик в Visual Studio. Ну и как минимум ты должен начать понимать в каких методах твоего кода может возникать ошибка.


Проблема с тем, что у меня возникает много вопросов связана с тремя вещами:
1. Мало "эталонных" примеров или описанных "техник" того, как стоит писать классы отрисовки, методы и вообще, как проектировать с архитектурной точки зрения подобные вещи.
2. Примеров в SDK всё же малова-то, как собственно и книг по этому направлению, и комьюнити тоже достаточно небольшое, это всё же не библиотека Qt какая-нибудь.
3. Как начинающий в данном вопросе я стараюсь как могу, вынужден изобретать велосипеды и по началу писать изначально что-то неверно, что тянет за собой более глубокие ошибки.
Поверьте отладчиком пользуюсь, иначе не двигался бы вперёд. Стараюсь обращаться только тогда, когда реально либо затык полный, либо что-то ну никак не могу нормально перевести в документации.


Ты задаёшь вектор оси болта (m_vecU) при помощи вызова m_pBoltObj->setOrient(m_vec); А кто за тебя будет задавать вектор m_vecV? В случае 90 и 270 градусов у тебя m_vecU совпадает с m_vecV и соответственно векторное произведение m_vecU.crossProduct(m_vecV) даёт нулевой вектор. Вот у тебя болт и "схлопывается". Так что не поленись в BoltJig::update() устанавливать и m_vecV.

Совершенно забыл, что в setOrient меняю направление только одного вектора, даже не заглядывал в него уже, и от того, думая, что и m_vecV меняется, не мог понять в чём дело, дебажить с заходом в Каждый саамый мелкий метод порой стоит, да .... Ошибка оказалась совершенно дебильная, извиняюсь, что сам за собой недоглядел.


Кто тебе сказал что одновременно можно запрашивать и угол и расстояние???? Для этой цели обычно используют запрос точки (с указанием базовой точки). А так как сделал ты - так делать нельзя.


Никто и не говорил, разбираюсь во всём самостоятельно, тут действовал по принципу "Попробую, вдруг заработает...". Буду иметь ввиду про базовуб точку, спасибо.


Зачем хранить все точки болта, записывать их в методе Bolt::dwgOutFields и считывать их в Bolt::dwgInFields, если ты их всё-равно каждый раз пересчитываешь? Максимально упрости и почисть код.


Я уже увидел в SDK более менее нормальный пример по этой части ( а именно в ...\Autodesk\Autodesk_ObjectARX_2017_Win_64_and_32_Bit\samples\com\AsdkSquareWrapper_dg\Square в файлах squarent.cpp и squarent.h), и судя по увиденному, массивы точек задаются прямо внутри методов класса, все перерасчёты производятся относительно каких-то базовых "опорных" для объекта точек и расстояний, а массивы точек каждый раз используются уже именно в самих методах и не хранятся в самом классе, если я верно уловил идею примера из SDK, и вашего комментария про "плохой код" и принцип того как надо производить обсчёт объекта.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Мало "эталонных" примеров или описанных "техник" того, как стоит писать классы отрисовки, методы и вообще, как проектировать с архитектурной точки зрения подобные вещи.
Эталонных примеров нет вообще. Примеры из ObjectARX SDK написаны для того, чтобы показать какие-то моменты в ObjectARX, но не претендуют на эталонность.
Никто и не говорил, разбираюсь во всём самостоятельно, тут действовал по принципу "Попробую, вдруг заработает...".
А вот тут бы лучше было поискать готовые примеры.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
(с указанием базовой точки).
Кстати, уже видел это в некоторых постах, в процессе гугления и прочего кода из разных источников, но подскажите, что имеется ввиду, причём в некоторых случаях видел прям метод basePoint(), так как тела метода предоставлено не было возможно там просто возвращалась какая-то точка, что была полем класса, но всё же, какая именно точка имеется ввиду или является "базовой" ? Ну вот к примеру для моего случая с болтом ? Та ли это точка, относительно которой я провожу все основные расчёты для отрисовки всей фигуры (в моём случае точка посередине соприкосновения резьбы и шляпки) или это какая-то другая ?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
но всё что какая именно точка имеется ввиду или является "базовой", ну вот к примеру для моего случая с болтом ? Та ли это точка, относительно которой я провожу все основные расчёты для отрисовки всей фигуры (в моём случае точка посередине соприкосновения резьбы и шляпки) ?
Любая точка, которая тебе удобна в качестве базовой. Вполне годится та точка, которую ты используешь. В данном случае имелось в виду, что ты в первой операции как бы вставляешь болт (аналогично со вставкой блока в AutoCAD), затем меняешь его характеристики относительно базовой точки (угол поворота, его диаметр, диаметр шляпки, длину резьбы).
Кстати почему у тебя диаметр шляпки в Jig всегда в два раза больше диаметра самого болта? А иначе быть не может???
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Кстати почему у тебя диаметр шляпки в Jig всегда в два раза больше диаметра самого болта? А иначе быть не может???
Это чисто мой "хардкод", чтобы хоть немного упростить себе задачи по изучению, но выполнять их всё же
с более сложным объектом чем какой-нибудь ромб/квадрат/круг, "захардкодив" хотя бы один параметр в объекте таким образом да.