Перейти к содержимому

Стояла у меня задача, для выполнения которой требовалось создание собственного типа для системного семейства Текст (Текстовое примечание).

Немного поискав информацию на просторах интернета, я наткнулся на данный пример, объясняющий, что для создания типа требуется создавать дубликат существующего типа. Вот только в примере совсем не уделено внимание тому, как и какие параметры задавать. Особенно остро стоит вопрос задания значения для параметра «Цвет».

Почитав в теме комментарии, я понял, что вопрос волновал многих и, к моему сожалению, в комментариях нет правильного ответа. Я решил исправить эту маленькую несправедливость и сделал небольшой пример создания типа для системного семейства Текст. Все пояснения я оставил в виде комментариев к коду.

Вот и сам пример:

В решении некоторых плагинов бывает возникает такая задача и мы начинаем искать решения в интернете, а там сложные формулы прямой на плоскости или в пространстве.

Но есть решение куда проще в реализации и понятнее. И поможет нам в этом скалярное произведение векторов (DotProduct):

Если скалярное произведение двух единичных векторов по модулю равно 1, то эти два вектора коллинеарны (параллельны друг другу).

Если произведение будет 1 – вектора направлены в одну сторону, а если -1 – в противоположные. Но в нашей задаче это не важно и нас интересует только модуль произведения. Из первого утверждения получаем метод проверки параллельности:

/// <summary>
/// Проверка параллельности двух векторов
/// </summary>
/// <param name="vector">Первый вектор</param>
/// <param name="checkedVector">Второй вектор</param>
/// <param name="tolerance">Допуск расстояния при проверке</param>
public static bool IsParallelTo(this XYZ vector, XYZ checkedVector, double tolerance = 0.0001)
{
    return Math.Abs(Math.Abs(vector.DotProduct(checkedVector)) - 1.0) < tolerance;
}

/// <summary>
/// Проверка параллельности двух отрезков
/// </summary>
/// <param name="line">Первый отрезок</param>
/// <param name="checkedLine">Второй отрезок</param>
/// <param name="tolerance">Допуск расстояния при проверке</param>
public static bool IsParallelTo(this Line line, Line checkedLine, double tolerance = 0.0001)
{
    return line.Direction.IsParallelTo(checkedLine.Direction, tolerance);
}

Мы уже решили половину задачи. А полное решение искомой задачи звучит так:

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

Причем это утверждение будет работать и в 3D пространстве, а не только на плоскости.

Ну и конечно код этого решения в виде метода расширения для отрезка:

/// <summary>
/// Лежат ли текущий и проверяемый отрезок на одной прямой. 
/// </summary>
/// <param name="firstLine">Текущий отрезок</param>
/// <param name="secondLine">Проверяемый отрезок</param>
/// <param name="tolerance">Допуск на сравнение чисел</param>
public static bool IsLieOnSameStraightLine(this Line firstLine, Line secondLine, double tolerance = 0.0001)
{
    // Если два отрезка не параллельны, то и дальнейшая проверка не требуется
    if (!firstLine.IsParallelTo(secondLine))
        return false;

    // Можно получить все концевые точки методом GetEndPoint(int), но это приведет к раздутию
    // кода и его некрасивости. Поэтому используем метод Tessellate(), который для отрезков вернет
    // те же самые две концевые точки
    var firstLinePoints = firstLine.Tessellate();
    var secondLinePoints = secondLine.Tessellate();

    // Вектор первого отрезка будем использовать как эталон проверки.
    // Свойство Direction всегда содержит единичный вектор
    var fv = firstLine.Direction;

    // Нам требуется проверять попарно концевые точки первого отрезка с концевыми точками второго.
    // Это удобно сделать двумя итерациями
    foreach (var firstLinePoint in firstLinePoints)
    {
        foreach (var secondLinePoint in secondLinePoints)
        {
            // Если два отрезка будут будут иметь общую концевую точку, то проверка сработает не верно,
            // так как произведение векторов даст 0.0. Такие пары просто пропускаем
            if (Math.Abs(firstLinePoint.DistanceTo(secondLinePoint)) < tolerance)
                continue;

            // Не важно из какой какую точку отнимать. Главное, привести к единичному вектору
            var v = (secondLinePoint - firstLinePoint).Normalize();

            // Если вектора не параллельны, то и отрезки не лежат на одной прямой
            if (!fv.IsParallelTo(v))
                return false;
        }
    }

    // Если в предыдущих итерациях мы не вышли из метода, значит два отрезка лежат на одной прямой
    return true;
}

Не забывайте, что в Revit есть отрезки, а есть лучи, и оба они представлены типом Line. Данный код не учитывает таких различий

Как в случае с AutoCAD, так и в случае с Revit вы можете столкнуться с проблемой зависания главного меню при открытии.

Иногда некоторые пользователи могут столкнуться с неприятной проблемой – основное меню AutoCAD зависает при открытии. Точнее – оно очень долго открывается.

При разработке плагинов для Revit сталкиваюсь с различными неожиданными результатами, которые больше похожи на обычные баги. О таких багах желательно знать заранее.

Сегодня расскажу о ориентации витража.

При разработке плагина, работающего с штриховками, столкнулся с интересной ситуацией - в Revit API нет методов определения типа штриховки. Речь идет не о типе "Условный" или "Моделирующий", а о типе "Основная" или "Пользовательская". Исследовав несколько различных штриховок я создал метод определения типа штриховки.

Возможно многие разработчики приложений сталкивались с проблемой неверного отображения содержимого Dockable Panel в случае, если в параметрах дисплея установлен масштаб, отличный от 100%. В этой статье я покажу пример решения этой проблемы.

Методы, описанные в данной статье, эволюционариовали в более лучшее и удобное решение, в дальнейшем описанное на Хабре

В моём плагине ModPlus все функции (плагины) имеют свою версию сборки под каждую версию поддерживаемого продукта. Т.е. для AutoCAD, на момент написания статьи, это 7 проектов на каждую функцию. Конечно, копипастить одно и тоже во всех проектах муторно и долго. Благо, есть несколько лайфкахов как свести все проблемы к минимуму и работать только с одним проектом. И сегодня я хотел бы рассказать о том, как менять версию сборки сразу во всех проектах. Как ни странно, но для многих новичков это может оказаться неизвестной фичей. Да что таить – я сам недавно только начал использовать этот метод =)

Являясь разработчиком уже достаточно объемного продукта и задумывая об официальности (т.е. о регистрации ИП или ООО и всём сопутствующем) я начал задумываться над тем, что одному такое очень тяжело тянуть. И есть в таком случае два варианта – наём постоянных сотрудников или наём фрилансеров. А так как я сам являюсь постоянным сотрудником и имею небольшой опыт обращения к фрилансерам, я сделал вывод – фриланс в этом случае – в случае начинающей небольшой фирмы - лучше! По крайней мере плюсы перевешивают минусы (не по количеству, а по весомости своей).

Вот какие плюсы и минусы я выделил:

Маленькая заметка для всех программистов, использующих в своих проектах WPF. Наверняка многие из вас задавались вопросом «как увеличить время отображения подсказок?» или «как сделать так, чтобы подсказка выскочила сразу при наведении мышки на элемент?»

Как оказалось, в WPF есть целая служба, которая предоставляет свойства и события для управления отображением и поведением подсказок – ToolTipService. Единственная проблема использования этого сервиса заключается в том, что IntelliSense не показывает нам наличие этого сервиса, и поэтому многие о нём просто не знают!

Самые полезные (лично для меня) свойства, которые предоставляет сервис:

  • InitialShowDelay - получает или задает интервал времени до открытия подсказки.
  • ShowDuration - получает или задает количество времени отображения подсказки.
  • ShowOnDisabled - получает или задает значение, указывающее, отображается ли всплывающая подсказка для объекта, который не активен.

Со всеми остальными свойствами и примером использования Вы можете ознакомиться в справке на MSDN. Берите себе на заметку!