Re: [ MathGL ] MatGL on C#

836 views
Skip to first unread message

mathgl....@gmail.com

unread,
Oct 12, 2012, 1:46:50 AM10/12/12
to mat...@googlegroups.com
Dear Artemio,

2012/10/11 Artemio Soto <artemio.s...@gmail.com>:
> Hi, I need some help on this.
>
> I am currently developping a software using C#, now, I have to do some 3D
> plotting so I thought I could use MathGL. Is there any one who can help me
> to install and run MathGL from C#?
>
> I use SharpDevelop to code C# and I have no experience at all on MathGL.
>
> Thanks

There are 2 possible ways.

1. You can use MathGL C function directly from C#.

2. You can try to create an interface to C# using SWIG
(http://www.swig.org/Doc1.3/CSharp.html) since MathGL contain files
for that (see lang/ folder in sources). I can help you to do this, but
I couldn't test the result -- I don't know C#.

--
All the best,
Alexey Balakin

Artemio Soto

unread,
Oct 19, 2012, 2:37:09 PM10/19/12
to mat...@googlegroups.com
Thanks, I'm currently checking those options.

mathgl....@gmail.com

unread,
Oct 22, 2012, 5:58:23 AM10/22/12
to mat...@googlegroups.com
OK. Can you send me results of yours checking?

2012/10/19 Artemio Soto <artemio.s...@gmail.com>:

mathgl....@gmail.com

unread,
Nov 2, 2012, 5:04:05 AM11/2/12
to mat...@googlegroups.com
I have no idea what is OpenTK.

For first look it is like OpenGL. So, OpenGL should be initialized for
using OpenTK, and this allows you to use OpennGL interface of MathGL
http://mathgl.sourceforge.net/doc_en/doc_en_116.html#Constructor

2012/11/1 Piotrek L <mindr...@gmail.com>:
> What about OpenTK? It looks like some fork for OpenGL for C#. I've never
> ever used any graphics library and I need so little piece of it's feature so
> I am looking for some really easy to implement lib which can handle my
> graphs.
>
> W dniu poniedziałek, 22 października 2012 11:58:24 UTC+2 użytkownik Alexey
> Balakin napisał:

Piotr Lewandowski

unread,
Nov 2, 2012, 5:25:28 PM11/2/12
to mat...@googlegroups.com
Thanks a lot Alexey! It gives me some hope that it all will works but another problem seems to be using c++ dll's from win32 mingw package in MSVS2010 and c#.
How can I directly access the mathgl c functions?

mathgl....@gmail.com

unread,
Nov 2, 2012, 5:51:38 PM11/2/12
to mat...@googlegroups.com
Dear Piotr,

You can just include <mgl2/mgl_cf.h> which contain declarations of all
C functions.

2012/11/3 Piotr Lewandowski <mindr...@gmail.com>:

Piotrek L

unread,
Nov 3, 2012, 4:25:53 PM11/3/12
to mat...@googlegroups.com
Well it's not so easy to include a c++/c code (its unmanaged) to c# (managed code).
I'm struggling with SWIG but its a real pain in the *** for visual studio 2010.
I can't make SWIG to process the mgl_cf file. For some reasons SWIG doesn't end its work with error but with some mysterious "completed" without any working dll.

Maybe you can tell me how do you prepare your python interface and maybe it will help.

mathgl....@gmail.com

unread,
Nov 6, 2012, 1:56:20 PM11/6/12
to mat...@googlegroups.com
Dear Piotrek,

2012/11/4 Piotrek L <mindr...@gmail.com>:
> Well it's not so easy to include a c++/c code (its unmanaged) to c# (managed
> code).
> I'm struggling with SWIG but its a real pain in the *** for visual studio
> 2010.
> I can't make SWIG to process the mgl_cf file. For some reasons SWIG doesn't
> end its work with error but with some mysterious "completed" without any
> working dll.
>
> Maybe you can tell me how do you prepare your python interface and maybe it
> will help.

Generally it is the standard procedure using SWIG
http://www.swig.org/Doc1.3/Python.html

You should change directory to folder lang/ of yours build tree, and execute

swig -python -c++ -I../include -o mgl_python.cpp mgl.i

for obtaining mgl_python.cpp. Later this file can be compiled into
dynamic library.

Piotrek L

unread,
Nov 18, 2012, 3:37:59 PM11/18/12
to mat...@googlegroups.com
Dear Alexey,

I'm in the middle of my way to success :) I've created mgl_csharp.cpp file but I can't compile it into dll. MSVS2010 says that there is some linker error with mglColor set methods. I've added libmgl.a and libmgl.dll.a and the same with wnd. It's solved some of linker problems but those with Color I could solve only by removing them from code. It gave me a dll file but I can't use it in my c# project because it gives some internal error when I invoke mglGraph().
Kind of gordian knot :/ 

mathgl....@gmail.com

unread,
Nov 19, 2012, 5:26:47 AM11/19/12
to mat...@googlegroups.com
Dear Piotrek,

Files *.a are libraries for GNU/MinGW compilers only. You need to
create import libraries for yours compiler (MSVS 2010). Also keep in
mind that you need to use proper 32bit or 64bit libraries. Because it
looks as 32bit *.dll is not compatible with 64bit application.

2012/11/19 Piotrek L <mindr...@gmail.com>:
> --

mathgl....@gmail.com

unread,
Mar 20, 2013, 5:09:10 AM3/20/13
to mat...@googlegroups.com
https://www.google.ru/search?q=use+c+functions+in+C%23

2013/3/20 Yvonne Tan <tyfy...@gmail.com>:
> How to "use MathGL C function directly from C#"? Sorry, I'm a beginner on
> both C# and MathGL.
> --
> You received this message because you are subscribed to the Google Groups
> "MathGL" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mathgl+un...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Yvonne Tan

unread,
May 30, 2013, 6:08:32 AM5/30/13
to mat...@googlegroups.com
Hi,

If I call C functions from C# directly, I need to know which function is in which dll file. For example, if I want to call "mgl_create_data_size()", which dll function should I import? Is it "libmgl.dll"?

Thanks,
Yvonne

mathgl....@gmail.com

unread,
May 30, 2013, 6:35:30 AM5/30/13
to mat...@googlegroups.com
Dear Yvonne,
Most of functions are located in libmgl.dll. Functions related to Qt, FLTK, GLUT (i.e. like mgl_create_graph_qt(), mgl_qt_run()) are located in libmgl-qt.dll, libmgl-fltk.dll, libmgl-glut.dll correspondingly.


2013/5/30 Yvonne Tan <tyfy...@gmail.com>

Yvonne Tan

unread,
Jun 2, 2013, 8:43:11 AM6/2/13
to mat...@googlegroups.com
Thanks, Alexey.
 
Another question. In C#, if I directly use C functions in .dll files, how can the compiler recognise variable types like HMDT and HMGL?

mathgl....@gmail.com

unread,
Jun 3, 2013, 5:19:42 AM6/3/13
to mat...@googlegroups.com
Hi,

HMDT, HMGL and similar types are just pointers. In "C" variant they are defined as void*. For Fortran functions they are replaced by "uintptr_t", i.e. by integer of proper size (i.e. int for 32bit, or long for 64bit). I think that the same can be used in C# too.


2013/6/2 Yvonne Tan <tyfy...@gmail.com>

Yvonne Tan

unread,
Jun 7, 2013, 1:29:00 AM6/7/13
to mat...@googlegroups.com
Yeah, in C# it can be replaced by IntPtr type. But I find out that in the sample codes there is "HMDT y = mgl_create_data_size(50,3,1);". Since the function "mgl_create_data_size()" is HMDT type (thus void type), how can it return value to the variable "y"?

mathgl....@gmail.com

unread,
Jun 7, 2013, 8:42:50 AM6/7/13
to mat...@googlegroups.com
Hi,
HMDT (and similar) is not type "void", but pointer to void (i.e. "void *"). Pointer to void is a pointer to arbitrary type, which don't require any type checking. By other words, you can assign any pointer to void* without any checking, but have to manually specify type when assign from void*.


2013/6/7 Yvonne Tan <tyfy...@gmail.com>

Yvonne Tan

unread,
Jun 18, 2013, 8:59:48 AM6/18/13
to mat...@googlegroups.com
Hello again!

Problem today - "Unable to find an entry point named 'mgl_set_axis_2d' in DLL 'libmgl.dll'."

Is this function really in this *.dll file?

mathgl....@gmail.com

unread,
Jun 18, 2013, 2:53:39 PM6/18/13
to mat...@googlegroups.com
Dear Yvonne,
Function mgl_set_axis_2d() is defined for MathGL v.1.* only. It is replaced by mgl_set_range* functions in v.2.*.


2013/6/18 Yvonne Tan <tyfy...@gmail.com>

Yvonne Tan

unread,
Jun 24, 2013, 10:00:22 AM6/24/13
to mat...@googlegroups.com
Hi, when I debug my program, it says "Plot: data dimension(s) is too small". What could be the reason and how to solve it? (how big is big enough...)

Piotr Lewandowski

unread,
Jun 25, 2013, 3:26:16 AM6/25/13
to mat...@googlegroups.com
Hi, I know it may be inappropriate but if I can suggest something I'd like to recommend ilnumerics.net http://ilnumerics.net/surface-plots.html - it's designed for c#.
I was amused by work of Alexey but it took me so much effort to make it works with c# that I start looking again and I found ilnumerics.
Now they totally rewritten they library and it's much more intuitive and full of functionality.
I hope I'm not violating any rule of this group with that post.

Best regards, 


2013/6/24 Yvonne Tan <tyfy...@gmail.com>
You received this message because you are subscribed to a topic in the Google Groups "MathGL" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mathgl/05QjQS44VhE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mathgl+un...@googlegroups.com.

mathgl....@gmail.com

unread,
Jun 25, 2013, 3:47:59 AM6/25/13
to mat...@googlegroups.com
Dear Yvonne,

This message say what Plot() function (http://mathgl.sourceforge.net/doc_en/doc_en_46.html#plot) was called with argument of non-appropriate data sizes. I.e. 1st dimension (nx) was 1 or 1st dimensions of data arrays (x, y or z) are different.

2013/6/24 Yvonne Tan <tyfy...@gmail.com>
Message has been deleted
Message has been deleted

Yvonne Tan

unread,
Jul 2, 2013, 10:22:16 PM7/2/13
to mat...@googlegroups.com
Thanks a lot, Alexey. Actually I found out this problem by myself yesterday so I delete the previous post. I have no idea why you still can read it lol

But I do have another question. In version 2.1.2 there is a data type called "mreal" which has not been seen in version 1.0. I have never seen it anywhere else either. Is it a type that you create by yourself? Can you explain this type? What should be the corresponding type in C#? float?


On Tuesday, July 2, 2013 10:36:21 PM UTC+8, Alexey Balakin wrote:
Dear Yvonne,

Most probably yours C# construction correspond to C++ code:

double arr[2][5] = {{1,2,3,4,5},{1,3,5,7,9}};

If yes then compiler place it as array of {5 doubles}, i.e. just as 2*5=10 double numbers. And arr is just a pointer to this array which should be used as double*. It is not double** since compiler avoid creating unnecessary array of pointers. So, for this code you need to use

mgl_data_set_double(f,(double*)arr,5,2);

Contrary, if you create double array manually as

double **arr2=new double*[2];
for(int i=0;i<2;i++) arr2[i] = new double[5];
...

then you need to use function

mgl_data_set_double2(f,arr2,2,5);

The matter is that no one can guarantee what arr2[1] will start just after arr2[0] (and so on). And MathGL have to use true pointers to pointers.


2013/7/1 Yvonne Tan <tyfy...@gmail.com>
Dear Alexey,

I met another problemDuring debuggingwhen it comes to the function "mgl_data_set_double2(...)", it popped out an "AccessViolationException wasunhandleddialog windowsaying "Attempted to read or write protected memoryThis is often an indication that other memory is corrupt." I have noidea how to solve this problem.

I defined and initialized the 2d array as: static double[,] arr = new double[2,5] { { 1, 2, 3, 4, 5 }, { 1, 3, 5, 7, 9 } };
Imported the function from libmgl.dll as: [DllImport("libmgl.dll")]private static extern void mgl_data_set_double2(IntPtr dat, double[,] A, int N1, int N2);
Then I called the function as :
IntPtr f = mgl_create_data();
mgl_data_set_double2(f,arr,2,5);

Where did I do wrong? I've been stuck in here for days. Although I know you don't know C#, can you at least give me an example of how to use this function in C and C++? And how to call this function from *.dll using C++?

And FYI, I've tested the "mgl_data_set_double(...)" function from my program and it works well. So I'm thinking does this problem has anything to do with C# passing 2d array to the C *.dll?

Thanks!

Yvonne

Yvonne Tan

unread,
Jul 2, 2013, 11:35:07 PM7/2/13
to mat...@googlegroups.com
Oh, and one more question. Can I plot the graphs directly in a Windows Form without triggering extra windows?

mathgl....@gmail.com

unread,
Jul 23, 2013, 2:51:42 AM7/23/13
to mat...@googlegroups.com
Dear Yvonne,

Data type "mreal" is just a double (default) or float, depending on the setting which you did at configuring using cmake.

About direct drawing. Yes, you can. See http://mathgl.sourceforge.net/doc_en/doc_en_17.html#Drawing-in-memory . I think that bitmap drawing is standard feature for any widget library.



2013/7/3 Yvonne Tan <tyfy...@gmail.com>

Yvonne Tan

unread,
Jul 24, 2013, 9:47:43 AM7/24/13
to mat...@googlegroups.com
Thanks, Alexey!

Since I'm not going to use any window library but to draw the bitmap on my C#-programmed windows form, my plan is to extract the respective R,G,B values of each pixel by using the function mgl_get_rgb() and use them as arguments in the C# method Color.FromArgb(int r, int g, int b). However, I met some problems

Can you tell me the format how you store the RGB values in the const unsigned char* array? To my understanding of your explanation on this function, for a x*y bitmap, the RGB values are stored as:

R[0,0]
G[0,0]
B[0,0]
R[0,1]
G[0,1]
B[0,1]
...
R[x,y]
G[x,y]
B[x,y]

And if I want to get the red value of pixel [i,j], the index should be [3*x*i+3*j+1] (which seems to be a little bit different from what you wrote on the pdf handbook).

But I always got the error message saying "Index was outside the bounds of the array". Is my understanding wrong? Can you help me out with this?

Many many thanks and best regards.

Yvonne Tan

unread,
Jul 24, 2013, 11:20:26 PM7/24/13
to mat...@googlegroups.com
And the string of RGB values is also with wrong values. It contains only blank spaces. And all the respectively extracted RGB values are 255. Below are my codes. What's wrong with it?! (I think more attention should be focused on the red part.)

namespace BitmapTest
{
    public partial class Form1 : Form
    {

        private static double[,] arr = new double[50, 40];
        static int row = arr.GetUpperBound(0) + 1;
        static int col = arr.GetUpperBound(1) + 1;

        void Initialize2DArray()
        {


            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    double x = i / (double)(row - 1);
                    double y = j / (double)(col - 1);

                    arr[i, j] = (double)(0.6 * Math.Sin(2 * Math.PI * x) * Math.Sin(3 * Math.PI * y) + 0.4 * Math.Cos(3 * Math.PI * x * y));
                }
            }

        }


        public Form1()
        {
            InitializeComponent();

            Initialize2DArray();
        }


        [DllImport("libmgl.dll")]
        private static extern void mgl_data_set_value(IntPtr dat, double v, int i, int j, int k);

        [DllImport("libmgl.dll")]
        private static extern IntPtr mgl_create_data_size(int nx, int ny, int nz);

        [DllImport("libmgl.dll")]
        private static extern void mgl_rotate(IntPtr gr, double TetX, double TetZ, double TetY);

        [DllImport("libmgl.dll")]
        private static extern void mgl_delete_data(IntPtr dat);

        [DllImport("libmgl.dll")]
        private static extern void mgl_box(IntPtr gr, int ticks);

        [DllImport("libmgl.dll")]
        private static extern void mgl_set_light(IntPtr gr, int enable);

        [DllImport("libmgl.dll")]
        private static extern void mgl_surf(IntPtr gr, IntPtr z, string sch, string opt);

        [DllImport("libmgl.dll")]
        private static extern string mgl_get_rgb(IntPtr gr);

        [DllImport("libmgl.dll")]
        private static extern IntPtr mgl_create_graph(int width, int height);


        static int Sample2D(IntPtr gr, IntPtr p)
        {
            IntPtr mgldt2d = mgl_create_data_size(row, col, 1);

            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    double dt = arr[i, j];

                    mgl_data_set_value(mgldt2d, dt, i, j, 0);
                }
            }

            mgl_rotate(gr, 60, 40, 0);
            mgl_box(gr, 1);
            mgl_set_light(gr, 1);
            mgl_surf(gr, mgldt2d, "", "");
            mgl_delete_data(mgldt2d);
            return 0;
        }


        private void button1_Click(object sender, EventArgs e)
        {
                IntPtr gr = mgl_create_graph(row,col);
                Sample2D(gr, (IntPtr)null);
                string buf = mgl_get_rgb(gr);

                Bitmap bitmap = new Bitmap(50, 40);
                for (int i = 0; i < 50; i++)
                    for (int j = 0; j < 40; j++)
                    {
                        int r = (int)(byte)char.GetNumericValue(buf[3 * 50 * i + 3 * j + 1]);
                        int g = (int)(byte)char.GetNumericValue(buf[3 * 50 * i + 3 * j + 2]);
                        int b = (int)(byte)char.GetNumericValue(buf[3 * 50 * i + 3 * j + 3]);
                        Color color = Color.FromArgb(r,g,b);
                        bitmap.SetPixel(i, j, color);
                    }

                pictureBox1.Image = bitmap;
                pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;

        }
    }
}

mathgl....@gmail.com

unread,
Jul 25, 2013, 2:49:38 PM7/25/13
to mat...@googlegroups.com
Dear Yvonne,

About mgl_get_rgb() -- it return unsigned char values (i.e. 0...255 per R,G,B channel). Each color take 3 bytes in order R,G,B. Position of element {i,j} is [3*i + 3*Width*j]. See http://mathgl.sourceforge.net/doc_en/doc_en_41.html#Bitmap-in-memory


2013/7/25 Yvonne Tan <tyfy...@gmail.com>
And the string of RGB values is also with wrong values. It contains only blank spaces. And all the respectively extracted RGB values are 255. Below are my codes. What's wrong with it?! (I think more attention should be focused on the red part.)
                IntPtr gr = mgl_create_graph(row,col);
                Sample2D(gr, (IntPtr)null);
                string buf = mgl_get_rgb(gr);

Are you sure what such conversion will not cut string at first pure color (at first '\0' value for R,G or B)?
 

                Bitmap bitmap = new Bitmap(50, 40);

Are you sure what row=50 and col=40? Why you don't use row, col explicitly for bitmap?

 
                for (int i = 0; i < 50; i++)
                    for (int j = 0; j < 40; j++)
                    {
                        int r = (int)(byte)char.GetNumericValue(buf[3 * 50 * i + 3 * j + 1]);

Are you sure what 1st element have index 1 (not 0 as in C/C++) ?
 
                        int g = (int)(byte)char.GetNumericValue(buf[3 * 50 * i + 3 * j + 2]);
                        int b = (int)(byte)char.GetNumericValue(buf[3 * 50 * i + 3 * j + 3]);
                        Color color = Color.FromArgb(r,g,b);
                        bitmap.SetPixel(i, j, color);

I expect what this code will be extremely slow. Most probably you can use output of mgl_get_rgb() directly as is. At least all known me widget libraries (including one in Python) have such function(s).

Yvonne Tan

unread,
Jul 26, 2013, 12:03:13 AM7/26/13
to mat...@googlegroups.com
Ahh, thanks for you advices! Yesterday I didn't find the function but today I did! Now it works!

Yvonne Tan

unread,
Aug 2, 2013, 6:42:25 AM8/2/13
to mat...@googlegroups.com
Hi, Alexey!

I met a very strange problem. It's also about the bitmap displaying. I use "Bitmap (Int32, Int32, Int32,PixelFormat, IntPtr)" (see http://msdn.microsoft.com/en-us/library/zy1a2d14.aspxin C# to draw the bitmap. 

First, I created a mglData object is of size [50,40]. The strange thing is that, if I create a mglGraph object of size [600,450] and a bitmap of the same size as the mglGraph object, the bitmap can be displayed well (I also tried size [428, 325], also worked); but if I make the mglGraph object of size [443, 319] and the bitmap of  the same size as the mglGraph object, exception will be thrown at line "Bitmap (Int32, Int32, Int32,PixelFormat, IntPtr)" saying that the parameter is not valid.

Why is this happening?

mathgl....@gmail.com

unread,
Aug 5, 2013, 3:18:55 AM8/5/13
to mat...@googlegroups.com
Hi, Yvonne

As I remember, MS Windows core DLL don't understand/allow bitmap files with width not divisible by 4. It was true for WinXP and early. Most probably such bug still present in later versions of Windows too. Try to google or experiment in this direction.


2013/8/2 Yvonne Tan <tyfy...@gmail.com>
--
You received this message because you are subscribed to the Google Groups "MathGL" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mathgl+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Yvonne Tan

unread,
Aug 10, 2013, 6:24:11 AM8/10/13
to mat...@googlegroups.com
Got it. Thanks a lot Alexey!

mathgl....@gmail.com

unread,
Jul 2, 2013, 10:36:21 AM7/2/13
to mat...@googlegroups.com
Dear Yvonne,

Most probably yours C# construction correspond to C++ code:

double arr[2][5] = {{1,2,3,4,5},{1,3,5,7,9}};

If yes then compiler place it as array of {5 doubles}, i.e. just as 2*5=10 double numbers. And arr is just a pointer to this array which should be used as double*. It is not double** since compiler avoid creating unnecessary array of pointers. So, for this code you need to use

mgl_data_set_double(f,(double*)arr,5,2);

Contrary, if you create double array manually as

double **arr2=new double*[2];
for(int i=0;i<2;i++) arr2[i] = new double[5];
...

then you need to use function

mgl_data_set_double2(f,arr2,2,5);

The matter is that no one can guarantee what arr2[1] will start just after arr2[0] (and so on). And MathGL have to use true pointers to pointers.


2013/7/1 Yvonne Tan <tyfy...@gmail.com>
Dear Alexey,

I met another problemDuring debuggingwhen it comes to the function "mgl_data_set_double2(...)", it popped out an "AccessViolationException wasunhandleddialog windowsaying "Attempted to read or write protected memoryThis is often an indication that other memory is corrupt." I have noidea how to solve this problem.

I defined and initialized the 2d array as: static double[,] arr = new double[2,5] { { 1, 2, 3, 4, 5 }, { 1, 3, 5, 7, 9 } };
Imported the function from libmgl.dll as: [DllImport("libmgl.dll")]private static extern void mgl_data_set_double2(IntPtr dat, double[,] A, int N1, int N2);
Then I called the function as :
IntPtr f = mgl_create_data();
mgl_data_set_double2(f,arr,2,5);

Where did I do wrong? I've been stuck in here for days. Although I know you don't know C#, can you at least give me an example of how to use this function in C and C++? And how to call this function from *.dll using C++?

And FYI, I've tested the "mgl_data_set_double(...)" function from my program and it works well. So I'm thinking does this problem has anything to do with C# passing 2d array to the C *.dll?

Thanks!

Yvonne

Reply all
Reply to author
Forward
0 new messages