1 /***************************************************************************
2  * base.h is part of Math Graphic Library
3  * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru>       *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU Lesser General Public License  as       *
7  *   published by the Free Software Foundation; either version 3 of the    *
8  *   License, or (at your option) any later version.                       *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU Lesser General Public     *
16  *   License along with this program; if not, write to the                 *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #ifndef _MGL_BASE_H_
21 #define _MGL_BASE_H_
22 //#if !defined(_MSC_VER) && !defined(__BORLANDC__)
23 #include "mgl2/abstract.h"
24 
25 #ifdef __cplusplus
26 
27 #if (MGL_HAVE_PTHREAD|MGL_HAVE_PTHR_WIDGET)
28 #include <pthread.h>
29 #endif
30 
31 #if MGL_HAVE_PTHREAD
32 #define MGL_PUSH(a,v,m)	{pthread_mutex_lock(&m);	a.push_back(v);	pthread_mutex_unlock(&m);}
33 #else
34 #define MGL_PUSH(a,v,m)	a.push_back(v);
35 #endif
36 
37 #if MGL_HAVE_PTHREAD
38 #define MGL_PUSHs(func,m)	{pthread_mutex_lock(&m);	func;	pthread_mutex_unlock(&m);}
39 #else
40 #define MGL_PUSHs(func,m)	{func;}
41 #endif
42 //-----------------------------------------------------------------------------
mgl_d(mreal v,mreal v1,mreal v2)43 inline mreal mgl_d(mreal v,mreal v1,mreal v2) { return v2!=v1?(v-v1)/(v2-v1):NAN; }
44 //-----------------------------------------------------------------------------
45 mglPoint GetX(HCDT x, int i, int j, int k=0);
46 mglPoint GetY(HCDT y, int i, int j, int k=0);
47 mglPoint GetZ(HCDT z, int i, int j, int k=0);
48 //-----------------------------------------------------------------------------
49 /// Class for replacement of std::vector
50 // NOTE memcpy is used --> no memory allocation in T
51 template <class T> class mglStack
52 {
53 	T **dat;
54 	unsigned MGL_PB;	///< size of buffer (real size is 2^pb == 1L<<pb).
55 	/** NOTE This limit the number of maximal points and primitives as (1<<MGL_PB)^2,
56 	  * i.e. as 10^12 for MGL_PB=20 or 4*10^9 for MGL_PB=16. See mgl_bsize().*/
57 	size_t nb;	///< used blocks
58 	size_t n;	///< used cells
59 	void *mutex;
60 public:
mglStack(const mglStack<T> & st)61 	mglStack(const mglStack<T> &st)
62 	{	mutex = 0;	n=0;	nb=1;	MGL_PB = mgl_bsize(0);
63 		dat = new T*[(size_t)1<<MGL_PB];
64 		*dat = new T[(size_t)1<<MGL_PB];	reserve(st.n);
65 		for(size_t i=0;i<nb;i++)
66 			memcpy(dat[i],st.dat[i],((size_t)1<<MGL_PB)*sizeof(T));
67 		n=st.n;	}
mglStack()68 	mglStack()
69 	{	mutex = 0;	n=0;	nb=1;	MGL_PB = mgl_bsize(0);
70 		dat = new T*[(size_t)1<<MGL_PB];
71 		*dat = new T[(size_t)1<<MGL_PB];	}
~mglStack()72 	~mglStack()	{	clear();	delete [](*dat);	delete []dat;	}
set_mutex(void * mtx)73 	inline void set_mutex(void *mtx)	{	mutex=mtx;	}
allocate(size_t num)74 	inline size_t allocate(size_t num)
75 	{	reserve(num);	size_t r=n;	n+=num;	return r;	}
reserve(size_t num)76 	void reserve(size_t num)
77 	{
78 		num = num?num+n:n+1;	// final required size
79 		if(num>(nb<<MGL_PB))
80 		{
81 			num = 1 + (num>>MGL_PB);
82 			for(;nb<num;nb++)	dat[nb] = new T[(size_t)1<<MGL_PB];
83 		}
84 	}
clear()85 	void clear()
86 	{
87 		if(mutex)	mgl_mutex_lock(mutex);
88 		for(size_t i=1;i<nb;i++)	delete [](dat[i]);
89 		n=0;	nb=1;
90 		if(mutex)	mgl_mutex_unlock(mutex);
91 	}
92 	T &operator[](size_t i)
93 	{	size_t d=i>>MGL_PB;	return dat[d][i-(d<<MGL_PB)];	}
94 	const T &operator[](size_t i)	const
95 	{	size_t d=i>>MGL_PB;	return dat[d][i-(d<<MGL_PB)];	}
push_back(const T & t)96 	void push_back(const T &t)
97 	{
98 		if(n>=(nb<<MGL_PB))	reserve(1);
99 		size_t d=n>>MGL_PB;	dat[d][n-(d<<MGL_PB)] = t;	n++;
100 	}
push_back(size_t num,const T * t)101 	void push_back(size_t num, const T *t)
102 	{
103 		if(n+num>=(nb<<MGL_PB))	reserve(num);
104 		for(size_t i=0;i<num;i++)
105 		{	size_t d=n>>MGL_PB;	dat[d][n-(d<<MGL_PB)] = t[i];	n++;	}
106 	}
size()107 	size_t size()	const	{	return n;	}
108 	const mglStack<T> &operator=(const mglStack<T> &st)
109 	{
110 		clear();	reserve(st.n);
111 		for(size_t i=0;i<nb;i++)
112 			memcpy(dat[i],st.dat[i],((size_t)1<<MGL_PB)*sizeof(T));
113 		n = st.n;	return st;
114 	}
115 };
116 //-----------------------------------------------------------------------------
117 /// Structure for transformation matrix
118 struct MGL_EXPORT mglMatrix
119 {
120 	float x,y,z,pf;
121 	float b[9];
122 	bool norot;	// flag to disable pnts rotation
mglMatrixmglMatrix123 	mglMatrix()	{	clear();	}
mglMatrixmglMatrix124 	mglMatrix(const mglMatrix &aa) : x(aa.x),y(aa.y),z(aa.z),pf(aa.pf),norot(aa.norot) 	{	memcpy(b,aa.b,9*sizeof(float));	}
125 	void Rotate(mreal tetz,mreal tetx,mreal tety);
126 	void RotateN(mreal Tet,mreal x,mreal y,mreal z);
clearmglMatrix127 	inline void clear()	{	x=y=z=pf=0;	memset(b,0,9*sizeof(float));	b[0]=b[4]=b[8]=1;	norot=false;	}
128 	inline const mglMatrix &operator=(const mglMatrix &a)
129 	{	x=a.x;	y=a.y;	z=a.z;	pf=a.pf;	memcpy(b,a.b,9*sizeof(float));	norot=false;	return a;	}
130 };
131 inline bool operator==(const mglMatrix &a, const mglMatrix &b)
132 {	return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)+(a.pf-b.pf)*(a.pf-b.pf)==0)&&!memcmp(b.b,a.b,9*sizeof(float));}
133 inline bool operator!=(const mglMatrix &a, const mglMatrix &b)
134 {	return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)+(a.pf-b.pf)*(a.pf-b.pf)!=0)||memcmp(b.b,a.b,9*sizeof(float));	}
135 //-----------------------------------------------------------------------------
136 /// Structure for simplest primitives
137 struct MGL_EXPORT mglPrim	// NOTE: use float for reducing memory size
138 {
139 	// NOTE: n4 is used as mark; n3 -- as pen style for type=0,1,4
140 	// NOTE: n3 is used as position of txt,font in Ptxt for type=6
141 	long n1,n2,n3,n4;	///< coordinates of corners
142 	short type;	///< primitive type (0-point, 1-line, 2-trig, 3-quad, 4-glyph, 6-text)
143 	short angl;	///< rotation angle for mask
144 	int id;		///< object id
145 	float z;	///< z-position
146 	float w;	///< width (if applicable) or ftet
147 	union
148 	{
149 		struct
150 		{
151 			float s;		///< size (if applicable) or fscl
152 			float p;
153 		};
154 		uint64_t m;
155 	};
mglPrimmglPrim156 	mglPrim():n1(0),n2(0),n3(0),n4(0),type(0),angl(0),id(0),z(0),w(0),m(0)	{}
mglPrimmglPrim157 	explicit mglPrim(int t):n1(0),n2(0),n3(0),n4(0),type(t),angl(0),id(0),z(0),w(0),m(0)	{}
mglPrimmglPrim158 	mglPrim(const mglPrim &aa) : n1(aa.n1),n2(aa.n2),n3(aa.n3),n4(aa.n4),type(aa.type),angl(aa.angl),id(aa.id),z(aa.z),w(aa.w),m(aa.m) 	{}
159 	const mglPrim &operator=(const mglPrim &aa)
160 	{	n1=aa.n1;	n2=aa.n2;	n3=aa.n3;	n4=aa.n4;	type=aa.type;	angl=aa.angl;	id=aa.id;	z=aa.z;	w=aa.w;	m=aa.m;	return aa;	}
161 };
162 bool operator<(const mglPrim &a,const mglPrim &b);
163 bool operator>(const mglPrim &a,const mglPrim &b);
164 //-----------------------------------------------------------------------------
165 /// Structure for light source
166 struct MGL_EXPORT mglLight
167 {
mglLightmglLight168 	mglLight():a(0),b(0),n(false)	{}
mglLightmglLight169 	mglLight(const mglLight &aa) : d(aa.d),r(aa.r),q(aa.q),p(aa.p),c(aa.c),a(aa.a),b(aa.b),n(aa.n)	{}
170 	const mglLight &operator=(const mglLight &aa)
171 	{	d=aa.d;	r=aa.r;	q=aa.q;	p=aa.p;	c=aa.c;	a=aa.a;	b=aa.b;	n=aa.n;	return aa;	}
172 
173 	mglPoint d;		///< Direction of light sources
174 	mglPoint r;		///< Position of light sources (NAN for infinity)
175 	mglPoint q;		///< Actual position of light sources (filled by LightScale() function)
176 	mglPoint p;		///< Actual direction of light sources (filled by LightScale() function)
177 	mglColor c;		///< Color of light sources
178 	float a;		///< Aperture of light sources
179 	float b;		///< Brightness of light sources
180 	bool n;			///< Availability of light sources
181 };
182 //-----------------------------------------------------------------------------
183 /// Structure for inplot
184 struct MGL_EXPORT mglBlock
185 {
186 	long n1,n2,n3,n4;	///< coordinates of corners {n1=x1,n2=x2,n3=y1,n4=y2}
187 
188 	mglLight light[10];	///< Light sources
189 	float AmbBr;		///< Default ambient light brightness
190 	float DifBr;		///< Default diffusive light brightness
191 	mglMatrix B;		///< Transformation matrix
192 	int id;		///< object id
193 
mglBlockmglBlock194 	mglBlock():n1(0),n2(0),n3(0),n4(0),AmbBr(0.5),DifBr(0.5),id(0)	{}
mglBlockmglBlock195 	mglBlock(const mglBlock &aa)	{	memcpy(this, &aa, sizeof(mglBlock));	}
196 	const mglBlock &operator=(const mglBlock &aa)
197 	{	n1=aa.n1;	n2=aa.n2;	n3=aa.n3;	n4=aa.n4;	for(int i=0;i<10;i++)	light[i]=aa.light[i];
198 		AmbBr=aa.AmbBr;	DifBr=aa.DifBr;	B=aa.B;	id=aa.id;	return aa;	}
199 };
200 //-----------------------------------------------------------------------------
201 /// Structure for group of primitives
202 struct MGL_EXPORT mglGroup
203 {
204 	std::vector<long> p;	///< list of primitives (not filled!!!)
205 	int Id;					///< Current list of primitives
206 	std::string Lbl;		///< Group label
IdmglGroup207 	mglGroup(const char *lbl="", int id=0) : Id(id), Lbl(lbl)	{}
mglGroupmglGroup208 	mglGroup(const mglGroup &aa) : p(aa.p),Id(aa.Id),Lbl(aa.Lbl)	{}
209 #if MGL_HAVE_RVAL
mglGroupmglGroup210 	mglGroup(mglGroup &&aa) : p(aa.p),Id(aa.Id),Lbl(aa.Lbl)	{}
211 #endif
212 	inline const mglGroup &operator=(const mglGroup &aa)	{	Lbl = aa.Lbl;	Id = aa.Id;	p = aa.p;	return aa;	}
213 };
214 //-----------------------------------------------------------------------------
215 /// Structure for text label
216 struct MGL_EXPORT mglText
217 {
218 	std::wstring text;
219 	std::string stl;
220 	float val;
textmglText221 	mglText(const wchar_t *txt=L"", const char *fnt="", float v=0) : text(txt), stl(fnt), val(v) {}
textmglText222 	mglText(const std::wstring &txt, float v=0): text(txt), val(v)	{}
mglTextmglText223 	mglText(const mglText &aa) : text(aa.text),stl(aa.stl),val(aa.val)	{}
224 #if MGL_HAVE_RVAL
mglTextmglText225 	mglText(mglText &&aa) : text(aa.text),stl(aa.stl),val(aa.val)	{}
226 #endif
227 	const mglText&operator=(const mglText &aa)	{ text=aa.text;	stl=aa.stl;	val=aa.val;	return aa;	}
228 };
229 //-----------------------------------------------------------------------------
230 /// Structure for internal point representation
231 struct MGL_EXPORT mglPnt	// NOTE: use float for reducing memory size
232 {
233 	union {	float dat[15];	struct {
234 		float x,y,z;	// coordinates
235 		float u,v,w;	// normales
236 		float r,g,b,a;	// RGBA color
237 		float xx,yy,zz;	// original coordinates
238 		float c,ta;	// index in color scheme
239 	}; };
240 	int sub;		// subplot id and rotation information (later will be in subplot)
xmglPnt241 	mglPnt(float X=0, float Y=0, float Z=0, float U=0, float V=0, float W=0, float R=0, float G=0, float B=0, float A=0, short s=0) :x(X),y(Y),z(Z),u(U),v(V),w(W),r(R),g(G),b(B),a(A),xx(X),yy(Y),zz(Z),c(0),ta(0),sub(s)	{}
mglPntmglPnt242 	mglPnt(const mglPnt &aa) : sub(aa.sub)	{	memcpy(dat,aa.dat,15*sizeof(float));	}
243 	inline const mglPnt&operator=(const mglPnt &aa)	{ sub=aa.sub;	memcpy(dat,aa.dat,15*sizeof(float));	return aa;	}
samemglPnt244 	inline bool same(const mglPnt &p, mreal d)	const {	return fabs(x-p.x)<d && fabs(y-p.y)<d;	}
245 };
246 inline mglPnt operator+(const mglPnt &a, const mglPnt &b)
247 //{	mglPnt p;	for(long i=0;i<10;i++)	p.dat[i] = a.dat[i]+b.dat[i];	p.sub=a.sub;	return p;	}
248 {	return mglPnt(a.x+b.x,a.y+b.y,a.z+b.z, a.u+b.u,a.v+b.v,a.w+b.w, a.r+b.r,a.g+b.g,a.b+b.b,a.a+b.a, a.sub);	}
249 inline mglPnt operator-(const mglPnt &a, const mglPnt &b)
250 //{	mglPnt p;	for(long i=0;i<10;i++)	p.dat[i] = a.dat[i]-b.dat[i];	p.sub=a.sub;	return p;	}
251 {	return mglPnt(a.x-b.x,a.y-b.y,a.z-b.z, a.u-b.u,a.v-b.v,a.w-b.w, a.r-b.r,a.g-b.g,a.b-b.b,a.a-b.a, a.sub);	}
252 inline mglPnt operator*(const mglPnt &a, float b)
253 //{	mglPnt p;	for(long i=0;i<10;i++)	p.dat[i] = a.dat[i]*b;	p.sub=a.sub;	return p;	}
254 {	return mglPnt(a.x*b,a.y*b,a.z*b, a.u*b,a.v*b,a.w*b, a.r*b,a.g*b,a.b*b,a.a*b, a.sub);	}
255 inline mglPnt operator*(float b, const mglPnt &a)
256 //{	mglPnt p;	for(long i=0;i<10;i++)	p.dat[i] = a.dat[i]*b;	p.sub=a.sub;	return p;	}
257 {	return mglPnt(a.x*b,a.y*b,a.z*b, a.u*b,a.v*b,a.w*b, a.r*b,a.g*b,a.b*b,a.a*b, a.sub);	}
258 //-----------------------------------------------------------------------------
259 /// Structure for glyph representation
260 struct MGL_EXPORT mglGlyph
261 {	// NOTE nt<0 is used to set char id for user-defined glyphs
262 	long nt, nl;		///< number of triangles and lines
263 	short *trig, *line;	///< vertexes of triangles and lines
264 
mglGlyphmglGlyph265 	mglGlyph():nt(0),nl(0),trig(0),line(0)	{}
mglGlyphmglGlyph266 	mglGlyph(const mglGlyph &a):nt(0),nl(0),trig(0),line(0)	{	*this=a;	}
mglGlyphmglGlyph267 	mglGlyph(long Nt, long Nl):nt(0),nl(0),trig(0),line(0)	{	Create(Nt,Nl);	}
~mglGlyphmglGlyph268 	~mglGlyph()	{	if(trig)	delete []trig;	if(line)	delete []line;	}
269 
270 	void Create(long Nt, long Nl);	///< Allocate memory for given sizes
271 	void Load(wchar_t id, const char *fname);	///< Load glyph 'id' from TTF/OTF file 'fname'
272 	bool operator==(const mglGlyph &g) const MGL_FUNC_PURE;
273 	inline bool operator!=(const mglGlyph &g) const MGL_FUNC_PURE
274 	{	return !(*this==g);	}
275 	inline const mglGlyph &operator=(const mglGlyph &a)
276 	{	Create(a.nt, a.nl);
277 		if(a.trig)	memcpy(trig, a.trig, 6*nt*sizeof(short));
278 		if(a.line)	memcpy(line, a.line, 2*nl*sizeof(short));
279 		return a;	}
280 };
281 //-----------------------------------------------------------------------------
282 #define MGL_TEXTURE_COLOURS 512
283 /// Structure for texture (color scheme + palette) representation
284 struct MGL_EXPORT mglTexture
285 {
286 	mglColor *col;	///< Colors itself
287 	long n;			///< Number of initial colors along u
288 	mglColor *c0;	///< Initial colors
289 	float *val;	///< Initial color positions
290 
291 	char Sch[260];	///< Color scheme used
292 	int Smooth;		///< Type of texture (smoothing and so on)
293 	float Alpha;	///< Transparency
294 
mglTexturemglTexture295 	mglTexture():n(0),c0(NULL),val(NULL),Smooth(0),Alpha(1)
296 	{	col = new mglColor[MGL_TEXTURE_COLOURS];	}
297 	mglTexture(const char *cols, int smooth=0,mreal alpha=1):n(0),c0(NULL),val(NULL)
298 	{	col = new mglColor[MGL_TEXTURE_COLOURS];	Set(cols,smooth,alpha);	}
mglTexturemglTexture299 	mglTexture(const mglTexture &aa) : n(aa.n),Smooth(aa.Smooth),Alpha(aa.Alpha)
300 	{	col = new mglColor[MGL_TEXTURE_COLOURS];	memcpy(Sch,aa.Sch,260);
301 		memcpy(col,aa.col,MGL_TEXTURE_COLOURS*sizeof(mglColor));
302 		c0 = new mglColor[2*aa.n];	memcpy(c0,aa.c0,2*aa.n*sizeof(mglColor));
303 		val = new float[aa.n];		memcpy(val,aa.val,aa.n*sizeof(float));	}
304 #if MGL_HAVE_RVAL
mglTexturemglTexture305 	mglTexture(mglTexture &&aa) : n(aa.n),c0(aa.c0),val(aa.val),Smooth(aa.Smooth),Alpha(aa.Alpha)
306 	{	col = aa.col;	memcpy(Sch,aa.Sch,260);	aa.col=aa.c0=0;	aa.val=0;	}
307 #endif
~mglTexturemglTexture308 	~mglTexture()	{	if(col)	delete []col;	Clear();	}
ClearmglTexture309 	void Clear()
310 	{	if(c0)	{	delete []c0;	delete []val;	}
311 		n=0;	c0=NULL;	val=NULL;	}
312 	void Set(const char *cols, int smooth=0,mreal alpha=1);
313 	void Set(HCDT val, const char *cols);
314 	void GetC(mreal u,mreal v,mglPnt &p) const;
315 	mglColor GetC(mreal u,mreal v=0) const MGL_FUNC_PURE;
IsSamemglTexture316 	inline bool IsSame(const mglTexture &t) const
317 	{	return n==t.n && !memcmp(col,t.col,MGL_TEXTURE_COLOURS*sizeof(mglColor));	}
318 	void GetRGBA(unsigned char *f) const;
319 	void GetRGBAPRC(unsigned char *f) const;
320 	void GetRGBAOBJ(unsigned char *f) const;	// Export repeating border colors, since OBJ by default wraps textures and we need an extra boundary to work around implementation quirks
321 	inline const mglTexture &operator=(const mglTexture &aa)
322 	{	n=aa.n;	Smooth=aa.Smooth;	Alpha=aa.Alpha;
323 		memcpy(col,aa.col,MGL_TEXTURE_COLOURS*sizeof(mglColor));
324 		memcpy(Sch,aa.Sch,260);	return aa;	}
325 };
326 //-----------------------------------------------------------------------------
327 const mglColor NC(-1,-1,-1);
328 const mglColor BC( 0, 0, 0);
329 const mglColor WC( 1, 1, 1);
330 const mglColor RC( 1, 0, 0);
331 //-----------------------------------------------------------------------------
332 /// Structure active points
333 struct MGL_EXPORT mglActivePos
334 {
335 	int x,y;	///< coordinates of active point
336 	int id;		///< object id for active point
337 	int n;		///< position of active point in command (object id)
338 };
339 //-----------------------------------------------------------------------------
340 #if defined(_MSC_VER)
341 MGL_EXTERN template class MGL_EXPORT mglStack<mglPnt>;
342 MGL_EXTERN template class MGL_EXPORT mglStack<mglPrim>;
343 MGL_EXTERN template class MGL_EXPORT std::vector<mglGroup>;
344 MGL_EXTERN template class MGL_EXPORT std::vector<mglText>;
345 MGL_EXTERN template class MGL_EXPORT std::vector<mglTexture>;
346 MGL_EXTERN template class MGL_EXPORT std::vector<mglGlyph>;
347 MGL_EXTERN template class MGL_EXPORT std::vector<mglBlock>;
348 MGL_EXTERN template class MGL_EXPORT std::vector<mglMatrix>;
349 MGL_EXTERN template class MGL_EXPORT mglStack<mglActivePos>;
350 #endif
351 //-----------------------------------------------------------------------------
352 /// Base class for canvas which handle all basic drawing
353 class MGL_EXPORT mglBase
354 {
355 public:
356 	mglBase();
357 	virtual ~mglBase();
358 
359 	mglPoint Min;		///< Lower edge of bounding box for graphics.
360 	mglPoint Max;		///< Upper edge of bounding box for graphics.
361 	mreal ZMin;			///< Adjusted minimal z-value 1D plots
362 	std::string Mess;	///< Buffer for receiving messages
363 	int ObjId;			///< object id for mglPrim
364 	int HighId;			///< object id to be highlited
365 	std::vector<mglGroup> Grp;	///< List of groups with names -- need for export
366 	mglStack<mglActivePos> Act;	///< Position of active points
367 	std::string PlotId;	///< Id of plot for saving filename (in GLUT window for example)
368 	int BBoxX1, BBoxY1, BBoxX2, BBoxY2;	///< BBox region for exporting 2d graphics
369 	std::vector<mglGlyph> UserGlf;	///< User-defined glyphs data
370 
371 	mreal CDef;			///< Default (current) color in texture
372 	mreal AlphaDef;		///< Default value of alpha channel (transparency)
373 	mreal BarWidth;		///< Relative width of rectangles in Bars().
374 	int MeshNum;		///< Set approximate number of lines in Mesh and Grid. By default (=0) it draw all lines.
375 	int FaceNum;		///< Set approximate number of visible faces and lines. By default (=0) it draw everything.
376 	char Arrow1, Arrow2;///< Style of arrows at end and at start of curve
377 	long InUse;			///< Smart pointer (number of users)
378 	uint32_t Flag;		///< Flags for controlling drawing
379 	mreal size_opt;		///< Value of size option (or NAN if not specified)
380 
get(uint32_t fl)381 	inline bool get(uint32_t fl) const	{	return Flag&fl;	}
set(uint32_t fl)382 	inline void set(uint32_t fl)	{	Flag |= fl;	}
clr(uint32_t fl)383 	inline void clr(uint32_t fl)	{	Flag &=~fl;	}
set(bool v,uint32_t fl)384 	inline void set(bool v,uint32_t fl)	{	Flag = v ? Flag|fl : Flag&(~fl);	}
385 
386 	/// Set axis range scaling -- simplified way to shift/zoom axis range -- need to replot whole image!
387 	inline void ZoomAxis(const mglPoint &p1=mglPoint(0,0,0,0), const mglPoint &p2=mglPoint(1,1,1,1))	{	AMin = p1;	AMax = p2;	}
388 	/// Set values of mglGraph::Min and mglGraph::Max
389 	inline void SetRanges(mreal x1, mreal x2, mreal y1, mreal y2, mreal z1=0, mreal z2=0, mreal c1=0, mreal c2=0)
390 	{	SetRanges(mglPoint(x1,y1,z1,c1),mglPoint(x2,y2,z2,c2));	}
391 	void SetRanges(const mglPoint &v1, const mglPoint &v2);
392 	/// Set values of mglGraph::Cmin and mglGraph::Cmax as minimal and maximal values of data a
393 	void CRange(HCDT a, bool add = false, mreal fact=0);
394 	void CRange(mreal v1,mreal v2,bool add=false);
395 	/// Set values of mglGraph::Min.x and mglGraph::Max.x as minimal and maximal values of data a
396 	void XRange(HCDT a, bool add = false, mreal fact=0);
397 	void XRange(mreal v1,mreal v2,bool add=false);
398 	/// Set values of mglGraph::Min.x and mglGraph::Max.x as minimal and maximal values of data a
399 	void YRange(HCDT a, bool add = false, mreal fact=0);
400 	void YRange(mreal v1,mreal v2,bool add=false);
401 	/// Set values of mglGraph::Min.x and mglGraph::Max.x as minimal and maximal values of data a
402 	void ZRange(HCDT a, bool add = false, mreal fact=0);
403 	void ZRange(mreal v1,mreal v2,bool add=false);
404 	/// Set ranges for automatic variables
405 	void SetAutoRanges(mreal x1, mreal x2, mreal y1=0, mreal y2=0, mreal z1=0, mreal z2=0, mreal c1=0, mreal c2=0);
406 	/// Set axis origin
407 	void SetOrigin(mreal x0, mreal y0, mreal z0=NAN, mreal c0=NAN);
408 	/// Save ranges into internal variable and put parsed
409 	mreal SaveState(const char *opt);
410 	/// Load ranges from internal variable
411 	void LoadState();
412 	/// Increase ZMin
AdjustZMin()413 	mreal AdjustZMin()	{	ZMin /= MGL_FEPSILON;	return Max.z - ZMin*(Max.z-Min.z);	}
414 
415 	/// Safetly set the transformation formulas for coordinate.
416 	void SetFunc(const char *EqX, const char *EqY, const char *EqZ=0, const char *EqA=0);
417 	/// Set one of predefined transformation rule
418 	void SetCoor(int how);
419 	/// Safetly set the cutting off condition (formula).
420 	void CutOff(const char *EqCut);
421 	/// Set to draw Ternary axis (triangle like axis, grid and so on)
422 	void Ternary(int tern);
423 
424 	/// Set cutting for points outside of bounding box
SetCut(bool val)425 	inline void SetCut(bool val)	{	set(val, MGL_ENABLE_CUT);	}
426 	/// Set additional cutting box
SetCutBox(mreal x1,mreal y1,mreal z1,mreal x2,mreal y2,mreal z2)427 	inline void SetCutBox(mreal x1, mreal y1, mreal z1, mreal x2, mreal y2, mreal z2)
428 	{	CutMin.Set(x1,y1,z1);	CutMax.Set(x2,y2,z2);	}
SetCutBox(const mglPoint & v1,const mglPoint & v2)429 	inline void SetCutBox(const mglPoint &v1, const mglPoint &v2)	{	CutMin=v1;	CutMax=v2;	}
430 	/// Reset mask to solid state
ResetMask()431 	inline void ResetMask()	{	mask = MGL_SOLID_MASK;	MaskAn = DefMaskAn;	}
432 	/// Set default mask rotation angle
SetMaskAngle(int angle)433 	inline void SetMaskAngle(int angle)	{	DefMaskAn = angle;	}
434 
435 	/// Set the using of light on/off.
Light(bool enable)436 	virtual bool Light(bool enable)
437 	{	bool t=get(MGL_ENABLE_LIGHT);	set(enable,MGL_ENABLE_LIGHT);	return t;	}
438 	/// Set to attach light sources to inplot.
AttachLight(bool enable)439 	virtual bool AttachLight(bool enable)
440 	{	bool t=get(MGL_LOCAL_LIGHT);	set(enable,MGL_LOCAL_LIGHT);	return t;	}
441 	/// Set ambient light brightness
442 	virtual void SetAmbient(mreal bright=0.5);
443 	/// Set diffusive light brightness
444 	virtual void SetDiffuse(mreal bright=0.5);
445 	/// Use diffusive light (only for local light sources)
SetDifLight(bool dif)446 	inline void SetDifLight(bool dif)	{	SetDiffuse(dif?0.5:0);	}
447 	/// Set the transparency on/off.
Alpha(bool enable)448 	virtual bool Alpha(bool enable)
449 	{	bool t=get(MGL_ENABLE_ALPHA);	set(enable,MGL_ENABLE_ALPHA);	return t;	}
450 	/// Set default value of alpha-channel
SetAlphaDef(mreal val)451 	inline void SetAlphaDef(mreal val)	{	AlphaDef=val;	}
452 	/// Set default palette
SetPalette(const char * colors)453 	inline void SetPalette(const char *colors)
454 	{	Txt[0].Set(mgl_have_color(colors)?colors:MGL_DEF_PAL,-1);	}
ResetPal()455 	inline void ResetPal()	{	CurrPal=0;	}
GetNumPal(long id)456 	inline long GetNumPal(long id) const	{	return Txt[labs(id)/256].n;	}
457 	/// Set default color scheme
SetDefScheme(const char * colors)458 	inline void SetDefScheme(const char *colors)
459 	{	Txt[1].Set(mgl_have_color(colors)?colors:MGL_DEF_SCH);	}
460 
461 	/// Set number of mesh lines
SetMeshNum(int val)462 	inline void SetMeshNum(int val)	{	MeshNum=val;	}
463 	/// Set relative width of rectangles in Bars, Barh, BoxPlot
SetBarWidth(mreal val)464 	inline void SetBarWidth(mreal val)	{	BarWidth=val>0?val:-BarWidth*val;	}
465 	/// Set size of marks
SetMarkSize(mreal val)466 	inline void SetMarkSize(mreal val)	{	MarkSize=val>0?0.02*val:-val*MarkSize;	}
467 	/// Set size of arrows
SetArrowSize(mreal val)468 	inline void SetArrowSize(mreal val)	{	ArrowSize=val>0?0.03*val:-val*ArrowSize;	}
469 	/// Get unscaled arrow size
GetArrowSize()470 	inline mreal GetArrowSize() const	{	return ArrowSize/0.03;	}
471 
472 	/// Set warning code ant fill Message
473 	void SetWarn(int code, const char *who);
GetWarn()474 	int inline GetWarn() const	{	return WarnCode;	}
475 
476 	virtual void StartAutoGroup (const char *)=0;
477 	void StartGroup(const char *name, int id);
478 	virtual void EndGroup()=0;	//	{	LoadState();	}
479 	/// Highlight group
Highlight(int id)480 	inline void Highlight(int id)	{	HighId=id;	}
481 
482 	/// Set FontSize by size in pt and picture DPI (default is 16 pt for dpi=72)
483 	virtual void SetFontSizePT(mreal pt, int dpi=72){	FontSize = pt*27.f/dpi;	}
484 	/// Set FontSize by size in centimeters and picture DPI (default is 0.56 cm = 16 pt)
485 	inline void SetFontSizeCM(mreal cm, int dpi=72)	{	SetFontSizePT(cm*28.45f,dpi);	}
486 	/// Set FontSize by size in inch and picture DPI (default is 0.22 in = 16 pt)
487 	inline void SetFontSizeIN(mreal in, int dpi=72)	{	SetFontSizePT(in*72.27f,dpi);	}
488 	/// Set font typeface. Note that each mglFont instance can be used with ONLY ONE mglGraph instance at a moment of time!
489 	void SetFont(mglFont *f);
490 	/// Get current typeface. Note that this variable can be deleted at next SetFont() call!
GetFont()491 	inline mglFont *GetFont()	{	return fnt;	}
492 	/// Restore font
493 	void RestoreFont();
494 	/// Load font from file
495 	void LoadFont (const char *name, const char *path=NULL);
496 	/// Copy font from another mglGraph instance
497 	void CopyFont(mglBase *gr);
498 	/// Set default font size
499 	void SetFontHscale(mreal val);
SetFontSize(mreal val)500 	inline void SetFontSize(mreal val)	{	FontSize=val>0 ? val:-FontSize*val;	}
GetFontSize()501 	inline mreal GetFontSize() const	{	return FontSize;	}
502 	mreal TextWidth(const char *text, const char *font, mreal size) const MGL_FUNC_PURE;
503 	mreal TextWidth(const wchar_t *text, const char *font, mreal size) const MGL_FUNC_PURE;
504 	mreal TextHeight(const char *text, const char *font, mreal size) const MGL_FUNC_PURE;
505 	mreal TextHeight(const wchar_t *text, const char *font, mreal size) const MGL_FUNC_PURE;
506 	mreal TextHeight(const char *font, mreal size) const MGL_FUNC_PURE;
FontFactor()507 	inline mreal FontFactor() const		{	return font_factor;	}
508 	virtual mreal GetRatio() const MGL_FUNC_CONST;
509 	virtual int GetWidth() const MGL_FUNC_CONST;
510 	virtual int GetHeight() const MGL_FUNC_CONST;
511 	/// Add user-defined glyph
512 	void DefineGlyph(HCDT x, HCDT y, unsigned char id=0);
513 
514 	/// Set to use or not text rotation
SetRotatedText(bool val)515 	inline void SetRotatedText(bool val)	{	set(val,MGL_ENABLE_RTEXT);	}
516 	/// Set default font style and color
SetFontDef(const char * font)517 	inline void SetFontDef(const char *font){	mgl_strncpy(FontDef, font, 31);	}
518 	/// Set to use or not text rotation
SetTickRotate(bool val)519 	inline void SetTickRotate(bool val)	{	set(val,MGL_TICKS_ROTATE);	}
520 	/// Set to use or not text rotation
SetTickSkip(bool val)521 	inline void SetTickSkip(bool val)	{	set(val,MGL_TICKS_SKIP);	}
522 
523 	/// Add string to legend
524 	void AddLegend(const char *text,const char *style);
525 	void AddLegend(const wchar_t *text,const char *style);
526 	/// Clear saved legend string
ClearLegend()527 	inline void ClearLegend()	{	Leg.clear();	}
528 
529 	/// Set plot quality
530 	virtual void SetQuality(int qual=MGL_DRAW_NORM)	{	Quality=qual;	}
GetQuality()531 	inline int GetQuality() const	{	return Quality;	}
532 	inline void SetDrawReg(long nx=1, long ny=1, long m=0)	{	dr_x=nx;	dr_y=ny;	dr_p=m;	}
533 
534 	// ~~~~~~~~~~~~~~~~~~~~~~ Developer functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
535 	/// Add point to the Pnt and return its position
536 	inline long AddPnt(const mglPoint &p, mreal c=-1, const mglPoint &n=mglPoint(NAN), mreal a=-1, int scl=1)
537 	{	return AddPnt(&B,p,c,n,a,scl);	}
538 	long AddPnt(const mglMatrix *M, const mglPoint &p, mreal c=-1, const mglPoint &n=mglPoint(NAN), mreal a=-1, int scl=1);
539 	bool AddPntQ(mglPnt &q, const mglMatrix *M, mglPoint p, mreal c=-1, mglPoint n=mglPoint(NAN), mreal a=-1, int scl=1);
540 	inline bool AddPntQ(mglPnt &q, mglPoint p, mreal c=-1, const mglPoint &n=mglPoint(NAN), mreal a=-1, int scl=1)
541 	{	return AddPntQ(q,&B,p,c,n,a,scl);	}
542 	inline bool AddPntQ(long id, const mglMatrix *M, const mglPoint &p, mreal c=-1, const mglPoint &n=mglPoint(NAN), mreal a=-1, int scl=1)
543 	{	return AddPntQ(Pnt[id],M,p,c,n,a,scl);	}
544 	inline bool AddPntQ(long id, const mglPoint &p, mreal c=-1, const mglPoint &n=mglPoint(NAN), mreal a=-1, int scl=1)
545 	{	return AddPntQ(Pnt[id],&B,p,c,n,a,scl);	}
SetPntOff(size_t id)546 	inline void SetPntOff(size_t id)	{	Pnt[id].x=NAN;	}
547 	long AllocPnts(size_t num);
548 	long PushPnts(size_t num, const mglPnt *qq);
549 	long CopyNtoC(long k, mreal c);
550 	bool CopyNtoC(mglPnt &q, long k, mreal c);
CopyNtoC(long id,long k,mreal c)551 	inline bool CopyNtoC(long id, long k, mreal c)
552 	{	return (id>=0)?CopyNtoC(Pnt[id],k,c):false;	}
553 	long CopyProj(long from, const mglPoint &p, const mglPoint &n, short sub=0);
554 	bool CopyProj(mglPnt &q, long from, const mglPoint &p, const mglPoint &n, short sub=0);
555 	void CopyProj(long id, long from, const mglPoint &p, const mglPoint &n, short sub=0)
556 	{	if(id>=0)	CopyProj(Pnt[id],from,p,n,sub);	}
DisablePnt(long id)557 	void DisablePnt(long id)	{	Pnt[id].x = NAN;	}
SetRGBA(long k,const mglColor & c)558 	void SetRGBA(long k, const mglColor &c)
559 	{	if(k>=0)	{mglPnt &p=Pnt[k];	p.r = c.r;	p.g = c.g;	p.b = c.b;	p.a = c.a;}	}
560 	virtual void Reserve(long n);	///< Allocate n-cells for Pnt and return current position
561 	/// Set to reduce accuracy of points (to reduce size of output files)
SetReduceAcc(bool val)562 	inline void SetReduceAcc(bool val)	{	set(val, MGL_REDUCEACC);	}
563 	/// Add glyph of current font to the Glf and return its position
564 	long AddGlyph(int s, long j);
565 	/// Add glyph to the Glf and return its position
566 	long AddGlyph(unsigned char id);
567 	/// Add active point as k-th element of Pnt
568 	void AddActive(long k,int n=0);
569 	/// Clear unused points and primitives
570 	void ClearUnused();
571 
GetPenWidth()572 	inline mreal GetPenWidth()	{	return PenWidth;	}
573 
GetB()574 	inline const mglMatrix *GetB()	const	{	return &B;	}
GetPntP(long i)575 	inline mglPoint GetPntP(long i) const
576 	{	const mglPnt &p=Pnt[i];	return mglPoint(p.x,p.y,p.z);	}
GetPntN(long i)577 	inline mglPoint GetPntN(long i) const
578 	{	const mglPnt &p=Pnt[i];	return mglPoint(p.u,p.v,p.w);	}
GetPntC(long i)579 	inline mglColor GetPntC(long i) const
580 	{	const mglPnt &p=Pnt[i];	return mglColor(p.r,p.g,p.b,p.a);	}
GetClrC(long i)581 	inline float GetClrC(long i) const	{	return Pnt[i].c;	}
GetGlf(long i)582 	inline const mglGlyph &GetGlf(long i) const	{	return Glf[i];	}
GetGlfNum()583 	inline long GetGlfNum() const		{	return Glf.size();	}
GetPnt(long i)584 	inline const mglPnt &GetPnt(long i) const	{	return Pnt[i];		}
GetPntNum()585 	inline long GetPntNum() const		{	return Pnt.size();	}
SamePnt(long i,long j)586 	inline bool SamePnt(long i, long j) const
587 	{
588 		if(i<0 || j<0)	return true;
589 		const mglPnt &p=Pnt[i], &q=Pnt[j];
590 		return mgl_isnan(p.x) || mgl_isnan(q.x) || (p.x==q.x && p.y==q.y);
591 	}
ValidPnt(size_t i)592 	inline bool ValidPnt(size_t i)	{	return mgl_isnum(Pnt[i].x);	}
593 //	inline mglPrim &GetPrm(long i)		{	return Prm[i];		}
594 	inline mglPrim &GetPrm(long i, bool sort=true)
595 	{	return (sort && PrmInd) ? Prm[PrmInd[i]]:Prm[i];	}
596 	inline const mglPrim &GetPrm(long i, bool sort=true) const
597 	{	return (sort && PrmInd) ? Prm[PrmInd[i]]:Prm[i];	}
GetPrmNum()598 	inline long GetPrmNum() const		{	return Prm.size();	}
GetPtx(long i)599 	inline const mglText &GetPtx(long i) const	{	return Ptx[i];		}
GetPtxNum()600 	inline long GetPtxNum() const		{	return Ptx.size();	}
GetTxt(long i)601 	inline const mglTexture &GetTxt(long i) const	{	return Txt[i];	}
GetTxtNum()602 	inline long GetTxtNum() const		{	return Txt.size();	}
603 	/// Scale coordinates and cut off some points
604 	virtual bool ScalePoint(const mglMatrix *M, mglPoint &p, mglPoint &n, bool use_nan=true) const;
605 
GetSub(size_t i)606 	inline const mglBlock &GetSub(size_t i) const	{	return Sub[i];	}
GetSub()607 	inline const mglBlock &GetSub() const	{	return Sub.back();	}
608 
609 	virtual mreal GetOrgX(char dir, bool inv=false) const=0;	///< Get Org.x (parse NAN value)
610 	virtual mreal GetOrgY(char dir, bool inv=false) const=0;	///< Get Org.y (parse NAN value)
611 	virtual mreal GetOrgZ(char dir, bool inv=false) const=0;	///< Get Org.z (parse NAN value)
612 
613 	/// Get color depending on single variable z, which should be scaled if scale=true
614 	inline mreal GetC(long s,mreal z,bool scale = true) const
615 	{	return s+(scale?GetA(z):(z<0?0:z/MGL_FEPSILON));	}
616 //	{	return s+(scale?GetA(z):(z>0?z/MGL_FEPSILON:0));	}
617 	/// Get alpha value depending on single variable a
618 	mreal GetA(mreal a) const MGL_FUNC_PURE;
619 	/// Set pen/palette
620 	char SetPenPal(const char *stl, long *id=0, bool pal=true);
621 	/// Add texture (like color scheme) and return the position of first color
622 	long AddTexture(const char *cols, int smooth=0);
623 //	inline mreal AddTexture(char col)	{	return AddTexture(mglColor(col));	}
624 	mreal AddTexture(mglColor col);
DefColor(mglColor col)625 	inline void DefColor(mglColor col)	{	CDef = AddTexture(col);	}
626 	/// Set mask for face coloring
627 	void SetMask(const char *mask);
628 	/// Set next color from palette
629 	mreal NextColor(long &id);
630 	mreal NextColor(long id, long sh);
631 
632 	virtual void mark_plot(long p, char type, mreal size=1)=0;
633 	virtual void arrow_plot(long p1, long p2, char st)=0;
634 	virtual void line_plot(long p1, long p2)=0;
635 	virtual void trig_plot(long p1, long p2, long p3)=0;
636 	virtual void quad_plot(long p1, long p2, long p3, long p4)=0;
637 	virtual void smbl_plot(long p1, char id, double size)=0;
638 	void curve_plot(size_t n, size_t kq, size_t step=1);
639 	virtual void Glyph(mreal x, mreal y, mreal f, int style, long icode, mreal col)=0;
640 	virtual float GetGlyphPhi(const mglPnt &q, float phi)=0;
641 	virtual mreal text_plot(long p,const wchar_t *text,const char *fnt,mreal size=-1,mreal sh=0,mreal  col=-('k'),bool rot=true)=0;
642 	void vect_plot(long p1, long p2, mreal s=1);
643 
644 	// check if visible
645 	virtual bool trig_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3) const =0;
646 	virtual bool quad_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4) const =0;
647 
mark_size()648 	inline mreal mark_size()	{	return MarkSize*font_factor;	}
649 //	inline char last_color()	{	return last_style[1];	}
last_line()650 	inline const char *last_line()	{	return last_style;	}
651 	int PrmCmp(size_t i, size_t j) const MGL_FUNC_PURE;	// compare 2 primitives with indexes i,j
652 	/// Check if plot termination is asked
NeedStop()653 	bool NeedStop()	{	if(event_cb)	event_cb(event_par);	return Stop;	}
654 	/// Ask to stop drawing
655 	void AskStop(bool stop=true)	{	Stop = stop;	}
656 	/// Set callback function for event processing
SetEventFunc(void (* func)(void *),void * par)657 	void SetEventFunc(void (*func)(void *), void *par)	{	event_cb=func;	event_par=par;	}
658 
659 protected:
660 	bool limit_pm1;		///< limit coordinates in range [-1,+1] for OpenGL only
661 	volatile bool Stop;	///< Flag that execution should be terminated.
662 	void (*event_cb)(void *);	///< Function to be called for event processing
663 	void *event_par;	///< Parameter for event processing function
664 
665 	mglPoint OMin;		///< Lower edge for original axis (before scaling)
666 	mglPoint OMax;		///< Upper edge for original axis (before scaling)
667 	mglPoint AMin;		///< Lower edge for axis scaling
668 	mglPoint AMax;		///< Upper edge for axis scaling
669 	mglPoint FMin;		///< Actual lower edge after transformation formulas.
670 	mglPoint FMax;		///< Actual upper edge after transformation formulas.
671 	mglPoint Org;		///< Center of axis cross section.
672 	int WarnCode;		///< Warning code
673 	size_t *PrmInd;		///< Indexes of sorted primitives
674 	mglStack<mglPnt> Pnt; 	///< Internal points
675 	mglStack<mglPrim> Prm;	///< Primitives (lines, triangles and so on) -- need for export
676 	std::vector<mglBlock> Sub;	///< InPlot regions
677 	std::vector<mglText> Ptx;	///< Text labels for mglPrim
678 	std::vector<mglText> Leg;	///< Text labels for legend
679 	std::vector<mglGlyph> Glf;	///< Glyphs data
680 	std::vector<mglTexture> Txt;	///< Pointer to textures
681 #if MGL_HAVE_PTHREAD
682 	pthread_mutex_t mutexPnt, mutexTxt, mutexLeg, mutexGlf, mutexAct, mutexDrw;
683 	pthread_mutex_t mutexSub, mutexPrm, mutexPtx, mutexStk, mutexGrp, mutexClf;
684 #endif
685 	void *lockClf;		///< pointer to mutex for mglStack
686 
687 	int TernAxis;		///< Flag that Ternary axis is used
688 	unsigned PDef;		///< Pen bit mask
689 	mreal pPos;			///< Current position in pen mask
690 	mreal PenWidth;		///< Pen width for further line plotting (must be >0 !!!)
691 //	long numT;			///< Number of textures
692 	mreal AmbBr;		///< Default ambient light brightness
693 	mreal DifBr;		///< Default diffusive light brightness
694 
695 	mreal persp;		///< Original value for perspective
696 	mglMatrix Bp;		///< Transformation matrix for View() and Zoom()
697 	mglMatrix B;		///< Transformation matrix
698 	mglMatrix B1;		///< Transformation matrix for colorbar
699 
700 	mglFont *fnt;		///< Class for printing vector text
701 	mreal FontSize;		///< The size of font for tick and axis labels
702 	char FontDef[32];	///< Font specification (see mglGraph::Puts). Default is Roman with align at center.
703 	int Quality;		///< Quality of plot (0x0-pure, 0x1-fast; 0x2-fine; 0x4 - low memory)
704 
705 	HMEX fx;			///< Transformation formula for x direction.
706 	HMEX fy;			///< Transformation formula for y direction.
707 	HMEX fz;			///< Transformation formula for z direction.
708 	HMEX fa;			///< Transformation formula for coloring.
709 	HMEX fc;			///< Cutting off condition (formula).
710 
711 	long CurrPal;		///< Current palette index
712 	mreal MarkSize;		///< The size of marks for 1D plots.
713 	mreal ArrowSize;	///< The size of arrows.
714 	char last_style[64];///< Last pen style	TODO: replace by std::string
715 	mreal font_factor;	///< Font scaling factor
716 
717 	long dr_x, dr_y, dr_p;	///< default drawing region for quality&4 mode
718 
719 	virtual void LightScale(const mglMatrix *M)=0;			///< Scale positions of light sources
720 	void ClearPrmInd();
721 
722 	// block for SaveState()
723 	mglPoint MinS;		///< Saved lower edge of bounding box for graphics.
724 	mglPoint MaxS;		///< Saved upper edge of bounding box for graphics.
725 	mreal MSS, ASS, FSS, ADS, MNS, LSS;	///< Saved state
726 	mreal PrevState;		///< Previous value of SaveState()
727 	long CSS;			///< Saved flags
728 	bool saved;			///< State is saved
729 	std::string leg_str;///< text to be save in legend
730 
731 	union
732 	{
733 		uint64_t mask;	///< Mask to be used for coloring
734 		unsigned char mask_ch[8];
735 	};
736 	int MaskAn;		///< Mask rotation angle in degrees
737 	int DefMaskAn;	///< Default mask rotation angle in degrees
738 
739 private:
mglBase(const mglBase &)740 	mglBase(const mglBase &){}	// copying is not allowed
741 	const mglBase &operator=(const mglBase &t){return t;}	// copying is not allowed
742 
743 	mglPoint CutMin;	///< Lower edge of bounding box for cut off.
744 	mglPoint CutMax;	///< Upper edge of bounding box for cut off.
745 
746 	bool RecalcCRange();	///< Recalculate internal parameter for correct coloring.
747 	void RecalcBorder();	///< Recalculate internal parameter for correct transformation rules.
748 	bool SetFBord(mreal x,mreal y,mreal z);	///< Set internal boundng box depending on transformation formula
749 	void ClearEq();			///< Clear the used variables for axis transformation
750 };
751 //-----------------------------------------------------------------------------
752 bool MGL_EXPORT mgl_check_dim0(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *name, bool less=false);
753 bool MGL_EXPORT mgl_check_dim1(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *name, bool less=false);
754 bool MGL_EXPORT mgl_check_dim2(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *name, bool less=false);
755 bool MGL_EXPORT mgl_check_dim3(HMGL gr, bool both, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *name);
756 bool MGL_EXPORT mgl_check_vec3(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *name);
757 bool MGL_EXPORT mgl_check_trig(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *name, int d=3);
758 bool MGL_EXPORT mgl_isnboth(HCDT x, HCDT y, HCDT z, HCDT a);
759 bool MGL_EXPORT mgl_isboth(HCDT x, HCDT y, HCDT z, HCDT a);
mgl_islog(mreal a,mreal b)760 inline bool mgl_islog(mreal a,mreal b)	{	return a*b>0 && (b/a+a/b)>=10.1;	}
761 //-----------------------------------------------------------------------------
762 #endif
763 #endif
764