Автоматизация работы с чертежами

Автор Alex152, 15.09.15, 23:47:15

« назад - далее »

0 Пользователи и 2 гостей просматривают эту тему.

Alex152

Доброго времени суток! Народ нужна ваша профессиональная помощь!! Мне как инженеру конструктору, в архиве несколько 1000 документов, необходимо автоматизировать работу с конструкторской документацией.
Для этого на Visual C# сделал оболочку, в базах sql регистрирую чертежи.
Перед регистрацией в базе чертежа или спецификации, его открываю считываю содержимое штампа.

            int[] myArr = new int[10]; // Коды строк чертежа
            myArr[0] = 2; // Обозначение
            myArr[1] = 1; // Наименование
            myArr[2] = 5; // Масса
            myArr[3] = 3; // Материал
            myArr[4] = 110; // Разработал
            myArr[5] = 111; // Проверил
            myArr[6] = 113; // нач КБ
            myArr[7] = 114; // Н контроль
            myArr[8] = 115; // Утв
            myArr[9] = 25; // Первичное прим.

                        ksDocument2D Doc = (ksDocument2D)kompas.Document2D();
                        Doc.ksOpenDocument((treeView1.SelectedNode.FullPath + @"\" + checkedListBox1.Text), true);
                        ksDocumentParam DocPm = (ksDocumentParam)kompas.GetParamStruct(35);
                        ksStamp st = (ksStamp)Doc.GetStamp();
                        st.ksOpenStamp();
                        foreach (int n in myArr)
                        {
                            st.ksColumnNumber(n);
                            ksTextItemParam itemParam = (ksTextItemParam)kompas.GetParamStruct((short)StructType2DEnum.ko_TextItemParam);
                            ksTextLineParam TextLine = (ksTextLineParam)kompas.GetParamStruct((short)StructType2DEnum.ko_TextLineParam);
                            ksDynamicArray f = (ksDynamicArray)st.ksGetStampColumnText(n);
                            if (f != null)
                            {
                                string str_stamp = "";
                                int rr = f.ksGetArrayCount();// определяет количество строк
                                for (int i1 = 0; i1 < f.ksGetArrayCount(); i1++ )
                                {
                                   
                                   f.ksGetArrayItem(i1, TextLine); // читает определенную строку строку
                                   ksDynamicArray f1 = (ksDynamicArray)TextLine.GetTextItemArr();
                                   f1.ksGetArrayItem(0, itemParam);
                                   str_stamp = str_stamp + itemParam.s;
                                }
                                ls.Add(str_stamp);
                            }
                            else
                            {
                                ls.Add("");
                            }

Получаю всю интересующую меня информацию. Но не могу прочитать, материал когда материал в 3 графе записан в виде дроби!!!! См. приложение.
Далее при необходимости из базы вызываю чертеж или спецификацию и заполняю штамп. Следующим образом.

                                ksDocument2D doc = (ksDocument2D)kompas.Document2D();
                                doc.ksOpenDocument((Directory + @"\" + Stamp[1].ToString().Trim() + ".cdw"), false);
                                ksStamp S = (ksStamp)doc.GetStamp(); // переменная штамп
                                S.ksOpenStamp();
                                ksTextItemParam itemParam = (ksTextItemParam)kompas.GetParamStruct((short)StructType2DEnum.ko_TextItemParam);
                                ksTextItemFont itemFont = (ksTextItemFont)itemParam.GetItemFont();
                                itemFont.SetBitVectorValue(ldefin2d.NEW_LINE, true);
                                S.ksColumnNumber(2);
                                itemParam.s = Stamp[2].ToString();//"Обозначение";
                                S.ksTextLine(itemParam);
                                S.ksColumnNumber(1);
                                itemParam.s = Stamp[3].ToString();// "Наименование";
                                doc.ksTextLine(itemParam);
                                S.ksColumnNumber(25);
                                itemParam.s = Stamp[4].ToString();// "Первичное прим";
                                doc.ksTextLine(itemParam);
                                S.ksColumnNumber(10);
                                itemParam.s = "Нач КБ";
                                S.ksSetTextLineAlign(0);
                                S.ksTextLine(itemParam);
                                S.ksColumnNumber(110);
                                itemParam.s = Stamp[5].ToString(); ; //---- разработал
                                S.ksTextLine(itemParam);
                                S.ksColumnNumber(111);
                                itemParam.s = rd["Cheked"].ToString(); //---- Проверил
                                S.ksTextLine(itemParam);
                                S.ksColumnNumber(112);
                                itemParam.s = rd["TechControl"].ToString(); //---- Т. контрол
                                S.ksTextLine(itemParam);
                                S.ksColumnNumber(113);
                                itemParam.s = rd["HeadKB"].ToString(); //---- Нач КБ
                                S.ksTextLine(itemParam);
                                S.ksColumnNumber(114);
                                itemParam.s = rd["StandartContrl"].ToString(); //---- Н. контрл
                                S.ksTextLine(itemParam);
                                S.ksColumnNumber(115);
                                itemParam.s = rd["Approved"].ToString(); //---- Утвердил
                                S.ksTextLine(itemParam);
                                S.ksCloseStamp();

Все заполняется вроде бы проблем нет, но не могу внести материал в виде дроби.
А также когда чертеж сборочный то не могу записать в графе 1 под наименованием "Сборочный чертеж". Пишется только в одну строку. Хотя при внесении чертежа в базу я читаю и 1-ую и 2-ую чтроку.

И так на повестке  3 вопроса:

1- как прочитать и идентифицировать материал который записан в виде дроби ?

2 - как внести материал в виде дроби в штамп чертежа?

3 - как в наименовании чертежа разместить 2 надписи одна под другой?
S.ksOpenStamp();
ksDynamicArray DynamicArray = (ksDynamicArray)kompas.GetDynamicArray((short)StructType2DEnum.ko_TextLineParam);

S.ksSetStampColumnText(1, DynamicArray); - в SDK есть такая вот функция, но сколько я с ней не бился она пока показывает 0. Возможно не верно указываю параметры

Дробь можно прочитать и записать одной строкой с использованием управляющих символов.
http://forum.ascon.ru/index.php/topic,23519.msg165572.html#msg165572
S:='Лист$dБ-60х3000х7000 ГОСТ 19903-74;12Х2НМФА-2-а ГОСТ 11269-76$';
Работу с текстом можете посмотреть в примерах: Step3, Step3a и Step5.

Две надписи одна над другой.
http://forum.ascon.ru/index.php/topic,903.msg4521.html#msg4521
+ Благодарностей: 1

Alex152

Большое спасибо! все работает! :)

Alex152

Доброго времени суток! Народ вновь нужна ваша профессиональная помощь!!
Продолжаю работать над своей программой, столкнулся вот с такой интересной проблемой.
С помощью KGAX просматриваю чертежи которые находятся у меня в базе. Для этого, для каждого чертежа  создаю ,новую форму с axKGAX. И там открываю. см. код ниже. Вроде все работает. НО!!! Когда параллельно с программой включен Компас, начинаются проблемы, а именно - пропадают функция закладок в Окно-> Показать закладки. А так же чертежи могут открыться не в просмотровом окне а в компасе. И так же при просмотре окон ( Окно-> Все окна ) тоже в компасе можно открыть просматриваемый документ.
А этого ни как нельзя допустить, потому что часть документов может находиться в утвержденном архиве и все изменения должны быть только через извещение.

1. Отсюда вопрос!!!! Как можно AxKGAX присвоить новый процесс kompas.exe, что бы  AxKGAX не цеплялся к уже открытому компасу, а работал в своем! А после закрытия все окон я бы его закрывал!

2. А так же хочу узнать у меня не работает MoveViewDocument(); для того что бы перемещать документ, как правильно его объявить??
Например ZoomEntireDocument() прекрасно отрабатывает при двойном нажатии мышки!

Жду ваших предложений!!

        public List<Form> _MasiveForm = new List<Form>();
        public List<string> _MasiveAxKGAX = new List<string>();
        public Form[] ViewForm = new Form[10];
        AxKGAXLib.AxKGAX[] axKGAX1 = new AxKGAXLib.AxKGAX[10];
        public int i = 0;
        public void CreateViewForm(int i,string NameForm, string TextForm, string NameFile, string extension)
        {
            if (!File.Exists(Set.Dir + @"\" + NameFile.Trim() + extension))
            {
                MessageBox.Show("Документ " + TextForm + " не обнаружен в архиве КД. Проверьте в Параметрах указанный путь к архиву");
                return;
            }
            i = _MasiveForm.Count;   
             ViewForm = new Form();
             axKGAX1 = new AxKGAXLib.AxKGAX();
            //------------------------------------------------
            //KompasObject k = axKGAX1.GetKompasObject();
            ViewForm.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             ViewForm.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
             ViewForm.Name = NameForm;
             ViewForm.Text = TextForm;
             ViewForm.Height = (System.Windows.Forms.Screen.GetWorkingArea(this).Height); // высота формы во весь экран
             ViewForm.StartPosition = FormStartPosition.CenterScreen; //Центровка по экрану
             ViewForm.Width = (System.Windows.Forms.Screen.GetWorkingArea(this).Width) / 2; // ширина формы
             ViewForm.FormClosed += new System.Windows.Forms.FormClosedEventHandler(ViewForm_FormClosed);
             ViewForm.ResumeLayout(false);
             ViewForm.Enabled = true;
             ViewForm.Visible = true;
             ViewForm.Show();           
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm1));
            ((System.ComponentModel.ISupportInitialize)(axKGAX1)).BeginInit();
            ViewForm.SuspendLayout();
            axKGAX1.Dock = System.Windows.Forms.DockStyle.Top;
            axKGAX1.Size = new System.Drawing.Size(ViewForm.Height - 100, ViewForm.Width);
            //--------------------------------------------------------------------------------------------------
             axKGAX1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top
             | System.Windows.Forms.AnchorStyles.Bottom)
             | System.Windows.Forms.AnchorStyles.Left)
             | System.Windows.Forms.AnchorStyles.Right))); // Описание формы axKGAX на новой создаваемой панели
            //---------------------------------------------------------------------------------------------------         
            axKGAX1.Enabled = true;
            axKGAX1.Location = new System.Drawing.Point(0, 0);
            axKGAX1.Name = "axKGAX1" + Convert.ToString(i);
            axKGAX1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axKGAX1.OcxState")));             
            axKGAX1.TabIndex = 0;           
            ViewForm.Controls.Add(axKGAX1);           
            axKGAX1.DocumenFileName = Set.Dir + @"\" + NameFile .Trim() + extension;
            //axKGAX1.MoveViewDocument();
            axKGAX1.OnKgMouseDblClick += new AxKGAXLib._DKGAXEvents_OnKgMouseDblClickEventHandler(axKGAX1_OnKgMouseDblClick);
            ((System.ComponentModel.ISupportInitialize)(axKGAX1)).EndInit();
            _MasiveForm.Add(ViewForm);
            _MasiveAxKGAX.Add(axKGAX1.Name.ToString());
            Data_str.Value.Clear();
            i++;
    }
        private void axKGAX1_OnKgMouseDblClick(object sender, AxKGAXLib._DKGAXEvents_OnKgMouseDblClickEvent e)
        {
            AxKGAXLib.AxKGAX ax = sender as AxKGAXLib.AxKGAX;
            for (int i = 0; i < _MasiveAxKGAX.Count; i++)
            {
                if (_MasiveAxKGAX.ToString() == ax.Name.ToString())
                {
                    axKGAX1.ZoomEntireDocument();
                    return;
                }
            }           
        }

Slaviation

ЦитироватьДля этого, для каждого чертежа  создаю ,новую форму с axKGAX. И там открываю
Может для просмотра документа достаточно его отрисовать через KompasObject::ksDrawKompasDocument на простой панельке?

Alex152

#5
Да наверно вы правы,я тоже уже об этом думал!
Порывшись здесь, на форуме, давно уже нашел пример отрисовки фрагмента компаса на панельке, ее выложил участник - Sabahs.
Но я ни как ее не могу реализовать у себя на c#. Подскажите что делаю не так???
Мои действия:
  Создаю простую форму на нее кидаю Panel1.
   При загрузки формы открываю компас!
   Создаю поле его Handle передаю функции ksDrawKompasDocument,
   ksDrawKompasDocument отдает 1 - значит отработало удачно.
  Но изображение на панели не отображается.

       [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern IntPtr SetParent(IntPtr hWndChild, // handle to window
                                                             IntPtr hWndNewParent // new parent window);
        KompasObject kompas;
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern bool ShowWindow(int hWnd, int nCmdShow);
        Panel Pole;
        private void Form1_Load(object sender, EventArgs e)
        {
           Pole = new Panel();
           Pole.Visible = true;
           SetParent(Pole.Handle, panel1.Handle);
            //Pole.Parent = panel1;
           Type t = Type.GetTypeFromProgID("KOMPAS.Application.5");
           kompas = (KompasObject)Activator.CreateInstance(t);
           //kompas.Visible = false;
           ShowWindow(kompas.ksGetHWindow(), 0);
           kompas.ksDrawKompasDocument((int)Pole.Handle, "d:\\Фрагмент.frw");                       
        }

#6
Потому, что у меня прорисовка реализована в событии WM_PAINT панели.

PS. Хорошая штука отладчик, один рас увидел и все вопросы отпали.
+ Благодарностей: 1

Alex152

Точно! А я и не подумал! Большое спасибо!
Поместил ksDrawKompasDocument в panel_Paint и сразу показывает!

        private void panel_Paint(object sender, PaintEventArgs e)
        {
           kompas.ksDrawKompasDocument((int)Pole.Handle, "d:\\101-10.06.01.00.01.cdw");
        }

Но тут возникает другой вопрос, а можно ли отрисованый чертеж на панели приближать и отдалять как это дает kgax??
А это очень необходимо при просмотре чертежа, особенно больших форматов!
+ Благодарностей: 1

Можно, kgax.DrawToDC - отрисовать документ на заданном HDC.

Alex152

Добрый день!
Очень понравилась функция ksDrawKompasDocument, на Panel все вырисовываться! для того что бы увеличить документ, воспользовался обычным масштабированием Panel. Увеличивает без снижения качества документа.
Но тут опять столкнулся с проблемкой. На Panel при вызове функции ksDrawKompasDocument, вырисовываться только 1 лист документа, а последующие скрыты.
Сколько листов в документе я могу узнать  int i = doc.ksGetDocumentPagesCount();
А как можно указать что бы  ksDrawKompasDocument отрисовывал лист 2, лист 3 и т.д. даже допускается выводить их по отдельности.

Конечно данную проблему можно решить и другим способом, например перевести документ в картинку
doc.SaveAsToRasterFormat("D:\\ДСК200-01.02.00.000 Модуль дробления.jpg", Param); и просматривать все его листы. Но хотелось бы обойтись без этого.

Использовать функцию в сообщении выше, не пробовали?
По идеи расширенный аналог функции ksDrawKompasDocument.

Alex152

Пробовал! Но ни чего не получилось! Поэтому и вернулся к  ksDrawKompasDocument.
Что сделал!
Добавил на форму KGAX, при загрузке формы указал файл axKGAX1.DocumenFileName = "d:\\KD000234.spw";
И прошу его отрисовать

bool r = axKGAX1.DrawToDC((int)Pole.Handle, 0, 0, 100, 100); - все время выдает false!

Согласно справки
(int)Pole.Handle - указатель окна где отрисовать.

0, 0, 100, 100 -  координаты окна первые 2 цифр, высота и ширина - 2цифры   

Подскажите, пожалуйста что не так у меня?

Координаты в функции это прямоугольник в координатах прорисовываемого документа, а Pole.Handle возможно нужно будет заменить на GetDC(Pole.Handle).

Alex152

Добрый день. функция DrawToDC, начала частично работать! но какие бы координаты прямоугольника не задавал выдает только один кусок чертежа см. фото
     
[System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern IntPtr GetDC(IntPtr hWnd);
        bool _ok = false;

        private void Form1_Load(object sender, EventArgs e)
        {
            axKGAX1.DocumenFileName = "D:\\KD000283.cdw";
        }
        private void button1_Click(object sender, EventArgs e)
        {
            _ok = true;
            panel1.Refresh();
        }
        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            if (_ok == true)
            {
                IntPtr Pole = GetDC(panel1.Handle);
                axKGAX1.ZoomEntireDocument();
                axKGAX1.DrawToDC((int)Pole, 0, 0, 1500, 1500); // странно прорисовка в панель идет но она все равно выдает false
            }
        }
Если DrawToDC расширенный аналог функции ksDrawKompasDocument, то как им управлять? Всего то надо приблизить, отдалить, показать документ со всеми листами.
Самое плохое что мне приходиться загружать на форму  axKGAX1, а с ним Компас ведет себя неадекватно.

Если так axKGAX1.DrawToDC((int)Pole, 1500, 1500, 3000, 3000); тоже этот же кусок рисует.

Alex152

Если задать axKGAX1.DrawToDC((int)Pole, 1500, 1500, 3000, 3000);
То изображения нет т.к. оно за полем формы
первые 2 цифры задают координаты точки вставки посмотрите фото я задал там  axKGAX1.DrawToDC((int)Pole, 50, 50, 3000, 3000);
смещение от верхнего левого угла поля панели на 50 мм !!
При заданном 3000, 3000 квадрате участок который был ранее только увеличился.

#16
Да  axKGAX1.DrawToDC работает не так, как написано в справке, да компонент TKGAX работает ниже плинтуса.
Много листовой документ можно вывести, но с потерей оформления листов, что то там намутили.
PS. TKGAX - не использовался, открыть для просмотра можно только фрагмент или чертёж, для этого нужно сделать двойной щелчок мышью по форме.

Alex152

Да!! без рамки так не пойдет, он еще и т.т. скрывает!
Спасибо!
Вернусь к старому варианту - одиночные документы буду через  ksDrawKompasDocument (жаль что он не может отдельно показать 2 лист)
А все остальные преобразовывать в картинки и показывать отдельно!

Bordes

Просто для интереса: а почему имено в картинки, а не в PDF (через конвертер КОМПАС) или в xps (через специальную печать на XPS Writer) ?  Прим. - Печать нужна именно специальная, чтобы закатать листы с разным форматом в 1 xps файл.

Alex152

Bordes да я именно так и сделал!
Весь просмотр организован через ПДФ, с ним все гораздо проще, чем с картинками, сразу не догадался!