Prod.: Engine, ver.: 6, ID: 60001731, HowTo : How can I check if an object is hidden from another object in a 3D view ?

HowTo : How can I check if an object is hidden from another object in a 3D view ?

Article60001731
TypeHowTo
ProductEngine
Version6
Date Added6/13/2012
Submitted byBertrand Munier
Keywords

Subject

How can I check if an object is hidden from another object in a 3D view ?

Summary

How can I check if an object is hidden from another object in a 3D view ? For example I have two polyfaces a big one in z=100 and a smaller one in z=0 and the view is in such a way that only one of the polyfaces is visible, the other polyface is behind the big one and is totally invisible on screen.

Solution

You need some “OpenGL” code in order to check if an object is behind (not visible) another one.

The code you need is like :
    vdPolyface purple;  // this is the polyface to check if is behind  the green polyface
        
        void test()
        { // just create the objects
            vdPolyface pf1 = new vdPolyface(doc); 
            pf1.CreateBox(new gPoint(0, 0), 1, 1, 1, 0);
            pf1.PenColor = new vdColor(Color.Purple);
            doc.Model.Entities.AddItem(pf1);
            purple = pf1; // this is the polyface to check if is behind the green polyface
 
            vdPolyface pf2 = new vdPolyface(doc);
            pf2.CreateBox(new gPoint(-2, 2), 4, 4, 4, 0);
            pf2.PenColor = new vdColor(Color.Green);
            doc.Model.Entities.AddItem(pf2); // this is the green polyface that hides the purple one
          
 
            doc.RenderMode = vdRender.Mode.Shade;
            //doc.CommandAction.View3D("VINW");
            doc.CommandAction.View3D("VINE");
            
            
        }
        bool IsObjectVisible = false;
        void test1() // this is the method that checks the “visibility” using the OnDrawAfter event
        {
            IsObjectVisible = false;
            doc.OnDrawAfter += new vdDocument.DrawAfterEventHandler(TestObjectVisibility_OnDrawAfter);
            doc.RenderMode = vdRender.Mode.Shade;
            doc.Redraw(true);
            doc.OnDrawAfter -= new vdDocument.DrawAfterEventHandler(TestObjectVisibility_OnDrawAfter);
            MessageBox.Show(IsObjectVisible ? "Object is visible" : "Object is not visible");
        }
 
        void TestObjectVisibility_OnDrawAfter(object sender, vdRender render)
        {
            double[] _modelMatrix = new double[16], _projMatrix = new double[16];
            int[] _viewport = new int[4];
            double pwinx = 0.0, pwiny = 0.0, pwinz = 0.0;
            //GET the active world to view and view to pixel matrixes
            VectorDraw.Render.OpenGL.OpenGLImports.glGetDoublev(VectorDraw.Render.OpenGL.OpenGLImports.Parameters.GL_PROJECTION_MATRIX, _projMatrix);
            VectorDraw.Render.OpenGL.OpenGLImports.glGetDoublev(VectorDraw.Render.OpenGL.OpenGLImports.Parameters.GL_MODELVIEW_MATRIX, _modelMatrix);
            VectorDraw.Render.OpenGL.OpenGLImports.glGetIntegerv(VectorDraw.Render.OpenGL.OpenGLImports.Parameters.GL_VIEWPORT, _viewport);
 
            Rectangle winrc = new Rectangle(_viewport[0], _viewport[1], _viewport[2], _viewport[3]);
            foreach (gPoint pt in purple.VertexList)
            {
 
                VectorDraw.Render.OpenGL.OpenGLImports.gluProject(pt.x, pt.y, pt.z, _modelMatrix, _projMatrix, _viewport, ref pwinx, ref pwiny, ref pwinz);
                Point winPt = new Point((int)pwinx, (int)pwiny);
                if (!winrc.Contains(winPt)) continue;
                //Get the existing depth in previous calculated pixel 
                double depth = VectorDraw.Render.OpenGL.OpenGLImports.glReadPixelDepth((int)(pwinx), (int)(pwiny));
                //the pt is visible if the pwinz is smaller than the existing(it is closest to eye)
                double def = pwinz - depth;
                if (def <= 0.000001)
                {
                    IsObjectVisible = true;
                    break;
                }
            }
 
        }