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(); } }
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; }