Ксения Носулько, старший математик-программист, C3D Labs, рассказывает о новых функциях 3D-моделирования в решателе C3D Solver.
Модуль С3D Solver предназначен для управления взаимосвязями между геометрическими объектами. Он состоит из двумерного и трехмерного решателей, которые обеспечивают автоматическое обновление геометрии при изменениях с сохранением всех ранее наложенных взаимосвязей. Эти взаимосвязи могут быть как размерными (например, расстояния или углы между объектами), так и логическими — совпадение точек, фиксация радиусов, параллельность, перпендикулярность и прочее.
В 2D-решателе появилась поддержка нового объекта — вспомогательной оси. Он задается точкой и направляющим вектором. Ось не является кривой, однако, подобно любому линейному объекту, подчиняется наложенным на нее ограничениям.
Пример кода:
// Координаты оси. struct GCE_axis { GCE_point origin; // Начало оси. GCE_vec2d dir; // Направление оси. }; // Зарегистрировать ось. geom_item GCE_AddAxis(GCE_system, const GCE_axis&); // Подчиняется ограничениям: GCE_FIX_GEOM, GCE_HORIZONTAL, GCE_VERTICAL, GCE_ANGLE_OX, GCE_PERPENDICULAR, GCE_PARALLEL.
Основное назначение вспомогательной оси — расширение возможностей работы с линейными размерами, включая направленные и касательные размеры, которые могут быть заданы в произвольном направлении (Рис. 1).
Для создания такого размера необходимо задать вспомогательную ось, наложить на нее желаемое ограничение (например, угол с осью OX или параллельность) и передать ее в структуру вспомогательных данных размерного ограничения. Solver гарантирует, что после разрешения системы ограничений касание вспомогательной оси с кривой в точке начала оси будет соблюдено.
Пример кода:
// Зарегистрировать ось. geom_item GCE_AddAxis(GCE_system gSys, const GCE_axis&); // Фиксация направления оси. constraint_item GCE_AddUnaryConstraint(GCE_system gSys, constraint_type cType, geom_item axis); // Параметры линейного размерного ограничения. struct GCE_ldim_pars { GCE_dim_pars dPars; // Числовое значение размера. geom_item hp[2]; // Вспомогательные точки или оси. }; // Наложить ограничение расстояния. constraint_item GCE_AddDistance(GCE_system gSys, geom_item g[2], const GCE_ldim_pars&);
Также развитие получил функционал паттернов: была реализована поддержка композиционных паттернов, связывающих геометрические объекты двумя закономерностями одновременно. Новый тип паттернов представляет собой систему ограничений, позволяющую, например, создавать концентрические структуры сочетанием линейного и углового паттернов (Рис. 2). Концептуально это сводится к алгебраическому описанию: над образцом производится серия преобразований — i раз в одном направлении, j раз в другом — результатом становится нужный экземпляр. Таким образом, два базовых паттерна объединяются в композиционный, формирующий особую структуру копий объекта.
Пример кода:
// Объявление композиции паттернов. pattern_item GCE_AddCompositionPattern(GCE_system, pattern_item, pattern_item); // Создание композиции паттернов. pattern_item pattern1 = GCE_AddAngularPattern(solver, point, angle); pattern_item pattern2 = GCE_AddLinearPattern(solver, vec); pattern_item pattern = GCE_AddCompositionPattern(solver, pattern1, pattern2); GCE_AddPatterned(solver, pattern, geom1, geom2, 2, 3);
Следующей важной темой в развитии паттернов стала зеркальная симметрия (Рис. 3). Она особенно полезна при создании круговых или линейных пазов, когда необходимо получить симметричное расположение элементов относительно заданной оси. В основе паттерна лежит принцип полной зависимости экземпляра от образца: копия всецело определяется своим оригиналом и не предполагает автономного поведения. Для задания такого паттерна требуется наличие оси — прямой, отрезка или их производных (например, эквидистанты или ограниченной кривой). Далее создаются объект паттерна, исходный объект и его симметричный экземпляр. В планах — интеграция зеркального паттерна с композиционным. Это откроет возможности создавать более сложные симметричные структуры, например чередующиеся сдвинутые копии, напоминающие следы на песке.
Пример кода:
// Объявление паттерна отражения по линейному объекту. // axis - Ось симметрии одного из типов: GCE_LINE, GCE_LINE_SEGMENT pattern_item GCE_AddSymmetricPattern(GCE_system, geom_item axis); // Создание зеркальной копии. geom_item line = GCE_AddLine(solver, lin); pattern_item patternS = GCE_AddSymmetricPattern(solver, line); geom_item arc = GCE_AddBoundedCurve(solver, circle, pnt[2]); geom_item instance = GCE_AddInstance(solver, patternS, arc, 1);
В числе свежих обновлений 2D-решателя стоит отметить новые функции, связанные с весами контрольных точек сплайна (Рис. 4). Ранее изменение веса требовало следующих действий: объект нужно было удалить, изменить его свойства и восстановить вместе со всеми наложенными ранее ограничениями. Сейчас процесс смены весов стал интерактивным и доступен на любой стадии разработки благодаря новой функции GCE_SetWeight. Особенно данная оптимизация ощутима при работе с паттернами, так как изменения автоматически распространяются на все семейство кривых. Это не только экономит время, но и повышает надежность работы со сплайнами.
Пример кода:
// Изменить вес контрольной точки сплайна. void GCE_SetWeight(GCE_system, geom_item spline, size_t pntIdx, double weight); // Вернуть вес контрольной точки сплайна. double GCE_WeightOf(GCE_system, geom_item spline, size_t pntIdx);
Что касается новшеств 3D-решателя, ключевой задачей стало улучшение диагностики определенности компонент сборки. В процессе моделирования важно понимать, все ли элементы конструкции определены и закреплены, заданы ли нужные ограничения. Функция GCM_IsWellDefined предоставляет такую диагностику, помогая понять, завершена ли геометрическая и кинематическая спецификация объекта. Ранее в случае частично определенных сборок возникала проблема: недоопределенные элементы могли влиять на диагностику полностью определенных, в результате чего пользователь терял понимание того, какие компоненты требуют доработки. Мы устранили эту проблему. Теперь C3D Solver уверенно различает полностью определенные и недоопределенные компоненты в составе недоопределенной сборки. Дополнительно были устранены сопутствующие ошибки и улучшен алгоритм анализа степеней свободы.
Пример кода:
typedef enum { // Геом. объект полностью определен или заморожен (DOF = 0). GCM_DOF_RESULT_WellDefined, // Геом. объект имеет переносную или поворотную подвижность. GCM_DOF_RESULT_UnderDefined, // Степень свободы геометрического объекта не вычислена. GCM_DOF_RESULT_Unknown } GCM_dof_result; // Является ли геом. объект полностью определенным или недоопределенным. GCM_dof_result GCM_IsWellDefined(GCM_system, GCM_geom gItem);
Развивая эту тему, стоит упомянуть о расширенном анализе степеней свобод. Помимо уже имеющейся информации о полной определенности, пользователю теперь доступны данные о трансляционных степенях свободы и мгновенных векторах перемещения для точки геометрического объекта. Эти данные предоставляет функция GCM_PointDOF. В планах также — определять ротационные степени свободы и соответствующие им оси, что позволит получать еще более точное понимание кинематики сборки.
Пример кода:
// Развернутая информация о степени свободы геометрического объекта. struct GCM_dof_record { GCM_dof_result result; // Код результата вычисления степени свободы. // Translational degree of freedom info. GCM_dof_type tdof; GCM_vec2d dir1; GCM_vec2d dir2; // Rotational degree of freedom info. GCM_dof_type rdof; GCM_point center; GCM_vec2d axis1; GCM_vec2d axis2; }; // Вычислить степени свободы точки, включая соответствующие им возможные трансляции. GCM_dof_record GCM_PointDOF(GCM_system, GCM_geom, const MbCartPoint3D& ctrlPnt);
При обновлении алгоритмов анализа степеней свобод заметное улучшение получил и драггинг. В частности, решения, реализованные при работе над предыдущей задачей, положительно повлияли на драггинг каркасных моделей, а также повысили стабильность других алгоритмов, использующих схожую логику.
Драггинг представляет собой интерактивный режим вычислений, в котором геометрические элементы перемещаются в соответствии со своими степенями свобод. Этот режим позволяет выполнять расчеты в реальном времени в ответ на действия пользователя — например, перемещения мыши при захвате объекта на чертеже и изменении его положения.
Одним из важных улучшений стало внедрение функции, которая, кроме обслуживания самого режима драггинга в плоскости экрана, автоматически отслеживает его начало и завершение для текущего захваченного объекта. Если ранее требовалось явно вызывать методы инициализации и финиширования, то теперь функция самостоятельно определяет момент начала и завершения драггинга. Она выявляет смену захваченного объекта или плоскости перетаскивания и при необходимости инициирует повторную настройку. Все это позволяет достичь более оптимальной и надежной работы при манипулировании элементами модели.
Пример кода:
// Инициализировать режим перетаскивания объектов в плоскости экрана. GCM_result GCM_PrepereReposition(GCM_system, GCM_geom moveGeom, const MbCartPoint3D&, const MbVector3D&); // Завершить режим "перетаскивания". void GCM_FinishReposition(GCM_system); /** Процедура, управляющая режимом перетаскивания. \param[in] cursor - Текущее положение курсора в ГСК. \param[in] zAxis - Нормаль к плоскости, в которой происходит перетаскивание, заданная в ГСК сборки. */ GCM_result GCM_SolveReposition(GCM_system, GCM_geom moveGeom, const MbCartPoint3D& cursor, const MbVector3D& zAxis);

Ксения Носулько
старший математик-программист
C3D Labs







