## Вычисление системы ограничений Основную задачу трехмерного геометрического решателя (см. Задача удовлетворения геометрических ограничений) выполняет функция ```cpp GCM_result GCM_Evaluate(GCM_system gSys) ``` которая вычислит новое состояние геометрии и раздаст диагностических коды тем ограничениям, которые не удалось удовлетворить. Функция не тратит время на вычисления, если на момент её вызова все ограничения удовлетворены. **GCM_Evaluate** вернет код GCM_RESULT_Ok, если найдено успешное решение для всех заданных ограничений. Любое другое возвращаемое значение говорит о том, что удовлетворить систему ограничений целиком не удалось. Таким образом, возвращаемое значение **GCM_Evaluate**, показывает либо успешный результат, либо диагностический код одного из не решенных ограничений, либо иное код, показывающий причину неудачного решения. Расшифровка диагностических кодов приведена в параграфе [Диагностические коды решения](./Diagnostic_codes_of_a_solution.md). После вызова **GCM_Evaluate** каждому геометрическому ограничению присваивается диагностический статус, который можно узнать с помощью вызова ```cpp GCM_result GCM_EvaluationResult(GCM_system gSys, GCM_constraint cItem) ``` который для каждого ограничения выдаст одно из возможных значений: - GCM_RESULT_None означает, что статус ограничения не определен, т.е. ограничение ни разу не вычислялось; - GCM_RESULT_Satisfied означает, что ограничение решено; - GCM_RESULT_Overconstrained, означает что ограничение участвует в группе противоречащих друг другу ограничений, которые не могут быть удовлетворены одновременно. Обычно удаление одного из таких ограничений исправляет ситуацию; - GCM_RESULT_Not_Satisfied, означает, что ограничение не удовлетворено (предусмотрено для случаев, когда не удается диагностировать причину неудачного решения); - GCM_RESULT_Unsolvable, означает, что ограничение не может быть решено. Возможные причины: противоречие ограничений друг другу, отсутствие необходимых ограничений, позиционирующих объекты (например, в кулачковом механизме), плохое начальное приближение; - GCM_RESULT_IncompatibleArguments, означает, что ограничение не применимо для объектов с данными типами геометрии. Например, совпадение плоскости и цилиндра не возможно выполнить; Подробнее о всех значениях GCM_result см. в параграфе [Диагностические коды решения](./Diagnostic_codes_of_a_solution.md). В результате вызова **GCM_Evaluate** меняется состояние геометрических объектов. Чтобы приложение могло применить результаты расчетов, необходимо запросить с помощью функции **GCM_Placement** значения ЛСК, позиционирующие объекты. Функция ```cpp MbPlacement3D GCM_Placement(GCM_system gSys, GCM_geom g) ``` возвращает положение (ЛСК) геометрического объекта **g** в соответствии с текущим состоянием геометрической модели. В параграфе [Представление геометрических объектов](./Representation_of_geometric_objects.md) уже говорилось, что свою ЛСК имеет каждый геометрический объект, даже если это примитив в роде точки. ЛСК удобна тем, что с ее помощью можно выразить положение объектов всех типов, включая не только твердые тела, но и простые объекты, такие как точка, прямая и плоскость. Также с помощью вызова **GCM_Origin** можно запросить точку начало только координат ЛСК. Это удобно, когда мы имеем дело с неориентированными объектами, такими как точка и сфера. Другая функция, применительно к радиусным объектам, таким как окружность, сфера или цилиндр вернет значение радиуса: ```cpp double GCM_Radius(GCM_system gSys, GCM_geom g) ``` Также с помощью функций: ```cpp double GCM_RadiusA(GCM_system gSys, GCM_geom g) ``` ```cpp double GCM_RadiusB(GCM_system gSys, GCM_geom g) ``` можно узнать большой и малый радиусы тороида и конуса. Приложение имеет возможность не только запрашивать текущее состояние геометрии, но и менять его, если по каким-либо причинам произошли изменения на стороне CAD-модели, требующие синхронизировать геометрический решатель. Для этого предусмотрен вызов ```cpp void GCM_SetPlacement(GCM_system gSys, GCM_geom g, const MbPlacement3D & place) ``` который меняет текущее значение ЛСК объекта. Исходные данные вызова: - **gSys** -- система геометрических ограничений; - **g** -- дескриптор геометрического объекта; - **place** -- новое положение (ЛСК), заданной в мировой системе координат. Заметим, эта функция только придает объекту новое состояние без переоценки системы ограничений. Вызов **GCM_Evaluate** может поменять заданное состояние, если имеются не удовлетворенные ограничения. В любой момент времени у каждого ограничения можно спросить удовлетворено оно или нет с помощью функции ```cpp bool GCM_IsSatisfied(GCM_system gSys, GCM_constraint cItem) ``` которая вернет true, если ограничение **cItem**, удовлетворено в текущем состоянии геометрии. Результат вызова **GCM_IsSatisfied** зависит только от текущего состояния геометрических аргументов ограничения и не связано с его диагностическим статусом, возвращаемым по запросу **GCM_EvaluationResult**.