Blob Blame History Raw
diff -urp mathgl-2.1.2/include/mgl2/canvas.h mathgl-2.1.2-stlerror/include/mgl2/canvas.h
--- mathgl-2.1.2/include/mgl2/canvas.h	2013-01-28 18:33:59.000000000 +0700
+++ mathgl-2.1.2-stlerror/include/mgl2/canvas.h	2013-04-23 09:33:14.801413395 +0700
@@ -373,15 +373,15 @@ protected:
 	mreal text_plot(long p,const wchar_t *text,const char *fnt,mreal size=-1,mreal sh=0,mreal  col=-('k'), bool rot=true);
 
 	void add_prim(mglPrim &a);	///< add primitive to list
-	void mark_draw(long p, char type, mreal size, mglDrawReg *d);
-	void arrow_draw(long p1, long p2, char st, mreal size, mglDrawReg *d);
-	virtual void line_draw(long p1, long p2, mglDrawReg *d);
-	virtual void trig_draw(long p1, long p2, long p3, bool anorm, mglDrawReg *d);
-	virtual void quad_draw(long p1, long p2, long p3, long p4, mglDrawReg *d);
-	virtual void pnt_draw(long p, mglDrawReg *d);
+    void mark_draw(const mglPnt &p, char type, mreal size, mglDrawReg *d);
+    void arrow_draw(const mglPnt &p1, const mglPnt &p2, char st, mreal size, mglDrawReg *d);
+    virtual void line_draw(const mglPnt &p1, const mglPnt &p2, mglDrawReg *d);
+    virtual void trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool anorm, mglDrawReg *d);
+    virtual void quad_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4, mglDrawReg *d);
+    virtual void pnt_draw(const mglPnt &p, mglDrawReg *d);
 	void arrow_draw(long n1, long n2, char st, float ll);
-	void arrow_plot_3d(long p1, long p2, char st, float ll);
-	void glyph_draw(const mglPrim *P, mglDrawReg *d);
+    void arrow_plot_3d(long n1, long n2, char st, float ll);
+    void glyph_draw(const mglPrim &P, mglDrawReg *d);
 	bool IsSame(const mglPrim &pr,mreal wp,mglColor cp,int st);
 
 	// restore normalized coordinates from screen ones
@@ -425,7 +425,7 @@ private:
 	/// Combine colors in 2 plane.
 	void combine(unsigned char *c1, const unsigned char *c2);
 	/// Fast drawing of line between 2 points
-	void fast_draw(long p1, long p2, mglDrawReg *d);
+    void fast_draw(const mglPnt &p1, const mglPnt &p2, mglDrawReg *d);
 
 	/// Additionally scale points p for positioning in image
 	void PostScale(mglPoint &p) const;
diff -urp mathgl-2.1.2/include/mgl2/opengl.h mathgl-2.1.2-stlerror/include/mgl2/opengl.h
--- mathgl-2.1.2/include/mgl2/opengl.h	2013-01-28 18:33:59.000000000 +0700
+++ mathgl-2.1.2-stlerror/include/mgl2/opengl.h	2013-04-23 09:34:13.701604344 +0700
@@ -45,10 +45,15 @@ public:
 	void Clf(mglColor Back=WC);
 
 protected:
-	void line_draw(long p1, long p2, mglDrawReg *d);
-	void trig_draw(long p1, long p2, long p3, bool anorm, mglDrawReg *d);
-	void quad_draw(long p1, long p2, long p3, long p4, mglDrawReg *d);
-	void pnt_draw(long p, mglDrawReg *d);
+    // provide fastest variant for usual points (not glyphs or marks)
+    void line_draw(long n1, long n2);
+    void trig_draw(long n1, long n2, long n3);
+    void quad_draw(long n1, long n2, long n3, long n4);
+    // variant for glyphs or marks
+    void line_draw(const mglPnt &p1, const mglPnt &p2, mglDrawReg *d);
+    void trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool anorm, mglDrawReg *d);
+    void quad_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4, mglDrawReg *d);
+    void pnt_draw(const mglPnt &p, mglDrawReg *d);
 
 	unsigned char **GetRGBLines(long &w, long &h, unsigned char *&f, bool solid=true);
 	void LightScale();
diff -urp mathgl-2.1.2/src/canvas.cpp mathgl-2.1.2-stlerror/src/canvas.cpp
--- mathgl-2.1.2/src/canvas.cpp	2013-01-28 18:34:04.000000000 +0700
+++ mathgl-2.1.2-stlerror/src/canvas.cpp	2013-04-23 09:57:19.486537407 +0700
@@ -301,7 +301,7 @@ mreal mglCanvas::GetOrgZ(char dir) const
 //-----------------------------------------------------------------------------
 //	Put primitives
 //-----------------------------------------------------------------------------
-#define MGL_MARK_PLOT	if(Quality&4)	mark_draw(p,type,size,&d);else	\
+#define MGL_MARK_PLOT   if(Quality&4)   mark_draw(Pnt[p],type,size,&d);else \
 						{	mglPrim a;	a.w = pw;	a.s = size;	\
 							a.n1 = p;	a.n4 = type;	add_prim(a);	}
 void mglCanvas::mark_plot(long p, char type, mreal size)
@@ -322,13 +322,14 @@ void mglCanvas::mark_plot(long p, char t
 	else	{	MGL_MARK_PLOT	}
 }
 //-----------------------------------------------------------------------------
-#define MGL_LINE_PLOT	if(Quality&4)	line_draw(p1,p2,&dd);else	\
+#define MGL_LINE_PLOT   if(Quality&4)   line_draw(Pnt[p1],Pnt[p2],&dd);else \
 						{	mglPrim a(1);	a.n3=PDef;	a.s = pPos;	\
 							a.n1 = p1;	a.n2 = p2;	a.w = pw;	add_prim(a);	}
 void mglCanvas::line_plot(long p1, long p2)
 {
 	if(PDef==0)	return;
 	if(p1<0 || p2<0 || mgl_isnan(Pnt[p1].x) || mgl_isnan(Pnt[p2].x))	return;
+    if(p1>p2)   {   long kk=p1; p1=p2;  p2=kk;  }   // rearrange start/end for proper dashing
 	long pp1=p1,pp2=p2;
 	mreal pw = fabs(PenWidth)*sqrt(font_factor/400), d;
 	d = hypot(Pnt[p1].x-Pnt[p2].x, Pnt[p1].y-Pnt[p2].y);
@@ -344,7 +345,7 @@ void mglCanvas::line_plot(long p1, long
 	pPos = fmod(pPos+d/pw/1.5, 16);
 }
 //-----------------------------------------------------------------------------
-#define MGL_TRIG_PLOT	if(Quality&4)	trig_draw(p1,p2,p3,true,&d);else	\
+#define MGL_TRIG_PLOT   if(Quality&4)   trig_draw(Pnt[p1],Pnt[p2],Pnt[p3],true,&d);else \
 						{	mglPrim a(2);	a.n1 = p1;	a.n2 = p2;	\
 							a.n3 = p3;	add_prim(a);}
 void mglCanvas::trig_plot(long p1, long p2, long p3)
@@ -358,7 +359,7 @@ void mglCanvas::trig_plot(long p1, long
 	else	{	MGL_TRIG_PLOT	}
 }
 //-----------------------------------------------------------------------------
-#define MGL_QUAD_PLOT	if(Quality&4)	quad_draw(p1,p2,p3,p4,&d);else	\
+#define MGL_QUAD_PLOT   if(Quality&4)   quad_draw(Pnt[p1],Pnt[p2],Pnt[p3],Pnt[p4],&d);else  \
 						{	mglPrim a(3);	a.n1 = p1;	a.n2 = p2;	\
 							a.n3 = p3;	a.n4 = p4;	add_prim(a);	}
 void mglCanvas::quad_plot(long p1, long p2, long p3, long p4)
@@ -480,7 +481,7 @@ void mglCanvas::Glyph(mreal x, mreal y,
 	d.PDef = s;		d.pPos = a.s;
 	d.ObjId=ObjId;	d.PenWidth=a.w;
 	
-	if(Quality&4)	glyph_draw(&a,&d);
+	if(Quality&4)   glyph_draw(a,&d);
 	else	add_prim(a);
 }
 //-----------------------------------------------------------------------------
@@ -708,6 +709,7 @@ void mglCanvas::AddLight(int n, mglPoint
 //-----------------------------------------------------------------------------
 void mglCanvas::arrow_plot(long n1, long n2, char st)
 {
+    if(n1<0 || n2<0 || !strchr("AVKSDTIO",st))  return;
 	float ll = PenWidth*ArrowSize*0.35*font_factor;
 	if((Quality&3)==3)
 		arrow_plot_3d(n1, n2, st, ll);
diff -urp mathgl-2.1.2/src/opengl.cpp mathgl-2.1.2-stlerror/src/opengl.cpp
--- mathgl-2.1.2/src/opengl.cpp	2013-01-28 18:34:04.000000000 +0700
+++ mathgl-2.1.2-stlerror/src/opengl.cpp	2013-04-23 11:09:18.381161728 +0700
@@ -41,11 +41,11 @@ void mglCanvasGL::Finish(bool fast)
 			p=Prm[i];	PDef=p.n3;	pPos=p.s;	PenWidth=p.w;
 			switch(p.type)
 			{
-			case 0:	mark_draw(p.n1,p.n4,p.s,0);	break;
-			case 1:	line_draw(p.n1,p.n2,0);		break;
-			case 2:	trig_draw(p.n1,p.n2,p.n3,true,0);	break;
-			case 3:	quad_draw(p.n1,p.n2,p.n3,p.n4,0);	break;
-			case 4:	glyph_draw(&p,0);	break;
+            case 0: mark_draw(Pnt[p.n1],p.n4,p.s,0);    break;
+            case 1: line_draw(p.n1,p.n2);   break;
+            case 2: trig_draw(p.n1,p.n2,p.n3);  break;
+            case 3: quad_draw(p.n1,p.n2,p.n3,p.n4); break;
+            case 4: glyph_draw(p,0);    break;
 			}
 		}
 		PDef=pdef;	pPos=ss;	PenWidth=ww;
@@ -231,26 +231,24 @@ unsigned char **mglCanvasGL::GetRGBLines
 	return p;
 }
 //-----------------------------------------------------------------------------
-void mglCanvasGL::trig_draw(long k1, long k2, long k3, bool, mglDrawReg *)
+void mglCanvasGL::quad_draw(long k1, long k2, long k3, long k4)
 {
-	if(k1<0 || k2<0 || k3<0)	return;
-	glBegin(GL_TRIANGLES);
-	glArrayElement(k1);	glArrayElement(k2);	glArrayElement(k3);
+    glBegin(GL_QUADS);
+    glArrayElement(k1); glArrayElement(k2);
+    glArrayElement(k4); glArrayElement(k3);
 	glEnd();
 }
 //-----------------------------------------------------------------------------
-void mglCanvasGL::quad_draw(long k1, long k2, long k3, long k4, mglDrawReg *)
+void mglCanvasGL::trig_draw(long k1, long k2, long k3)
 {
-	if(k1<0 || k2<0 || k3<0 || k4<0)	return;
-	glBegin(GL_QUADS);
-	glArrayElement(k1);	glArrayElement(k2);
-	glArrayElement(k4);	glArrayElement(k3);
+    glBegin(GL_TRIANGLES);
+    glArrayElement(k1); glArrayElement(k2); glArrayElement(k3);
 	glEnd();
 }
 //-----------------------------------------------------------------------------
-void mglCanvasGL::line_draw(long k1, long k2, mglDrawReg *)
+void mglCanvasGL::line_draw(long k1, long k2)
 {
-	if(k1<0 || k2<0 || PDef==0)	return;
+	if(PDef==0) return;
 /*	unsigned pdef = PDef*0x10001;
 	pdef = pdef << (int(100*pPos+0.5)%16);
 	set_pen(pdef&0xffff,PenWidth);*/
@@ -260,12 +258,39 @@ void mglCanvasGL::line_draw(long k1, lon
 	glEnd();
 }
 //-----------------------------------------------------------------------------
-void mglCanvasGL::pnt_draw(long k1, mglDrawReg *)
+void mglCanvasGL::quad_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4, mglDrawReg *)
+{
+    glBegin(GL_QUADS);
+    glNormal3f(p1.u,p1.v,p1.w); glColor4f(p1.r,p1.g,p1.b,p1.a); glVertex3f(p1.x,p1.y,p1.z);
+    glNormal3f(p2.u,p2.v,p2.w); glColor4f(p2.r,p2.g,p2.b,p2.a); glVertex3f(p2.x,p2.y,p2.z);
+    glNormal3f(p3.u,p3.v,p3.w); glColor4f(p3.r,p3.g,p3.b,p3.a); glVertex3f(p3.x,p3.y,p3.z);
+    glNormal3f(p4.u,p4.v,p4.w); glColor4f(p4.r,p4.g,p4.b,p4.a); glVertex3f(p4.x,p4.y,p4.z);
+    glEnd();
+}
+//-----------------------------------------------------------------------------
+void mglCanvasGL::trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool, mglDrawReg *)
+{
+    glBegin(GL_TRIANGLES);
+    glNormal3f(p1.u,p1.v,p1.w); glColor4f(p1.r,p1.g,p1.b,p1.a); glVertex3f(p1.x,p1.y,p1.z);
+    glNormal3f(p2.u,p2.v,p2.w); glColor4f(p2.r,p2.g,p2.b,p2.a); glVertex3f(p2.x,p2.y,p2.z);
+    glNormal3f(p3.u,p3.v,p3.w); glColor4f(p3.r,p3.g,p3.b,p3.a); glVertex3f(p3.x,p3.y,p3.z);
+    glEnd();
+}
+//-----------------------------------------------------------------------------
+void mglCanvasGL::line_draw(const mglPnt &p1, const mglPnt &p2, mglDrawReg *)
+{
+    if(PDef==0) return;
+    set_pen(PDef,PenWidth);
+    glBegin(GL_LINES);
+    glColor4f(p1.r,p1.g,p1.b,p1.a); glVertex3f(p1.x,p1.y,p1.z);
+    glColor4f(p2.r,p2.g,p2.b,p2.a); glVertex3f(p2.x,p2.y,p2.z);
+    glEnd();
+}
+//-----------------------------------------------------------------------------
+void mglCanvasGL::pnt_draw(const mglPnt &p1, mglDrawReg *)
 {
-	if(k1<0)	return;
 	glBegin(GL_POINTS);
-	glArrayElement(k1);
+	glColor4f(p1.r,p1.g,p1.b,p1.a); glVertex3f(p1.x,p1.y,p1.z);
 	glEnd();
 }
 //-----------------------------------------------------------------------------
-
diff -urp mathgl-2.1.2/src/pixel.cpp mathgl-2.1.2-stlerror/src/pixel.cpp
--- mathgl-2.1.2/src/pixel.cpp	2013-01-28 18:34:04.000000000 +0700
+++ mathgl-2.1.2-stlerror/src/pixel.cpp	2013-04-23 10:34:47.308501443 +0700
@@ -304,11 +304,11 @@ void mglCanvas::pxl_primdr(size_t id, si
 		d.ObjId = p.id;	d.PenWidth=p.w;
 		switch(p.type)
 		{
-		case 0:	mark_draw(p.n1,p.n4,p.s,&d);	break;
-		case 1:	line_draw(p.n1,p.n2,&d);		break;
-		case 2:	trig_draw(p.n1,p.n2,p.n3,true,&d);	break;
-		case 3:	quad_draw(p.n1,p.n2,p.n3,p.n4,&d);	break;
-		case 4:	glyph_draw(&p,&d);	break;
+        case 0: mark_draw(Pnt[p.n1],p.n4,p.s,&d);   break;
+        case 1: line_draw(Pnt[p.n1],Pnt[p.n2],&d);      break;
+        case 2: trig_draw(Pnt[p.n1],Pnt[p.n2],Pnt[p.n3],true,&d);   break;
+        case 3: quad_draw(Pnt[p.n1],Pnt[p.n2],Pnt[p.n3],Pnt[p.n4],&d);  break;
+        case 4: glyph_draw(p,&d);   break;
 		}
 	}
 }
@@ -586,17 +586,16 @@ unsigned char **mglCanvas::GetRGBLines(l
 /* Bilinear interpolation r(u,v) = r0 + (r1-r0)*u + (r2-r0)*v + (r3+r0-r1-r2)*u*v
 	is used (where r is one of {x,y,z,R,G,B,A}. Variables u,v are determined
 	for each point (x,y) and selected one pair which 0<u<1 and 0<v<1.*/
-void mglCanvas::quad_draw(long k1, long k2, long k3, long k4, mglDrawReg *d)
+void mglCanvas::quad_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4, mglDrawReg *d)
 {
 	if(!(Quality&3))
 	{
-		fast_draw(k1,k2,d);	fast_draw(k1,k3,d);
-		fast_draw(k4,k2,d);	fast_draw(k4,k3,d);	return;
+        fast_draw(p1,p2,d); fast_draw(p1,p3,d);
+        fast_draw(p4,p2,d); fast_draw(p4,p3,d); return;
 	}
 	unsigned char r[4];
 	long y1,x1,y2,x2;
 	float dd,dsx,dsy;
-	const mglPnt &p1=Pnt[k1], &p2=Pnt[k2], &p3=Pnt[k3], &p4=Pnt[k4];
 	mglPnt d1=p2-p1, d2=p3-p1, d3=p4+p1-p2-p3, p;
 
 	x1 = long(fmin(fmin(p1.x,p2.x),fmin(p3.x,p4.x)));	// bounding box
@@ -612,7 +611,7 @@ void mglCanvas::quad_draw(long k1, long
 	dsy = 4*(d2.y*d3.x - d2.x*d3.y)*d1.x;
 
 	if((d1.x==0 && d1.y==0) || (d2.x==0 && d2.y==0) || !(Quality&2))
-	{	trig_draw(k1,k2,k4,true,d);	trig_draw(k1,k3,k4,true,d);	return;	}
+	{   trig_draw(p1,p2,p4,true,d); trig_draw(p1,p3,p4,true,d); return; }
 
 	mglPoint n1 = mglPoint(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z)^mglPoint(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z);
 	mglPoint n2 = mglPoint(p2.x-p4.x,p2.y-p4.y,p2.z-p4.z)^mglPoint(p3.x-p4.x,p3.y-p4.y,p3.z-p4.z);
@@ -657,17 +656,16 @@ void mglCanvas::quad_draw(long k1, long
 /* Linear interpolation r(u,v) = r0 + (r1-r0)*u + (r2-r0)*v is used, where r is
 	one of {x,y,z,R,G,B,A}. Variables u,v are determined for each point (x,y).
 	Point plotted is u>0 and v>0 and u+v<1.*/
-void mglCanvas::trig_draw(long k1, long k2, long k3, bool anorm, mglDrawReg *d)
+void mglCanvas::trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool anorm, mglDrawReg *d)
 {
 	if(!(Quality&3))
 	{
-		fast_draw(k1,k2,d);	fast_draw(k1,k3,d);
-		fast_draw(k2,k3,d);	return;
+        fast_draw(p1,p2,d); fast_draw(p1,p3,d);
+        fast_draw(p2,p3,d); return;
 	}
 	unsigned char r[4];
 	long y1,x1,y2,x2;
 	float dxu,dxv,dyu,dyv;
-	const mglPnt &p1=Pnt[k1], &p2=Pnt[k2], &p3=Pnt[k3];
 	mglPnt d1=p2-p1, d2=p3-p1, p;
 
 	dxu = d2.x*d1.y - d1.x*d2.y;
@@ -704,10 +702,9 @@ void mglCanvas::trig_draw(long k1, long
 	}
 }
 //-----------------------------------------------------------------------------
-void mglCanvas::line_draw(long k1, long k2, mglDrawReg *dr)
+void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, mglDrawReg *dr)
 {
-	if(k1>k2)	{	long kk=k1;	k1=k2;	k2=kk;	}	// rearrange start/end for proper dashing
-	if(!(Quality&3))	{	fast_draw(k1,k2,dr);	return;	}
+	if(!(Quality&3))    {   fast_draw(p1,p2,dr);    return; }
 	unsigned char r[4];
 	long y1,x1,y2,x2;
 
@@ -715,7 +712,6 @@ void mglCanvas::line_draw(long k1, long
 	float dz = Width>2 ? 1 : 1e-5*Width;		// provide additional height to be well visible on the surfaces
 
 	if(dr->ObjId==HighId)	{	pw *= 2;	dpw=2;	}
-	const mglPnt &p1=Pnt[k1], &p2=Pnt[k2];
 	mglPnt d=p2-p1, p;
 	bool hor = fabs(d.x)>fabs(d.y);
 
@@ -777,9 +773,8 @@ void mglCanvas::line_draw(long k1, long
 	set(aa,MGL_ENABLE_ALPHA);
 }
 //-----------------------------------------------------------------------------
-void mglCanvas::fast_draw(long k1, long k2, mglDrawReg *dr)
+void mglCanvas::fast_draw(const mglPnt &p1, const mglPnt &p2, mglDrawReg *dr)
 {
-	const mglPnt &p1=Pnt[k1], &p2=Pnt[k2];
 	mglPnt d=p2-p1;
 	unsigned char r[4];	col2int(p1,r,dr->ObjId);
 	long y1,x1,y2,x2;
@@ -807,12 +802,11 @@ void mglCanvas::fast_draw(long k1, long
 	}
 }
 //-----------------------------------------------------------------------------
-void mglCanvas::pnt_draw(long k, mglDrawReg *dr)
+void mglCanvas::pnt_draw(const mglPnt &p, mglDrawReg *dr)
 {
 	register long i,j,s,x,y;
 	register float v,pw=3*dr->PenWidth,dpw=3;
 	if(dr->ObjId==HighId)	{	pw *= 2;	dpw=2;	}
-	const mglPnt &p=Pnt[k];
 	unsigned char cs[4], cc;
 	col2int(p,cs,dr->ObjId);	cc = cs[3];
 	if(cc==0)	return;
@@ -829,21 +823,17 @@ void mglCanvas::pnt_draw(long k, mglDraw
 	}
 }
 //-----------------------------------------------------------------------------
-void mglCanvas::mark_draw(long k, char type, mreal size, mglDrawReg *d)
+void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *d)
 {
-	const mglPnt &q=Pnt[k];
 	unsigned char cs[4];	col2int(q,cs,d->ObjId);	cs[3] = size>0 ? 255 : 255*q.t;
-	mglPnt p=q;
+	mglPnt p0=q,p1=q,p2=q,p3=q;
 	mreal ss=fabs(size);
 	register long i,j;
-#if MGL_HAVE_PTHREAD
-	pthread_mutex_lock(&mutexPnt);
-#endif
-	size_t pos = Pnt.size(), qos=pos;
+
 	if(type=='.' || ss==0)
 	{
 		if(d)	d->PenWidth = ss?ss:sqrt(font_factor/400);
-		pnt_draw(k,d);
+		pnt_draw(q,d);
 	}
 	else
 	{
@@ -856,107 +846,100 @@ void mglCanvas::mark_draw(long k, char t
 		switch(type)
 		{
 		case 'P':
-			p.x = q.x-ss;	p.y = q.y-ss;	Pnt.push_back(p);
-			p.x = q.x+ss;	p.y = q.y-ss;	Pnt.push_back(p);	line_draw(pos,pos+1,d);
-			p.x = q.x+ss;	p.y = q.y+ss;	Pnt.push_back(p);	line_draw(pos+1,pos+2,d);
-			p.x = q.x-ss;	p.y = q.y+ss;	Pnt.push_back(p);	line_draw(pos+2,pos+3,d);
-			line_draw(pos+3,pos,d);	qos+=4;
+            p0.x = q.x-ss;  p0.y = q.y-ss;  p1.x = q.x+ss;  p1.y = q.y-ss;
+            p2.x = q.x+ss;  p2.y = q.y+ss;  p3.x = q.x-ss;  p3.y = q.y+ss;
+            line_draw(p0,p1,d); line_draw(p1,p2,d);
+            line_draw(p2,p3,d); line_draw(p3,p0,d);
 		case '+':
-			p.x = q.x-ss;	p.y = q.y;		Pnt.push_back(p);
-			p.x = q.x+ss;	p.y = q.y;		Pnt.push_back(p);	line_draw(qos,qos+1,d);
-			p.x = q.x;	p.y = q.y-ss;		Pnt.push_back(p);
-			p.x = q.x;	p.y = q.y+ss;		Pnt.push_back(p);	line_draw(qos+2,qos+3,d);
+            p0.x = q.x-ss;  p0.y = q.y; p1.x = q.x+ss;  p1.y = q.y; line_draw(p0,p1,d);
+            p2.x = q.x; p2.y = q.y-ss;  p3.x = q.x; p3.y = q.y+ss;  line_draw(p2,p3,d);
 			break;
 		case 'X':
-			p.x = q.x-ss;	p.y = q.y-ss;	Pnt.push_back(p);
-			p.x = q.x+ss;	p.y = q.y-ss;	Pnt.push_back(p);	line_draw(pos,pos+1,d);
-			p.x = q.x+ss;	p.y = q.y+ss;	Pnt.push_back(p);	line_draw(pos+1,pos+2,d);
-			p.x = q.x-ss;	p.y = q.y+ss;	Pnt.push_back(p);	line_draw(pos+2,pos+3,d);
-			line_draw(pos+3,pos,d);	qos+=4;
+            p0.x = q.x-ss;  p0.y = q.y-ss;  p1.x = q.x+ss;  p1.y = q.y-ss;
+            p2.x = q.x+ss;  p2.y = q.y+ss;  p3.x = q.x-ss;  p3.y = q.y+ss;
+            line_draw(p0,p1,d); line_draw(p1,p2,d);
+            line_draw(p2,p3,d); line_draw(p3,p0,d);
 		case 'x':
-			p.x = q.x-ss;	p.y = q.y-ss;	Pnt.push_back(p);
-			p.x = q.x+ss;	p.y = q.y+ss;	Pnt.push_back(p);	line_draw(qos,qos+1,d);
-			p.x = q.x+ss;	p.y = q.y-ss;	Pnt.push_back(p);
-			p.x = q.x-ss;	p.y = q.y+ss;	Pnt.push_back(p);	line_draw(qos+2,qos+3,d);
+            p0.x = q.x-ss;  p0.y = q.y-ss;  p1.x = q.x+ss;  p1.y = q.y+ss;  line_draw(p0,p1,d);
+            p2.x = q.x+ss;  p2.y = q.y-ss;  p3.x = q.x-ss;  p3.y = q.y+ss;  line_draw(p2,p3,d);
 			break;
 		case 'S':
-			p.x = q.x-ss;	p.y = q.y-ss;	Pnt.push_back(p);
-			p.x = q.x-ss;	p.y = q.y+ss;	Pnt.push_back(p);
-			p.x= q.x+ss;	p.y= q.y+ss;	Pnt.push_back(p);
-			p.x = q.x+ss;	p.y = q.y-ss;	Pnt.push_back(p);
-			quad_draw(pos,pos+1,pos+3,pos+2,d);	qos+=4;
+            p0.x = q.x-ss;  p0.y = q.y-ss;  p1.x = q.x-ss;  p1.y = q.y+ss;
+            p2.x= q.x+ss;   p2.y= q.y+ss;   p3.x = q.x+ss;  p3.y = q.y-ss;
+            quad_draw(p0,p1,p3,p2,d);
 		case 's':
-			p.x = q.x-ss;	p.y = q.y-ss;	Pnt.push_back(p);
-			p.x = q.x+ss;	p.y = q.y-ss;	Pnt.push_back(p);	line_draw(qos,qos+1,d);
-			p.x = q.x+ss;	p.y = q.y+ss;	Pnt.push_back(p);	line_draw(qos+1,qos+2,d);
-			p.x = q.x-ss;	p.y = q.y+ss;	Pnt.push_back(p);	line_draw(qos+2,qos+3,d);
-			line_draw(qos+3,qos,d);	break;
+            p0.x = q.x-ss;  p0.y = q.y-ss;  p1.x = q.x+ss;  p1.y = q.y-ss;
+            p2.x = q.x+ss;  p2.y = q.y+ss;  p3.x = q.x-ss;  p3.y = q.y+ss;
+            line_draw(p0,p1,d); line_draw(p1,p2,d);
+            line_draw(p2,p3,d); line_draw(p3,p0,d);
+            break;
 		case 'D':
-			p.x = q.x;	p.y = q.y-ss;		Pnt.push_back(p);
-			p.x = q.x+ss;	p.y = q.y;		Pnt.push_back(p);
-			p.x= q.x;	p.y= q.y+ss;		Pnt.push_back(p);
-			p.x = q.x-ss;	p.y = q.y;		Pnt.push_back(p);
-			quad_draw(pos,pos+1,pos+3,pos+2,d);	qos+=4;
+            p0.x = q.x; p0.y = q.y-ss;  p1.x = q.x+ss;  p1.y = q.y;
+            p2.x= q.x;  p2.y= q.y+ss;   p3.x = q.x-ss;  p3.y = q.y;
+            quad_draw(p0,p1,p3,p2,d);
 		case 'd':
-			p.x = q.x;	p.y = q.y-ss;		Pnt.push_back(p);
-			p.x = q.x+ss;	p.y = q.y;		Pnt.push_back(p);	line_draw(qos,qos+1,d);
-			p.x = q.x;	p.y = q.y+ss;		Pnt.push_back(p);	line_draw(qos+1,qos+2,d);
-			p.x = q.x-ss;	p.y = q.y;		Pnt.push_back(p);	line_draw(qos+2,qos+3,d);
-			line_draw(qos+3,qos,d);	break;
+            p0.x = q.x; p0.y = q.y-ss;  p1.x = q.x+ss;  p1.y = q.y;
+            p2.x = q.x; p2.y = q.y+ss;  p3.x = q.x-ss;  p3.y = q.y;
+            line_draw(p0,p1,d); line_draw(p1,p2,d);
+            line_draw(p2,p3,d); line_draw(p3,p0,d);
+            break;
 		case 'Y':
-			p.x = q.x;	p.y = q.y;			Pnt.push_back(p);
-			p.x = q.x;	p.y = q.y-ss;		Pnt.push_back(p);	line_draw(pos,pos+1,d);
-			p.x = q.x-0.8*ss;	p.y = q.y+0.6*ss;	Pnt.push_back(p);	line_draw(pos,pos+2,d);
-			p.x = q.x+0.8*ss;	p.y = q.y+0.6*ss;	Pnt.push_back(p);	line_draw(pos,pos+3,d);
+            p1.x = q.x; p1.y = q.y-ss;  line_draw(q,p1,d);
+            p2.x = q.x-0.8*ss;  p2.y = q.y+0.6*ss;  line_draw(q,p2,d);
+            p3.x = q.x+0.8*ss;  p3.y = q.y+0.6*ss;  line_draw(q,p3,d);
 			break;
 		case '*':
-			p.x = q.x-ss;		p.y = q.y;	Pnt.push_back(p);
-			p.x = q.x+ss;		p.y = q.y;	Pnt.push_back(p);	line_draw(pos,pos+1,d);
-			p.x = q.x-0.6*ss;	p.y = q.y-0.8*ss;	Pnt.push_back(p);
-			p.x = q.x+0.6*ss;	p.y = q.y+0.8*ss;	Pnt.push_back(p);	line_draw(pos+2,pos+3,d);
-			p.x = q.x-0.6*ss;	p.y = q.y+0.8*ss;	Pnt.push_back(p);
-			p.x = q.x+0.6*ss;	p.y = q.y-0.8*ss;	Pnt.push_back(p);	line_draw(pos+4,pos+5,d);
+            p0.x = q.x-ss;      p0.y = q.y;
+            p1.x = q.x+ss;      p1.y = q.y; line_draw(p0,p1,d);
+            p0.x = q.x-0.6*ss;  p0.y = q.y-0.8*ss;
+            p1.x = q.x+0.6*ss;  p1.y = q.y+0.8*ss;  line_draw(p0,p1,d);
+            p0.x = q.x-0.6*ss;  p0.y = q.y+0.8*ss;
+            p1.x = q.x+0.6*ss;  p1.y = q.y-0.8*ss;  line_draw(p0,p1,d);
 			break;
 		case 'T':
-			p.x = q.x-ss;	p.y = q.y-ss/2;	Pnt.push_back(p);
-			p.x = q.x+ss;	p.y = q.y-ss/2;	Pnt.push_back(p);
-			p.x= q.x;		p.y= q.y+ss;	Pnt.push_back(p);
-			trig_draw(pos,pos+1,pos+2,false,d);	qos+=3;
+            p0.x = q.x-ss;  p0.y = q.y-ss/2;
+            p1.x = q.x+ss;  p1.y = q.y-ss/2;
+            p2.x= q.x;      p2.y= q.y+ss;
+            trig_draw(p0,p1,p2,false,d);
 		case '^':
-			p.x = q.x-ss;	p.y = q.y-ss/2;	Pnt.push_back(p);
-			p.x = q.x+ss;	p.y = q.y-ss/2;	Pnt.push_back(p);	line_draw(qos,qos+1,d);
-			p.x= q.x;		p.y= q.y+ss;	Pnt.push_back(p);	line_draw(qos+1,qos+2,d);
-			line_draw(qos+2,qos,d);		break;
+            p0.x = q.x-ss;  p0.y = q.y-ss/2;
+            p1.x = q.x+ss;  p1.y = q.y-ss/2;
+            p2.x= q.x;      p2.y= q.y+ss;
+            line_draw(p0,p1,d); line_draw(p1,p2,d);
+            line_draw(p2,p0,d); break;
 		case 'V':
-			p.x = q.x-ss;	p.y = q.y+ss/2;	Pnt.push_back(p);
-			p.x = q.x+ss;	p.y = q.y+ss/2;	Pnt.push_back(p);
-			p.x= q.x;		p.y= q.y-ss;	Pnt.push_back(p);
-			trig_draw(pos,pos+1,pos+2,false,d);	qos+=3;
+            p0.x = q.x-ss;  p0.y = q.y+ss/2;
+            p1.x = q.x+ss;  p1.y = q.y+ss/2;
+            p2.x= q.x;      p2.y= q.y-ss;
+            trig_draw(p0,p1,p2,false,d);
 		case 'v':
-			p.x = q.x-ss;	p.y = q.y+ss/2;	Pnt.push_back(p);
-			p.x = q.x+ss;	p.y = q.y+ss/2;	Pnt.push_back(p);	line_draw(qos,qos+1,d);
-			p.x= q.x;		p.y= q.y-ss;	Pnt.push_back(p);	line_draw(qos+1,qos+2,d);
-			line_draw(qos+2,qos,d);		break;
+            p0.x = q.x-ss;  p0.y = q.y+ss/2;
+            p1.x = q.x+ss;  p1.y = q.y+ss/2;
+            p2.x= q.x;      p2.y= q.y-ss;
+            line_draw(p0,p1,d); line_draw(p1,p2,d);
+            line_draw(p2,p0,d); break;
 		case 'L':
-			p.x = q.x+ss/2;	p.y = q.y+ss;	Pnt.push_back(p);
-			p.x = q.x+ss/2;	p.y = q.y-ss;	Pnt.push_back(p);
-			p.x= q.x-ss;	p.y= q.y;		Pnt.push_back(p);
-			trig_draw(pos,pos+1,pos+2,false,d);	qos+=3;
+            p0.x = q.x+ss/2;    p0.y = q.y+ss;
+            p1.x = q.x+ss/2;    p1.y = q.y-ss;
+            p2.x= q.x-ss;       p2.y= q.y;
+            trig_draw(p0,p1,p2,false,d);
 		case '<':
-			p.x = q.x+ss/2;	p.y = q.y+ss;	Pnt.push_back(p);
-			p.x = q.x+ss/2;	p.y = q.y-ss;	Pnt.push_back(p);	line_draw(qos,qos+1,d);
-			p.x= q.x-ss;	p.y= q.y;		Pnt.push_back(p);	line_draw(qos+1,qos+2,d);
-			line_draw(qos+2,qos,d);		break;
+            p0.x = q.x+ss/2;    p0.y = q.y+ss;
+            p1.x = q.x+ss/2;    p1.y = q.y-ss;
+            p2.x= q.x-ss;       p2.y= q.y;
+            line_draw(p0,p1,d); line_draw(p1,p2,d);
+            line_draw(p2,p0,d); break;
 		case 'R':
-			p.x = q.x-ss/2;	p.y = q.y+ss;	Pnt.push_back(p);
-			p.x = q.x-ss/2;	p.y = q.y-ss;	Pnt.push_back(p);
-			p.x= q.x+ss;	p.y= q.y;		Pnt.push_back(p);
-			trig_draw(pos,pos+1,pos+2,false,d);	qos+=3;
+            p0.x = q.x-ss/2;    p0.y = q.y+ss;
+            p1.x = q.x-ss/2;    p1.y = q.y-ss;
+            p2.x= q.x+ss;       p2.y= q.y;
+            trig_draw(p0,p1,p2,false,d);
 		case '>':
-			p.x = q.x-ss/2;	p.y = q.y+ss;	Pnt.push_back(p);
-			p.x = q.x-ss/2;	p.y = q.y-ss;	Pnt.push_back(p);	line_draw(qos,qos+1,d);
-			p.x= q.x+ss;	p.y= q.y;		Pnt.push_back(p);	line_draw(qos+1,qos+2,d);
-			line_draw(qos+2,qos,d);		break;
+            p0.x = q.x-ss/2;    p0.y = q.y+ss;
+            p1.x = q.x-ss/2;    p1.y = q.y-ss;
+            p2.x= q.x+ss;       p2.y= q.y;
+            line_draw(p0,p1,d); line_draw(p1,p2,d);
+            line_draw(p2,p0,d); break;
 		case 'O':
 			for(j=long(-ss);j<=long(ss);j++)	for(i=long(-ss);i<=long(ss);i++)
 			{
@@ -967,24 +950,20 @@ void mglCanvas::mark_draw(long k, char t
 		case 'o':
 			for(i=0;i<=20;i++)
 			{
-				p.x = q.x+ss*cos(i*M_PI/10);	p.y = q.y+ss*sin(i*M_PI/10);	Pnt.push_back(p);
-				if(i>0)	line_draw(pos+i-1,pos+i,d);
+                p0 = p1;    p1.x = q.x+ss*cos(i*M_PI/10);   p1.y = q.y+ss*sin(i*M_PI/10);
+                if(i>0) line_draw(p0,p1,d);
 			}
 			break;
 		case 'C':
-			pnt_draw(k,d);
+			pnt_draw(q,d);
 			for(i=0;i<=20;i++)
 			{
-				p.x = q.x+ss*cos(i*M_PI/10);	p.y = q.y+ss*sin(i*M_PI/10);	Pnt.push_back(p);
-				if(i>0)	line_draw(pos+i-1,pos+i,d);
+                p0 = p1;    p1.x = q.x+ss*cos(i*M_PI/10);   p1.y = q.y+ss*sin(i*M_PI/10);
+                if(i>0) line_draw(p0,p1,d);
 			}
 			break;
 		}
-		Pnt.erase(Pnt.begin()+pos,Pnt.end());
 	}
-#if MGL_HAVE_PTHREAD
-	pthread_mutex_unlock(&mutexPnt);
-#endif
 }
 //-----------------------------------------------------------------------------
 // scale direction for new view/zoom
@@ -1009,31 +988,31 @@ float mglCanvas::GetGlyphPhi(const mglPn
 	return phi;
 }
 //-----------------------------------------------------------------------------
-void mglCanvas::glyph_draw(const mglPrim *P, mglDrawReg *d)
+void mglCanvas::glyph_draw(const mglPrim &P, mglDrawReg *d)
 {
-	float phi = GetGlyphPhi(Pnt[P->n2],P->w);
+	float phi = GetGlyphPhi(Pnt[P.n2],P.w);
 	if(mgl_isnan(phi))	return;
 
-	mglPnt p=Pnt[P->n1];
-	mreal pf=sqrt((Bp.b[0]*Bp.b[0]+Bp.b[1]*Bp.b[1]+Bp.b[3]*Bp.b[3]+Bp.b[4]*Bp.b[4])/2), f = P->p*pf;
+    mglPnt p=Pnt[P.n1];
+    mreal pf=sqrt((Bp.b[0]*Bp.b[0]+Bp.b[1]*Bp.b[1]+Bp.b[3]*Bp.b[3]+Bp.b[4]*Bp.b[4])/2), f = P.p*pf;
 #if MGL_HAVE_PTHREAD
 	pthread_mutex_lock(&mutexPnt);
 #endif
 	Push();		B.clear();
-	B.b[0] = B.b[4] = B.b[8] = P->s;
+	B.b[0] = B.b[4] = B.b[8] = P.s;
 	RotateN(phi,0,0,1);
 	B.x=p.x;	B.y=p.y;	B.z=p.z;	B.pf = 1;
 	p.u *= pf;	p.v *= pf;
 
-	const mglGlyph &g = Glf[P->n4];
-	if(P->n3&8)
+    const mglGlyph &g = Glf[P.n4];
+    if(P.n3&8)
 	{
-		if(!(P->n3&4))	glyph_line(p,f,true, d);
+		if(!(P.n3&4))   glyph_line(p,f,true, d);
 		glyph_line(p,f,false, d);
 	}
 	else
 	{
-		if(!(P->n3&4))	glyph_fill(p,f,g, d);
+		if(!(P.n3&4))   glyph_fill(p,f,g, d);
 		glyph_wire(p,f,g, d);
 	}
 	Pop();
@@ -1045,27 +1024,27 @@ void mglCanvas::glyph_draw(const mglPrim
 void mglCanvas::glyph_fill(const mglPnt &pp, mreal f, const mglGlyph &g, mglDrawReg *d)
 {
 	if(!g.trig || g.nt<=0)	return;
-	long ik,ii,pos=Pnt.size();
-	mglPnt p=pp;	p.u=p.v=NAN;
-	mglPoint p1,p2,p3;
+    long ik,ii;
+    mglPnt q0=pp, q1=pp, q2=pp;
+    q0.u=q0.v=q1.u=q1.v=q2.u=q2.v=NAN;
+    mglPoint p1,p2,p3;
 	for(ik=0;ik<g.nt;ik++)
 	{
 		ii = 6*ik;	p1 = mglPoint(f*g.trig[ii]+pp.u,f*g.trig[ii+1]+pp.v,0);	PostScale(p1);
 		ii+=2;		p2 = mglPoint(f*g.trig[ii]+pp.u,f*g.trig[ii+1]+pp.v,0);	PostScale(p2);
 		ii+=2;		p3 = mglPoint(f*g.trig[ii]+pp.u,f*g.trig[ii+1]+pp.v,0);	PostScale(p3);
-		p.x = p1.x;	p.y = p1.y;	p.z = p1.z;	Pnt.push_back(p);
-		p.x = p2.x;	p.y = p2.y;	p.z = p2.z;	Pnt.push_back(p);
-		p.x = p3.x;	p.y = p3.y;	p.z = p3.z;	Pnt.push_back(p);
-		ii = Pnt.size()-3;	trig_draw(ii,ii+1,ii+2,false,d);
+        q0.x = p1.x;    q0.y = p1.y;    q0.z = p1.z;
+        q1.x = p2.x;    q1.y = p2.y;    q1.z = p2.z;
+        q2.x = p3.x;    q2.y = p3.y;    q2.z = p3.z;
+        trig_draw(q0,q1,q2,false,d);
 	}
-	Pnt.erase(Pnt.begin()+pos,Pnt.end());
 }
 //-----------------------------------------------------------------------------
 void mglCanvas::glyph_wire(const mglPnt &pp, mreal f, const mglGlyph &g, mglDrawReg *d)
 {
 	if(!g.line || g.nl<=0)	return;
-	long ik,ii,il=0,pos=Pnt.size();
-	mglPnt p=pp;	p.u=p.v=NAN;
+    long ik,ii,il=0;
+    mglPnt q0=pp, q1=pp;    q0.u=q0.v=q1.u=q1.v=NAN;
 	if(d)	{	d->PDef = 0xffff;	d->PenWidth=0.75;	}
 	mglPoint p1,p2;
 	for(ik=0;ik<g.nl;ik++)
@@ -1084,19 +1063,18 @@ void mglCanvas::glyph_wire(const mglPnt
 			p2 = mglPoint(f*g.line[ii]+pp.u,f*g.line[ii+1]+pp.v,0);
 		}
 		PostScale(p1);	PostScale(p2);
-		p.x = p1.x;	p.y = p1.y;	p.z = p1.z;	Pnt.push_back(p);
-		p.x = p2.x;	p.y = p2.y;	p.z = p2.z;	Pnt.push_back(p);
-		ii = Pnt.size()-2;	line_draw(ii,ii+1,d);
+        q0.x = p1.x;    q0.y = p1.y;    q0.z = p1.z;
+        q1.x = p2.x;    q1.y = p2.y;    q1.z = p2.z;
+        line_draw(q0,q1,d);
 	}
-	Pnt.erase(Pnt.begin()+pos,Pnt.end());
 }
 //-----------------------------------------------------------------------------
 void mglCanvas::glyph_line(const mglPnt &pp, mreal f, bool solid, mglDrawReg *d)
 {
-	mglPnt p=pp;	p.u=p.v=NAN;
+    mglPnt q0=pp,q1=pp,q2=pp,q3=pp;
+    q0.u=q0.v=q1.u=q1.v=q2.u=q2.v=q3.u=q3.v=NAN;
 	if(d)	{	d->PDef = 0xffff;	d->PenWidth=1;	}
 	mglPoint p1,p2,p3,p4;
-	long pos=Pnt.size();
 
 	mreal dy = 0.004;
 	p1 = mglPoint(pp.u,pp.v-dy,0);	PostScale(p1);
@@ -1104,18 +1082,17 @@ void mglCanvas::glyph_line(const mglPnt
 	p3 = mglPoint(fabs(f)+pp.u,pp.v+dy,0);	PostScale(p3);
 	p4 = mglPoint(fabs(f)+pp.u,pp.v-dy,0);	PostScale(p4);
 
-	p.x = p1.x;	p.y = p1.y;	p.z = p1.z;	Pnt.push_back(p);
-	p.x = p2.x;	p.y = p2.y;	p.z = p2.z;	Pnt.push_back(p);
-	p.x = p3.x;	p.y = p3.y;	p.z = p3.z;	Pnt.push_back(p);
-	p.x = p4.x;	p.y = p4.y;	p.z = p4.z;	Pnt.push_back(p);
+    q0.x = p1.x;    q0.y = p1.y;    q0.z = p1.z;
+    q1.x = p2.x;    q1.y = p2.y;    q1.z = p2.z;
+    q2.x = p3.x;    q2.y = p3.y;    q2.z = p3.z;
+    q3.x = p4.x;    q3.y = p4.y;    q3.z = p4.z;
 
-	if(solid)	quad_draw(pos,pos+1,pos+3,pos+2,d);
+	if(solid)   quad_draw(q0,q1,q3,q2,d);
 	else
 	{
-		line_draw(pos,pos+1,d);	line_draw(pos+2,pos+1,d);
-		line_draw(pos,pos+3,d);	line_draw(pos+2,pos+3,d);
+        line_draw(q0,q1,d); line_draw(q2,q1,d);
+        line_draw(q0,q3,d); line_draw(q2,q3,d);
 	}
-	Pnt.erase(Pnt.begin()+pos,Pnt.end());
 }
 //-----------------------------------------------------------------------------
 long mglCanvas::setPp(mglPnt &q, const mglPoint &p)
@@ -1127,7 +1104,6 @@ long mglCanvas::setPp(mglPnt &q, const m
 //-----------------------------------------------------------------------------
 void mglCanvas::arrow_draw(long n1, long n2, char st, float ll)
 {
-	if(n1<0 || n2<0 || !strchr("AVKSDTIO",st))	return;
 	const mglPnt &p1=Pnt[n1], &p2=Pnt[n2];
 	mglPnt q=p1; 	//q.u=q.v=q.w=0;
 	
@@ -1178,7 +1154,6 @@ void mglCanvas::arrow_draw(long n1, long
 //-----------------------------------------------------------------------------
 void mglCanvas::arrow_plot_3d(long n1, long n2, char st, float ll)
 {
-	if(n1<0 || n2<0 || !strchr("AVKSDTIO",st))	return;
 	const mglPnt &p1=Pnt[n1], &p2=Pnt[n2];
 	mglPnt q=p1; 	//q.u=q.v=q.w=0;