private void DrawFacialView(ToothGraphic toothGraphic) {
			Gl.glPushMatrix();//remember position of origin
			Gl.glTranslatef(TcData.GetTransX(toothGraphic.ToothID),//Move the tooth to the correct position for facial view
				TcData.GetTransYfacial(toothGraphic.ToothID),
				0);
			RotateAndTranslateUser(toothGraphic);
			if(toothGraphic.Visible
				|| (toothGraphic.IsCrown && toothGraphic.IsImplant)
				|| toothGraphic.IsPontic)
			{
				DrawTooth(toothGraphic);
			}
			Gl.glDisable(Gl.GL_DEPTH_TEST);
			if(toothGraphic.DrawBigX) {
				Gl.glDisable(Gl.GL_LIGHTING);
				Gl.glEnable(Gl.GL_BLEND);
				//move the bigX 6mm to the Facial so it will paint in front of the tooth
				Gl.glTranslatef(0,0,6f);
				Gl.glBlendFunc(Gl.GL_SRC_ALPHA,Gl.GL_ONE_MINUS_SRC_ALPHA);
				Gl.glLineWidth(2f*TcData.PixelScaleRatio);//thickness of line depends on size of window
				Gl.glColor3f (
					(float)toothGraphic.colorX.R/255f,
					(float)toothGraphic.colorX.G/255f,
					(float)toothGraphic.colorX.B/255f);
				if(ToothGraphic.IsMaxillary(toothGraphic.ToothID)){
					Gl.glBegin(Gl.GL_LINES);
					Gl.glVertex2f(-2f,12f);
					Gl.glVertex2f(2f,-6f);
					Gl.glEnd();
					Gl.glBegin(Gl.GL_LINES);
					Gl.glVertex2f(2f,12f);
					Gl.glVertex2f(-2f,-6f);
					Gl.glEnd();
				}
				else{
					Gl.glBegin(Gl.GL_LINES);
					Gl.glVertex2f(-2f,6f);
					Gl.glVertex2f(2f,-12f);
					Gl.glEnd();
					Gl.glBegin(Gl.GL_LINES);
					Gl.glVertex2f(2f,6f);
					Gl.glVertex2f(-2f,-12f);
					Gl.glEnd();
				}
			}
			Gl.glPopMatrix();//reset to origin
			if(toothGraphic.Visible && toothGraphic.IsRCT) {//draw RCT
				Gl.glPushMatrix();
				Gl.glTranslatef(0,0,10f);//move RCT forward 10mm so it will be visible.
				Gl.glTranslatef(TcData.GetTransX(toothGraphic.ToothID),TcData.GetTransYfacial(toothGraphic.ToothID),0);
				Gl.glDisable(Gl.GL_LIGHTING);
				Gl.glEnable(Gl.GL_BLEND);
				Gl.glColor3f(
					(float)toothGraphic.colorRCT.R/255f,
					(float)toothGraphic.colorRCT.G/255f,
					(float)toothGraphic.colorRCT.B/255f);
					//.5f);//only 1/2 darkness
				Gl.glBlendFunc(Gl.GL_SRC_ALPHA,Gl.GL_ONE_MINUS_SRC_ALPHA);
				Gl.glLineWidth(2.2f*TcData.PixelScaleRatio);
				Gl.glPointSize(1.8f*TcData.PixelScaleRatio);//point is slightly smaller since no antialiasing
				RotateAndTranslateUser(toothGraphic);
				List<LineSimple> lines=toothGraphic.GetRctLines();
				for(int i=0;i<lines.Count;i++){
					Gl.glBegin(Gl.GL_LINE_STRIP);
					for(int j=0;j<lines[i].Vertices.Count;j++){
						Gl.glVertex3f(lines[i].Vertices[j].X,lines[i].Vertices[j].Y,lines[i].Vertices[j].Z);
					}
					Gl.glEnd();
				}
				Gl.glPopMatrix();
				//This section is a necessary workaround for OpenGL.
				//It draws a point at each intersection to hide the unsightly transitions between line segments.
				Gl.glPushMatrix();
				Gl.glTranslatef(0,0,10.5f);//move forward 10.5mm so it will cover the lines
				Gl.glTranslatef(TcData.GetTransX(toothGraphic.ToothID),TcData.GetTransYfacial(toothGraphic.ToothID),0);
				RotateAndTranslateUser(toothGraphic);
				Gl.glDisable(Gl.GL_BLEND);
				for(int i=0;i<lines.Count;i++){
					Gl.glBegin(Gl.GL_POINTS);
					for(int j=0;j<lines[i].Vertices.Count;j++) {
						//but ignore the first and last.  We are only concerned with where lines meet.
						if(j==0 || j==lines[i].Vertices.Count-1) {
							continue;
						}
						Gl.glVertex3f(lines[i].Vertices[j].X,lines[i].Vertices[j].Y,lines[i].Vertices[j].Z);
					}
					Gl.glEnd();
				}
				Gl.glPopMatrix();
			}
			ToothGroup groupBU=toothGraphic.GetGroup(ToothGroupType.Buildup);//during debugging, not all teeth have a BU group yet.
			if(toothGraphic.Visible && groupBU!=null && groupBU.Visible) {//BU or Post
				Gl.glPushMatrix();
				Gl.glTranslatef(0,0,13f);//move BU forward 13mm so it will be visible.
				Gl.glTranslatef(TcData.GetTransX(toothGraphic.ToothID),TcData.GetTransYfacial(toothGraphic.ToothID),0);
				Gl.glDisable(Gl.GL_LIGHTING);
				Gl.glDisable(Gl.GL_BLEND);
				Color colorBU=toothGraphic.GetGroup(ToothGroupType.Buildup).PaintColor;
				Gl.glColor3f(
					(float)colorBU.R/255f,
					(float)colorBU.G/255f,
					(float)colorBU.B/255f);
				RotateAndTranslateUser(toothGraphic);
				Gl.glCallList(displayListOffset+toothGraphic.GetIndexForDisplayList(toothGraphic.GetGroup(ToothGroupType.Buildup)));
				//Triangle poly=toothGraphic.GetBUpoly();
				//Gl.glBegin(Gl.GL_POLYGON);
				//for(int i=0;i<poly.Vertices.Count;i++) {
				//	Gl.glVertex3f(poly.Vertices[i].X,poly.Vertices[i].Y,poly.Vertices[i].Z);
				//}
				//Gl.glEnd();
				Gl.glPopMatrix();
			}
			if(toothGraphic.IsImplant){
				Gl.glPushMatrix();
				Gl.glTranslatef(TcData.GetTransX(toothGraphic.ToothID),//Move the tooth to the correct position for facial view
					TcData.GetTransYfacial(toothGraphic.ToothID),
					0);
				RotateAndTranslateUser(toothGraphic);
				if(ToothGraphic.IsMaxillary(toothGraphic.ToothID)) {
					//flip the implant upside down
					Gl.glRotatef(180f,0,0,1f);
				}
				Gl.glEnable(Gl.GL_LIGHTING);
				Gl.glEnable(Gl.GL_BLEND);
				Gl.glEnable(Gl.GL_DEPTH_TEST);
				ToothGroup group=(ToothGroup)TcData.ListToothGraphics["implant"].Groups[0];
				float[] material_color=new float[] {
					(float)toothGraphic.colorImplant.R/255f,
					(float)toothGraphic.colorImplant.G/255f,
					(float)toothGraphic.colorImplant.B/255f,
					(float)toothGraphic.colorImplant.A/255f
				};//RGBA
				Gl.glMaterialfv(Gl.GL_FRONT,Gl.GL_SPECULAR,specular_color_normal);
				Gl.glMaterialfv(Gl.GL_FRONT,Gl.GL_SHININESS,shininess);
				Gl.glMaterialfv(Gl.GL_FRONT,Gl.GL_AMBIENT_AND_DIFFUSE,material_color);
				Gl.glBlendFunc(Gl.GL_ONE,Gl.GL_ZERO);
				Gl.glHint(Gl.GL_POLYGON_SMOOTH_HINT,Gl.GL_NICEST);
				for(int i=0;i<group.Faces.Count;i++){//  .GetLength(0);i++) {//loop through each face
					Gl.glBegin(Gl.GL_POLYGON);
					for(int j=0;j<group.Faces[i].IndexList.Count;j++){//.Length;j++) {//loop through each vertex
						//The index for both will always be the same because we enforce a 1:1 relationship.
						//We show grabbing a float[3], but we could just as easily use the index itself.
						Gl.glVertex3fv(TcData.ListToothGraphics["implant"].VertexNormals[group.Faces[i].IndexList[j]].Vertex.GetFloatArray());//Vertices[group.Faces[i][j][0]]);
						Gl.glNormal3fv(TcData.ListToothGraphics["implant"].VertexNormals[group.Faces[i].IndexList[j]].Normal.GetFloatArray()); //.Normals[group.Faces[i][j][1]]);
					}
					Gl.glEnd();
				}
				Gl.glPopMatrix();
			}
		}
Exemple #2
0
		private void DrawFacialView(ToothGraphic toothGraphic,Matrix defOrient) {
			Matrix toothTrans=Matrix.Identity;
			toothTrans.Translate(GetTransX(toothGraphic.ToothID),
				GetTransYfacial(toothGraphic.ToothID),
				0);
			Matrix rotAndTranUser=ToothRotationAndTranslationMatrix(toothGraphic);
			device.Transform.World=rotAndTranUser*toothTrans*defOrient;
			if(toothGraphic.Visible
				||(toothGraphic.IsCrown && toothGraphic.IsImplant)
				||toothGraphic.IsPontic) 
			{
				DrawTooth(toothGraphic);
			}
			device.RenderState.ZBufferEnable=false;
			device.RenderState.Lighting=false;
			Matrix lineMatrix=ScreenSpaceMatrix();
			Line line=new Line(device);
			line.GlLines=true;
			if(toothGraphic.DrawBigX) {
				//Thickness of line depends on size of window.
				//The line size needs to be slightly larger than in OpenGL because
				//lines are drawn with polygons in DirectX and they are anti-aliased,
				//even when the line.Antialias flag is set.
				line.Width=2.2f*TcData.PixelScaleRatio;
				line.Begin();
				if(ToothGraphic.IsMaxillary(toothGraphic.ToothID)) {
					line.DrawTransform(new Vector3[] {
						new Vector3(-2f,12f,0f),
						new Vector3(2f,-6f,0f),},
						lineMatrix,
						toothGraphic.colorX);
					line.DrawTransform(new Vector3[] {
						new Vector3(2f,12f,0f),
						new Vector3(-2f,-6f,0f),},
						lineMatrix,
						toothGraphic.colorX);
				} 
				else {
					line.DrawTransform(new Vector3[] {
						new Vector3(-2f,6f,0f),
						new Vector3(2f,-12f,0f),},
						lineMatrix,
						toothGraphic.colorX);
					line.DrawTransform(new Vector3[] {
						new Vector3(2f,6f,0f),
						new Vector3(-2f,-12f,0f),},
						lineMatrix,
						toothGraphic.colorX);
				}
				line.End();
			}
			if(toothGraphic.Visible && toothGraphic.IsRCT) {//draw RCT
				//Thickness of lines depend on size of window.
				//The line size needs to be slightly larger than in OpenGL because
				//lines are drawn with polygons in DirectX and they are anti-aliased,
				//even when the line.Antialias flag is set.
				line.Width=2.5f*TcData.PixelScaleRatio;
				line.Begin();
				List<LineSimple> linesSimple=toothGraphic.GetRctLines();
				for(int i=0;i<linesSimple.Count;i++) {
					if(linesSimple[i].Vertices.Count<2){
						continue;//Just to avoid internal errors, even though not likely.
					}
					//Convert each line strip into very simple two point lines so that line extensions can be calculated more easily below.
					//Items in the array are tuples of (2D point,bool indicating end point).
					List <object> twoPointLines=new List<object> ();
					for(int j=0;j<linesSimple[i].Vertices.Count-1;j++){
					  twoPointLines.Add(new Vector3(
							linesSimple[i].Vertices[j  ].X,
							linesSimple[i].Vertices[j  ].Y,
							linesSimple[i].Vertices[j  ].Z));
						twoPointLines.Add(j==0);
					  twoPointLines.Add(new Vector3(
							linesSimple[i].Vertices[j+1].X,
							linesSimple[i].Vertices[j+1].Y,
							linesSimple[i].Vertices[j+1].Z));
						twoPointLines.Add(j==linesSimple[i].Vertices.Count-2);
					}
					//Draw each individual two point line. The lines must be broken down from line strips so that when individual two point
					//line locations are modified they do not affect any other two point lines within the same line strip.
					for(int j=0;j<twoPointLines.Count;j+=4){
					  Vector3 p1=(Vector3)twoPointLines[j];
						bool p1IsEndPoint=(bool)twoPointLines[j+1];
					  Vector3 p2=(Vector3)twoPointLines[j+2];
						bool p2IsEndPoint=(bool)twoPointLines[j+3];
					  Vector3 lineDir=p2-p1;
					  lineDir.Normalize();//Gives the line direction a single unit length.
					  float extSize=0.25f;//The number of units to extend each end of the two point line.
						if(!p1IsEndPoint){//Do not extend the endpoints for the ends of the line strips.
							p1=p1-extSize*lineDir;
						}
						if(!p2IsEndPoint){//Do not extend the endpoints for the ends of the line strips.
							p2=p2+extSize*lineDir;
						}
					  Vector3[] lineVerts=new Vector3[] {p1,p2};
					  line.DrawTransform(lineVerts,lineMatrix,toothGraphic.colorRCT);
					}
				}
				line.End();
			}
			ToothGroup groupBU=toothGraphic.GetGroup(ToothGroupType.Buildup);//during debugging, not all teeth have a BU group yet.
			if(toothGraphic.Visible && groupBU!=null && groupBU.Visible) {//BU or Post
				device.RenderState.ZBufferEnable=false;
				device.RenderState.Lighting=true;
				device.Lights[0].Enabled=false;//Disable the scene light.
				device.Lights[1].Ambient=Color.White;
				device.Lights[1].Enabled=true;
				Color colorBU=toothGraphic.GetGroup(ToothGroupType.Buildup).PaintColor;
				device.VertexFormat=CustomVertex.PositionNormal.Format;
				device.SetStreamSource(0,toothGraphic.vb,0);
				Material material=new Material();
				material.Ambient=colorBU;
				device.Material=material;
				device.Indices=groupBU.facesDirectX;
				device.DrawIndexedPrimitives(PrimitiveType.TriangleList,0,0,toothGraphic.VertexNormals.Count,0,groupBU.NumIndicies/3);
				device.Lights[0].Enabled=true;
				device.Lights[1].Enabled=false;
			}
			if(toothGraphic.IsImplant) {
				DrawImplant(toothGraphic);
			}
			line.Dispose();
			device.RenderState.ZBufferEnable=true;
			device.RenderState.Lighting=true;
		}