Манипуляция наборами выборов
Вы можете добавлять примитивы к набору выборов или удалять их из этого, вызывая функции acedSSAdd () и acedSSDel (), которые являются подобными опциям Add и Remove, когда AutoCAD в интерактивном режиме запрашивает пользователя выбирать объекты или удалять объекты.
ОБРАТИТЕ ВНИМАНИЕ На acedSSAdd () функция может также использоваться, чтобы создать новый набор выборов, как показано в следующем примере. Как с acedSSGet (), acedSSAdd () создает новый выбор, устанавливают только, если это возвращает RTNORM.
Следующий типовой кодовый фрагмент создает набор выборов, который включает первые и последние примитивы в текущий рисунок.
ads_name fname, lname; // Entity names
ads_name ourset; // Selection set name
// Get the first entity in the drawing.
if (acdbEntNext(NULL, fname) != RTNORM) {
acdbFail("No entities in drawing\n");
return BAD;
}
// Create a selection set that contains the first entity.
if (acedSSAdd(fname, NULL, ourset) != RTNORM) {
acdbFail("Unable to create selection set\n");
return BAD;
}
// Get the last entity in the drawing.
if (acdbEntLast(lname) != RTNORM) {
acdbFail("No entities in drawing\n");
return BAD;
}
// Add the last entity to the same selection set.
if (acedSSAdd(lname, ourset, ourset) != RTNORM) {
acdbFail("Unable to add entity to selection set\n");
return BAD;
}
Пример выполняется правильно, даже если имеется только один примитив в базе данных (когда и acdbEntNext () и acdbEntLast () устанавливают их параметры в то же самое имя примитива). Если acedSSAdd () пропускают имя примитива, который является уже в наборе выборов, это игнорирует запрос и не сообщает о ошибке.
Поскольку пример также иллюстрирует, вторые и третьи параметры к acedSSAdd () можно пропускать как то же самое имя набора выбора. То есть если запрос успешен, набор выборов, названный обоими параметрами содержит дополнительного члена после acedSSAdd () возвращения (если указанный примитив не был уже в наборе выборов).
Следующий запрос удаляет примитив, с которым выбором установленный был создан в предыдущем примере.
AcedSSDel (fname, ourset);
Если имеются больше чем один примитив в рисунке (то есть если fname и lname не равны), выбор устанавливает ourset, теперь содержит только lname, последний{*прошлый*} примитив в рисунке.
Функция acedSSLength () возвращает число примитивов в наборе выборов, и acedSSMemb () испытания,является ли специфический примитив членом набора выборов. Наконец, функция acedSSName () возвращает имя специфического примитива в наборе выборов, используя индекс в набор (примитивы в наборе выборов пронумерованы от 0).
ОБРАТИТЕ ВНИМАНИЕ, поскольку наборы выбора могут быть весьма большие, len параметр, возвращенный acedSSLength () должен быть объявлен как длинное целое число. Я параметр, используемый как индекс в звонит к acedSSName () должен также быть длинное целое число. (В этом контексте, стандартные компиляторы C правильно преобразуют простое целое число.)
Следующий типовой код показывает несколько, вызывает к acedSSName ().
ads_name sset, ent1, ent4, lastent;
long ilast;
// Create the selection set (by prompting the user).
acedSSGet(NULL, NULL, NULL, NULL, sset);
// Get the name of first entity in sset.
if (acedSSName(sset, 0L, ent1) != RTNORM)
return BAD;
// Get the name of the fourth entity in sset.
if (acedSSName(sset, 3L, ent4) != RTNORM) {
acdbFail("Need to select at least four entities\n");
return BAD;
}
// Find the index of the last entity in sset.
if (acedSSLength(sset, &ilast) != RTNORM)
return BAD;
// Get the name of the last entity in sset.
if (acedSSName(sset, ilast-1, lastent) != RTNORM)
return BAD;
Преобразование Наборов Выбора
Функция acedXformSS () преобразовывает выбор, установленный, применяя матрицу преобразования (типа ads_matrix) к примитивам в наборе. Это обеспечивает эффективную альтернативу к вызову ВРАЩАЮЩЕГОСЯ, МАСШТАБУ, ЗЕРКАЛУ, или командам ПЕРЕМЕЩЕНИЯ с acedCommand () (или acedCmd ()) или к изменению{*замене*} значений в базе данных с acdbEntMod (). Набор выборов может быть получен способом из обычных путей. Матрица должна делать однородное масштабирование. То есть элементы в векторе масштабирования S X S Y S Z должны весь быть равными; в матричном примечании, М. 00 М. 11 М. 22.
Если вектор масштаба - не, униформа, acedXformSS () сообщает о ошибке.
Следующий типовой код устанавливает выбор, используя поле пересечения, и затем применяет следующую матрицу к этому.
| 0.5 0.0 0.0 20.0 |
| 0.0 0.5 0.0 5.0 |
| 0.0 0.0 0.5 0.0 |
| 0.0 0.0 0.0 1.0 |
Применение{*обращение*} этой матрицы масштабирует примитивы половиной (который перемещает их к началу координат) и транслирует их местоположение (20.0,5.0).
int rc, i, j;
ads_point pt1, pt2;
ads_matrix matrix;
ads_name ssname;
// Initialize pt1 and pt2 here.
rc = acedSSGet("C", pt1, pt2, NULL, ssname);
if (rc == RTNORM) {
// Initialize to identity.
ident_init(matrix);
// Initialize scale factors.
matrix[0][0] = matrix[1][1] = matrix[2][2] = 0.5;
// Initialize translation vector.
matrix[0][T] = 20.0;
matrix[1][T] = 5.0;
rc = acedXformSS(ssname, matrix);
}
Когда Вы вызываете acedDragGen (), Вы должны определить подобную функцию, чтобы позволить пользователям в интерактивном режиме управлять эффектом преобразования. Объявление функции должно иметь следующую форму:
Int scnf (ads_point запятая, ads_matrix mt)
Это должно возвратить RTNORM, если это изменило матрицу, RTNONE, если это делало не, или RTERROR, если это обнаруживает ошибку.
AcedDragGen () функция вызывает функцию scnf, каждый раз пользователь перемещает курсор. Scnf () функция устанавливает новое значение матрицы mt.
Когда scnf () возвращения с состоянием RTNORM, acedDragGen () применяет новую матрицу к набору выборов. Если не имеется никакой потребности изменить матрицу (для примера, если scnf () просто отображает переходные векторы с acedGrVecs ()), scnf () должен возвратить RTNONE. В этом случае{*регистре*}, acedDragGen () игнорирует mt и не преобразовывает набор выборов.
В следующем примере, функция заставляет матрицу просто двигаться (транслируют) набор выборов без того, чтобы масштабировать или вращение.
int dragsample(usrpt, matrix)
ads_point usrpt
ads_matrix matrix;
{
ident_init(matrix); // Initialize to identity.
// Initialize translation vector.
matrix[0][T] = usrpt[X];
matrix[1][T] = usrpt[Y];
matrix[2][T] = usrpt[Z];
return RTNORM; // Matrix was modified.
}
Наоборот, следующая версия dragsample () масштабирует набор выборов в текущем XY плане, но не перемещает это.
int dragsample(usrpt, matrix)
ads_point usrpt
ads_matrix matrix;
{
ident_init(matrix); // Initialize to identity.
matrix[0][0] = userpt[X];
matrix[1][1] = userpt[Y];
return RTNORM; // Matrix was modified.
}
Запрос к acedDragGen () который использует функцию преобразования, напоминает это:
int rc;
ads_name ssname;
ads_point return_pt;
// Prompt the user for a general entity selection:
if (acedSSGet(NULL, NULL, NULL, NULL, ssname) == RTNORM)
rc = acedDragGen(ssname, // The new entities
"Scale the selected objects by dragging", // Prompt
0, // Display normal cursor (crosshairs)
dragsample, // Pointer to the transform function
return_pt); // Set to the specified location
Более сложные преобразования могут вращать примитивы, комбинировать{*объединять*} преобразования (как в acedXformSS () пример), и т.д.
Объединение матриц преобразования известно как матричный состав. Следующая функция составляет две матрицы преобразования, возвращая их изделие{*программу*} в resmat.
void xformcompose(ads_matrix xf1, ads_matrix xf2,
ads_matrix resmat)
{
int i, j, k;
ads_real sum;
for (i=0; i<=3; i++) {
for (j=0; j<=3; j++) {
sum = 0.0;
for (k=0; k<3; k++) {
sum += xf1[i,k] * xf2[k,j];
}
resmat[i,j] = sum;
}
}
}