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; }
///<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 Face Copy() { Face f=new Face(); f.IndexList=new List<int>(this.IndexList); return f; }