public virtual Object3d Clone() { Object3d obj = new Object3d(); try { obj.m_name = UVDLPApp.Instance().Engine3D.GetUniqueName( this.m_name); // need to find unique name obj.m_fullname = this.m_fullname; obj.tag = this.tag; foreach (Polygon ply in m_lstpolys) { Polygon pl2 = new Polygon(); pl2.m_color = ply.m_color; pl2.m_points = new Point3d[3]; obj.m_lstpolys.Add(pl2); pl2.m_points[0] = new Point3d(ply.m_points[0]); pl2.m_points[1] = new Point3d(ply.m_points[1]); pl2.m_points[2] = new Point3d(ply.m_points[2]); } foreach (Polygon ply in obj.m_lstpolys) { foreach (Point3d pnt in ply.m_points) { obj.m_lstpoints.Add(pnt); // a fair bit of overlap, but whatever... } } obj.Update(); } catch (Exception ex) { DebugLogger.Instance().LogError(ex); } return obj; }
public static Object3d Sphere(float radius, int rings, int sectors) { try { Object3d sp = new Object3d(); sp.Name = "Sphere"; float R = 1f/(float)(rings-1); float S = 1f/(float)(sectors-1); float M_PI = (float)Math.PI;// *0.0174532925f; // with deg2rad float M_PI_2 = M_PI / 2; for(int r = 0; r < rings; r++) { for(int s = 0; s < sectors; s++) { float y =(float) Math.Sin( - M_PI_2 + M_PI * r * R ); float x = (float)Math.Cos(2 * M_PI * s * S) * (float)Math.Sin(M_PI * r * R); float z = (float)Math.Sin(2 * M_PI * s * S) * (float)Math.Sin(M_PI * r * R); Point3d pnt = new Point3d(x * radius, y * radius, z * radius); sp.m_lstpoints.Add(pnt); } } //indices.resize(rings * sectors * 4); //std::vector<GLushort>::iterator i = indices.begin(); for(int r = 0; r < rings - 1; r++) { for (int s = 0; s < sectors - 1; s++) { Polygon p1 = new Polygon(); Polygon p2 = new Polygon(); sp.m_lstpolys.Add(p1); sp.m_lstpolys.Add(p2); p1.m_points = new Point3d[3]; p2.m_points = new Point3d[3]; p1.m_points[2] = sp.m_lstpoints[r * sectors + s]; p1.m_points[1] = sp.m_lstpoints[r * sectors + (s + 1)]; p1.m_points[0] = sp.m_lstpoints[(r + 1) * sectors + (s + 1)]; p2.m_points[2] = sp.m_lstpoints[(r + 1) * sectors + (s + 1)]; p2.m_points[1] = sp.m_lstpoints[(r + 1) * sectors + s]; p2.m_points[0] = sp.m_lstpoints[r * sectors + s]; } } sp.Update(); sp.Rotate(90 * 0.0174532925f, 0, 0); sp.Update(); return sp; } catch(Exception ex) { DebugLogger.Instance().LogError(ex); return null; } }
public ISectData(Object3d o, Polygon p, Point3d isect, Point3d orgin, Vector3d dir) { intersect = new Point3d(); intersect.Set(isect); origin = new Point3d(); direction = new Vector3d(); origin.Set(orgin); direction.Set(dir); obj = o; poly = p; }
public PolyLine3d(PolyLine3d src) { tag = 0; m_color = src.m_color; m_derived = src.m_derived; minx = src.minx; miny = src.miny; minz = src.minz; maxx = src.maxx; maxy = src.maxy; maxz = src.maxz; linewidth = 1; visible = true; m_points = new List<Point3d>(); foreach (Point3d pnt in src.m_points) { Point3d p = new Point3d(pnt.x, pnt.y, pnt.z); m_points.Add(p); } }
/// <summary> /// This will return true if this poly and the specified share and edge (2 points) /// use this sparingly, it's a n^2 time routine /// </summary> /// <param name="ply"></param> /// <returns></returns> public bool SharesEdge(Polygon ply) { bool ret = false; int cnt = 0; foreach(Point3d pnt in m_points) { foreach (Point3d pnt2 in ply.m_points) { if (pnt.Matches(pnt2)) { cnt++; } } } if (cnt == 2) { ret = true; } return ret; }
// given the top or bottom starting index, make the surface face private void MakeTopBottomFace(int idx, int numdivs, bool top) { try { int centeridx = idx + numdivs; for (int cnt = 0; cnt < numdivs; cnt++) { Polygon plt = new Polygon(); m_lstpolys.Add(plt); plt.m_points = new Point3d[3]; // create some point storage plt.m_points[0] = (Point3d)m_lstpoints[centeridx]; // the first point is always the center pointt if (top) { plt.m_points[2] = (Point3d)m_lstpoints[(cnt + 1) % numdivs + idx]; plt.m_points[1] = (Point3d)m_lstpoints[idx + cnt]; } else { plt.m_points[1] = (Point3d)m_lstpoints[(cnt + 1) % numdivs + idx]; plt.m_points[2] = (Point3d)m_lstpoints[idx + cnt]; } } } catch (Exception ex) { DebugLogger.Instance().LogError(ex.Message); } }
void FillTriangleInMap(Polygon ply) { // order points by height Point3d p1 = ply.m_points[0]; Point3d p2 = ply.m_points[1]; Point3d p3 = ply.m_points[2]; OrderPoints(ref p1, ref p2); OrderPoints(ref p2, ref p3); OrderPoints(ref p1, ref p2); // find first crossing line int ix = (int)((p1.x - m_platex) / m_spacing); float x = (float)(ix + 1)*m_spacing + m_platex; if (p2.x <= x) { FillColumnInMap(ix, p1.y, p2.y); if (p3.x < x) // all in the same column { FillColumnInMap(ix, p1.y, p3.y); return; } } float m13 = (p3.y - p1.y) / (p3.x - p1.x); float n13 = p1.y - (m13 * p1.x); float oy1, oy2; if (p2.x > x) { float m12 = (p2.y - p1.y) / (p2.x - p1.x); float n12 = p1.y - (m12 * p1.x); oy1 = p1.y; oy2 = p1.y; while (p2.x > x) { float y1 = m12 * x + n12; float y2 = m13 * x + n13; FillColumnInMap(ix, y1, y2, oy1, oy2); oy1 = y1; oy2 = y2; x += m_spacing; ix++; } } if (p3.x < x) { // same column as p2 FillColumnInMap(ix, p2.y, p3.y); return; } float m23 = (p3.y - p2.y) / (p3.x - p2.x); float n23 = p2.y - (m23 * p2.x); oy1 = p2.y; oy2 = p2.y; while (p3.x > x) { float y1 = m23 * x + n23; float y2 = m13 * x + n13; FillColumnInMap(ix, y1, y2, oy1, oy2); oy1 = y1; oy2 = y2; x += m_spacing; ix++; } FillColumnInMap(ix, oy1, oy2, p3.y, p3.y); }
public static bool IntersectPoly(Polygon poly, Point3d start, Point3d end,ref Point3d intersection) { if (intersect3D_RayTriangle(start, end, poly, ref intersection) == 1) return true; return false; }
// intersect3D_RayTriangle(): find the 3D intersection of a ray with a triangle // Input: a ray R, and a triangle T // Output: *I = intersection point (when it exists) // Return: -1 = triangle is degenerate (a segment or point) // 0 = disjoint (no intersect) // 1 = intersect in unique point I1 // 2 = are in the same plane static int intersect3D_RayTriangle(Point3d startp, Point3d endp, Polygon T,ref Point3d I) { // Vector3d u, v, n; // triangle vectors // Vector3d dir, w0, w; // ray vectors float r, a, b; // params to calc ray-plane intersect // get triangle edge vectors and plane normal //u = T.m_points[1] - T.m_points[0]; u.Set(T.m_points[1].x - T.m_points[0].x, T.m_points[1].y - T.m_points[0].y, T.m_points[1].z - T.m_points[0].z); //v = T.m_points[2] - T.m_points[0]; v.Set(T.m_points[2].x - T.m_points[0].x, T.m_points[2].y - T.m_points[0].y, T.m_points[2].z - T.m_points[0].z); n = Vector3d.cross(u , v); // cross product //n = T.m_normal; //if (n == 0) // triangle is degenerate // return -1; // do not deal with this case //dir = endp - startp;//dir = R.P1 - R.P0; // ray direction vector dir.Set(endp.x - startp.x, endp.y - startp.y, endp.z - startp.z); //w0 = startp - T.m_points[0];//w0 = R.P0 - T.V0; w0.Set(startp.x - T.m_points[0].x, startp.y - T.m_points[0].y, startp.z - T.m_points[0].z); a = (float)-Vector3d.dot(n, w0); //a = -dot(n, w0); b = (float)Vector3d.dot(n, dir);//b = dot(n, dir); if(Math.Abs(b) < .0001) { // ray is parallel to triangle plane if (a == 0) // ray lies in triangle plane return 2; else return 0; // ray disjoint from plane } // get intersect point of ray with triangle plane r = a / b; if (r < 0.0) // ray goes away from triangle return 0; // => no intersect // for a segment, also test if (r > 1.0) => no intersect //*I = R.P0 + r * dir; // intersect point of ray and plane I.x = startp.x + r * dir.x; I.y = startp.y + r * dir.y; I.z = startp.z + r * dir.z; if (float.IsNaN(I.x)) { // what's going on here? I.x = -1.0f; } // is I inside T? double uu, uv, vv, wu, wv, D; uu = Vector3d.dot(u, u); uv = Vector3d.dot(u, v); vv = Vector3d.dot(v, v); //w = I - T.m_points[0];// V0; w.Set(I.x - T.m_points[0].x,I.y - T.m_points[0].y,I.z - T.m_points[0].z);// V0; wu = Vector3d.dot(w, u); wv = Vector3d.dot(w, v); D = uv * uv - uu * vv; // get and test parametric coords double s, t; s = (uv * wv - vv * wu) / D; if (s < 0.0 || s > 1.0) // I is outside T return 0; t = (uv * wu - uu * wv) / D; if (t < 0.0 || (s + t) > 1.0) // I is outside T return 0; return 1; // I is in T }
/// <summary> /// This function loads an ascii STL file /// </summary> /// <param name="filename"></param> /// <returns></returns> public bool LoadSTL_ASCII(string filename) { try { StreamReader sr = new StreamReader(filename); m_fullname = filename; m_name = Path.GetFileName(filename); //first line should be "solid <name> " string line = sr.ReadLine(); string []toks = line.Split(' '); if (!toks[0].ToLower().StartsWith("solid")) return false; // does not start with "solid" while (!sr.EndOfStream) { line = sr.ReadLine().Trim();//facet if (line.ToLower().StartsWith("facet")) { line = sr.ReadLine().Trim();//outerloop if (!line.ToLower().StartsWith("outer loop")) { return false; } Polygon poly = new Polygon();//create a new polygon m_lstpolys.Add(poly); // add it to the object's polygon list poly.m_points = new Point3d[3]; // create the storage for 3 points for (int idx = 0; idx < 3; idx++)//read the point, will break somehow on bad 4 vertext faces. { poly.m_points[idx] = new Point3d(); // create a new point at the poly's indexed point list m_lstpoints.Add(poly.m_points[idx]); // add this point to the object's list of point char[] delimiters = new char[] { ' ' }; line = sr.ReadLine().Trim(); // vertex toks = line.Split(delimiters, StringSplitOptions.RemoveEmptyEntries); if (!toks[0].ToLower().Equals("vertex")) { return false; } poly.m_points[idx].x = (float)float.Parse(toks[1].Trim(), System.Globalization.NumberStyles.Any); poly.m_points[idx].y = (float)float.Parse(toks[2].Trim(), System.Globalization.NumberStyles.Any); poly.m_points[idx].z = (float)float.Parse(toks[3].Trim(), System.Globalization.NumberStyles.Any); } line = sr.ReadLine().Trim();//endloop if (!line.Equals("endloop")) { return false; } line = sr.ReadLine().Trim().ToLower(); // endfacet if (!line.Equals("endfacet")) { return false; } } // endfacet else if (line.ToLower().StartsWith("endsolid")) { Update(); // initial positions please... } else { DebugLogger.Instance().LogError("Error in LoadSTL ASCII, facet expected"); } } // end of input stream sr.Close(); } catch (Exception ex ) { DebugLogger.Instance().LogError(ex.StackTrace); DebugLogger.Instance().LogError(ex.Message); return false; } FindMinMax(); return true; }
void AddTriangle(int v1, int v2, int v3) { Point3d pt1 = m_pointList[v1].pt; Point3d pt2 = m_pointList[v2].pt; Point3d pt3 = m_pointList[v3].pt; Polygon p = new Polygon(); p.m_points = new Point3d[] { pt1, pt2, pt3 }; // calculate normal Vector3d edge1 = new Vector3d(pt1.x - pt2.x, pt1.y - pt2.y, pt1.z - pt2.z); Vector3d edge2 = new Vector3d(pt3.x - pt2.x, pt3.y - pt2.y, pt3.z - pt2.z); p.m_normal = Vector3d.cross(edge1, edge2); p.m_normal.Normalize(); m_curObject.m_lstpolys.Add(p); }
public bool LoadSTL_Binary(string filename) { BinaryReader br = null; try { br = new BinaryReader(File.Open(filename, FileMode.Open)); m_fullname = filename; m_name = Path.GetFileNameWithoutExtension(filename); byte[] data = new byte[80]; data = br.ReadBytes(80); // read the header uint numtri = br.ReadUInt32(); for (uint c = 0; c < numtri; c++) { Polygon p = new Polygon(); m_lstpolys.Add(p); // add this polygon to the object p.m_normal.Load(br); // load the normal p.m_points = new Point3d[3]; // create storage for (int pc = 0; pc < 3; pc++) //iterate through the points { Point3d pnt = new Point3d(); pnt.Load(br); m_lstpoints.Add(pnt); p.m_points[pc] = pnt; } uint attr = br.ReadUInt16(); // attribute COULD be used for color /* The VisCAM and SolidView software packages use the two "attribute byte count" bytes at the end of every triangle to store a 15-bit RGB color: bit 0 to 4 are the intensity level for blue (0 to 31), bits 5 to 9 are the intensity level for green (0 to 31), bits 10 to 14 are the intensity level for red (0 to 31), bit 15 is 1 if the color is valid, or 0 if the color is not valid (as with normal STL files). */ //BBBBBGGGGGRRRRRV //VRRRRRGGGGGBBBBB byte R, G, B, used; B = (byte)((attr & 0x001f)<<3); G = (byte)((attr>>5 & 0x001f)<<3); R = (byte)((attr>>10 & 0x001f)<<3); used = (byte)(attr >> 15 & 0x0001); if (used != 0) { p.m_colorsource = Color.FromArgb(255, R, G, B); p.m_color = p.m_colorsource; } } Update(); // initial positions please... br.Close(); return true; } catch (Exception) { if(br!=null) br.Close(); return false; } }
//determine when on the model it was selected public void Select(Polygon ply) { //based on the polygon passed in, we need to identify which segment of the model this belongs to m_seltype = eSelType.eWhole; // mark it whole for (int c = psi_base; c < pei_base; c++) { if(ply == m_lstpolys[c]) { m_seltype = eSelType.eBase; } } for (int c = psi_tip; c < pei_tip; c++) { if (ply == m_lstpolys[c]) { m_seltype = eSelType.eTip; } } for (int c = 0; c < m_lstpolys.Count; c++) { m_lstpolys[c].m_color = Color.Yellow; } }
/// <summary> /// This function loads an ascii STL file /// </summary> /// <param name="filename"></param> /// <returns></returns> public bool LoadSTL_ASCII(string filename) { try { StreamReader sr = new StreamReader(filename); m_fullname = filename; m_name = Path.GetFileName(filename); //first line should be "solid <name> " string line = sr.ReadLine(); string []toks = line.Split(' '); if (!toks[0].ToLower().StartsWith("solid")) return false; // does not start with "solid" while (!sr.EndOfStream) { line = sr.ReadLine().Trim(); if (line.ToLower().StartsWith("facet")) { line = sr.ReadLine().Trim();//outerloop Polygon poly = new Polygon();//create a new polygon m_lstpolys.Add(poly); // add it to the polygon list poly.m_points = new Point3d[3]; // create the storage for (int idx = 0; idx < 3; idx++)//read the point { Point3d tmp = new Point3d(); // create a temp point char[] delimiters = new char[] {' '}; line = sr.ReadLine().Trim();//outerloop toks = line.Split(delimiters,StringSplitOptions.RemoveEmptyEntries); // tmp.x = float.Parse(toks[1].Trim()); // tmp.y = float.Parse(toks[2].Trim()); // tmp.z = float.Parse(toks[3].Trim()); float tf = 0.0f; Single.TryParse(toks[1],out tf); tmp.x = tf; Single.TryParse(toks[2], out tf); tmp.y = tf; Single.TryParse(toks[3], out tf); tmp.z = tf; poly.m_points[idx] = AddUniqueVert(tmp); } poly.CalcNormal(); poly.CalcCenter(); line = sr.ReadLine().Trim();//endloop } } sr.Close(); } catch (Exception ) { return false; } FindMinMax(); return true; }
public bool GenerateFromBitmap(string file, ScaleFactor f) { try { m_name = Path.GetFileName(file); Bitmap bm = new Bitmap(file); // add 3d points for (int y = 0; y < bm.Height; y++) { for (int x = 0; x < bm.Width; x++) { Color clr = bm.GetPixel(x, y); Point3d pnt = new Point3d(); pnt.x = f.x * ((double)x); pnt.y = f.y * ((double)y); pnt.z = f.z * ((double)clr.R); m_lstpoints.Add(pnt); } } // now generate polys for (int y = 0; y < bm.Height; y++) { for (int x = 0; x < bm.Width; x++) { if (y == (bm.Height - 1)) { continue; } if (x == (bm.Width - 1)) { continue; } Polygon ply = new Polygon(); ply.m_points = new Point3d[3]; int idx1 = (y * bm.Width) + x; int idx2 = (y * bm.Width) + x + 1; int idx3 = (y * bm.Width) + x + bm.Width; ply.m_points[0] = (Point3d)m_lstpoints[idx1]; ply.m_points[1] = (Point3d)m_lstpoints[idx2]; ply.m_points[2] = (Point3d)m_lstpoints[idx3]; ply.CalcCenter(); ply.CalcNormal(); m_lstpolys.Add(ply); Polygon ply2 = new Polygon(); ply2.m_points = new Point3d[3]; idx1 = (y * bm.Width) + x + 1; idx2 = (y * bm.Width) + x + bm.Width + 1; idx3 = (y * bm.Width) + x + bm.Width; ply2.m_points[0] = (Point3d)m_lstpoints[idx1]; ply2.m_points[1] = (Point3d)m_lstpoints[idx2]; ply2.m_points[2] = (Point3d)m_lstpoints[idx3]; ply2.CalcCenter(); ply2.CalcNormal(); m_lstpolys.Add(ply2); } } return(true); } catch (Exception) { return(false); } }
void FillTiles() { m_tilePointsTop = new Point3d[m_ntilesx + 1, m_ntilesy + 1]; m_tilePointsBot = new Point3d[m_ntilesx + 1, m_ntilesy + 1]; int x, y; for (x = 0; x < m_ntilesx; x++) { for (y = 0; y < m_ntilesy; y++) { if (m_tileMap[x, y]) { Polygon plt = new Polygon(); m_lstpolys.Add(plt); plt.m_points = new Point3d[3]; plt.m_points[0] = GetTilePointTop(x, y); plt.m_points[1] = GetTilePointTop(x + 1, y); plt.m_points[2] = GetTilePointTop(x + 1, y + 1); plt = new Polygon(); m_lstpolys.Add(plt); plt.m_points = new Point3d[3]; plt.m_points[0] = GetTilePointTop(x, y); plt.m_points[1] = GetTilePointTop(x + 1, y + 1); plt.m_points[2] = GetTilePointTop(x, y + 1); Polygon plb = new Polygon(); m_lstpolys.Add(plb); plb.m_points = new Point3d[3]; plb.m_points[0] = GetTilePointBot(x, y); plb.m_points[1] = GetTilePointBot(x + 1, y + 1); plb.m_points[2] = GetTilePointBot(x + 1, y); plb = new Polygon(); m_lstpolys.Add(plb); plb.m_points = new Point3d[3]; plb.m_points[0] = GetTilePointBot(x, y); plb.m_points[1] = GetTilePointBot(x, y + 1); plb.m_points[2] = GetTilePointBot(x + 1, y + 1); } } } }
public bool GenerateFromBitmap(string file, Vector3d f) { try { m_name = Path.GetFileName(file); Bitmap bm = new Bitmap(file); // add 3d points for (int y = 0; y < bm.Height; y++) { for (int x = 0; x < bm.Width; x++) { Color clr = bm.GetPixel(x, y); Point3d pnt = new Point3d(); pnt.x = f.x * ((float)x); pnt.y = f.y * ((float)y); pnt.z = f.z * ((float)clr.R); m_lstpoints.Add(pnt); } } // now generate polys for (int y = 0; y < bm.Height ; y++) { for (int x = 0; x < bm.Width ; x++) { if (y == (bm.Height - 1)) continue; if (x == (bm.Width - 1)) continue; Polygon ply = new Polygon(); ply.m_points = new Point3d[3]; int idx1 = (y * bm.Width) + x; int idx2 = (y * bm.Width) + x + 1; int idx3 = (y * bm.Width) + x + bm.Width ; ply.m_points[0] = (Point3d)m_lstpoints[idx1]; ply.m_points[1] = (Point3d)m_lstpoints[idx2]; ply.m_points[2] = (Point3d)m_lstpoints[idx3]; ply.CalcCenter(); ply.CalcNormal(); m_lstpolys.Add(ply); Polygon ply2 = new Polygon(); ply2.m_points = new Point3d[3]; idx1 = (y * bm.Width) + x + 1; idx2 = (y * bm.Width) + x + bm.Width + 1; idx3 = (y * bm.Width) + x + bm.Width; ply2.m_points[0] = (Point3d)m_lstpoints[idx1]; ply2.m_points[1] = (Point3d)m_lstpoints[idx2]; ply2.m_points[2] = (Point3d)m_lstpoints[idx3]; ply2.CalcCenter(); ply2.CalcNormal(); m_lstpolys.Add(ply2); } } Update(); return true; } catch (Exception) { return false; } }
public bool LoadDXF(string filename) { try { StreamReader sr = new StreamReader(filename); m_fullname = filename; m_name = Path.GetFileName(filename); while (!sr.EndOfStream) { string line = sr.ReadLine(); line = line.Trim(); if (line.ToUpper() == "3DFACE") { Polygon poly = new Polygon();//create a new polygon m_lstpolys.Add(poly); // add it to the polygon list Point3d []pnts; LoadDXFPolyPoints(out pnts, sr); poly.m_points = new Point3d[pnts.Length]; // create the storage int idx = 0; foreach(Point3d p in pnts) { poly.m_points[idx++] = AddUniqueVert(p); } } } sr.Close(); if (NumPolys > 0) { Update(); return true; } else { return false; } }catch( Exception) { return false; } }
public bool LoadSTL_Binary(string filename) { BinaryReader br = null; try { br = new BinaryReader(File.Open(filename, FileMode.Open)); m_fullname = filename; m_name = Path.GetFileName(filename); byte[] data = new byte[80]; data = br.ReadBytes(80); // read the header uint numtri = br.ReadUInt32(); for (uint c = 0; c < numtri; c++) { Polygon p = new Polygon(); m_lstpolys.Add(p); // add this polygon to the object p.m_normal.Load(br); // load the normal p.m_points = new Point3d[3]; // create storage for (int pc = 0; pc < 3; pc++) //iterate through the points { Point3d pnt = new Point3d(); pnt.Load(br); m_lstpoints.Add(pnt); p.m_points[pc] = pnt; } uint attr = br.ReadUInt16(); // not used attribute } Update(); // initial positions please... br.Close(); return true; } catch (Exception) { if(br!=null) br.Close(); return false; } }
void AddShape(float[] shape, Point3d ptTop, Point3d ptBot, float scale, int rotate90) { int i; int npoints = shape.Length / 2; // create 3d points from shape Point3d[] ptops = new Point3d[npoints]; Point3d[] pbots = new Point3d[npoints]; for (i = 0; i < npoints; i++) { ptops[i] = CreatePoint(shape[i*2], shape[i*2 + 1], ptTop.z, scale, rotate90, ptTop.x, ptTop.y); pbots[i] = CreatePoint(shape[i*2], shape[i*2 + 1], ptBot.z, scale, rotate90, ptBot.x, ptBot.y); } // top + bottom for (i = 0; i < npoints-1; i++) { Polygon plt = new Polygon(); m_lstpolys.Add(plt); plt.m_points = new Point3d[3]; plt.m_points[0] = ptTop; plt.m_points[1] = ptops[i + 1]; plt.m_points[2] = ptops[i]; Polygon plb = new Polygon(); m_lstpolys.Add(plb); plb.m_points = new Point3d[3]; plb.m_points[0] = ptBot; plb.m_points[1] = pbots[i]; plb.m_points[2] = pbots[i + 1]; } // side for (i = 1; i < npoints-2; i ++) { Polygon plt = new Polygon(); m_lstpolys.Add(plt); plt.m_points = new Point3d[3]; plt.m_points[0] = ptops[i]; plt.m_points[1] = ptops[i + 1]; plt.m_points[2] = pbots[i]; Polygon plb = new Polygon(); m_lstpolys.Add(plb); plb.m_points = new Point3d[3]; plb.m_points[0] = ptops[i+1]; plb.m_points[1] = pbots[i + 1]; plb.m_points[2] = pbots[i]; } }
public bool LoadObjFile(string fileName) { try { if (string.IsNullOrEmpty(fileName)) { return false; } if (!File.Exists(fileName)) { DebugLogger.Instance().LogError("3ds file could not be found " + fileName); return false; // throw new ArgumentException("3ds file could not be found", "fileName"); } this.m_fullname = fileName; this.m_name = Path.GetFileNameWithoutExtension(fileName); using (StreamReader sr = File.OpenText(fileName)) { int curLineNo = 0; string line = null; bool done = false; //ArrayList lclpoints = new ArrayList(); ArrayList lclply = new ArrayList(); ArrayList lclnrm = new ArrayList(); while ((line = sr.ReadLine()) != null) { curLineNo++; if (done || line.Trim() == string.Empty || line.StartsWith("#")) { continue; } string[] parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); switch (parts[0]) { case "v": // vertex Point3d pnt = new Point3d(); float[] v = ParseVector(parts); pnt.x = v[0]; pnt.y = v[1]; pnt.z = v[2]; m_lstpoints.Add(pnt); break; case "vn": // vertex normal lclnrm.Add(ParseVector(parts)); break; //case "g": // done = true; // break; case "f": // a face if (parts.Length < 3) { throw new FormatException(string.Format("Face found with less three indices (line {0})", curLineNo)); } Polygon ply; int fp1, fp2, fp3; // 4 pointed poly becomes 2 tris // 5 pointed poly becomes 3 tris // 6 pointed poly becomes 4 tris int numpnts = parts.Length - 1; // take off one int numpoly = numpnts - 2; int partidx = 1; fp1 = ParseFacePart(parts[partidx]) - 1; // point 0 is common to all polygons partidx++; for (int c = 0; c < numpoly; c++) { ply = new Polygon(); // create a new poly m_lstpolys.Add(ply); // add it to this object ply.m_points = new Point3d[3]; // create point storage //set the points fp2 = ParseFacePart(parts[partidx]) - 1; fp3 = ParseFacePart(parts[partidx+1]) - 1; ply.m_points[0] = (Point3d)m_lstpoints[fp1]; ply.m_points[1] = (Point3d)m_lstpoints[fp2]; ply.m_points[2] = (Point3d)m_lstpoints[fp3]; partidx++; ply.Update(); // update all the info } break; } } // Console.WriteLine("v: {0} n: {1} q:{2}", vectors.Count,normals.Count, quads.Count); } return true; } catch (Exception ex) { DebugLogger.Instance().LogError(ex.Message); return false; } }
/* * Given a radius length r and an angle t in radians and a circle's center (h,k), * you can calculate the coordinates of a point on the circumference as follows * (this is pseudo-code, you'll have to adapt it to your language): * float x = r*cos(t) + h; * float y = r*sin(t) + k; */ public void Create(double bottomradius, double topradius, double height, int numdivscirc, int numdivsheight) { //generate sets of points that describe a circle vertically // int idx = 0; // this points to the first point in the circle double zlev = 0.0; // start at the bottom of the cylinder //Name = "Cylinder"; // for (int cnt = 0; cnt < numdivsheight; cnt++) // { GenerateCirclePoints(bottomradius, numdivscirc, zlev); // bottom zlev += height; GenerateCirclePoints(topradius, numdivscirc, zlev); // top // now generate side polygons for (int cnt = 0; cnt < numdivscirc; cnt++) { /* left * 3 |\ | \ |__\ | 2 1 | | right | | 2 3 | _____ \ | \ | \ | \| \| 1 * * */ // the left looks correct int topidx = numdivscirc + 1; // index to the first point in the top circle Polygon plyl = new Polygon(); m_lstpolys.Add(plyl); plyl.m_points = new Point3d[3]; // create some point storage plyl.m_points[0] = (Point3d)m_lstpoints[cnt]; plyl.m_points[1] = (Point3d)m_lstpoints[(cnt + 1) % numdivscirc]; plyl.m_points[2] = (Point3d)m_lstpoints[cnt + topidx]; plyl.CalcCenter(); plyl.CalcNormal(); // bottom faces int centeridx = numdivscirc; Polygon plb = new Polygon(); m_lstpolys.Add(plb); plb.m_points = new Point3d[3]; // create some point storage plb.m_points[0] = (Point3d)m_lstpoints[centeridx]; // the first point is always the center point plb.m_points[1] = (Point3d)m_lstpoints[(cnt + 1) % numdivscirc]; plb.m_points[2] = (Point3d)m_lstpoints[cnt]; plb.CalcCenter(); plb.CalcNormal(); Polygon plyr = new Polygon(); m_lstpolys.Add(plyr); plyr.m_points = new Point3d[3]; // create some point storage plyr.m_points[0] = (Point3d)m_lstpoints[(cnt + 1) % numdivscirc]; plyr.m_points[1] = (Point3d)m_lstpoints[((cnt + 1) % numdivscirc) + topidx]; // plyr.m_points[2] = (Point3d)m_lstpoints[cnt + topidx]; // the point directly above it plyr.CalcCenter(); plyr.CalcNormal(); //int topidx = numdivscirc + 1; // index to the first point in the top circle // top faces centeridx = topidx + numdivscirc; Polygon plt = new Polygon(); m_lstpolys.Add(plt); plt.m_points = new Point3d[3]; // create some point storage plt.m_points[0] = (Point3d)m_lstpoints[centeridx]; // the first point is always the center pointt plt.m_points[2] = (Point3d)m_lstpoints[(cnt + 1) % numdivscirc + topidx]; plt.m_points[1] = (Point3d)m_lstpoints[topidx + cnt]; plt.CalcCenter(); plt.CalcNormal(); } //idx += numdivscirc; // } CalcCenter(); CalcMinMaxes(); }
private Object3d ConvertFrom(List<csgjs_polygon> lstply) { Object3d obj = new Object3d(); for (int i = 0; i < lstply.Count; i++) { csgjs_polygon poly = lstply[i]; for (int j = 2; j < poly.vertices.Count; j++) { Polygon ply = new Polygon(); // create a new polygon ply.m_points = new Point3d[3]; obj.m_lstpolys.Add(ply); //add it to the list Point3d p0 = new Point3d(); Point3d p1 = new Point3d(); Point3d p2 = new Point3d(); p0.Set(poly.vertices[0].pos.x, poly.vertices[0].pos.y, poly.vertices[0].pos.z); p1.Set(poly.vertices[j - 1].pos.x, poly.vertices[j - 1].pos.y, poly.vertices[j - 1].pos.z); p2.Set(poly.vertices[j].pos.x, poly.vertices[j].pos.y, poly.vertices[j].pos.z); ply.m_points[0] = p0; ply.m_points[1] = p1; ply.m_points[2] = p2; obj.m_lstpoints.Add(p0); obj.m_lstpoints.Add(p1); obj.m_lstpoints.Add(p2); } } obj.Update(); return obj; }
Object3d ProcessObjectChunk(ThreeDSChunk chunk, Object3d e) { while (chunk.BytesRead < chunk.Length) { ThreeDSChunk child = new ThreeDSChunk(reader); switch ((Groups)child.ID) { case Groups.C_OBJECT_MESH: ProcessObjectChunk(child, e); break; case Groups.C_OBJECT_VERTICES: //e.vertices = ReadVertices(child); e.m_lstpoints = ReadVertices(child); break; case Groups.C_OBJECT_FACES: //e.indices = Triangle []tris = ReadIndices(child); foreach (Triangle t in tris) { Polygon p = new Polygon(); p.m_points = new Point3d[3]; p.m_points[0] = (Point3d)e.m_lstpoints[t.vertex1]; p.m_points[1] = (Point3d)e.m_lstpoints[t.vertex2]; p.m_points[2] = (Point3d)e.m_lstpoints[t.vertex3]; e.m_lstpolys.Add(p); } e.Update(); if (child.BytesRead < child.Length) ProcessObjectChunk(child, e); break; case Groups.C_OBJECT_MATERIAL: string name2 = ProcessString(child); Console.WriteLine(" Uses Material: {0}", name2); Material mat; if (materials.TryGetValue(name2, out mat)) e.material = mat; else Console.WriteLine(" Warning: Material '{0}' not found. ", name2); SkipChunk(child); break; case Groups.C_OBJECT_UV: int cnt = reader.ReadUInt16(); child.BytesRead += 2; Console.WriteLine(" TexCoords: {0}", cnt); //e.texcoords = new TexCoord[cnt]; //TexCoord tc = new TexCoord(); for (int ii = 0; ii < cnt; ii++) { //should add this to a list somewhere TexCoord tc = new TexCoord(reader.ReadSingle(), reader.ReadSingle()); } child.BytesRead += (cnt * (4 * 2)); break; default: SkipChunk(child); break; } chunk.BytesRead += child.BytesRead; //Console.WriteLine ( " ID: {0} Length: {1} Read: {2}", chunk.ID.ToString("x"), chunk.Length , chunk.BytesRead ); } return e; }
private static void CreateGroundPlane() { m_gp = new Object3d(); m_gp.Name = "GroundPlane"; Point3d p0=new Point3d(-500,-500,0); Point3d p1=new Point3d(500,-500,0); Point3d p2=new Point3d(500,500,0); Point3d p3=new Point3d(-500,500,0); m_gp.m_lstpoints.Add(p0); m_gp.m_lstpoints.Add(p1); m_gp.m_lstpoints.Add(p2); m_gp.m_lstpoints.Add(p3); Polygon ply0 = new Polygon(); ply0.m_points = new Point3d[3]; ply0.m_points[0] = p0; ply0.m_points[1] = p1; ply0.m_points[2] = p2; Polygon ply1 = new Polygon(); ply1.m_points = new Point3d[3]; ply1.m_points[0] = p0; ply1.m_points[1] = p2; ply1.m_points[2] = p3; m_gp.m_lstpolys.Add(ply0); m_gp.m_lstpolys.Add(ply1); m_gp.tag = Object3d.OBJ_GROUND; // groundplane tag m_gp.Update(); // p1.m }
public static bool IntersectPoly(Polygon poly, Point3d start, Point3d end,ref Point3d intersection) { //intersect a Polygon with a ray in world space bool retval = false; double deltaX, deltaY, deltaZ, t, T, S; double A, B, C, D;//the Polygon plane double denom; if (TstPnt[0] == null) // create if not created already { TstPnt[0] = new TestPoint(); TstPnt[1] = new TestPoint(); TstPnt[2] = new TestPoint(); TstPnt[3] = new TestPoint(); } A = poly.plane.a; B = poly.plane.b; C = poly.plane.c; D = poly.plane.d; deltaX = end.x - start.x; deltaY = end.y - start.y; deltaZ = end.z - start.z; denom = (A * deltaX + B * deltaY + C * deltaZ); if (denom == 0.0)//ray is parallel, no intersection { retval = false; return retval; } T = (-1) / denom; S = (A * start.x + B * start.y + C * start.z); t = (S + D) * T; //at this point we have a possible intersection //project to a major world axis and test for containment in the poly intersection.x = (float)(start.x + (t * deltaX)); intersection.y = (float)(start.y + (t * deltaY)); intersection.z = (float)(start.z + (t * deltaZ)); numTstPnt = poly.m_points.Length; // test the X/Y plane for (long counter = 0; counter < poly.m_points.Length; counter++) { TstPnt[counter].X = poly.m_points[counter].x; TstPnt[counter].Y = poly.m_points[counter].y; } if (CrossingsTest(intersection.x, intersection.y) == 1) { retval = true; return retval; } // Test the X/Z plane for (long counter = 0; counter < poly.m_points.Length; counter++) { TstPnt[counter].X = poly.m_points[counter].x; TstPnt[counter].Y = poly.m_points[counter].z; } if (CrossingsTest(intersection.x, intersection.y) == 1) { retval = true; } return retval; }
/* Given a radius length r and an angle t in radians and a circle's center (h,k), * you can calculate the coordinates of a point on the circumference as follows * (this is pseudo-code, you'll have to adapt it to your language): float x = r*cos(t) + h; float y = r*sin(t) + k; */ public void Create(double bottomradius, double topradius, double height, int numdivscirc, int numdivsheight) { //generate sets of points that describe a circle vertically // int idx = 0; // this points to the first point in the circle double zlev = 0.0; // start at the bottom of the cylinder //Name = "Cylinder"; // for (int cnt = 0; cnt < numdivsheight; cnt++) // { GenerateCirclePoints(bottomradius, numdivscirc, zlev); // bottom zlev += height; GenerateCirclePoints(topradius, numdivscirc, zlev); // top // now generate side polygons for (int cnt = 0; cnt < numdivscirc; cnt++) { /* left 3 |\ | \ |__\ 2 1 right 2 3 _____ \ | \ | \ | \| 1 * * */ // the left looks correct int topidx = numdivscirc + 1; // index to the first point in the top circle Polygon plyl = new Polygon(); m_lstpolys.Add(plyl); plyl.m_points = new Point3d[3]; // create some point storage plyl.m_points[0] = (Point3d)m_lstpoints[cnt]; plyl.m_points[1] = (Point3d)m_lstpoints[(cnt + 1) % numdivscirc]; plyl.m_points[2] = (Point3d)m_lstpoints[cnt + topidx]; plyl.CalcCenter(); plyl.CalcNormal(); // bottom faces int centeridx = numdivscirc; Polygon plb = new Polygon(); m_lstpolys.Add(plb); plb.m_points = new Point3d[3]; // create some point storage plb.m_points[0] = (Point3d)m_lstpoints[centeridx]; // the first point is always the center point plb.m_points[1] = (Point3d)m_lstpoints[(cnt + 1) % numdivscirc]; plb.m_points[2] = (Point3d)m_lstpoints[cnt]; plb.CalcCenter(); plb.CalcNormal(); Polygon plyr = new Polygon(); m_lstpolys.Add(plyr); plyr.m_points = new Point3d[3]; // create some point storage plyr.m_points[0] = (Point3d)m_lstpoints[(cnt + 1) % numdivscirc]; plyr.m_points[1] = (Point3d)m_lstpoints[((cnt + 1) % numdivscirc) + topidx]; // plyr.m_points[2] = (Point3d)m_lstpoints[cnt + topidx]; // the point directly above it plyr.CalcCenter(); plyr.CalcNormal(); //int topidx = numdivscirc + 1; // index to the first point in the top circle // top faces centeridx = topidx + numdivscirc; Polygon plt = new Polygon(); m_lstpolys.Add(plt); plt.m_points = new Point3d[3]; // create some point storage plt.m_points[0] = (Point3d)m_lstpoints[centeridx]; // the first point is always the center pointt plt.m_points[2] = (Point3d)m_lstpoints[(cnt + 1) % numdivscirc + topidx]; plt.m_points[1] = (Point3d)m_lstpoints[topidx + cnt]; plt.CalcCenter(); plt.CalcNormal(); } //idx += numdivscirc; // } CalcCenter(); CalcMinMaxes(); }
/* The object selection plane is used to help move objects around * This is a plane is centered at the object center and faces the center of the view * This is used to determine an intersection along the plane to help move the object * This is created by picking a center point, and using the camera's forward and right vectors to generate * 2 polygons that form a forward-facing plane at a distance of the camera to the point along the forward vector * parameters: * center is the center of the currently selected object * fromcamera is the vector from the camera to the center of the selected object * cameraup is the up vector of the camera */ public static void UpdateObjectSelectionPlane(Point3d center, Vector3d cameraup, Vector3d cameraright) { //get the currently selected object //create 2 polygons //forward facing towards the camera /* p0 p1 *------ |\ | | \ | | * | object center | \ | | \| ------| p3 p2 */ Point3d p0; Point3d p1; Point3d p2; Point3d p3; if (m_selplane == null) { m_selplane = new Object3d(); m_selplane.Name = "Selection Plane"; p0 = new Point3d(); p1 = new Point3d(); p2 = new Point3d(); p3 = new Point3d(); // add the points m_selplane.m_lstpoints.Add(p0); m_selplane.m_lstpoints.Add(p1); m_selplane.m_lstpoints.Add(p2); m_selplane.m_lstpoints.Add(p3); //new polygon Polygon ply0 = new Polygon(); ply0.m_points = new Point3d[3]; //set poly points ply0.m_points[0] = p0; ply0.m_points[1] = p1; ply0.m_points[2] = p2; //add the polygon to the model m_selplane.m_lstpolys.Add(ply0); Polygon ply1 = new Polygon(); ply1.m_points = new Point3d[3]; ply1.m_points[0] = p0; ply1.m_points[1] = p2; ply1.m_points[2] = p3; m_selplane.m_lstpolys.Add(ply1); m_selplane.tag = Object3d.OBJ_SEL_PLANE; // groundplane tag } else { //references to already created points p0 = m_selplane.m_lstpoints[0]; p1 = m_selplane.m_lstpoints[1]; p2 = m_selplane.m_lstpoints[2]; p3 = m_selplane.m_lstpoints[3]; } float scaler = 100.0f; p0.Set((cameraup.x / 2) - (cameraright.x / 2), (cameraup.y / 2) - (cameraright.y / 2), (cameraup.z/2) - (cameraright.z/2)); p1.Set((cameraup.x / 2) + (cameraright.x / 2), (cameraup.y / 2) + (cameraright.y / 2), (cameraup.z / 2) + (cameraright.z / 2)); p2.Set((-cameraup.x / 2) + (cameraright.x / 2), (-cameraup.y / 2) + (cameraright.y / 2), (-cameraup.z / 2) + (cameraright.z / 2)); p3.Set((-cameraup.x / 2) - (cameraright.x / 2), (-cameraup.y / 2) - (cameraright.y / 2), (-cameraup.z / 2) - (cameraright.z / 2)); p0.x *= scaler; p0.y *= scaler; p0.z *= scaler; p1.x *= scaler; p1.y *= scaler; p1.z *= scaler; p2.x *= scaler; p2.y *= scaler; p2.z *= scaler; p3.x *= scaler; p3.y *= scaler; p3.z *= scaler; // initial positions m_selplane.Update(); // center it on the object m_selplane.Translate(center.x, center.y, center.z); }
private void makeWalls(int li, int ui, int numdivs) { for (int cnt = 0; cnt < numdivs; cnt++) { int topidx = ui;// +1;// numdivs + 1; // index to the first point in the top circle Polygon plyl = new Polygon(); m_lstpolys.Add(plyl); plyl.m_points = new Point3d[3]; // create some point storage plyl.m_points[0] = (Point3d)m_lstpoints[cnt + li]; plyl.m_points[1] = (Point3d)m_lstpoints[((cnt + 1) % numdivs) + li]; plyl.m_points[2] = (Point3d)m_lstpoints[cnt + topidx + li]; Polygon plyr = new Polygon(); m_lstpolys.Add(plyr); plyr.m_points = new Point3d[3]; // create some point storage plyr.m_points[0] = (Point3d)m_lstpoints[(cnt + 1) % numdivs + li]; plyr.m_points[1] = (Point3d)m_lstpoints[((cnt + 1) % numdivs) + topidx + li]; // plyr.m_points[2] = (Point3d)m_lstpoints[cnt + topidx + li]; // the point directly above it } }
public bool SpheresIntersect(Polygon ply) { bool retval = false; Vector3d vec = m_center - ply.m_center; float dist = (vec.x * vec.x) + (vec.y * vec.y) + (vec.z * vec.z); float mindist = m_radius * ply.m_radius; if (dist <= (mindist * mindist)) retval = true; return retval; }