Как написать свою графическую библиотеку

13 / 13 / 5

Регистрация: 29.06.2011

Сообщений: 85

1

Как написать графическую библиотеку?

09.07.2011, 17:28. Показов 9424. Ответов 24


Есть много графических библиотек(MFC, VCL, WxWidgets). А как можно создать свою(хотя-бы примитивную)???

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Эксперт С++

3211 / 1459 / 73

Регистрация: 09.08.2009

Сообщений: 3,441

Записей в блоге: 2

09.07.2011, 18:06

2

Цитата
Сообщение от Плутон
Посмотреть сообщение

А как можно создать свою(хотя-бы примитивную)???

как обычно. с помощью клавиатуры и рук



0



13 / 13 / 5

Регистрация: 29.06.2011

Сообщений: 85

09.07.2011, 18:54

 [ТС]

3

Ну а с чего начать, как организовать? И вообще примеры или исходники есть у кого-нибудь(на форуме или вообще)?



0



Каратель

Эксперт С++

6607 / 4026 / 401

Регистрация: 26.03.2010

Сообщений: 9,273

Записей в блоге: 1

10.07.2011, 02:45

4

Цитата
Сообщение от Плутон
Посмотреть сообщение

графических библиотек

это библиотеки по работе с графикой, а вы перечислили

Цитата
Сообщение от Плутон
Посмотреть сообщение

MFC, VCL, WxWidgets

библиотеки визуальных компонентов

Цитата
Сообщение от Плутон
Посмотреть сообщение

Ну а с чего начать, как организовать? И вообще примеры или исходники есть у кого-нибудь(на форуме или вообще)?

не берети дурного в голову и тяжелого в руки, оно вам надо? если вы задаете такие вопросы на форуме, значит вы еще очень мало знаете, и вам еще стоит подучится



1



-=ЮрА=-

Заблокирован

Автор FAQ

10.07.2011, 10:47

5

Лучший ответ Сообщение было отмечено как решение

Решение

В С++ уже всё написано, для консоли вот так юзать

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CRect Rect;
        GetWindowRect(hWnd,&Rect);
 
        HDC hDC = GetWindowDC(hWnd);
        if(hDC)
        {
            SetBkMode(hDC,TRANSPARENT);
            SetTextColor(hDC,BLK);
            SelectObject(hDC,WHT_PEN);
            Rectangle(hDC,
                5,
                100,
                Rect.right - Rect.left - 25,
                Rect.bottom - Rect.top - 10);
            SelectObject(hDC,BLK_PEN);
//...Дальше твой полёт фантазии

Миниатюры

Как написать графическую библиотеку?
 

Вложения

Тип файла: rar shema.exe.rar (3.5 Кб, 72 просмотров)



3



13 / 13 / 5

Регистрация: 29.06.2011

Сообщений: 85

10.07.2011, 10:48

 [ТС]

6

Спасибо!



0



-=ЮрА=-

Заблокирован

Автор FAQ

10.07.2011, 10:51

7

Если есть желание поиздеваться над рабочим столом вот

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "iostream.h"
#include "windows.h"
 
int main(int argc, char* argv[])
{
    HWND hWnd = GetDesktopWindow();
    HDC hDC = GetWindowDC(hWnd);
    int i;
    cin >> i;
    HPEN hPen = CreatePen(PS_SOLID,4,RGB(255,0,0));
    SelectObject(hDC,hPen);
    TextOut(hDC,150,10,"YurA",10);
    Ellipse(hDC,-100,-100,100,100);
    return 0;
}

Введи любое число и посмотри что будет на рабочем столе, не бойся при обновлении стола всё проходит



1



Freelance

Эксперт С++

2887 / 1822 / 356

Регистрация: 09.09.2010

Сообщений: 3,841

10.07.2011, 13:49

8

Цитата
Сообщение от -=ЮрА=-
Посмотреть сообщение

В С++ уже всё написано

Это же WinAPI, не ? Как оно может быть напсаное в С++`се ?



0



бжни

2473 / 1684 / 135

Регистрация: 14.05.2009

Сообщений: 7,162

10.07.2011, 14:02

9

Цитата
Сообщение от asics
Посмотреть сообщение

Это же WinAPI, не ? Как оно может быть напсаное в С++`се ?

есть подозрение, что

Цитата
Сообщение от Плутон
Посмотреть сообщение

(MFC, VCL, WxWidgets)

тоже используют для отрисовки winapi



0



Freelance

Эксперт С++

2887 / 1822 / 356

Регистрация: 09.09.2010

Сообщений: 3,841

10.07.2011, 14:52

10

alex_x_x, Это вы к чему ?



0



Эксперт С++

5053 / 3114 / 271

Регистрация: 11.11.2009

Сообщений: 7,045

10.07.2011, 15:03

11

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



0



13 / 13 / 5

Регистрация: 29.06.2011

Сообщений: 85

10.07.2011, 16:12

 [ТС]

12

Ну конечно они используют winapi, что они ещё будут использовать?



0



-=ЮрА=-

Заблокирован

Автор FAQ

10.07.2011, 16:17

13

с каких пор console aplication стало винапи???



0



Freelance

Эксперт С++

2887 / 1822 / 356

Регистрация: 09.09.2010

Сообщений: 3,841

10.07.2011, 16:18

14

Цитата
Сообщение от Плутон
Посмотреть сообщение

Ну конечно они используют winapi,

Исходя из этих слов и выплывает ответ на ваш вопрос:

Цитата
Сообщение от Плутон
Посмотреть сообщение

А как можно создать свою



0



13 / 13 / 5

Регистрация: 29.06.2011

Сообщений: 85

10.07.2011, 16:20

 [ТС]

15

Ну вот и хорошо



0



Freelance

Эксперт С++

2887 / 1822 / 356

Регистрация: 09.09.2010

Сообщений: 3,841

10.07.2011, 16:21

16

Цитата
Сообщение от -=ЮрА=-
Посмотреть сообщение

с каких пор console aplication стало винапи???

По-вашему winapi это только формашлепство, а если мы апишные функции используем в консоли, то это уже не винапи ? Тогда что это ?



0



13 / 13 / 5

Регистрация: 29.06.2011

Сообщений: 85

10.07.2011, 16:22

 [ТС]

17

Кстати, Юра, ваш первый пример на Win7 не работает)))((((

Добавлено через 35 секунд

Цитата
Сообщение от asics
Посмотреть сообщение

Сообщение от -=ЮрА=-
с каких пор console aplication стало винапи???
По-вашему winapi это только формашлепство, а если мы апишные функции используем в консоли, то это уже не винапи ? Тогда что это ?

Вот-вот.



0



бжни

2473 / 1684 / 135

Регистрация: 14.05.2009

Сообщений: 7,162

10.07.2011, 18:01

18

ну формально консольным может быть и .net приложение



0



-=ЮрА=-

Заблокирован

Автор FAQ

10.07.2011, 18:26

19

Плутон, понятное дело что на 7-ке мало приложений работает, особо если платформа 64-я…

По-вашему winapi это только формашлепство, а если мы апишные функции используем в консоли, то это уже не винапи ? Тогда что это ?

Тоже самое можно сказать об MFC!Если уж так вдаваться вглубь любое приложение — это лишь скомпилированный набор непосредственных директив процессору, тогда уже точней будет что не на апи или консоли или МФЦ делаем проекты, а на основе асамблера, какое это вообще отношение имеет к указанной тематике?



0



бжни

2473 / 1684 / 135

Регистрация: 14.05.2009

Сообщений: 7,162

10.07.2011, 18:36

20

Цитата
Сообщение от -=ЮрА=-
Посмотреть сообщение

Тоже самое можно сказать об MFC!Если уж так вдаваться вглубь любое приложение — это лишь скомпилированный набор непосредственных директив процессору, тогда уже точней будет что не на апи или консоли или МФЦ делаем проекты, а на основе асамблера, какое это вообще отношение имеет к указанной тематике?

такое, что абстрагированное от железа ПО обязано работать через некоторую прослойку API, в данном случае WinApi



0



Example image created with this library

363908/ezdib.png

Limited resource examples

363908/ezdib_mono_dotmatrix.png

Downloads

  • Download ezdib.zip — 28.6 KB
  • Repository

Introduction

I am always needing to add simple graphics output to console,
services, embedded, or other applications that do not have natural
graphics ability for debugging purposes. So I have brought together
several functions to make this easy.

In this article I will provide code and explanation for a simple graphics
library that can perform in the most limited circumstances.

So features of this library that I believe will make it unique and worthwhile will be…

  • Usable in C and C++.
  • Be small and contained entirely in two files,
    Namely ezdib.h and ezdib.c.
    Just drop them in and go.
  • Support saving dib (.bmp) files.
  • Provide basic functions for drawing pixels, circles, rectangles, fills, text,
    as well as raw buffer access. You can tell from the image provided much of what
    is possible.
  • Be completely self-contained. This includes the font functions and fonts.
  • Be easy to customize and extend, including adding new fonts.

Creating a blank image.

The ezd_create() functions allocates the memory for the image and returns
all the image details opaquely behind a handle of type HEZDIMAGE. The following
code creates a 640 x 480 image using 24 bits per pixel. This library is only
supporting 1, 24 and 32 bit pixel depths. I believe this provides good functionality
without compromising simplicity.

Notice the negative height. Somewhere in the distant past, someone decided
to store Windows images upside down. Using a negative height will cause the images to
be stored in memory right side up. All functions in this library will work just fine
either way, but be aware that coordinates on the Y axis will be reversed depending on
which way you choose to go.

HEZDIMAGE hDib = ezd_create( 640, -480, 24 );

ezd_fill( hDib, 0x606060 );

ezd_save( hDib, "test.bmp" );

ezd_destroy( hDib );

Drawing and text functions.

I have attempted to keep these functions as simple as possible while
still keeping them reasonably fast. My hope is that you can look at these
functions and easily understand what’s going on and have no problems adding
your own functionality.

Line drawing is implemented using incremental division or
Bresenham’s Line Algorithm.
The flood fill is a simple four directional fill.
The rest aren’t interesting enough to mention, but all the details are in the code ;)

ezd_line( hDib, 100, 100, 200, 200, 0x00ff00 ),

ezd_fill_rect( hDib, 300, 200, 350, 280, 0xffff00 );

ezd_set_pixel( hDib, 50, 50, 0xffffff );

ezd_rect( hDib, 50, 50, 100, 100, 0x000000 );

ezd_circle( hDib, 100, 100, 10, 0x000000 );

ezd_flood_fill( hDib, 100, 100, 0x000000, 0x808080 );

Probably the most interesting of the drawing functions is the text functions.
The following code exemplifies creating a font and drawing text into the image.

HEZDFONT hFont = ezd_load_font( EZD_FONT_TYPE_MEDIUM, 0, 0 );

ezd_text( hDib, hFont, "Hello World!", -1, 10, 10, 0xffffff );

ezd_destroy_font( hFont );

The fonts are in a very simple raster based format. Only 8 bit ASCII
characters are supported. The format is outlined below.

| [character] | [width] | [height] | [bitmap] ~ |
  • character — One byte representing the glyph character
  • width — One byte specifies the character width in bits
  • height — One byte specifies the character height in bits
  • bitmap — One bit per pixel bitmap padded to one byte

Here is an exert from an actual font definition. You can simply pass a
pointer to the byte array to the ezd_load_font() function. If
EZD_STATIC_FONTS is not defined, ezd_load_font() will copy
the font table, index the glyphs, and return a handle. If EZD_STATIC_FONTS
is defined, the function will simply return the pointer you passed in, cast
to type HEZDFONT.

static const unsigned char my_font [] =
{
		'.', 1, 6,	0x08,

		't', 8, 0,

		' ', 3, 0,

	'!', 1, 6,	0xea,
	'@', 4, 6,	0x69, 0xbb, 0x87,
	'#', 5, 6,	0x57, 0xd5, 0xf5, 0x00,
	'$', 5, 6,	0x23, 0xe8, 0xe2, 0xf8,
	...

	'0', 3, 6,	0x56, 0xd4, 0x31,
	'1', 2, 6,	0xd5, 0x42,
	'2', 4, 6,	0xe1, 0x68, 0xf0,
	...

	'A', 4, 6,	0x69, 0xf9, 0x90,
	'B', 4, 6,	0xe9, 0xe9, 0xe0,
	'C', 4, 6,	0x78, 0x88, 0x70,
	...
};

...

HEZDFONT hFont = ezd_load_font( my_font, 0, 0 );

Embedded systems

I have added several features to specifically address the issues faced
by embedded designs. This library may still be a bit beefy for a tiny 8051
system, but as long as you have a reasonable system, you should be able to
squeeze this library in. If you enable all the following macros, you will
basically be left with a pure C implementation.

The following macros are explained in ezdib.c and can
be defined there, although, good practices would probably be to define these
in your make or project files.

#define EZD_STATIC_FONTS

Defining this macro will eliminate the glyph indexing. This means that
font rendering may be slightly slower, but no extra memory will have to be
allocated.

#define EZD_NO_MEMCPY

If you don’t have string.h, you can enable this macro and the library
will use internal substitutes for memcpy and memset.
These will probably be a bit slower of course.

#define EZD_NO_ALLOCATION

You can enable this macro to disable the use of
malloc, calloc, and free.
You will then need to pass in static buffers using ezd_initialize()
and ezd_set_image_buffer(). The EZD_HEADER_SIZE
macro will indicate the minimum space needed for the image header.
See the code below.

const int w = 320, h = 240;
char user_header[ EZD_HEADER_SIZE ];
char user_image_buffer[ w * h / 8 ];

hDib = ezd_initialize( user_header, sizeof( user_header ), w, -h, 1,
                           EZD_FLAG_USER_IMAGE_BUFFER );
if ( !hDib )
    return -1;

if ( !ezd_set_image_buffer( hDib, user_image_buffer, sizeof( user_image_buffer ) ) )
    return -1;

#define EZD_NO_FILES

You’re embedded system may not support or even have a file system. Use this
macro to disable file system output.

#define EZD_NO_MATH

If you don’t have math.h. This is used by the circle drawing
functions.

Monochrome images / one bit per pixel color depths.

This library also supports one bit per pixel color depths. So if you’re stuck
with a monochrome LCD display, and can afford the space for a back buffer, you can
use this mode to render images. Maybe if you’re memory mapped you can render
straight to the device using ezd_set_image_buffer().

Example rendered to a monochrome image

363908/ezdib_mono.png

Unbuffered graphics output

What about the worst case scenario. You have a tiny processor with no space
for a back buffer. Or maybe you just want to use some type of serial display
device, like a dot matrix screen.

As long as you can provide a ‘set pixel’ function that takes the X and Y coords,
a color, and render it. You can use this library.

Here’s an example that uses a custom set pixel function to emulate a dot matrix
display.

typedef struct _SDotMatrixData
{
    int w;
    int h;
    HEZDIMAGE pDib;
} SDotMatrixData;

int dotmatrix_writer( void *pUser, int x, int y, int c, int f )
{
    HEZDIMAGE hDib = (HEZDIMAGE)pUser;
    if ( !hDib )
        return 0;

    ...

    return 1;
}

SDotMatrixData dmd;
const int w = 640, h = 480;
HEZDIMAGE hDmd;

printf( "Creating dotmatrix.bmpn" );

hDmd = ezd_create( w, -h, 24, 0 );
if ( !hDmd )
    return -1;

ezd_fill( hDmd, 0 );

hDib = ezd_create( w, -h, 1, EZD_FLAG_USER_IMAGE_BUFFER );
if ( !hDib )
    return -1;

ezd_set_pixel_callback( hDib, &dotmatrix_writer, hDmd );

...

Example ‘dot matrix device’ output

363908/ezdib_dotmatrix.png

Unbuffered ASCII output

As a final fun example, here’s a complete program that implements a set pixel
function that renders the output to an ASCII string buffer.

typedef struct _SAsciiData
{
    int sw;
    unsigned char *buf;
} SAsciiData;

int ascii_writer( void *pUser, int x, int y, int c, int f )
{
    SAsciiData *p = (SAsciiData*)pUser;
    if ( !p )
        return 0;

    unsigned char ch = (unsigned char)( f & 0xff );
    if ( ( '0' <= ch && '9' >= ch )
         || ( 'A' <= ch && 'Z' >= ch )
         || ( 'a' <= ch && 'z' >= ch ) )

                p->buf[ y * p->sw + x ] = (unsigned char)f;

    else

                p->buf[ y * p->sw + x ] = (unsigned char)c;

    return 1;
}

int main( int argc, char* argv[] )
{
    int b, x, y;
    HEZDIMAGE hDib;
    HEZDFONT hFont;
    SAsciiData ad;
    const int w = 44, h = 20;
    char ascii[ ( w + 1 ) * h + 1 ];
    char user_header[ EZD_HEADER_SIZE ];

    hDib = ezd_initialize( user_header, sizeof( user_header ),
                                   w, -h, 1, EZD_FLAG_USER_IMAGE_BUFFER );
    if ( !hDib )
        return -1;

        ascii[ ( w + 1 ) * h ] = 0;

        for ( y = 0; y < h - 1; y++ )
        ascii[ y * ( w + 1 ) + w ] = 'n';

        ad.sw = w + 1; ad.buf = ascii;
    ezd_set_pixel_callback( hDib, &ascii_writer, &ad );

        ezd_fill( hDib, ' ' );

        ezd_rect( hDib, 0, 0, w - 1, h - 1, '.' );

        ezd_circle( hDib, 30, 10, 8, 'o' );

        ezd_arc( hDib, 30, 10, 5, 0.6, 2.8, '-' );

        ezd_set_pixel( hDib, 28, 8, 'O' );
    ezd_set_pixel( hDib, 32, 8, 'O' );

        ezd_line( hDib, 30, 10, 30, 11, '|' );

        hFont = ezd_load_font( EZD_FONT_TYPE_SMALL, 0, 0 );
    if ( hFont )
        ezd_text( hDib, hFont, "ThenEnd", -1, 4, 4, '#' );

    if ( hFont )
        ezd_destroy_font( hFont );

    if ( hDib )
        ezd_destroy( hDib );

        printf( "%sn", ascii );

    return 0;
}
............................................
.                                          .
.                             o            .
.                          ooooooo         .
.   TTT  h  h  eeee      oo       oo       .
.    T   h  h  e        oo         oo      .
.    T   hhhh  eee      o           o      .
.    T   h  h  e       o             o     .
.    T   h  h  eeee    o    O   O    o     .
.                      o             o     .
.                     oo      |      oo    .
.   EEEE  n  n  ddd    o      |      o     .
.   E     nn n  d  d   o  -       -  o     .
.   EEE   n nn  d  d   o   -     -   o     .
.   E     n  n  d  d    o   -----   o      .
.   EEEE  n  n  ddd     oo         oo      .
.                        oo       oo       .
.                          ooooooo         .
.                             o            .
............................................

Wishlist

I hope you find the code useful and flexible. Some things I’d like
to add to the project would be.

  • AVI, animated gif, or other video output.
  • Font editing script, maybe written in javascript? The one I used for
    creating these fonts is a bit cumbersome.

This member has not yet provided a Biography. Assume it’s interesting and varied, and probably something to do with programming.

Example image created with this library

363908/ezdib.png

Limited resource examples

363908/ezdib_mono_dotmatrix.png

Downloads

  • Download ezdib.zip — 28.6 KB
  • Repository

Introduction

I am always needing to add simple graphics output to console,
services, embedded, or other applications that do not have natural
graphics ability for debugging purposes. So I have brought together
several functions to make this easy.

In this article I will provide code and explanation for a simple graphics
library that can perform in the most limited circumstances.

So features of this library that I believe will make it unique and worthwhile will be…

  • Usable in C and C++.
  • Be small and contained entirely in two files,
    Namely ezdib.h and ezdib.c.
    Just drop them in and go.
  • Support saving dib (.bmp) files.
  • Provide basic functions for drawing pixels, circles, rectangles, fills, text,
    as well as raw buffer access. You can tell from the image provided much of what
    is possible.
  • Be completely self-contained. This includes the font functions and fonts.
  • Be easy to customize and extend, including adding new fonts.

Creating a blank image.

The ezd_create() functions allocates the memory for the image and returns
all the image details opaquely behind a handle of type HEZDIMAGE. The following
code creates a 640 x 480 image using 24 bits per pixel. This library is only
supporting 1, 24 and 32 bit pixel depths. I believe this provides good functionality
without compromising simplicity.

Notice the negative height. Somewhere in the distant past, someone decided
to store Windows images upside down. Using a negative height will cause the images to
be stored in memory right side up. All functions in this library will work just fine
either way, but be aware that coordinates on the Y axis will be reversed depending on
which way you choose to go.

HEZDIMAGE hDib = ezd_create( 640, -480, 24 );

ezd_fill( hDib, 0x606060 );

ezd_save( hDib, "test.bmp" );

ezd_destroy( hDib );

Drawing and text functions.

I have attempted to keep these functions as simple as possible while
still keeping them reasonably fast. My hope is that you can look at these
functions and easily understand what’s going on and have no problems adding
your own functionality.

Line drawing is implemented using incremental division or
Bresenham’s Line Algorithm.
The flood fill is a simple four directional fill.
The rest aren’t interesting enough to mention, but all the details are in the code ;)

ezd_line( hDib, 100, 100, 200, 200, 0x00ff00 ),

ezd_fill_rect( hDib, 300, 200, 350, 280, 0xffff00 );

ezd_set_pixel( hDib, 50, 50, 0xffffff );

ezd_rect( hDib, 50, 50, 100, 100, 0x000000 );

ezd_circle( hDib, 100, 100, 10, 0x000000 );

ezd_flood_fill( hDib, 100, 100, 0x000000, 0x808080 );

Probably the most interesting of the drawing functions is the text functions.
The following code exemplifies creating a font and drawing text into the image.

HEZDFONT hFont = ezd_load_font( EZD_FONT_TYPE_MEDIUM, 0, 0 );

ezd_text( hDib, hFont, "Hello World!", -1, 10, 10, 0xffffff );

ezd_destroy_font( hFont );

The fonts are in a very simple raster based format. Only 8 bit ASCII
characters are supported. The format is outlined below.

| [character] | [width] | [height] | [bitmap] ~ |
  • character — One byte representing the glyph character
  • width — One byte specifies the character width in bits
  • height — One byte specifies the character height in bits
  • bitmap — One bit per pixel bitmap padded to one byte

Here is an exert from an actual font definition. You can simply pass a
pointer to the byte array to the ezd_load_font() function. If
EZD_STATIC_FONTS is not defined, ezd_load_font() will copy
the font table, index the glyphs, and return a handle. If EZD_STATIC_FONTS
is defined, the function will simply return the pointer you passed in, cast
to type HEZDFONT.

static const unsigned char my_font [] =
{
		'.', 1, 6,	0x08,

		't', 8, 0,

		' ', 3, 0,

	'!', 1, 6,	0xea,
	'@', 4, 6,	0x69, 0xbb, 0x87,
	'#', 5, 6,	0x57, 0xd5, 0xf5, 0x00,
	'$', 5, 6,	0x23, 0xe8, 0xe2, 0xf8,
	...

	'0', 3, 6,	0x56, 0xd4, 0x31,
	'1', 2, 6,	0xd5, 0x42,
	'2', 4, 6,	0xe1, 0x68, 0xf0,
	...

	'A', 4, 6,	0x69, 0xf9, 0x90,
	'B', 4, 6,	0xe9, 0xe9, 0xe0,
	'C', 4, 6,	0x78, 0x88, 0x70,
	...
};

...

HEZDFONT hFont = ezd_load_font( my_font, 0, 0 );

Embedded systems

I have added several features to specifically address the issues faced
by embedded designs. This library may still be a bit beefy for a tiny 8051
system, but as long as you have a reasonable system, you should be able to
squeeze this library in. If you enable all the following macros, you will
basically be left with a pure C implementation.

The following macros are explained in ezdib.c and can
be defined there, although, good practices would probably be to define these
in your make or project files.

#define EZD_STATIC_FONTS

Defining this macro will eliminate the glyph indexing. This means that
font rendering may be slightly slower, but no extra memory will have to be
allocated.

#define EZD_NO_MEMCPY

If you don’t have string.h, you can enable this macro and the library
will use internal substitutes for memcpy and memset.
These will probably be a bit slower of course.

#define EZD_NO_ALLOCATION

You can enable this macro to disable the use of
malloc, calloc, and free.
You will then need to pass in static buffers using ezd_initialize()
and ezd_set_image_buffer(). The EZD_HEADER_SIZE
macro will indicate the minimum space needed for the image header.
See the code below.

const int w = 320, h = 240;
char user_header[ EZD_HEADER_SIZE ];
char user_image_buffer[ w * h / 8 ];

hDib = ezd_initialize( user_header, sizeof( user_header ), w, -h, 1,
                           EZD_FLAG_USER_IMAGE_BUFFER );
if ( !hDib )
    return -1;

if ( !ezd_set_image_buffer( hDib, user_image_buffer, sizeof( user_image_buffer ) ) )
    return -1;

#define EZD_NO_FILES

You’re embedded system may not support or even have a file system. Use this
macro to disable file system output.

#define EZD_NO_MATH

If you don’t have math.h. This is used by the circle drawing
functions.

Monochrome images / one bit per pixel color depths.

This library also supports one bit per pixel color depths. So if you’re stuck
with a monochrome LCD display, and can afford the space for a back buffer, you can
use this mode to render images. Maybe if you’re memory mapped you can render
straight to the device using ezd_set_image_buffer().

Example rendered to a monochrome image

363908/ezdib_mono.png

Unbuffered graphics output

What about the worst case scenario. You have a tiny processor with no space
for a back buffer. Or maybe you just want to use some type of serial display
device, like a dot matrix screen.

As long as you can provide a ‘set pixel’ function that takes the X and Y coords,
a color, and render it. You can use this library.

Here’s an example that uses a custom set pixel function to emulate a dot matrix
display.

typedef struct _SDotMatrixData
{
    int w;
    int h;
    HEZDIMAGE pDib;
} SDotMatrixData;

int dotmatrix_writer( void *pUser, int x, int y, int c, int f )
{
    HEZDIMAGE hDib = (HEZDIMAGE)pUser;
    if ( !hDib )
        return 0;

    ...

    return 1;
}

SDotMatrixData dmd;
const int w = 640, h = 480;
HEZDIMAGE hDmd;

printf( "Creating dotmatrix.bmpn" );

hDmd = ezd_create( w, -h, 24, 0 );
if ( !hDmd )
    return -1;

ezd_fill( hDmd, 0 );

hDib = ezd_create( w, -h, 1, EZD_FLAG_USER_IMAGE_BUFFER );
if ( !hDib )
    return -1;

ezd_set_pixel_callback( hDib, &dotmatrix_writer, hDmd );

...

Example ‘dot matrix device’ output

363908/ezdib_dotmatrix.png

Unbuffered ASCII output

As a final fun example, here’s a complete program that implements a set pixel
function that renders the output to an ASCII string buffer.

typedef struct _SAsciiData
{
    int sw;
    unsigned char *buf;
} SAsciiData;

int ascii_writer( void *pUser, int x, int y, int c, int f )
{
    SAsciiData *p = (SAsciiData*)pUser;
    if ( !p )
        return 0;

    unsigned char ch = (unsigned char)( f & 0xff );
    if ( ( '0' <= ch && '9' >= ch )
         || ( 'A' <= ch && 'Z' >= ch )
         || ( 'a' <= ch && 'z' >= ch ) )

                p->buf[ y * p->sw + x ] = (unsigned char)f;

    else

                p->buf[ y * p->sw + x ] = (unsigned char)c;

    return 1;
}

int main( int argc, char* argv[] )
{
    int b, x, y;
    HEZDIMAGE hDib;
    HEZDFONT hFont;
    SAsciiData ad;
    const int w = 44, h = 20;
    char ascii[ ( w + 1 ) * h + 1 ];
    char user_header[ EZD_HEADER_SIZE ];

    hDib = ezd_initialize( user_header, sizeof( user_header ),
                                   w, -h, 1, EZD_FLAG_USER_IMAGE_BUFFER );
    if ( !hDib )
        return -1;

        ascii[ ( w + 1 ) * h ] = 0;

        for ( y = 0; y < h - 1; y++ )
        ascii[ y * ( w + 1 ) + w ] = 'n';

        ad.sw = w + 1; ad.buf = ascii;
    ezd_set_pixel_callback( hDib, &ascii_writer, &ad );

        ezd_fill( hDib, ' ' );

        ezd_rect( hDib, 0, 0, w - 1, h - 1, '.' );

        ezd_circle( hDib, 30, 10, 8, 'o' );

        ezd_arc( hDib, 30, 10, 5, 0.6, 2.8, '-' );

        ezd_set_pixel( hDib, 28, 8, 'O' );
    ezd_set_pixel( hDib, 32, 8, 'O' );

        ezd_line( hDib, 30, 10, 30, 11, '|' );

        hFont = ezd_load_font( EZD_FONT_TYPE_SMALL, 0, 0 );
    if ( hFont )
        ezd_text( hDib, hFont, "ThenEnd", -1, 4, 4, '#' );

    if ( hFont )
        ezd_destroy_font( hFont );

    if ( hDib )
        ezd_destroy( hDib );

        printf( "%sn", ascii );

    return 0;
}
............................................
.                                          .
.                             o            .
.                          ooooooo         .
.   TTT  h  h  eeee      oo       oo       .
.    T   h  h  e        oo         oo      .
.    T   hhhh  eee      o           o      .
.    T   h  h  e       o             o     .
.    T   h  h  eeee    o    O   O    o     .
.                      o             o     .
.                     oo      |      oo    .
.   EEEE  n  n  ddd    o      |      o     .
.   E     nn n  d  d   o  -       -  o     .
.   EEE   n nn  d  d   o   -     -   o     .
.   E     n  n  d  d    o   -----   o      .
.   EEEE  n  n  ddd     oo         oo      .
.                        oo       oo       .
.                          ooooooo         .
.                             o            .
............................................

Wishlist

I hope you find the code useful and flexible. Some things I’d like
to add to the project would be.

  • AVI, animated gif, or other video output.
  • Font editing script, maybe written in javascript? The one I used for
    creating these fonts is a bit cumbersome.

This member has not yet provided a Biography. Assume it’s interesting and varied, and probably something to do with programming.

Давно хотел попробовать с нуля создать свою простенькую графическую библиотеку типо OpenGL или там DirectX, исключительно из спортивного интереса(давно интересуюсь этой темой и как то писал простенький рендер трассировкой лучей на java, но сейчас хочу сделать отрисовку в реальном времени). может кто подсказать библиотеки для c++ ну или подскажите куда копать. Одной из целей является отрисовка вращающихся моделек формата obj. По сути, все что нужно от библиотеки-рисование точки заданного центра в заданных координатах, ну или формирование битмапа и его отрисовка целиком

задан 9 апр 2017 в 17:56

Defernus's user avatar

6

Если не смотреть вглубь работы графических карт, не принимать в расчёт шейдера и прочие вещи, которые уже давно написаны и вылизаны до максимальной степени в графических библиотеках аля Direct3D / OpenGL, то можете попытаться писать на WinAPI, рисуя на контексте (HDC). ( Считай это наводкой ). Если хочешь ещё ниже к ядру оси, почитай про GDI и реализуй свой WinAPI.

Впрочем, нет смысла городить велосипеды, когда есть достаточно уже обкатанные рабочие либы, лучше воспользоваться ими. По опыту скажу, рисовал модели Maya ( это те самые *.obj ) и при помощи WinAPI, и при помощи OpenGL, на OpenGL это в разы быстрее.

ответ дан 9 апр 2017 в 21:16

kbsx32's user avatar

kbsx32kbsx32

263 бронзовых знака

Неясно чего вы хотите, что OpenGL что DirectX не являются библиотеками, у них есть одинаковые функции, но по существу они отличаются хотя бы тем, что первый это стандарт по котору программируется графика на разных языка и кроссплатформенно, а второй — DirectX набор библиотек от майкрософта для написания мультимедийного софта.

Одной из целей является отрисовка вращающихся моделек формата obj

Для этого будет вполне достаточно использовать OpenGL 4.x например, парсить .obj файл и применять базовые функции этого API для рисования примитивов, наряду с некоторыми базовыми матричными операциями для всяких пространственных преобразований

А написание своего OpenGL или Direct3D относится к разработке собственного рендера — грубо говоря набора низкоуровневых функций позволящих например, быстро отрисовать линию по какому-нибудь алгоритму или закрасить многоугольник каким-нибудь цветом — тоесть здесь совсем другие вещи применяются, в основном мало связанные с той типичной 3D математикой с которой сталкиваешься при непосредственном использовании OpenGL или Direct3D

Так что определитесь…

ответ дан 9 апр 2017 в 20:14

ampawd's user avatar

ampawdampawd

3,6841 золотой знак14 серебряных знаков29 бронзовых знаков

1

Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Новые комментарии

Большое спасибо. Единственный код который прошел без каких либо ошибок. Ура!!!

Скажите пожалуйста, подскажите алгоритм по которому по заданным точкам можно определить тип многогранника, скажем это куб или прямоугольный параллелепипед. Нашел теорию по этим фигурам:

https://www.mat…
https://www.mat…

Акцентировать внимание…

Всем у кого не работает.
файл wizard.script
Ещё одно упоминание Glut32 в строке
«if (!VerifyLibFile(dir_nomacro_lib, _T(«glut32»), _T(«GLUT’s»))) return false;»
меняем на
«if (!VerifyLibFile(dir_nomacro_lib, _T(«freeglut»), _T(«GLUT’s»))) return…

огромное спасибо за подробное объяснение про 3д графику на питоне, в интернете очень мало подобной информации

Счетчики и рейтинг

Создание собственной графической библиотеки

11. Ноябрь 2014 — 0:15 | admin

Время на прочтение
7 мин

Количество просмотров 384K

Содержание курса

  • Статья 1: алгоритм Брезенхэма
  • Статья 2: растеризация треугольника + отсечение задних граней
  • Статья 3: Удаление невидимых поверхностей: z-буфер
  • Статья 4: Необходимая геометрия: фестиваль матриц
    • 4а: Построение перспективного искажения
    • 4б: двигаем камеру и что из этого следует
    • 4в: новый растеризатор и коррекция перспективных искажений
  • Статья 5: Пишем шейдеры под нашу библиотеку
  • Статья 6: Чуть больше, чем просто шейдер: просчёт теней

Улучшение кода

  • Статья 3.1: Настала пора рефакторинга
  • Статья 3.14: Красивый класс матриц


Official translation (with a bit of polishing) is available here.


Постановка задачи

Цель этого цикла статей — показать, как работает OpenGL, написав его (сильно упрощённый!) клон самостоятельно. На удивление часто сталкиваюсь с людьми, которые не могут преодолеть первоначальный барьер обучения OpenGL/DirectX. Таким образом, я подготовил краткий цикл из шести лекций, после которого мои студенты выдают неплохие рендеры.

Итак, задача ставится следующим образом: не используя никаких сторонних библиотек (особенно графических) получить примерно такие картинки:

Внимание, это обучающий материал, который в целом повторит структуру библиотеки OpenGL. Это будет софтверный рендер, я не ставлю целью показать, как писать приложения под OpenGL. Я ставлю целью показать, как сам OpenGL устроен. По моему глубокому убеждению, без понимания этого написание эффективных приложений с использованием 3D библиотек невозможно.

Я постараюсь не перевалить за 500 строк в конечном коде. Моим студентам требуется от 10 до 20 часов программирования, чтобы начать выдавать подобные рендеры. На вход получаем текстовый файл с полигональной сеткой + картинки с текстурами, на выход отрендеренную модель. Никакого графического интерфейса, запускаемая программа просто генерирует файл с картинкой.

Поскольку целью является минимизация внешних зависимостей, то я даю своим студентам только один класс, позволяющий работать с TGA файлами. Это один из простейших форматов, поддерживающий картинки в формате RGB/RGBA/чёрно-белые. То есть, в качестве отправной точки мы получаем простой способ работы с картинками. Заметьте, единственная функциональность, доступная в самом начале (помимо загрузки и сохранения изображения), это возможность установить цвет одного пикселя.

Никаких функций отрисовки отрезков-треугольников, это всё придётся писать вручную.

Я даю свой исходный код, который пишу параллельно со студентами, но не рекомендую его использовать, в этом просто нет смысла.

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

#include "tgaimage.h"

const TGAColor white = TGAColor(255, 255, 255, 255);
const TGAColor red   = TGAColor(255, 0,   0,   255);

int main(int argc, char** argv) {
        TGAImage image(100, 100, TGAImage::RGB);
        image.set(52, 41, red);
        image.flip_vertically(); // i want to have the origin at the left bottom corner of the image
        image.write_tga_file("output.tga");
        return 0;
}

output.tga должен выглядеть примерно так:

Алгоритм Брезенхэма

Цель первой лекции — сделать рендер в проволочной сетке, для этого нужно научиться рисовать отрезки.
Можно просто пойти и почитать, что такое алгоритм Брезенхэма, но большинство моих студентов буксуют, читая сразу целочисленную версию, поэтому давайте напишем код сами.

Как выглядит простейший код, рисующий отрезок между двумя точками (x0, y0) и (x1, y1)?
Видимо, как-то так:

void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
    for (float t=0.; t<1.; t+=.01) {
        int x = x0*(1.-t) + x1*t;
        int y = y0*(1.-t) + y1*t;
        image.set(x, y, color);
    }
}

Снапшот кода доступен на гитхабе.


Проблема этого кода (помимо эффективности) это выбор константы, которую я взял равной .01.
Если вдруг мы возьмём её равной .1, то наш отрезок будет выглядеть вот так:

Мы легко можем найти нужный шаг: это просто количество пикселей, которые нужно нарисовать.
Простейший (с ошибками!) код выглядит примерно так:

void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
    for (int x=x0; x<=x1; x++) {
        float t = (x-x0)/(float)(x1-x0);
        int y = y0*(1.-t) + y1*t;
        image.set(x, y, color);
    }
}

Осторожно: наипервейший источник ошибок в подобном коде у моих студентов — это целочисленное деление типа (x-x0)/(x1-x0).

Далее, если мы попробуем этим кодом нарисовать вот такие линии:

line(13, 20, 80, 40, image, white);
line(20, 13, 40, 80, image, red);
line(80, 40, 13, 20, image, red);

То выяснится, что одна линия хороша, вторая с дырками, а третьей вовсе нет.
Обратите внимание, что первая и вторая строчки (в коде) дают одну и ту же линию разного цвета. Белую мы уже видели, она хорошо отрисовывается. Я надеялся перекрасить белую в красный цвет, не получилось. Это тест на симметричность: результат отрисовки сегмента не должен зависеть от порядка точек: сегмент (a,b) дожен быть ровно таким же, как и сегмент (b,a).


Дырки в одном из сегментов из-за того, что его высота больше ширины.
Мои студенты часто мне предлагают такой фикс: if (dx>dy) {for (int x)} else {for (int y)}.
Ну ёлки!

void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
    bool steep = false;
    if (std::abs(x0-x1)<std::abs(y0-y1)) { // if the line is steep, we transpose the image
        std::swap(x0, y0);
        std::swap(x1, y1);
        steep = true;
    }
    if (x0>x1) { // make it left-to-right
        std::swap(x0, x1);
        std::swap(y0, y1);
    }

    for (int x=x0; x<=x1; x++) {
        float t = (x-x0)/(float)(x1-x0);
        int y = y0*(1.-t) + y1*t;
        if (steep) {
            image.set(y, x, color); // if transposed, de-transpose
        } else {
            image.set(x, y, color);
        }
    }
}


Этот код работает прекрасно. Именно подобной сложности код я хочу видеть в финальной версии нашего рендера.
Разумеется, он неэффективен (множественные деления и тому подобное), но он короткий и читаемый.
Заметьте, в нём нет ассертов, в нём нет проверок на выход за границы, это плохо.
Но я стараюсь не загромождать именно этот код, так как его много читают, при этом я систематически напоминаю про необходимости проверок.

Итак, предыдущий код прекрасно работает, но он может быть оптимизирован.

Оптимизация — опасная вещь, нужно чётко представлять, на какой платформе будет работать код.
Оптимизировать код под графическую карту или просто под центральный процессор — совсем разные вещи.
Перед и во время любой оптимизации код нужно профилировать.
Попробуйте угадать, какая операция здесь наиболее ресурсоёмкая?

Для тестов я рисую 1000000 раз 3 отрезка, которые мы рисовали перед этим. Мой процессор: is Intel® Core(TM) i5-3450 CPU @ 3.10GHz.
Этот код для каждого пикселя вызывает конструктор копирования TGAColor.
А это 1000000 * 3 отрезка * примерно 50 пикслей на отрезок. Немало вызовов.
Где начнём оптимизацию?
Профилировщик нам скажет.

Я откомпилировал код с ключами g++ -ggdb -g3 -pg -O0; затем запустил gprof:

  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 69.16      2.95     2.95  3000000     0.00     0.00  line(int, int, int, int, TGAImage&, TGAColor)
 19.46      3.78     0.83 204000000     0.00     0.00  TGAImage::set(int, int, TGAColor)
  8.91      4.16     0.38 207000000     0.00     0.00  TGAColor::TGAColor(TGAColor const&)
  1.64      4.23     0.07        2    35.04    35.04  TGAColor::TGAColor(unsigned char, unsigned char, unsigned char, unsigned char)
  0.94      4.27     0.04                             TGAImage::get(int, int)

10% рабочего времени — это копирование цвета.
Но ещё 70% проводятся в вызове line()! Тут и будем оптимизировать.


Заметим, что каждое деление имеет один и тот же делитель, давайте его вынесем за пределы цикла.
Переменная error даёт нам дистанцию до идеальной прямой от нашего текущего пикселя (x, y).
Каждый раз, как error превышает один пиксель, мы увеличиваем (уменьшаем) y на единицу, и на единицу же уменьшаем ошибку.

Код доступен здесь.

void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
    bool steep = false;
    if (std::abs(x0-x1)<std::abs(y0-y1)) {
        std::swap(x0, y0);
        std::swap(x1, y1);
        steep = true;
    }
    if (x0>x1) {
        std::swap(x0, x1);
        std::swap(y0, y1);
    }
    int dx = x1-x0;
    int dy = y1-y0;
    float derror = std::abs(dy/float(dx));
    float error = 0;
    int y = y0;
    for (int x=x0; x<=x1; x++) {
        if (steep) {
            image.set(y, x, color);
        } else {
            image.set(x, y, color);
        }
        error += derror;

        if (error>.5) {
            y += (y1>y0?1:-1);
            error -= 1.;
        }
    }
}

  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 38.79      0.93     0.93  3000000     0.00     0.00  line(int, int, int, int, TGAImage&, TGAColor)
 37.54      1.83     0.90 204000000     0.00     0.00  TGAImage::set(int, int, TGAColor)
 19.60      2.30     0.47 204000000     0.00     0.00  TGAColor::TGAColor(int, int)
  2.09      2.35     0.05        2    25.03    25.03  TGAColor::TGAColor(unsigned char, unsigned char, unsigned char, unsigned char)
  1.25      2.38     0.03                             TGAImage::get(int, int)

А зачем нам нужны плавающие точки? Едиственная причина — это одно деление на dx и сравнение с .5 в теле цикла.
Мы можем избавиться от плавающей точки, заменив переменную error другой, назовём её error2, она равна error*dx*2.
Вот эквивалентный код:

void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
    bool steep = false;
    if (std::abs(x0-x1)<std::abs(y0-y1)) {
        std::swap(x0, y0);
        std::swap(x1, y1);
        steep = true;
    }
    if (x0>x1) {
        std::swap(x0, x1);
        std::swap(y0, y1);
    }
    int dx = x1-x0;
    int dy = y1-y0;
    int derror2 = std::abs(dy)*2;
    int error2 = 0;
    int y = y0;
    for (int x=x0; x<=x1; x++) {
        if (steep) {
            image.set(y, x, color);
        } else {
            image.set(x, y, color);
        }
        error2 += derror2;

        if (error2 > dx) {
            y += (y1>y0?1:-1);
            error2 -= dx*2;
        }
    }
}

  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 42.77      0.91     0.91 204000000     0.00     0.00  TGAImage::set(int, int, TGAColor)
 30.08      1.55     0.64  3000000     0.00     0.00  line(int, int, int, int, TGAImage&, TGAColor)
 21.62      2.01     0.46 204000000     0.00     0.00  TGAColor::TGAColor(int, int)
  1.88      2.05     0.04        2    20.02    20.02  TGAColor::TGAColor(unsigned char, unsigned char, unsigned char, unsigned char)

Другой разговор, теперь достаточно убрать ненужные копии при вызове функции, передвая цвет по ссылке (или просто включив флаг компиляции -O3) и всё готово. Ни единого умножения, ни единого деления в коде.
Время работы снизилось с 2.95 секунды до 0.64.

Проволочный рендер.

Теперь всё готово для создания проволочного рендера. Снимок кода и тестовая модель находятся здесь.

Я использовал wavefront obj формат файла для хранения модели. Всё, что нам нужно для рендера, это прочитать из файла массив вершин вида

v 0.608654 -0.568839 -0.416318
[…]
это координаты x,y,z, одна вершина на строку файла

и граней
f 1193/1240/1193 1180/1227/1180 1179/1226/1179
[…]

Тут нас интересуют первое число после каждого пробела, это номер вершины в массиве, который мы прочитали ранее. Таким образом эта строчка говорит, что вершины 1193, 1180 и 1179 образуют треугольник.

Файл model.cpp содержит простейший парсер.

Пишем такой цикл в наш main.cpp и вуаля, наш проволочный рендер готов.

    for (int i=0; i<model->nfaces(); i++) {
        std::vector<int> face = model->face(i);
        for (int j=0; j<3; j++) {
            Vec3f v0 = model->vert(face[j]);
            Vec3f v1 = model->vert(face[(j+1)%3]);
            int x0 = (v0.x+1.)*width/2.;
            int y0 = (v0.y+1.)*height/2.;
            int x1 = (v1.x+1.)*width/2.;
            int y1 = (v1.y+1.)*height/2.;
            line(x0, y0, x1, y1, image, white);
        }
    }

В следующий раз будем рисовать 2D треугольники и подправлять наш рендер.

Часть 2. Сделай сам, или Как создать свою библиотеку для КОМПАС-3D

Создание библиотек фрагментов и моделей

Создание библиотек шаблонов

Создание пользовательских библиотек с помощью КОМПАС-Макро

КОМПАС-Мастер

Заключение

В предыдущей статье мы рассказали о значении прикладных библиотек в развитии современных систем моделирования. В частности, читатели узнали о возможностях конструкторских библиотек системы КОМПАС-3D и могли оценить, в какой мере использование таких приложений облегчает повседневную работу инженера.
В настоящей статье в общих чертах рассматривается, с чего начать создание собственных библиотек, чтобы сделать конструкторские решения более точными, а проектирование более быстрым, легким и удобным.

Как уже отмечалось, ни один набор библиотек к графической системе не может охватить всё множество различных направлений и отраслей промышленности и в полной мере удовлетворить требования всех категорий пользователей. Спектр задач конструкторско-технологической подготовки производства стал настолько широким, что решение некоторых из них как стандартными, так и прикладными средствами, предоставленными компанией — разработчиком ПО, может отнимать слишком много времени и быть нерациональным, а в редких случаях даже невозможным.

Огромный перечень областей применения САПР — первая причина, по которой любая из современных CAD-систем должна быть максимально открытой и обязательно содержать инструменты для создания пакета пользовательских библиотек. Второй причиной является ориентация на заказчика. Если, например, подавляющее большинство предприятий, использующих ту или иную систему, работают в машиностроении, а единицы — в области производства медицинского оборудования, то разработчики прикладных библиотек вынуждены подстраиваться под первую категорию. Но для заказчиков КОМПАС никаких проблем не возникнет — они  могут создать библиотеки самостоятельно.

Перечислим основные способы создания библиотек:

•  создание библиотеки фрагментов (эскизов) или моделей на основе базовых возможностей системы КОМПАС-3D;

•  создание библиотеки шаблонов с помощью Менеджера шаблонов;

•  использование специальной макросреды КОМПАС-Макро для подготовки пользовательского приложения;

•  применение инструментальных средств КОМПАС-Мастер, то есть собственно написание (программирование) библиотек.

Какой из этих вариантов выбрать? Всё зависит от поставленных целей и от вашего представления о будущей библиотеке: какой она должна быть, что будет делать (создавать, редактировать, выполнять какие-либо другие действия), насколько мощными и гибкими должны быть ее функции. Большое значение имеет и уровень вашей подготовки как разработчика. Простые библиотеки не требуют почти никаких специальных знаний, но и возможностей предоставляют немного. Создание более сложных модулей невозможно без некоторых навыков и опыта (иногда из совсем другой предметной области, в частности из программирования), при этом чем сложнее проектируемая библиотека, тем более глубокие знания необходимы. Под сложностью библиотеки здесь следует понимать уровень автоматизации тех конструкторских решений, которые будут реализованы в создаваемом приложении. Но не стоит думать, что наиболее автоматизированная библиотека всегда является лучшим решением. Чересчур автоматизированные приложения не оставляют места инициативе и не дают возможности варьировать решения.

Создание библиотек фрагментов и моделей

Для создания библиотек этого типа вам не потребуется никаких специальных навыков, кроме умения работать в КОМПАС-График или в КОМПАС-3D. С помощью таких библиотек каждый проектировщик может систематизировать свой набор наиболее часто используемых элементов, чтобы облегчить доступ к ним при разработке новых чертежей или моделей.

Создать свою библиотеку фрагментов совсем несложно. Для этого в окне Менеджера библиотек нужно воспользоваться командой контекстного меню Добавить описание > Библиотеки документов. В появившемся диалоговом окне открытия библиотеки следует выбрать тип файла: КОМПАС-Библиотеки фрагментов (*.lfr), если вы создаете хранилище для чертежей или эскизов, или КОМПАС-Библиотеки моделей (*.l3d) — для наполнения будущей библиотеки 3D-моделями. В итоге в окне Менеджера библиотек должна появиться ваша библиотека, пока еще пустая. После запуска к ней можно добавлять фрагменты и модели с помощью команд контекстного меню.

Главное преимущество библиотек фрагментов — простота их создания и применения. Большим плюсом таких приложений является также то, что при появлении новых версий КОМПАС не нужно подгонять или изменять их структуру под только что выпущенный релиз. Достаточно загрузить старый файл библиотеки в Менеджер библиотек, и можете не сомневаться — всё будет работать.

Недостатком подобных библиотек является ограниченность их функциональных возможностей. Автоматизация таких библиотек достигается только за счет параметризации объектов, которыми вы наполняете приложение, а библиотека лишь ускоряет процесс поиска и вставки нужного графического элемента в документ и обеспечивает лучшие условия для их хранения (не в отдельных файлах, раскиданных по жесткому диску, а упорядоченно, в едином файле-библиотеке).

Более широкими возможностями, по сравнению с библиотеками фрагментов, обладают библиотеки шаблонов КОМПАС-3D.

Создание библиотеки моделей

Создание библиотеки моделей

Пример пользовательской библиотеки, содержащей модели шпонок, и ее применение

Пример пользовательской библиотеки, содержащей модели шпонок, и ее применение

Пример пользовательской библиотеки шаблонов для создания трехмерной модели гайки

Пример пользовательской библиотеки шаблонов для создания трехмерной модели гайки

Создание библиотек шаблонов

Библиотека шаблонов — это прикладная библиотека, состоящая из базового параметризованного чертежа или трехмерной модели, таблицы переменных, набранной в соответствии с некоторыми правилами в табличном редакторе MS Excel, и схемы — документа КОМПАС-3D или рисунка, содержащего имена переменных. Библиотека представляет собой файл с расширением *.tlm, с помощью которого переменным параметризованного фрагмента или детали ставятся в соответствие значения, набранные в Excel-таблице. Для создания библиотек шаблонов предназначено специальное приложение под названием Менеджер шаблонов.

Разработку шаблона следует начинать с создания его прототипа (фрагмента или детали), пользуясь стандартными средствами КОМПАС-График или КОМПАС-3D. Затем необходимо параметризовать вычерченный фрагмент или эскизы модели и назначить внешними все переменные, которые вы планируете вводить (набирать) в таблице Excel. Следующим шагом является создание таблицы значений. Такая таблица формируется в редакторе Excel и включает названия внешних параметризованных переменных,  флаги видимости колонок значений в Менеджере шаблонов, конкретные значения или их интервал для каждой переменной и др. Детально с правилами заполнения таблиц к шаблонам вы можете ознакомиться в файле-справке и примерах, поставляемых вместе с библиотекой шаблонов. Формирование еще одной составной части шаблона — схемы параметров — не вызовет особых затруднений. Схемой может быть любой графический файл системы КОМПАС-3D или файл-рисунок в формате *.bmp, *.gif или *.jpg.

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

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

Каковы же существенные отличия библиотек шаблонов от библиотек фрагментов? Прежде всего это возможность вставки в документ не всего фрагмента, а отдельных его слоев, а также наличие ряда дискретных значений для переменной, что исключает ввод или выбор пользователем ошибочных значений. Кроме того, переменные шаблонов могут быть различных типов, в том числе логических и строковых, а в размерных надписях фрагмента-заготовки несложно резервировать переменные для текстовых подстановок (они должны выделяться с обеих сторон знаком #). Главным же преимуществом библиотек шаблонов является то, что при использовании шаблона не приходится изменять вручную параметризованные переменные, как это делалось бы при вставке фрагмента или модели из библиотеки фрагментов. При вставке объекта в активный документ Менеджер шаблонов сам позаботится о том, чтобы подставить нужные значения из выбранного пользователем ряда.

Безусловно, на разработку шаблонов уходит больше времени и при этом одних только навыков работы с КОМПАС уже будет недостаточно — придется изучить принципы работы Менеджера библиотек. Зато применение шаблонов дает возможность достаточно гибко автоматизировать создание типовых элементов и вместе с тем не запрещает динамично управлять процессом формирования библиотечного элемента.

Создание прикладных библиотек с помощью API

Создание прикладных библиотек с помощью API

Муфты, сгенерированные с помощью приложения, разработанного в среде КОМПАС-Мастер

Муфты, сгенерированные с помощью приложения, разработанного
в среде КОМПАС-Мастер

Создание пользовательских библиотек с помощью КОМПАС-Макро

КОМПАС-Макро — это интегрированная в систему КОМПАС-3D среда разработки конструкторских приложений на основе языка программирования Python. Почему за основу выбран именно Python? Во-первых, Python распространяется бесплатно и, как следствие, не налагает никаких ограничений на использование и распространение написанных на нем программ. Во-вторых, сегодня Python — один из самых простых и понятных языков программирования, однако при всей своей простоте он мало в чем уступает таким «китам» объектно-ориентированного программирования, как C++ и Object Pascal (Delphi).

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

Если же вы не понаслышке знакомы с основами объектно-ориентированного программирования и у вас есть желание разрабатывать самые мощные библиотеки на базе КОМПАС-3D, то использовать вы можете КОМПАС-Мастер.

Среда разработки прикладных библиотек к КОМПАС-3D

Среда разработки прикладных библиотек к КОМПАС-3D

КОМПАС-Мастер

КОМПАС-Мастер… Согласитесь, звучит несколько загадочно. Навевает мысли об утилите наподобие Мастера записи компакт-дисков в Windows. Но оказывается, все намного серьезнее.

КОМПАС-Мастер — это очень мощные инструментальные средства разработки приложений (библиотек) неограниченной сложности, функционирующих в среде КОМПАС-3D. С помощью КОМПАС-Мастер прикладной программист получает доступ ко всем без исключения функциям системы. То есть абсолютно всё, что пользователь может делать вручную, — будь то создание или редактирование графического документа, открытие и закрытие файлов, работа со спецификациями, создание таблиц, оформление чертежей, сохранение файлов в различных форматах, вставка рисунков и т.д. и т.п. — все это может быть автоматизировано с использованием КОМПАС-Мастер.

Доступ к внутренним функциям КОМПАС-График и КОМПАС-3D обеспечивается двумя путями:

•  через экспортные функции, оформленные в виде dll-модулей, которые разработчик подключает к своей программе, — при создании плоских чертежей; через использование СОМ-объектов — при программном формировании твердотельных моделей;

•  с помощью технологии Automation (Автоматизации), реализованной через API (Application Programming Interface — программный интерфейс приложения) системы КОМПАС. Управление и взаимодействие с системой при этом оформлено через интерфейсы IDispatch.

Использование интерфейсов IDispatch возможно в любой из наиболее распространенных сегодня сред программирования (Visual C++, Delphi, C++Builder, Visual Basic). Интеграция с такими мощными программными пакетами позволяет, помимо применения графического инструментария КОМПАС, использовать в создаваемых модулях все преимущества современного объектно-ориентированного программирования.

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

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

Зато, преодолев все эти трудности, вы получите удобное и гибкое приложение, обладающее функциональностью и интерфейсом, которые полностью удовлетворяют вашим требованиям. Программу можно заставить «думать» — самостоятельно выбирать, анализировать и обрабатывать необходимые данные, производить определенные действия в зависимости от прочитанных значений, делать сложные расчеты и выводы по их результатам и пр. И всё это для того, чтобы максимально облегчить работу инженера, избавить его от выполнения рутинных операций.

Заключение

Мы закончили рассказ о  наборе разнообразных приложений к системе КОМПАС-3D. Главная цель этого обзора — показать значение прикладных библиотек для улучшения качества и ускорения проектирования в целом и с использованием КОМПАС-3D в частности. Учитывая, что стандартные библиотеки не всегда могут удовлетворить всех пользователей, в статьях были рассмотрены различные способы создания конструктором собственных приложений — от простых утилит до сложных модулей, обладающих мощной функциональностью.

Наверняка  искушенные пользователи КОМПАС-3D знают и активно применяют эти возможности. Данный  материал поможет систематизировать их знания о системе и ее приложениях. Полезной окажется данная статья и для молодых специалистов конструкторско-технологических отделов, которые зачастую являются экспертами при выборе и внедрении САПР. Надеемся, вышеизложенная информация будет учтена при принятии важных решений и генерации новых идей и в конечном счете будет способствовать повышению качества проектируемой продукции.

САПР и графика 2`2006

Понравилась статья? Поделить с друзьями:
  • Как написать свою биографию образец для школьника
  • Как написать свою биографию образец для студента
  • Как написать свою биографию образец для опеки
  • Как написать свою биографию на английском языке
  • Как написать свою библиотеку на питоне