Форум профессиональных мебельщиков PROMEBELclub

Форум профессиональных мебельщиков PROMEBELclub (https://промебельклуб.рф/forum/index.php)
-   Базис-мебельщик. Скрипты (https://промебельклуб.рф/forum/forumdisplay.php?f=273)
-   -   БАЗИС 10 - Скрипты (https://промебельклуб.рф/forum/showthread.php?t=12463)

Letos 11.02.2019 09:57

Цитата:

Сообщение от Ozimko (Сообщение 471221)
Вопрос - есть ли команда РАЗРУШИТЬ БЛОК?

Здесь уже был ответ на такой вопрос. Но это решение хорошо работает только если блок был создан скриптом (если вы собираетесь разрушить объект "obj", то этот код вам подойдёт).

Letos 13.02.2019 10:28

Цитата:

Сообщение от IStiv (Сообщение 471161)
Всем доброго времени.
прошу совета помощи.
Задача состоит в определении где находится присадка под петли верх/низ/лево/право у панели. Скриптом.

Определить верх/низ решаемо, Y ось всегда вверх и получив координаты контура и приведя их к мировым - можно определить где верх, а где низ, и исходя из этого определить вверху или внизу присадка, вытащив координаты отверстий.
Ситуация еще осложнена тем что панель не одна(так бы можно было привязаться к какой то координате), а целая кухня панелей любой конфигурации.
Однако ситуация когда отверстия могут быть с двух сторон - исключена.

А вот с лево/право не понятно как быть.
Т.е. вопрос есть ли какой то способ , прогрммно определить лево/право панели ?
( лицом при этом будет задняя сторона панели , где отверстия).

Есть решение. Ограничения этого решения:
  • Ось Х или У панели должна быть параллельна глобальной оси У (Если над панелью не было никаких "извращений", то так должно быть всегда).
  • Проверка идёт по фурнитуре с типом установки "пласть-пласть", поэтому может выдать результат не только для петель, а, например, и для уголков.
  • Если установлена одна петля (например, снизу слева), то в текущем варианте присадка не определится. Можно проверять наличие направления побитовым И, например код под условием "if (pos & LEFT)" выполнится, только если в результате определения позиции есть "лево".

Я попытался максимально откомментировать код, чтобы не возникали вопросы "что за переменная/условие/функция и как оно работает".

Всё, что идёт до Model.UnselectAll() - основные функции для работы скрипта. Ниже - пример, как этим пользоваться (им я и тестировал). В текущем варианте скрипт бегает по всем панелям, определяет позицию, потом выделяет панель, алертом сообщает информацию, снимает выделение и обрабатывает следующую панель.

Код

Код:

// Четыре константы направлений - бит смещённый на несколько порядков.
// В побитовом представлении выглядит так:
// Лево = 0001, Право = 0010, Верх = 0100, Низ = 1000.
// Для взаимодействия с ними используются "побитовое И" и "побитовое ИЛИ".
// "Побитовое И" возвращает 1 если в обоих сравниваемых разрядах оба значения
// равны 1. Например: 11 & 5 = 1 (побитово: 1011 & 0101 = 0001).
// "Побитовое И" возвращает 1 если в хотя бы в одном из сравниваемых разрядах
// значение равно 1. Например: 9 | 5 = 13 (побитово: 1001 | 0101 = 1101).
const LEFT = 1 << 0, RIGHT = 1 << 1, UP = 1 << 2, DOWN= 1 << 3

/**векторное произведение векторов */
function VectorCross(v1, v2) {
    return {
        x: v1.y * v2.z - v1.z * v2.y,
        y: v1.z * v2.x - v1.x * v2.z,
        z: v1.x * v2.y - v1.y * v2.x
    }
}
/** получить обратный вектор */
function VectorNegate(v) {
    return {
        x: -v.x,
        y: -v.y,
        z: -v.z
    }
}
/** расстояние от точки до плоскости
 * Плоскость определяется точкой на плоскости и нормалью
 */
function PointPlaneDistance(point, planePoint, planeNormal) {
    return (point.x - planePoint.x) * planeNormal.x +
        (point.y - planePoint.y) * planeNormal.y +
        (point.z - planePoint.z) * planeNormal.z;
}
/** сравнение двух вещественных чисел с точностью 0.001*/
function Equals(n1, n2) {
    return Math.abs(n1 - n2) < 0.001;
}
/** сравнение двух векторов */
function EqualsV(v1, v2) {
    return Equals(v1.x, v2.x) &&
        Equals(v1.y, v2.y) &&
        Equals(v1.z, v2.z);
}
/** Проверка направления (отверстия)
 * Возвращает true, если вектор gDir сонаправлен с осью Z панели
 */
function CheckDirection(gDir, panel) {
    return (EqualsV(gDir, panel.NToGlobal(AxisZ)) ||
        EqualsV(gDir, panel.NToGlobal(Axis_Z)))
}

/**
 * Проверка отверстия
 * Возвращает комбинацию смещения относительно панели
 * @param {Panel} panel
 */
function CheckHole(hole, fast, panel) {
    var result = 0;
    /** Направление отверстия в ЛСК панели
    * Указывает направление "вперёд" для панели
    */
    var holeDir = panel.NToObject(fast.NToGlobal(hole.Direction));
    /** Глобальная ось Y в ЛСК панели (вектор "вверх" панели)*/
    var UpAxis = panel.NToObject(AxisY);
    /** Вектор, указывающий направление "влево" панели */
    var leftAxis = VectorCross(UpAxis, holeDir);
    /** Центр отверстия */
    var holeCenter = fast.ToGlobal({
        x: hole.Position.x + hole.Direction.x * (hole.Depth / 2),
        y: hole.Position.y + hole.Direction.y * (hole.Depth / 2),
        z: hole.Position.z + hole.Direction.z * (hole.Depth / 2),
    })
    // перевод центра отверстия в ЛСК панели
    holeCenter = panel.ToObject(holeCenter);
    /** центр панели в её ЛСК. Используется как точка на плоскости разделяющей
    * "право-лево" и "верх-низ"
    */
    var panelCenter = {
        x: (panel.GMin.x + panel.GMax.x) / 2,
        y: (panel.GMin.y + panel.GMax.y) / 2,
        z: (panel.GMin.z + panel.GMax.z) / 2
    };
    // Если расстояние от центра отверстия до плоскости, определённой центром
    // панели и направлением "влево" положительное, значит отверстие слева.
    // Иначе - справа. Если центр отверстия находится в центре панели, с большой
    // вероятностью результатом будет "слева"
    if (PointPlaneDistance(holeCenter, panelCenter, leftAxis) > -0.001)
        result |= LEFT;
    else
        result |= RIGHT;
    // Если расстояние от центра отверстия до плоскости, определённой центром
    // панели и направлением "вверх" положительное, значит отверстие сверху.
    // Иначе - снизу. Если центр отверстия находится в центре панели, с большой
    // вероятностью результатом будет "снизу"
    if (PointPlaneDistance(holeCenter, panelCenter, UpAxis) > -0.001)
        result |= UP;
    else
        result |= DOWN;
    return result;
}

/**
 * Получение позиций петель (или другой фурнитуры по типу "пласть-пласть")
 * @param {Panel} panel
 */
function GetHingePosition(panel) {
    var fasts = panel.FindConnectedFasteners();
    // Изначально в результате все направления. Побитово: 1111
    var result = LEFT | RIGHT | UP | DOWN;
    for (var i = 0; i < fasts.length; i++) {
        var fast = fasts[i];
        // (DatumMode == 2) - проверка, что фурнитура устанавливается по типу
        // "пласть-пласть"
        if (fast.DatumMode == 2) {
            var holes = fast.Holes;
            if (holes && holes.Count > 0) {
                for (var j = 0; j < holes.Count; j++) {
                    var hole = holes[j]
                    // Проверка направления отверстия (переведённого в ГСК)
                    if (CheckDirection(fast.NToGlobal(hole.Direction), panel)) {
                        // Побитовым И из результата отсекаются те направления,
                        // которые не были возвращены функцией CheckHole.
                        result &= CheckHole(hole, fast, panel);
                    }
                }
            }
        }
    }
    return result;
}

Model.UnSelectAll();
Model.forEachPanel((panel) => {
    var pos = GetHingePosition(panel);
    var msg = `панель ${panel.Name} : ${panel.UID}\n`;
    // Сверяем результат с константами направления.
    switch (pos) {
        case LEFT:
            msg += 'Присадка слева';
            break;
        case RIGHT:
            msg += 'Присадка справа';
            break;
        case UP:
            msg += 'Присадка сверху';
            break;
        case DOWN:
            msg += 'Присадка снизу';
            break;
        default:
            msg += 'Присадка не определена';
    }
    panel.Selected = true;
    alert(msg);
    panel.Selected = false;
})

[свернуть]

prodboard 14.02.2019 03:44

Добрый день.
Нужен специалист по скриптам в Базисе.

Есть идея реализовать интеграцию между нашим продуктом и Базис мебельщиком через модуль скрипта самого Базиса.

Просьба связываться по скайпу yason_sd

Прошу прощения за флуд, и если сообщение не к месту

IStiv 16.02.2019 13:15

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

ранее я их просто удалял, а потом возвращал.
потом скрипт стал сложнее , добавился Action.Commit(); и так делать стало нельзя.
я стал писать в пользовательские свойства метку "не проверять", и смотреть ее наличие.
но возникает куча доп.кода и это как то проблемно.

м.б. есть какой то простой способ устанавливать/сбрасывать некое свойство каждого элемента модели, при котором скрипт этот элемент просто не видит?

v22884 16.02.2019 14:26

Цитата:

Сообщение от IStiv (Сообщение 471505)
устанавливать/сбрасывать некое свойство каждого элемента модели

UserProperty не вариант?

Letos 17.02.2019 09:50

Цитата:

Сообщение от IStiv (Сообщение 471505)
м.б. есть какой то простой способ устанавливать/сбрасывать некое свойство каждого элемента модели, при котором скрипт этот элемент просто не видит?

Может я не понял ваших намерений, но чем вам не подходит менять видимость объекта?

IStiv 17.02.2019 13:58

Цитата:

Сообщение от Letos (Сообщение 471519)
Может я не понял ваших намерений, но чем вам не подходит менять видимость объекта?

Visible? - это не подходит, т.к. выключается видимость в модели(визиуально). но скрипт этот элемент "видит". м.б. я как то не правильно делаю?
PHP код:

obj.Visible false;
Action.Commit(); 

суть в том что нужно сделать ,к примеру какой то блок, временно недоступным для скрипта. а потом доступным).
UserProperty - ну как бы подходит. то это заморочно. ибо мне к примеру надо исключать из обработки блоки. Значит надо свойство навершивать на всю структуру ниже. потом проверять. потом стирать. а таких мест в коде уже много. у меня та еще "архитектура" конечно. но скрипты уже разрослись..

Letos 17.02.2019 14:29

Цитата:

Сообщение от IStiv (Сообщение 471532)
Visible? - это не подходит, т.к. выключается видимость в модели(визиуально). но скрипт этот элемент "видит". м.б. я как то не правильно делаю?
PHP код:

obj.Visible false;
Action.Commit(); 

суть в том что нужно сделать ,к примеру какой то блок, временно недоступным для скрипта. а потом доступным).
UserProperty - ну как бы подходит. то это заморочно. ибо мне к примеру надо исключать из обработки блоки. Значит надо свойство навершивать на всю структуру ниже. потом проверять. потом стирать. а таких мест в коде уже много. у меня та еще "архитектура" конечно. но скрипты уже разрослись..

Я так понимаю, вы в коде определяете, что скрипт "видит". Вы просто можете добавить условие "if (obj.Visible)" и под ним обрабатывать объект. Если объект будет с выключенной видимостью, он просто не пройдёт это условие и не будет обрабатываться.
Если вам нужно исключать из обработки все блоки, можно ещё воспользоваться условием "if (!obj.List)", но это, скорее, частный случай решения задачи.

IStiv 17.02.2019 14:38

Цитата:

Сообщение от Letos (Сообщение 471533)
"if (obj.Visible)" и под ним обрабатывать объект. Если объект будет с выключенной видимостью, он просто не пройдёт это условие и не будет обрабатываться.

это понятно.так же можно и со свойствами. но загвоздка в том что нужно для функций а-ля "для каждой панели сделать то то" - везде проверять видимость для панелей. и для блоков. и для фурнитуры. а я накодил уже кучу и "впихивать" сейчас эти проверки в 15 местах по всему приложению не хочется. а задача простая - исключить из обработки блоки с определенными именами.
идеально было некое свойство" не доступен для скрипта" отключил/включил.и чтобы для блока , это на все дерево вниз распостранялось.
если никакого фокуса нет. буду "городить" с Visible или свойствами*PARDON*

Карякин 18.02.2019 08:11

Товарищи специалисты! помогите советом. Отверстия одного диаметра глухие и сквозные у нас по одной цене, но для диаметра 5 мм есть еще метка (5*2) В операциях нашел Пользовательские вычисляемые, "придумал" формулу- (все глухие 5мм+все сквозные 5 мм)-отверстия 5*2, а какие команды использовать в скрипте не пойму. беру параметры с модели, просто складываю, использую оператор var, все равно не видит и не считает. Помогите,пожалуйста.


Текущее время: 14:57. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
© 2007-2023 PROMEBEL