Официальный форум российского программного комплекса T-FLEX PLM


Поиск  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Регистрация
Войти
 
Вопрос по API
 
Подскажите, пжалста, можно ли с помощью макроса программно вставить в сборку 3D-фрагмент из DOCs (важно!)? Почитал хэлп по API, нашел только методы, которые вставляют фрагменты по пути к файлу, т.е. фрагменты с диска.
Страницы: Пред. 1 2 3 4 5 6 7 След.
Ответы
 
Цитата
ВладиславКМВ написал:
Нужен макрос для автоматизации однотипных действий.
Делаю планировку 2D. В качестве подосновы чертежа берётся изображение. На изображении нет размеров, масштаб изображения произвольный, но планировку надо сделать близко к реальным размерам. По имеющимся на изображении цифрам вычисляю вручную масштаб, назначаю переменную М. Дальше назначаю эту переменную в качестве масштаба изображению. И хотя теперь можно получит почти реальные размеры, дополнительно делаю умножение значения каждой линии построения на этот масштаб (по умолчанию 1:1) Теперь при корректировке переменной масштаба в любую сторону одновременно корректируются и линии построения и подоснова. Но... линий построения много и нужно в каждую вставлять мастаб (см. скрин). Можно ли это делать с помощью макроса и одной кнопки? Скрытый текст
Макрос меняет у всех линий построения значение на новое. Минус в том, что вместо изменения выражения у линии построения, на каждую линию построения создается новая переменная, равная старому значению умноженному на переменную M, и эта переменная подставляется в значение линии построения. Не нашел чтобы можно было подставлять выражение для линии построения.
 
Цитата
Андрей Мальчук написал:
Либо с относительными путями, если текстуры из комплекта поставки флекса, либо - полный путь, с именем диска и пр.
Можно ещё свои текстуры поместить в папку Textures программы и давать относительные ссылки на них. Спасибо, не знал, что переменную можно и сюда впихнуть.

Цитата
Андрей Мальчук написал:
Предположим, вы же знаете размер оконного проема или дверного в реале, присутсвующего на картинке?
Нет, размеров проёмов не знаю. Вычисляю по площадям, если они есть на изображении, что, понятно, не даёт точных результатов.
Успех это способность идти от одной неудачи к другой без потери энтузиазма.
(У.Черчиль)
 
Цитата
Анатолий Ледяев написал:
Макрос меняет у всех линий построения значение на новое. Минус в том, что вместо изменения выражения у линии построения, на каждую линию построения создается новая переменная, равная старому значению умноженному на переменную M, и эта переменная подставляется в значение линии построения. Не нашел чтобы можно было подставлять выражение для линии построения.
Нормально, работает. Можно и так. Но пока не могу добавить этот макрос в свой проект и проверить. Сначала скопировал файл с макросом в папку Macros программы. Однако в числе общих макросов он не появился. Тогда создал модуль в своём проекте и скопировал туда код из вашего модуля. Но теперь не получается скомпилировать макрос. Выдаётся сообщение об ошибке. Что я не так?
Скрытый текст
Успех это способность идти от одной неудачи к другой без потери энтузиазма.
(У.Черчиль)
 
Пересохранил. В проекте нужно было добавить ещё одну ссылку. Заодно текст немного подредактировал, и скомпилировал, должен работать если добавите в папку с макросами.
 
Отлично, Анатолий! Благодарю за макрос. После перезапуска ТФ макрос появился в общем списке. Месседж бокс действительно был лишним, если линий за сотню замучаешься соглашаться. Была небольшая проблема. У вас переменная М в коде написана латиницей, исправил на кирилицу (у меня переменная написана русским шрифтом), и всё работает. :applanse:
Да, есть вопрос, откуда появляются многочисленные нулевые линии? У меня их изначально всего две. А после отработки макроса набегает ещё несколько.
Скрытый текст
Изменено: ВладиславКМВ - 17.05.2016 22:01:18
Успех это способность идти от одной неудачи к другой без потери энтузиазма.
(У.Черчиль)
 
Цитата
ВладиславКМВ написал:
Отлично, Анатолий! Благодарю за макрос. После перезапуска ТФ макрос появился в общем списке. Месседж бокс действительно был лишним, если линий за сотню замучаешься соглашаться. Была небольшая проблема. У вас переменная М в коде написана латиницей, исправил на кирилицу (у меня переменная написана русским шрифтом), и всё работает.
Да, есть вопрос, откуда появляются многочисленные нулевые линии? У меня их изначально всего две. А после отработки макроса набегает ещё несколько.
Скрытый текст
Не за что. По нулевым линиям не знаю откуда, попробуйте перед запуском макроса делать удаление лишних объектов, возможно не будут появляться.
Скрытый текст
Изменено: Анатолий Ледяев - 17.05.2016 23:13:49 (корректировка)
 
Доброго дня, товарисчи.
Написал я макрос, а вот как мне его с кнопки клавиатуры запускать?
Через KeyPressEventHandler()? Или есть способы попроще?
Изменено: FRei - 11.08.2018 20:28:26
 
FRei, самый простой способ обработки события KeyEventArgs через класс расширения CustomCommand, например:
Код
using System.Windows.Forms;
using TFlex.Command;
using TFlex.Model;

namespace Test
{
    public class UserCommand : CustomCommand
    {
        public UserCommand(CommandState cmd) : base (cmd)
        {

        }

        public override void OnKeyPressed(TFlex.Command.KeyEventArgs e)
        {
            if (e.Code == TFlex.KeyCode.keyC_B)
            {
                MessageBox.Show("Key code: Ctrl + B"); // обработка команды пользователя
            }

            base.OnKeyPressed(e); // передача управления для обработки стандартных команд приложения
        }
    }

    public class TestMacro
    {
        static readonly Document document = TFlex.Application.ActiveDocument;

        public static void Run()
        {
            if (document == null || document.ActiveView == null)
                return;

            CommandState cmd = new CommandState();
            UserCommand userCommand = new UserCommand(cmd);
            userCommand.Run(document.ActiveView);
        }
    }
}

чтобы корректно запустить макрос, нужно подключить событие ViewActivated в редакторе макросов (см. вложение). Когда один из видов документа будет активным, сработает макрос TestMacro, который запустит цикл обработки команд пользователя.
T-FLEX CAD 16.0.48.0
 
Цитата
чтобы корректно запустить макрос, нужно подключить событие ViewActivated в редакторе макросов (см. вложение). Когда один из видов документа будет активным, сработает макрос TestMacro , который запустит цикл обработки команд пользователя.
Спасибо! И еще надо в ссылки добавить TFlexCommandAPI.dll. Без неё не едет :D
 
Подглючивает что-то. :(

Скрытый текст
Изменено: FRei - 13.08.2018 12:16:18
 
FRei, этот пример нельзя использовать в контексте события ViewActivated. должен быть обработчик событий типа KeyPressEventHandler на уровне класса Plugin.
T-FLEX CAD 16.0.48.0
 
Цитата
vite написал:
обработчик событий типа KeyPressEventHandler на уровне класса Plugin .
Вот на него моих куриных мозгов не хватает.
Итак, в Вашем коде нужно заменить объект типа usercommand на plugincommand. Он так же запускается методом run(view). В объекте такой же метод OnKeyPressed( KeyEventArgs e). Так?
При этом еще и объект plugin создать нужно, поскольку конструктор объекта объявляется как PluginCommand(Plugin OwnerPlugin ) ?
Подозреваю, что отправите смотреть исходники плагина Stars.
 
FRei, вы меня не правильно поняли, нужно получить доступ к оконной процедуре главного окна приложения для обработки события KeyPressEventHandler, чего пока нет в API. классы PluginCommand и CustomCommand просто реализуют интерфейс пользовательских команд, которые внутри также имеют свои обработчики. эти классы предоставляют немного больше возможностей для расширенной обработки команд меню. т.е. сначала выполняется команда меню, потом обрабатывается контекст клавиатуры. несмотря на то, что макрос частично отрабатывает на событии ViewActivated, он по прежнему работает некорректно. у меня, к примеру, неправильно работает селектор. по мимо прочего, каждый клик мыши повторно запускает метод Run.
T-FLEX CAD 16.0.48.0
 
FRei, если очень нужно, могу предложить временное решение:
Код
using System;
using System.Runtime.InteropServices;
using TFlex.Model;

namespace TFlex
{
    public class Factory : PluginFactory
    {
        public override Plugin CreateInstance()
        {
            return new PluginInstance(this);
        }

        public override Guid ID
        {
            get
            {
                return new Guid("{83FC6A2C-16BD-4F00-A067-7AB1038E4553}");
            }
        }

        public override string Name
        {
            get
            {
                return "T-FLEX CAD Extension";
            }
        }
    }
    
    public partial class PluginInstance : Plugin
    {
        const int GWLP_WNDPROC = (-4);
        const uint WM_KEYDOWN = 0x0100;

        [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Auto)]
        private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]
        private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

        [DllImport("user32.dll", EntryPoint = "CallWindowProc", CharSet = CharSet.Auto)]
        private static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);

        private delegate IntPtr WinProcDelegate(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);

        private static IntPtr handle = IntPtr.Zero;
        private static IntPtr oldWndProc = IntPtr.Zero;
        private WinProcDelegate newWndProc;
        
        private IntPtr WindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
        {
            if (uMsg == WM_KEYDOWN)
            {
                switch ((int)wParam)
                {
                    case 0x21: // PAGE UP
                        RotateView(45);
                        break;
                    case 0x22: // PAGE DOWN
                        RotateView(-45);
                        break;
                }
            }

            return CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
        }

        private void RotateView(float angle)
        {
            Document document = TFlex.Application.ActiveDocument;
            Model.Model3D.View3D view3D = (document.ActiveView as Model.Model3D.View3D);
            Model.Model3D.View3D.Parameters p = view3D.GetParameters();
            p.AutoResize = true;
            p.CameraType = Model.Model3D.View3D.CameraType.Orthographic;
            p.Angle = (p.Angle + angle);
            view3D.SetParameters(p);
        }
      
        public PluginInstance(Factory factory) : base(factory) {}
        
        protected override void NewDocumentCreatedEventHandler(DocumentEventArgs args)
        {
            args.Document.AttachPlugin(this);
        }
        
        protected override void DocumentOpenEventHandler(DocumentEventArgs args)
        {
            args.Document.AttachPlugin(this);
        }
        
        protected override void ViewActivatedEventHandler(ViewEventArgs args)
        {
            base.ViewActivatedEventHandler(args);

            if (args.View is Model.Model3D.View3D)
            {
                if (handle == IntPtr.Zero)
                {
                    handle = args.View.HWnd;
                    newWndProc = new WinProcDelegate(WindowProc);
                    oldWndProc = GetWindowLongPtr(handle, GWLP_WNDPROC);
                    SetWindowLongPtr(handle, GWLP_WNDPROC, Marshal.GetFunctionPointerForDelegate(newWndProc));
                }
                else if (handle != args.View.HWnd)
                {
                    oldWndProc = GetWindowLongPtr(handle, GWLP_WNDPROC);
                    SetWindowLongPtr(handle, GWLP_WNDPROC, Marshal.GetFunctionPointerForDelegate(newWndProc));
                }
            }
        }

        protected override void ViewDeactivatedEventHandler(ViewEventArgs args)
        {
            base.ViewDeactivatedEventHandler(args);

            if (handle != IntPtr.Zero)
            {
                SetWindowLongPtr(handle, GWLP_WNDPROC, oldWndProc);
                newWndProc = null;
                handle = IntPtr.Zero;
            }
        }
    }
}

этот код нужно компилировать в модуль расширения DLL. стандартный вариант поворота работает в режиме просмотра (клавиши: PgUp и PgDn). тоже самое я сделал для режима "эскиз".
T-FLEX CAD 16.0.48.0
 
vite, спасибо за пример. Раз пошло дело к dll, то хочу спросить возможно ли использование VS code c .net core?
 
FRei, возможно...
T-FLEX CAD 16.0.48.0
 
Подскажите пожалуйста, есть у меня в модели линейный массив,

что-то не пойму, как мне перебрать его элементы и сделать с ними что-то, например, изменить свойство VisibleInScene? Есть класс LinearArrayOperation, но в нем нет ссылок на порождаемые объекты.
 
FRei, по поводу перебора элементов не уверен что это возможно.
пример изменения видимости объекта:

Код
using TFlex.Model;
using TFlex.Model.Model3D;

namespace Test
{
    public class Class22
    {
        public static void Run()
        {
            Document document = TFlex.Application.ActiveDocument;

            if (document == null)
                return;

            foreach (ModelObject i in document.GetObjects())
            {
                if (i.GroupType == ObjectType.LinearArray && i.Name == "Линейный массив_1")
                {
                    LinearArrayOperation linearArray = i as LinearArrayOperation;

                    document.BeginChanges("");

                    linearArray.VisibleInScene = false;

                    document.EndChanges();

                    break;
                }
            }
        }
    }
}
T-FLEX CAD 16.0.48.0
 
vite, спасибо за пример, но он "выключит" весь массив мне же надо "выключить" отдельные элементы, например матрица индикатора:
 
FRei, есть возможность добавить элементы в коллекцию исключений по индексу, например:
Код
document.BeginChanges("");

linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(1), new Parameter(0)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(3), new Parameter(0)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(1), new Parameter(1)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(2), new Parameter(1)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(3), new Parameter(1)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(2), new Parameter(2)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(3), new Parameter(2)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(1), new Parameter(3)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(3), new Parameter(3)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(1), new Parameter(4)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(2), new Parameter(4)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(1), new Parameter(5)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(2), new Parameter(5)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(3), new Parameter(5)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(1), new Parameter(6)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(2), new Parameter(6)));
linearArray.Exclusions.Add(new Exclusion(linearArray, new Parameter(3), new Parameter(6)));

document.EndChanges();

если понадобится обновить коллекцию исключений, нужно предварительно ее очистить:
Код
linearArray.Exclusions.Clear();
T-FLEX CAD 16.0.48.0
Страницы: Пред. 1 2 3 4 5 6 7 След.