//------------------------------------------------------------------------------ // Constructors public OctreeLeaf(int ID, int depth, Vectors min, Vectors max, ref List <bool> used, double R, OctreeBranch parent, eOctPos p) : base(ID, depth, min, max, R, parent, p) { PtData.findptsCube(_bbMin, _bbMax, R, p, ref used, parent.PtsIdx, out _pts); if (_pts.Count > 0) { _DisplayListPT = -1; _DisplayListLN = -1; _DisplayListCTN = -1; _PCA_result = false; _SurfaceNum = -1; CalculateSigma(); if (OctreeNode._MINPTSPCA <= NumPts) { _PCA_result = DoPCATest(); } } else { throw new Exception("Invalid Leaf pts: " + _pts.Count); } }
//------------------------------------------------------------------------------ // private void BTN_Cone_Click(object sender, EventArgs e) { if (PtData.ptCloud_Xcount() < 1) { PtData.genCone(200.0d, 20.0d, 15.0d, 0.001d, _CREATE_POINTS); Reader._progress = 100; } }
//------------------------------------------------------------------------------ // private void BTN_Clear_Click_1(object sender, EventArgs e) { if (_state > 0) { _state = 0; Reader._progress = 0; _ProcessingProgress = 0; _Scene = null; _VManage = null; OctreeNode._CUROCTDEPTH = -1; PtData.Clear(); PtData.Initialize(); _Scene = new Scene(); _VManage = new ViewManager(); } }
//----------------------------------------------------------------------------- static private void GLdrawPtsCloud() { double x = 0.0d, y = 0.0d, z = 0.0d; Gl.glPointSize(10.0f); Gl.glBegin(Gl.GL_POINTS); int pt = 0; for (; pt < PtData.ptCloud_Xcount(); pt++) { PtData.Pt(pt, ref x, ref y, ref z); Gl.glColor3f(1.0f, 1.0f, 1.0f); Gl.glVertex3d(x, y, z); } Gl.glEnd(); }
//------------------------------------------------------------------------------ public string InitScene(ref double ProcProg) { Vectors Avg; DateTime startTime = DateTime.Now, stopTime; // build Octree _Ot.Init(); _Ot.OctreeSurface(ref _Sc, ref ProcProg); stopTime = DateTime.Now; //_Ot.ReSetDrawList(_drawMode); TimeSpan duration = stopTime - startTime; PtData.ptCloud_avg(out Avg); _Offeset = Avg; return(duration.ToString()); }
//------------------------------------------------------------------------------ private void CalculateSigma() { if (NumPts > 0) { double x = 0.0d; double y = 0.0d; double z = 0.0d; _sigma = new Vectors(0.0, 0.0, 0.0); //we need to calculate for (int pt = 0; pt < NumPts; pt++) { PtData.Pt(_pts[pt], ref x, ref y, ref z); _sigma.addXYZ(x, y, z); } _sigma /= (double)NumPts; } }
//------------------------------------------------------------------------------ // Constructors public OctreeBranch(int ID, int depth, Vectors min, Vectors max, List <int> parentpts, double R) : base(ID, depth, min, max, R, null, eOctPos.eRoot) { _pts = parentpts; _chld = new List <OctreeNode>(OctreeNode._OCT); // the oct part // we dont care about it it is the root node _vnorm.set(0.0d, 0.0d, 0.0d, 1.0d); _eigenvec2.set(0.0d, 0.0d, 0.0d, 1.0d); _eigenvec3.set(0.0d, 0.0d, 0.0d, 1.0d); _rg.set(0.0d, 0.0d, 0.0d, 1.0d); PtData.ptCloud_avg(out _sigma); // we are creating the root node so need to calculate the Draw Ratio for points if (_pts.Count > _MAXDRAWPOINTS) { _DRAWRATIO = (double)_MAXDRAWPOINTS / (double)_pts.Count; } }
//------------------------------------------------------------------------------ #endregion MOUSE_FN #region OPENGL //------------------------------------------------------------------------------ // Initialise the Scenario public void InitGL() { Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); float[] lightPosition = { 1.0f, 1.0f, 1.0f, 0.0f }; Gl.glLightModeli(Gl.GL_LIGHT_MODEL_AMBIENT, Gl.GL_TRUE); Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, lightPosition); Gl.glEnable(Gl.GL_LIGHTING); Gl.glEnable(Gl.GL_LIGHT0); Gl.glEnable(Gl.GL_DEPTH_TEST); Gl.glDisable(Gl.GL_CULL_FACE); _VManage.Init(simpleOpenGlControl1.Width, simpleOpenGlControl1.Height); Vectors c, s; PtData.ptCloud_avg(out s); PtData.ptCloudCtr(out c); _VManage.Reposition(c, s - c, new Vectors(0, 0, 1)); _Scene.drawMode = Scene.eDrawMode.eDM_LEAFSURFACE; OctreeData_Show(-1); int i = -1; SurfData_Show(ref i); }
//----------------------------------------------------------------------------- static public int ptCloudDisplaylist() { int ptList; float[] Ambient1; float[] Ambient2; Vectors min, max; Colour.Deep_Pink().tofloat3f(out Ambient1); Colour.Dark_Orange().tofloat3f(out Ambient2); ptList = Gl.glGenLists(1); Gl.glNewList(ptList, Gl.GL_COMPILE); Gl.glDisable(Gl.GL_LIGHTING); Gl.glEnable(Gl.GL_LINE_SMOOTH_HINT); PtData.ptCloud_min(out min); PtData.ptCloud_max(out max); drawBBCube(min._X, max._X, min._Y, max._Y, min._Z, max._Z, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity); Gl.glDisable(Gl.GL_LINE_SMOOTH_HINT); Gl.glEnable(Gl.GL_LIGHTING); Gl.glEndList(); return(ptList); }
}// analyse //---------------------------------------------------------------------------- static public void PCA_eigentestlst() { List <int> i = new List <int>() { 0, 1, 2 }; PtData.addPt(2, 1, 1); PtData.addPt(1, 2, 1); PtData.addPt(1, 1, 2); PCA p = new PCA(i, i.Count); System.Diagnostics.Debug.WriteLine(" normal = {0}", p._normal.ToString()); System.Diagnostics.Debug.WriteLine(" eigenval = {0}", p.eigenval.ToString()); System.Diagnostics.Debug.WriteLine(" decent = {0}", p.dcent.ToString()); System.Diagnostics.Debug.WriteLine(" mean = {0}", p.Mean.ToString()); for (int j = 0; j <= 2; j++) { Vectors v = p.eigen.GetEigenvector(j); System.Diagnostics.Debug.WriteLine("" + j + ", eigenvalue=" + p.eigen.GetEigenvalue(j) + ";"); System.Diagnostics.Debug.WriteLine("Eigenvector(" + v._X + "," + v._Y + "," + v._Z + ")"); } // EXPECTED RESULTS FROM TEST // Normal[ -0.57735026, -0.57735026, -0.57735026 ] // eigenval-7.4505806E-9 // dcent -2.309401 // mean 1.3333334:1.3333334:1.3333334:1.0 // 0 eigenvalue= -7.4505806E-9 // Eigenvector = -0.57735026,-0.57735026,-0.57735026 // 1 eigenvalue= 0.3333333 // Eigenvector = 0.81649655,-0.40824828,-0.40824828 // 2 eigenvalue= 0.3333333 // Eigenvector = 0.0,-0.70710677, 0.70710677 }
//------------------------------------------------------------------------------ // Init public void Init() { Trace.WriteLine("_Octree-Init-Start"); Vectors bbmin, bbmax; int c = PtData.ptCloud_Xcount(); List <int> pts = new List <int>(c); PtData.ptCloud_min(out bbmin); PtData.ptCloud_max(out bbmax); int i = 0; for (; i < c; i++) { pts.Add(i); } double xr = Math.Abs(bbmax._X - bbmin._X); double yr = Math.Abs(bbmax._Y - bbmin._Y); double zr = Math.Abs(bbmax._Z - bbmin._Z); double r = xr; if (r < yr) { r = yr; } if (r < zr) { r = zr; } //make our bounding box bigger than the data r += C.CONST.EPSILON; bbmin.addXYZ(-C.CONST.EPSILON, -C.CONST.EPSILON, -C.CONST.EPSILON); bbmax.addXYZ(C.CONST.EPSILON, C.CONST.EPSILON, C.CONST.EPSILON); Vectors newbbmax = new Vectors(bbmin._X + r, bbmin._Y + r, bbmin._Z + r); _Tree = new OctreeBranch(0, 0, bbmin, newbbmax, pts, r); DateTime startTime = DateTime.Now; Trace.WriteLine("_Octree-Split-Start" + startTime.ToString()); Split(); DateTime stopTime = DateTime.Now; TimeSpan duration = stopTime - startTime; Trace.WriteLine("_Octree-Split-End:" + duration.ToString()); Vectors idx = new Vectors(_Tree.vMin); double minr = (r / (Math.Pow(2.0d, (double)(OctreeNode._CUROCTDEPTH))));//((double)(OctreeNode._CUROCTDEPTH) * (OctreeNode._CUROCTDEPTH) * (OctreeNode._CUROCTDEPTH))); //idx._X+= minr; //idx._Y+= minr; //idx._Z+= minr; // calculate its gobal position _Tree.GlobalPosition(minr, idx); // Find the Adjcent cells startTime = DateTime.Now; Trace.WriteLine("_Octree-Adjacent-Start" + startTime.ToString()); AdjacentLeaf(); //AdjacentTree(); stopTime = DateTime.Now; duration = stopTime - startTime; Trace.WriteLine("_Octree-Adjacent-End:" + duration.ToString()); Trace.WriteLine("_Octree-Init-End"); }
//------------------------------------------------------------------------------ public void WriteOctreeData(string filename) { OctreeNode o = null; if (_drawID == 0) { o = _Tree; } else { _Tree.getOctNode(_drawID, ref o); } if (o == null) { o = _Tree; } int count = 0; try { string[] celldata; OctreeData(out celldata, -1); FileStream file = File.Create(filename + _drawID.ToString() + "_data.txt"); using (StreamWriter sw = new StreamWriter(file)) { foreach (string s in celldata) { sw.WriteLine("{0}", s); } sw.Close(); } FileStream fs = File.Create(filename + _drawID.ToString() + "_points.XYZ"); using (StreamWriter sw = new StreamWriter(fs)) { double x = 0.0f, y = 0.0f, z = 0.0f; while (count < o.PtsIdx.Count) { PtData.Pt(o.PtsIdx[count], ref x, ref y, ref z); bool good = true; if (double.IsInfinity(x) || double.IsNaN(x)) { good = false; } if (double.IsInfinity(y) || double.IsNaN(y)) { good = false; } if (double.IsInfinity(z) || double.IsNaN(z)) { good = false; } if (good == true) { sw.WriteLine("{0} {1} {2}", x, y, z); } else { System.Diagnostics.Debug.WriteLine("Error : Bad Data ln = " + count); throw new SystemException("Error : Bad Data ln = " + count); } count++; } sw.Close(); } } catch (SystemException s) { System.Diagnostics.Debug.WriteLine("{0}", s.Message.ToString()); } }
//------------------------------------------------------------------------------ private void buildDisplayLists_PT() { if (NumPts > 0) //OctreeNode._MINPTS) // always show points { _DisplayListPT = Gl.glGenLists(1); Gl.glNewList(_DisplayListPT, Gl.GL_COMPILE); double x = 0.0d, y = 0.0d, z = 0.0d; Gl.glDisable(Gl.GL_LIGHTING); Gl.glPointSize(2.0f); Gl.glBegin(Gl.GL_POINTS); float[] g; int p = 0; Vectors c = new Vectors(_vnorm); if (NumPts > OctreeNode._MINPTS) { Colour.Azure().tofloat3f(out g); } else { Colour.Light_Blue().tofloat3f(out g); } c.multiply(_vnorm, _rg._X); c.normalize(); //for (; p < (_pts.Count * _DRAWRATIO); p++) //{ // Gl.glColor3f(g[0], g[1], g[2]); // //Gl.glNormal3d(c._X, c._Y, c._Z); // PtData.Pt(_pts[p], ref x, ref y, ref z); // Gl.glVertex3d(x, y, z); //} double Avgx = 0.0d, Avgy = 0.0d, Avgz = 0.0d; p = 0; int j = 0; int end = _pts.Count; for (; p < end; p++) { //PtData.Pt(_pts[p], ref x, ref y, ref z); if (j < (1.0 / _DRAWRATIO)) { j++; PtData.Pt(_pts[p], ref x, ref y, ref z); Avgx += x; Avgy += y; Avgz += z; } else { Avgx /= j; j = 0; Gl.glColor3f(g[0], g[1], g[2]); Gl.glVertex3d(x, y, z); Avgx = 0.0d; Avgy = 0.0d; Avgz = 0.0d; } } Gl.glEnable(Gl.GL_LIGHTING); Gl.glEnd(); Gl.glEndList(); } }
}// analyse _pts //------------------------------------------------------------------------------ public void analyseLst(List <int> p, int number) { // calculate point count, centroid and // then plane by pca // p[0-2][] are coordinates // p[3][] if present, is weight int n = 0; //point count int i = 0; // means _m.set(0.0, 0.0, 0.0, 1.0d); double Ptx = 0.0d, Pty = 0.0d, Ptz = 0.0d; while (i < number) { _m._W = 1.0d; PtData.Pt(p[i], ref Ptx, ref Pty, ref Ptz); _m._X += Ptx; _m._Y += Pty; _m._Z += Ptz; n++; i++; } _m /= n; // covariance double x, y, z; double xx, yy, zz; xx = yy = zz = 0.0d; double xy, yz, xz; xy = yz = xz = 0.0d; i = number - 1; while (i >= 0) { _m._W = 1.0; PtData.Pt(p[i], ref Ptx, ref Pty, ref Ptz); x = Ptx - _m._X; //p[0][i] - _m._X; y = Pty - _m._Y; //p[1][i] - _m._Y; z = Ptz - _m._Z; //p[2][i] - _m._Z; xx += x * x; yy += y * y; zz += z * z; xy += x * y; yz += y * z; xz += x * z; i--; } // standardize xx /= (double)n; yy /= (double)n; zz /= (double)n; xy /= (double)n; yz /= (double)n; xz /= (double)n; // setup matrix double[,] cov = new double[3, 3]; cov[0, 0] = xx; cov[0, 1] = xy; cov[0, 2] = xz; cov[1, 0] = xy; cov[1, 1] = yy; cov[1, 2] = yz; cov[2, 0] = xz; cov[2, 1] = yz; cov[2, 2] = zz; // do pca, smallest eigenvector is normal _e = new Eigen(cov); _e.EigenStuff(); _normal = _e.GetEigenvector(0); _eigenval = _e.GetEigenvalue(0); _dcent = _normal._X * _m._X + _normal._Y * _m._Y + _normal._Z * _m._Z; }// analyse _pts