///<summary>Specify a line as a series of points. It's implied that they are grouped by threes.</summary> public LineSimple(params float[] coords) { Vertices=new List<Vertex3f>(); Vertex3f vertex=new Vertex3f(); for(int i=0;i<coords.Length;i++) { vertex.X=coords[i]; i++; vertex.Y=coords[i]; i++; vertex.Z=coords[i]; Vertices.Add(vertex); vertex=new Vertex3f(); } }
///<summary>Specify a line as a series of points. It's implied that they are grouped by threes.</summary> public LineSimple(params float[] coords) { Vertices = new List <Vertex3f>(); Vertex3f vertex = new Vertex3f(); for (int i = 0; i < coords.Length; i++) { vertex.X = coords[i]; i++; vertex.Y = coords[i]; i++; vertex.Z = coords[i]; Vertices.Add(vertex); vertex = new Vertex3f(); } }
///<summary>This gets the entire set of lines for one perio row for one sequence type. The allowed types are GM, MGJ, and CAL. Each LineSimple is a series of connected lines. But the result could have interruptions, so we return a list, each item in the list being continuous. There may be zero items in the list. Each line in the list is guaranteed to have at least 2 points in it.</summary> public List<LineSimple> GetHorizontalLines(PerioSequenceType sequenceType,bool isMaxillary,bool isBuccal) { List<LineSimple> retVal=new List<LineSimple>(); int startTooth=1; int stopTooth=17;//doesn't perform a loop for 17. if(!isMaxillary) { startTooth=32;//We still go Left to Right, even on mand. stopTooth=16; } LineSimple line=new LineSimple(); Vertex3f vertex; int val1=-1; int val2=-1; int val3=-1; int t=startTooth; PerioSurf surf1; PerioSurf surf2; PerioSurf surf3; while(t!=stopTooth){ if(!ListToothGraphics[t.ToString()].Visible && !ListToothGraphics[t.ToString()].IsImplant) { //stop any existing line. if(line.Vertices.Count==1) {//if there is already one point, then clear it, because a line can't have one point. line.Vertices.Clear(); } if(line.Vertices.Count>1) {//if 2 or more points in the line, then add the line to the result. retVal.Add(line); line=new LineSimple();//and initialize a new line for future points. } //increment to next tooth if(isMaxillary) { t++; } else { t--; } continue; } //We are considering 3 points per tooth. Reinitialize for the new tooth. val1=-1; val2=-1; val3=-1; surf1=PerioSurf.None; surf2=PerioSurf.None; surf3=PerioSurf.None; for(int i=0;i<ListPerioMeasure.Count;i++) { if(ListPerioMeasure[i].IntTooth!=t) { continue; } if(ListPerioMeasure[i].SequenceType!=sequenceType) { continue; } //so we are now on the specific PerioMeasure for this sequence and tooth. It contains 6 values, and we will use 3. PerioMeasure pmGM=null; //We need to draw MGJ as dist from GM, not CEJ if(sequenceType==PerioSequenceType.MGJ) {//we only care about this if we are trying to calculate MGJ for(int m=0;m<ListPerioMeasure.Count;m++) { if(ListPerioMeasure[m].IntTooth==t && ListPerioMeasure[m].SequenceType==PerioSequenceType.GingMargin) { pmGM=ListPerioMeasure[m];//get the GM for this same tooth. break; } } } if(isBuccal) { if(ToothGraphic.IsRight(t.ToString())) { val1=ListPerioMeasure[i].DBvalue; val2=ListPerioMeasure[i].Bvalue; val3=ListPerioMeasure[i].MBvalue; if(sequenceType==PerioSequenceType.MGJ && pmGM!=null) { if(pmGM.DBvalue!=-1) { val1+=PerioMeasures.AdjustGMVal(pmGM.DBvalue); } if(pmGM.Bvalue!=-1) { val2+=PerioMeasures.AdjustGMVal(pmGM.Bvalue); } if(pmGM.MBvalue!=-1) { val3+=PerioMeasures.AdjustGMVal(pmGM.MBvalue); } } surf1=PerioSurf.DB; surf2=PerioSurf.B; surf3=PerioSurf.MB; } else {//for UL and LL val1=ListPerioMeasure[i].MBvalue; val2=ListPerioMeasure[i].Bvalue; val3=ListPerioMeasure[i].DBvalue; if(sequenceType==PerioSequenceType.MGJ && pmGM!=null) { if(pmGM.MBvalue!=-1) { val1+=PerioMeasures.AdjustGMVal(pmGM.MBvalue); } if(pmGM.Bvalue!=-1) { val2+=PerioMeasures.AdjustGMVal(pmGM.Bvalue); } if(pmGM.DBvalue!=-1) { val3+=PerioMeasures.AdjustGMVal(pmGM.DBvalue); } } surf1=PerioSurf.MB; surf2=PerioSurf.B; surf3=PerioSurf.DB; } } else {//lingual if(ToothGraphic.IsRight(t.ToString())) { val1=ListPerioMeasure[i].DLvalue; val2=ListPerioMeasure[i].Lvalue; val3=ListPerioMeasure[i].MLvalue; if(sequenceType==PerioSequenceType.MGJ && pmGM!=null) { if(pmGM.DLvalue!=-1) { val1+=PerioMeasures.AdjustGMVal(pmGM.DLvalue); } if(pmGM.Lvalue!=-1) { val2+=PerioMeasures.AdjustGMVal(pmGM.Lvalue); } if(pmGM.MLvalue!=-1) { val3+=PerioMeasures.AdjustGMVal(pmGM.MLvalue); } } surf1=PerioSurf.DL; surf2=PerioSurf.L; surf3=PerioSurf.ML; } else {//for UL and LL val1=ListPerioMeasure[i].MLvalue; val2=ListPerioMeasure[i].Lvalue; val3=ListPerioMeasure[i].DLvalue; if(sequenceType==PerioSequenceType.MGJ && pmGM!=null) { if(pmGM.MLvalue!=-1) { val1+=PerioMeasures.AdjustGMVal(pmGM.MLvalue); } if(pmGM.Lvalue!=-1) { val2+=PerioMeasures.AdjustGMVal(pmGM.Lvalue); } if(pmGM.DLvalue!=-1) { val3+=PerioMeasures.AdjustGMVal(pmGM.DLvalue); } } surf1=PerioSurf.ML; surf2=PerioSurf.L; surf3=PerioSurf.DL; } } } //We have now filled our 3 points with values and need to evaluate those values. //Any or all of the values may still be -1. if(val1==-1) { //we won't add a point to this line if(line.Vertices.Count==1) {//if there is already one point, then clear it, because a line can't have one point. line.Vertices.Clear(); } if(line.Vertices.Count>1) {//if 2 or more points in the line, then add the line to the result. retVal.Add(line); line=new LineSimple();//and initialize a new line for future points. } } else {//just add a point to the current line. vertex=new Vertex3f(); vertex.Z=0;//we don't use z if(isMaxillary) { //this is safe to run on all sequence types because -1 has already been handled and because other types wouldn't have values > 100. //Also safe to process on the vals that are MGJ, calculated above, because if they are ever negative, //it would be an obvious entry error, and the MGJ line would just harmlessly disappear for -1 vals. vertex.Y=PerioMeasures.AdjustGMVal(val1); } else { vertex.Y=-PerioMeasures.AdjustGMVal(val1); } vertex.X=GetXShiftPerioSite(t,surf1)+ToothGraphic.GetDefaultOrthoXpos(t); line.Vertices.Add(vertex); } //val2-------------------------- if(val2==-1) { if(line.Vertices.Count==1) { line.Vertices.Clear(); } if(line.Vertices.Count>1) { retVal.Add(line); line=new LineSimple(); } } else { vertex=new Vertex3f(); vertex.Z=0; if(isMaxillary) { vertex.Y=PerioMeasures.AdjustGMVal(val2); } else { vertex.Y=-PerioMeasures.AdjustGMVal(val2); } vertex.X=GetXShiftPerioSite(t,surf2)+ToothGraphic.GetDefaultOrthoXpos(t); line.Vertices.Add(vertex); } //val3------------------------- if(val3==-1) { if(line.Vertices.Count==1) { line.Vertices.Clear(); } if(line.Vertices.Count>1) { retVal.Add(line); line=new LineSimple(); } } else { vertex=new Vertex3f(); vertex.Z=0; if(isMaxillary) { vertex.Y=PerioMeasures.AdjustGMVal(val3); } else { vertex.Y=-PerioMeasures.AdjustGMVal(val3); } vertex.X=GetXShiftPerioSite(t,surf3)+ToothGraphic.GetDefaultOrthoXpos(t); line.Vertices.Add(vertex); } //increment to next tooth if(isMaxillary) { t++; } else { t--; } } if(line.Vertices.Count>1) { retVal.Add(line); } return retVal; }
///<summary>Should only be run on startup for efficiency.</summary> private void ImportObj() { byte[] buffer=null; if(toothID=="1" || toothID=="16") { buffer=Properties.Resources.tooth1; } else if(toothID=="2" || toothID=="15") { buffer=Properties.Resources.tooth2; } else if(toothID=="3" || toothID=="14") { //file+="3.obj"; buffer=Properties.Resources.tooth3; } else if(toothID=="4" || toothID=="13") { buffer=Properties.Resources.tooth4; } else if(toothID=="5" || toothID=="12") { buffer=Properties.Resources.tooth5; } else if(toothID=="6" || toothID=="11") { buffer=Properties.Resources.tooth6; } else if(toothID=="7" ||toothID=="10") { buffer=Properties.Resources.tooth7; } else if(toothID=="8" || toothID=="9") { buffer=Properties.Resources.tooth8; } else if(toothID=="17" || toothID=="32") { buffer=Properties.Resources.tooth32; } else if(toothID=="18" || toothID=="31") { buffer=Properties.Resources.tooth31; } else if(toothID=="19" || toothID=="30") { buffer=Properties.Resources.tooth30; } else if(toothID=="20" || toothID=="29") { buffer=Properties.Resources.tooth29; } else if(toothID=="21" || toothID=="28") { buffer=Properties.Resources.tooth28; } else if(toothID=="22" || toothID=="27") { buffer=Properties.Resources.tooth27; } else if(toothID=="23" || toothID=="24" || toothID=="25" ||toothID=="26") { buffer=Properties.Resources.tooth25; } else if(toothID=="A" || toothID=="J") { buffer=Properties.Resources.toothA; } else if(toothID=="B" || toothID=="I") { buffer=Properties.Resources.toothB; } else if(toothID=="C" || toothID=="H") { buffer=Properties.Resources.toothC; } else if(toothID=="D" || toothID=="G") { buffer=Properties.Resources.toothD; } else if(toothID=="E" || toothID=="F") { buffer=Properties.Resources.toothE; } else if(toothID=="P" || toothID=="O" || toothID=="Q" || toothID=="N") { buffer=Properties.Resources.toothP; } else if(toothID=="R" || toothID=="M") { buffer=Properties.Resources.toothR; } else if(toothID=="S" || toothID=="L") { buffer=Properties.Resources.toothS; } else if(toothID=="T" || toothID=="K") { buffer=Properties.Resources.toothT; } else if(toothID=="implant"){ buffer=Properties.Resources.implant; } bool flipHorizontally=false; if(toothID!="implant" && IdToInt(toothID)>=9 && IdToInt(toothID)<=24) { flipHorizontally=true; } //There will not necessarily be the same number of vertices as normals. //But as they get paired up later, we will create a 1:1 relationship. List<Vertex3f> verts=new List<Vertex3f>(); List<Vertex3f> norms=new List<Vertex3f>(); Groups=new List<ToothGroup>(); //ArrayList ALf=new ArrayList();//faces always part of a group List<Face> faces=new List<Face>(); MemoryStream stream=new MemoryStream(buffer); using(StreamReader sr = new StreamReader(stream)){ String line; Vertex3f vertex; string[] items; string[] subitems; Face face; ToothGroup group=null; while((line = sr.ReadLine()) != null) { if(line.StartsWith("#")//comment || line.StartsWith("mtllib")//material library. We build our own. || line.StartsWith("usemtl")//use material || line.StartsWith("o")) {//object. There's only one object continue; } if(line.StartsWith("v ")) {//vertex items=line.Split(new char[] { ' ' }); vertex=new Vertex3f();//float[3]; if(flipHorizontally) { vertex.X=-Convert.ToSingle(items[1],CultureInfo.InvariantCulture); } else { vertex.X=Convert.ToSingle(items[1],CultureInfo.InvariantCulture); } vertex.Y=Convert.ToSingle(items[2],CultureInfo.InvariantCulture); vertex.Z=Convert.ToSingle(items[3],CultureInfo.InvariantCulture); verts.Add(vertex); continue; } if(line.StartsWith("vn")) {//vertex normal items=line.Split(new char[] { ' ' }); vertex=new Vertex3f();//new float[3]; if(flipHorizontally) { vertex.X=-Convert.ToSingle(items[1],CultureInfo.InvariantCulture); } else { vertex.X=Convert.ToSingle(items[1],CultureInfo.InvariantCulture); } vertex.Y=Convert.ToSingle(items[2],CultureInfo.InvariantCulture); vertex.Z=Convert.ToSingle(items[3],CultureInfo.InvariantCulture); norms.Add(vertex); continue; } if(line.StartsWith("g")) {//group if(group != null) { //move all faces into the existing group group.Faces=new List<Face>(faces); //move the existing group into the AL Groups.Add(group); } //start a new group to which all subsequent faces will be attached. group=new ToothGroup(); faces=new List<Face>(); //group.PaintColor=Color.FromArgb(255,255,253,209);//default to enamel switch(line) { default: group.GroupType=ToothGroupType.None; break; case "g cube1_Cementum": group.GroupType=ToothGroupType.Cementum; break; case "g cube1_Enamel2": group.GroupType=ToothGroupType.Enamel; break; case "g cube1_M": group.GroupType=ToothGroupType.M; break; case "g cube1_D": group.GroupType=ToothGroupType.D; break; case "g cube1_F": group.GroupType=ToothGroupType.F; break; case "g cube1_I": group.GroupType=ToothGroupType.I; break; case "g cube1_L": group.GroupType=ToothGroupType.L; break; case "g cube1_V": group.GroupType=ToothGroupType.V; break; case "g cube1_B": group.GroupType=ToothGroupType.B; break; case "g cube1_O": group.GroupType=ToothGroupType.O; break; case "g cube1_Canals": group.GroupType=ToothGroupType.Canals; break; case "g cube1_Buildup": group.GroupType=ToothGroupType.Buildup; break; case "g cube1_Implant": group.GroupType=ToothGroupType.Implant; break; case "g cube1_EnamelF": group.GroupType=ToothGroupType.EnamelF; break; case "g cube1_DF": group.GroupType=ToothGroupType.DF; break; case "g cube1_MF": group.GroupType=ToothGroupType.MF; break; case "g cube1_IF": group.GroupType=ToothGroupType.IF; break; } } if(line.StartsWith("f")) {//face. Usually 4 vertices, but not always. items=line.Split(new char[] { ' ' }); face=new Face(); VertexNormal vertnorm; int vertIdx; int normIdx; //do we need to load these backwards for flipping, so they'll still be counterclockwise? //It seems to work anyway, but it's something to keep in mind for later. for(int i=1;i<items.Length;i++){//face.GetLength(0);i++) { subitems=items[i].Split(new char[] { '/' });// eg: 9//9 this is an index to a given vertex/normal. vertnorm=new VertexNormal();//unlike the old way of just storing idxs, we will actually store vertices. vertIdx=Convert.ToInt32(subitems[0])-1; normIdx=Convert.ToInt32(subitems[2])-1; vertnorm.Vertex=verts[vertIdx]; vertnorm.Normal=norms[normIdx]; face.IndexList.Add(GetIndexForVertNorm(vertnorm)); } faces.Add(face); continue; } }//while readline //For the very last group, move all faces into the group group.Faces=new List<Face>(faces);//new int[ALf.Count][][]; //move the last group into the AL Groups.Add(group); } //MessageBox.Show(Vertices[2,2].ToString()); }
public static D3ObjectGroup ImportObjectsFromObjFile(string strObjData) { D3ObjectGroup d3ObjectGroup = new D3ObjectGroup(); string[] lines = strObjData.Split(new string[] { "\r\n" }, StringSplitOptions.None); int i = 0; List <Vertex3f> listV = new List <Vertex3f>(); List <Vertex3f> listT = new List <Vertex3f>(); List <Vertex3f> listN = new List <Vertex3f>(); Vertex3f vertex; Vertex3f texture; Vertex3f normal; VertexNormal vertnorm; D3Object d3Object = null; string[] items; string[] subitems; int idxV; int idxT; int idxN; Face face; while (i < lines.Length) { //Debug.WriteLine(i.ToString()); if (lines[i].StartsWith("#") || //comment lines[i].StartsWith("mtllib") || //material library. We build our own. lines[i].StartsWith("usemtl")) //use material { i++; continue; //we don't care about any of these } if (lines[i].StartsWith("o")) //object. For example "o cube1" //vertices and normals are per object as they are pulled out of the file, //but we need to regroup them per d3Object. { i++; continue; } if (lines[i].StartsWith("v ")) //vertex. For example "v -0.34671119 0.22176000 0.83703486" { items = lines[i].Split(' '); vertex = new Vertex3f(); vertex.X = Convert.ToSingle(items[1], CultureInfo.InvariantCulture); vertex.Y = Convert.ToSingle(items[2], CultureInfo.InvariantCulture); vertex.Z = Convert.ToSingle(items[3], CultureInfo.InvariantCulture); listV.Add(vertex); i++; continue; } if (lines[i].StartsWith("vt")) //vertex. For example "vt 0.72553915 0.63685900" { items = lines[i].Split(' '); texture = new Vertex3f(); texture.X = Convert.ToSingle(items[1], CultureInfo.InvariantCulture); texture.Y = Convert.ToSingle(items[2], CultureInfo.InvariantCulture); //texture.Z=Convert.ToSingle(items[3],CultureInfo.InvariantCulture); listT.Add(texture); i++; continue; } if (lines[i].StartsWith("vn")) //normal. For example "vn -0.32559605 -0.84121753 -0.43167149" { items = lines[i].Split(' '); normal = new Vertex3f(); normal.X = Convert.ToSingle(items[1], CultureInfo.InvariantCulture); normal.Y = Convert.ToSingle(items[2], CultureInfo.InvariantCulture); normal.Z = Convert.ToSingle(items[3], CultureInfo.InvariantCulture); listN.Add(normal); i++; continue; } if (lines[i].StartsWith("g")) //group. For example "g cylinder2_default" { if (d3Object != null) { d3ObjectGroup.D3Objects.Add(d3Object); //add the previous object to the group } d3Object = new D3Object(); //start the new one, including the new list of VNs d3Object.Name = lines[i].Substring(2); i++; continue; } if (lines[i].StartsWith("f")) //face. For example "f 12//384 51//443 384//336 383//335". Format is v//n { items = lines[i].Split(' '); //5 items in this example //create triangle fan, preserving counterclockwise order for (int f = 2; f < items.Length - 1; f++) //one face/triangle per loop, 2 triangles in this case { face = new Face(); //only grab three vertices //first vertex is always the 0 for the fan subitems = items[1].Split('/'); //12,,384 for the first triangle idxV = Convert.ToInt32(subitems[0]) - 1; //11 for the first triangle if (subitems[1] == "") //no texture { idxT = -1; } else { idxT = Convert.ToInt32(subitems[1]) - 1; } idxN = Convert.ToInt32(subitems[2]) - 1; //383 for the first triangle vertnorm = new VertexNormal(); vertnorm.Vertex = listV[idxV]; if (idxT != -1) { vertnorm.Texture = listT[idxT]; } vertnorm.Normal = listN[idxN]; face.IndexList.Add(d3Object.GetIndexForVertNorm(vertnorm)); //second vertex subitems = items[f].Split('/'); //51,,443 for the first triangle idxV = Convert.ToInt32(subitems[0]) - 1; //50 for the first triangle if (subitems[1] == "") //no texture { idxT = -1; } else { idxT = Convert.ToInt32(subitems[1]) - 1; } idxN = Convert.ToInt32(subitems[2]) - 1; //442 for the first triangle vertnorm = new VertexNormal(); vertnorm.Vertex = listV[idxV]; if (idxT != -1) { vertnorm.Texture = listT[idxT]; } vertnorm.Normal = listN[idxN]; face.IndexList.Add(d3Object.GetIndexForVertNorm(vertnorm)); //third vertex subitems = items[f + 1].Split('/'); //384,,336 for the first triangle idxV = Convert.ToInt32(subitems[0]) - 1; //383 for the first triangle if (subitems[1] == "") //no texture { idxT = -1; } else { idxT = Convert.ToInt32(subitems[1]) - 1; } idxN = Convert.ToInt32(subitems[2]) - 1; //335 for the first triangle vertnorm = new VertexNormal(); vertnorm.Vertex = listV[idxV]; if (idxT != -1) { vertnorm.Texture = listT[idxT]; } vertnorm.Normal = listN[idxN]; face.IndexList.Add(d3Object.GetIndexForVertNorm(vertnorm)); d3Object.Faces.Add(face); } i++; continue; } //might be another kind of row that we missed above i++; } if (d3Object != null) { d3ObjectGroup.D3Objects.Add(d3Object); //add the last object to the group } return(d3ObjectGroup); }
public Vertex3f Copy() { Vertex3f vf=new Vertex3f(this.X,this.Y,this.Z); return vf; }
public Vertex3f Copy() { Vertex3f vf = new Vertex3f(this.X, this.Y, this.Z); return(vf); }
///<summary>This gets the entire set of lines for one perio row for one sequence type. The allowed types are GM, MGJ, and CAL. Each LineSimple is a series of connected lines. But the result could have interruptions, so we return a list, each item in the list being continuous. There may be zero items in the list. Each line in the list is guaranteed to have at least 2 points in it.</summary> public List<LineSimple> GetHorizontalLines(PerioSequenceType sequenceType,bool isMaxillary,bool isBuccal) { List<LineSimple> retVal=new List<LineSimple>(); int startTooth=1; int stopTooth=17;//doesn't perform a loop for 17. if(!isMaxillary) { startTooth=32;//We still go Left to Right, even on mand. stopTooth=16; } LineSimple line=new LineSimple(); Vertex3f vertex; int val1=-1; int val2=-1; int val3=-1; int t=startTooth; PerioSurf surf1; PerioSurf surf2; PerioSurf surf3; while(t!=stopTooth){ if(!ListToothGraphics[t.ToString()].Visible && !ListToothGraphics[t.ToString()].IsImplant) { //stop any existing line. if(line.Vertices.Count==1) {//if there is already one point, then clear it, because a line can't have one point. line.Vertices.Clear(); } if(line.Vertices.Count>1) {//if 2 or more points in the line, then add the line to the result. retVal.Add(line); line=new LineSimple();//and initialize a new line for future points. } //increment to next tooth if(isMaxillary) { t++; } else { t--; } continue; } //We are considering 3 points per tooth. Reinitialize for the new tooth. val1=-1; val2=-1; val3=-1; surf1=PerioSurf.None; surf2=PerioSurf.None; surf3=PerioSurf.None; for(int i=0;i<ListPerioMeasure.Count;i++) { if(ListPerioMeasure[i].IntTooth!=t) { continue; } if(ListPerioMeasure[i].SequenceType!=sequenceType) { continue; } PerioMeasure pmGM=null; //We need to draw MGJ as dist from GM, not CEJ if(sequenceType==PerioSequenceType.MGJ) { for(int m=0;m<ListPerioMeasure.Count;m++) { if(ListPerioMeasure[m].IntTooth==t && ListPerioMeasure[m].SequenceType==PerioSequenceType.GingMargin) { pmGM=ListPerioMeasure[m]; break; } } } if(isBuccal) { if(ToothGraphic.IsRight(t.ToString())) { val1=ListPerioMeasure[i].DBvalue; val2=ListPerioMeasure[i].Bvalue; val3=ListPerioMeasure[i].MBvalue; if(sequenceType==PerioSequenceType.MGJ && pmGM!=null) { if(pmGM.DBvalue!=-1) { val1+=pmGM.DBvalue; } if(pmGM.Bvalue!=-1) { val2+=pmGM.Bvalue; } if(pmGM.MBvalue!=-1) { val3+=pmGM.MBvalue; } } surf1=PerioSurf.DB; surf2=PerioSurf.B; surf3=PerioSurf.MB; } else {//for UL and LL val1=ListPerioMeasure[i].MBvalue; val2=ListPerioMeasure[i].Bvalue; val3=ListPerioMeasure[i].DBvalue; if(sequenceType==PerioSequenceType.MGJ && pmGM!=null) { if(pmGM.MBvalue!=-1) { val1+=pmGM.MBvalue; } if(pmGM.Bvalue!=-1) { val2+=pmGM.Bvalue; } if(pmGM.DBvalue!=-1) { val3+=pmGM.DBvalue; } } surf1=PerioSurf.MB; surf2=PerioSurf.B; surf3=PerioSurf.DB; } } else {//lingual if(ToothGraphic.IsRight(t.ToString())) { val1=ListPerioMeasure[i].DLvalue; val2=ListPerioMeasure[i].Lvalue; val3=ListPerioMeasure[i].MLvalue; if(sequenceType==PerioSequenceType.MGJ && pmGM!=null) { if(pmGM.DLvalue!=-1) { val1+=pmGM.DLvalue; } if(pmGM.Lvalue!=-1) { val2+=pmGM.Lvalue; } if(pmGM.MLvalue!=-1) { val3+=pmGM.MLvalue; } } surf1=PerioSurf.DL; surf2=PerioSurf.L; surf3=PerioSurf.ML; } else {//for UL and LL val1=ListPerioMeasure[i].MLvalue; val2=ListPerioMeasure[i].Lvalue; val3=ListPerioMeasure[i].DLvalue; if(sequenceType==PerioSequenceType.MGJ && pmGM!=null) { if(pmGM.MLvalue!=-1) { val1+=pmGM.MLvalue; } if(pmGM.Lvalue!=-1) { val2+=pmGM.Lvalue; } if(pmGM.DLvalue!=-1) { val3+=pmGM.DLvalue; } } surf1=PerioSurf.ML; surf2=PerioSurf.L; surf3=PerioSurf.DL; } } } //We have now filled our 3 points with values and need to evaluate those values. //Any or all of the values may still be -1. if(val1==-1) { //we won't add a point to this line if(line.Vertices.Count==1) {//if there is already one point, then clear it, because a line can't have one point. line.Vertices.Clear(); } if(line.Vertices.Count>1) {//if 2 or more points in the line, then add the line to the result. retVal.Add(line); line=new LineSimple();//and initialize a new line for future points. } } else {//just add a point to the current line. vertex=new Vertex3f(); vertex.Z=0;//we don't use z if(isMaxillary) { vertex.Y=val1; } else { vertex.Y=-val1; } vertex.X=GetXShiftPerioSite(t,surf1)+ToothGraphic.GetDefaultOrthoXpos(t); line.Vertices.Add(vertex); } //val2-------------------------- if(val2==-1) { if(line.Vertices.Count==1) { line.Vertices.Clear(); } if(line.Vertices.Count>1) { retVal.Add(line); line=new LineSimple(); } } else { vertex=new Vertex3f(); vertex.Z=0; if(isMaxillary) { vertex.Y=val2; } else { vertex.Y=-val2; } vertex.X=GetXShiftPerioSite(t,surf2)+ToothGraphic.GetDefaultOrthoXpos(t); line.Vertices.Add(vertex); } //val3------------------------- if(val3==-1) { if(line.Vertices.Count==1) { line.Vertices.Clear(); } if(line.Vertices.Count>1) { retVal.Add(line); line=new LineSimple(); } } else { vertex=new Vertex3f(); vertex.Z=0; if(isMaxillary) { vertex.Y=val3; } else { vertex.Y=-val3; } vertex.X=GetXShiftPerioSite(t,surf3)+ToothGraphic.GetDefaultOrthoXpos(t); line.Vertices.Add(vertex); } //increment to next tooth if(isMaxillary) { t++; } else { t--; } } if(line.Vertices.Count>1) { retVal.Add(line); } return retVal; }
public static D3ObjectGroup ImportObjectsFromObjFile(string strObjData) { D3ObjectGroup d3ObjectGroup=new D3ObjectGroup(); string[] lines=strObjData.Split(new string[] {"\r\n"},StringSplitOptions.None); int i=0; List<Vertex3f> listV=new List<Vertex3f>(); List<Vertex3f> listT=new List<Vertex3f>(); List<Vertex3f> listN=new List<Vertex3f>(); Vertex3f vertex; Vertex3f texture; Vertex3f normal; VertexNormal vertnorm; D3Object d3Object=null; string[] items; string[] subitems; int idxV; int idxT; int idxN; Face face; while(i<lines.Length){ //Debug.WriteLine(i.ToString()); if(lines[i].StartsWith("#")//comment || lines[i].StartsWith("mtllib")//material library. We build our own. || lines[i].StartsWith("usemtl"))//use material { i++; continue;//we don't care about any of these } if(lines[i].StartsWith("o")) {//object. For example "o cube1" //vertices and normals are per object as they are pulled out of the file, //but we need to regroup them per d3Object. i++; continue; } if(lines[i].StartsWith("v ")) {//vertex. For example "v -0.34671119 0.22176000 0.83703486" items=lines[i].Split(' '); vertex=new Vertex3f(); vertex.X=Convert.ToSingle(items[1],CultureInfo.InvariantCulture); vertex.Y=Convert.ToSingle(items[2],CultureInfo.InvariantCulture); vertex.Z=Convert.ToSingle(items[3],CultureInfo.InvariantCulture); listV.Add(vertex); i++; continue; } if(lines[i].StartsWith("vt")) {//vertex. For example "vt 0.72553915 0.63685900" items=lines[i].Split(' '); texture=new Vertex3f(); texture.X=Convert.ToSingle(items[1],CultureInfo.InvariantCulture); texture.Y=Convert.ToSingle(items[2],CultureInfo.InvariantCulture); //texture.Z=Convert.ToSingle(items[3],CultureInfo.InvariantCulture); listT.Add(texture); i++; continue; } if(lines[i].StartsWith("vn")) {//normal. For example "vn -0.32559605 -0.84121753 -0.43167149" items=lines[i].Split(' '); normal=new Vertex3f(); normal.X=Convert.ToSingle(items[1],CultureInfo.InvariantCulture); normal.Y=Convert.ToSingle(items[2],CultureInfo.InvariantCulture); normal.Z=Convert.ToSingle(items[3],CultureInfo.InvariantCulture); listN.Add(normal); i++; continue; } if(lines[i].StartsWith("g")) {//group. For example "g cylinder2_default" if(d3Object!=null) { d3ObjectGroup.D3Objects.Add(d3Object);//add the previous object to the group } d3Object=new D3Object();//start the new one, including the new list of VNs d3Object.Name=lines[i].Substring(2); i++; continue; } if(lines[i].StartsWith("f")) {//face. For example "f 12//384 51//443 384//336 383//335". Format is v//n items=lines[i].Split(' ');//5 items in this example //create triangle fan, preserving counterclockwise order for(int f=2;f<items.Length-1;f++) {//one face/triangle per loop, 2 triangles in this case face=new Face(); //only grab three vertices //first vertex is always the 0 for the fan subitems=items[1].Split('/');//12,,384 for the first triangle idxV=Convert.ToInt32(subitems[0])-1;//11 for the first triangle if(subitems[1]=="") {//no texture idxT=-1; } else { idxT=Convert.ToInt32(subitems[1])-1; } idxN=Convert.ToInt32(subitems[2])-1;//383 for the first triangle vertnorm=new VertexNormal(); vertnorm.Vertex=listV[idxV]; if(idxT!=-1) { vertnorm.Texture=listT[idxT]; } vertnorm.Normal=listN[idxN]; face.IndexList.Add(d3Object.GetIndexForVertNorm(vertnorm)); //second vertex subitems=items[f].Split('/');//51,,443 for the first triangle idxV=Convert.ToInt32(subitems[0])-1;//50 for the first triangle if(subitems[1]=="") {//no texture idxT=-1; } else { idxT=Convert.ToInt32(subitems[1])-1; } idxN=Convert.ToInt32(subitems[2])-1;//442 for the first triangle vertnorm=new VertexNormal(); vertnorm.Vertex=listV[idxV]; if(idxT!=-1) { vertnorm.Texture=listT[idxT]; } vertnorm.Normal=listN[idxN]; face.IndexList.Add(d3Object.GetIndexForVertNorm(vertnorm)); //third vertex subitems=items[f+1].Split('/');//384,,336 for the first triangle idxV=Convert.ToInt32(subitems[0])-1;//383 for the first triangle if(subitems[1]=="") {//no texture idxT=-1; } else { idxT=Convert.ToInt32(subitems[1])-1; } idxN=Convert.ToInt32(subitems[2])-1;//335 for the first triangle vertnorm=new VertexNormal(); vertnorm.Vertex=listV[idxV]; if(idxT!=-1) { vertnorm.Texture=listT[idxT]; } vertnorm.Normal=listN[idxN]; face.IndexList.Add(d3Object.GetIndexForVertNorm(vertnorm)); d3Object.Faces.Add(face); } i++; continue; } //might be another kind of row that we missed above i++; } if(d3Object!=null) { d3ObjectGroup.D3Objects.Add(d3Object);//add the last object to the group } return d3ObjectGroup; }