Пример #1
0
        Object3d GetSupportParrent(float x, float y, float z)
        {
            //Object3d obj;
            List <Object3d> matchingObjects = new List <Object3d>();

            foreach (Object3d obj in UVDLPApp.Instance().Engine3D.m_objects)
            {
                if (obj.tag != Object3d.OBJ_NORMAL)
                {
                    continue;
                }
                if ((x > obj.m_min.x) && (x < obj.m_max.x) && (y > obj.m_min.y) && (y < obj.m_max.y))
                {
                    matchingObjects.Add(obj);
                }
            }
            if (matchingObjects.Count == 0)
            {
                return(null); // Should not happen!
            }
            if (matchingObjects.Count == 1)
            {
                return(matchingObjects[0]); // the easy case.
            }
            Point3d origin;

            origin = new Point3d(); // bottom point
            origin.Set(x, y, 0.0f);
            //intersected = false; // reset the intersected flag to be false

            Vector3d up = new Vector3d(); // the up vector

            up.x = 0.0f;
            up.y = 0.0f;
            up.z = 1.0f;

            List <ISectData> lstISects = RTUtils.IntersectObjects(up, origin, matchingObjects, false);
            Object3d         objFound  = null;
            float            minzdiff  = 99999999f;

            // find the intersection closest to z.
            foreach (ISectData htd in lstISects)
            {
                float zdiff = Math.Abs(htd.intersect.z - z);
                if (zdiff < minzdiff)
                {
                    minzdiff = zdiff;
                    objFound = htd.obj;
                }
            }
            return(objFound);
        }
Пример #2
0
        private void glControl1_MouseMove(object sender, MouseEventArgs e)
        {
            double dx = 0, dy = 0;

            if (lmdown || rmdown || mmdown)
            {
                dx  = e.X - mdx;
                dy  = e.Y - mdy;
                mdx = e.X;
                mdy = e.Y;
            }
            dx /= 2;
            dy /= 2;

            if (lmdown)
            {
                m_camera.RotateRightFlat((float)dx);
                m_camera.RotateUp((float)dy);
                m_axisCam.RotateRightFlat((float)dx);
                m_axisCam.RotateUp((float)dy);

                UpdateView();
            }
            else if (mmdown)
            {
                m_camera.MoveForward((float)dy);
                UpdateView();
            }
            else if (rmdown)
            {
                m_camera.Move((float)dx, (float)dy);
                UpdateView();
            }

            // if no object selected, bail
            if (UVDLPApp.Instance().SelectedObject == null)
            {
                return;
            }

            if (m_movingobjectmode)                            // if we're moving an object - shift key down
            {
                List <ISectData> hits = TestHitTest(e.X, e.Y); // hit-test all
                // examine the last isect data
                foreach (ISectData dat in hits)
                {
                    //remember to break out of this foreach loop after executing a movement.

                    // either we're moving a support
                    if (UVDLPApp.Instance().SelectedObject.tag == Object3d.OBJ_SUPPORT)
                    {
                        // if it's the base we're moving,
                        //allow the base to change types
                        // see if it intersects with the ground, or an object
                        //cast as a support object
                        Support sup = (Support)UVDLPApp.Instance().SelectedObject;
                        if (sup.SelectionType == Support.eSelType.eWhole)
                        {
                            // we're in modify mode, but we're still moving the whole support
                            if (dat.obj.tag == Object3d.OBJ_SEL_PLANE)
                            {
                                //we should really try a top/ bottom intersection / scale to hieg
                                // move the support
                                sup.Translate(
                                    (float)(dat.intersect.x - UVDLPApp.Instance().SelectedObject.m_center.x),
                                    (float)(dat.intersect.y - UVDLPApp.Instance().SelectedObject.m_center.y),
                                    0.0f);
                                // now we've moved the object approximately to where it needs to be
                                //turn it back into a base
                                sup.SubType = Support.eSubType.eBase;
                                //get the center location
                                Point3d           centroid = sup.Centroid();
                                Engine3D.Vector3d upvec    = new Engine3D.Vector3d();
                                upvec.Set(0, 0, 1);
                                Point3d origin = new Point3d();
                                origin.Set(centroid.x, centroid.y, .001f);    // above the ground plane
                                List <ISectData> isects = RTUtils.IntersectObjects(upvec, origin, UVDLPApp.Instance().Engine3D.m_objects, false);
                                foreach (ISectData isd in isects)
                                {
                                    if (isd.obj.tag == Object3d.OBJ_NORMAL)    // if we've intersected a normal object upwards
                                    {
                                        sup.SelectionType = Support.eSelType.eTip;
                                        sup.MoveFromTip(isd);
                                        sup.SelectionType = Support.eSelType.eWhole;
                                        break;
                                    }
                                }
                                //starting at the x/y ground plane, hittest upward
                                break;
                            }
                        }
                        else if (sup.SelectionType == Support.eSelType.eBase)
                        {
                            //going to change this to test for intersection with object, or ground plane
                            // if intersected with an object, change to intra type
                            // and set the base on the object
                            // if intersected with ground, change to base type and put on ground
                            if (dat.obj.tag == Object3d.OBJ_GROUND)
                            {
                                // make sure we're a base tip
                                sup.SubType = Support.eSubType.eBase;
                                // position the bottom to the intersection point
                                sup.PositionBottom(dat);
                                break;
                            }
                            else if (dat.obj.tag == Object3d.OBJ_NORMAL)     // intersected with an object
                            {
                                //should check with the normal of the object to see if it's facing upwards
                                sup.SubType = Support.eSubType.eIntra;
                                // position the bottom to the intersection point
                                sup.PositionBottom(dat);
                                break;
                            }
                        }
                        else if (sup.SelectionType == Support.eSelType.eTip)
                        {
                            if (dat.obj.tag == Object3d.OBJ_NORMAL)     // intersected with an object
                            {
                                sup.MoveFromTip(dat);
                                UpdateView();
                                break;
                            }
                        }
                    }
                    else     // or a normal object based on object selection plane
                    {
                        if (dat.obj.tag == Object3d.OBJ_SEL_PLANE)
                        {
                            UVDLPApp.Instance().SelectedObject.Translate(
                                (float)(dat.intersect.x - UVDLPApp.Instance().SelectedObject.m_center.x),
                                (float)(dat.intersect.y - UVDLPApp.Instance().SelectedObject.m_center.y),
                                0.0f);
                        }
                        break;
                    }
                }
                UpdateView();
            }
        }
Пример #3
0
        private List <ISectData> TestHitTest(int X, int Y)
        {
            if (!loaded)
            {
                return(null);
            }
            // String mess = "";
            // mess = "Screen X,Y = (" + X.ToString() + "," + Y.ToString() + ")\r\n";

            /*
             * (Note that most window systems place the mouse coordinate origin in the upper left of the window instead of the lower left.
             * That's why window_y is calculated the way it is in the above code. When using a glViewport() that doesn't match the window height,
             * the viewport height and viewport Y are used to determine the values for window_y and norm_y.)
             *
             * The variables norm_x and norm_y are scaled between -1.0 and 1.0. Use them to find the mouse location on your zNear clipping plane like so:
             *
             * float y = near_height * norm_y;
             * float x = near_height * aspect * norm_x;
             * Now your pick ray vector is (x, y, -zNear).
             */
            int w = glControl1.Width;
            int h = glControl1.Height;
            //  mess += "Screen Width/Height = " + w.ToString() + "," + h.ToString() + "\r\n";
            float aspect = ((float)glControl1.Width) / ((float)glControl1.Height);
            //mess += "Screen Aspect = " + aspect.ToString() + "\r\n";

            int    window_y    = (h - Y) - h / 2;
            double norm_y      = (double)(window_y) / (double)(h / 2);
            int    window_x    = X - w / 2;
            double norm_x      = (double)(window_x) / (double)(w / 2);
            float  near_height = .2825f; // no detectable error

            float y = (float)(near_height * norm_y);
            float x = (float)(near_height * aspect * norm_x);

            /*
             * To transform this eye coordinate pick ray into object coordinates, multiply it by the inverse of the ModelView matrix in use
             * when the scene was rendered. When performing this multiplication, remember that the pick ray is made up of a vector and a point,
             * and that vectors and points transform differently. You can translate and rotate points, but vectors only rotate.
             * The way to guarantee that this is working correctly is to define your point and vector as four-element arrays,
             * as the following pseudo-code shows:
             *
             * float ray_pnt[4] = {0.f, 0.f, 0.f, 1.f};
             * float ray_vec[4] = {x, y, -near_distance, 0.f};
             * The one and zero in the last element determines whether an array transforms as a point or a vector when multiplied by the
             * inverse of the ModelView matrix.*/
            Vector4 ray_pnt = new Vector4(0.0f, 0.0f, 0.0f, 1.0f);
            //Vector4 ray_vec = new Vector4((float)norm_x, (float)norm_y, -1.0f, 0);
            Vector4 ray_vec = new Vector4((float)x, (float)y, -1f, 0);

            ray_vec.Normalize();

            //mess += "Eye Pick Vec =  (" + String.Format("{0:0.00}", ray_vec.X) + ", " + String.Format("{0:0.00}", ray_vec.Y) + "," + String.Format("{0:0.00}", ray_vec.Z) + ")\r\n";

            Matrix4 modelViewMatrix;

            GL.GetFloat(GetPName.ModelviewMatrix, out modelViewMatrix);
            Matrix4 viewInv = Matrix4.Invert(modelViewMatrix);

            Vector4 t_ray_pnt = new Vector4();
            Vector4 t_ray_vec = new Vector4();

            Vector4.Transform(ref ray_vec, ref viewInv, out t_ray_vec);
            Vector4.Transform(ref ray_pnt, ref viewInv, out t_ray_pnt);
            //mess += "World Pick Vec =  (" + String.Format("{0:0.00}", t_ray_vec.X) + ", " + String.Format("{0:0.00}", t_ray_vec.Y) + "," + String.Format("{0:0.00}", t_ray_vec.Z) + ")\r\n";
            //mess += "World Pick Pnt =  (" + String.Format("{0:0.00}", t_ray_pnt.X) + ", " + String.Format("{0:0.00}", t_ray_pnt.Y) + "," + String.Format("{0:0.00}", t_ray_pnt.Z) + ")\r\n";

            Point3d origin    = new Point3d();
            Point3d intersect = new Point3d();

            Engine3D.Vector3d dir = new Engine3D.Vector3d();

            origin.Set(t_ray_pnt.X, t_ray_pnt.Y, t_ray_pnt.Z);
            dir.Set(t_ray_vec.X, t_ray_vec.Y, t_ray_vec.Z); // should this be scaled?

            List <ISectData> isects = RTUtils.IntersectObjects(dir, origin, UVDLPApp.Instance().Engine3D.m_objects, true);

            if (isects.Count > 0)
            {
                foreach (ISectData isect in isects)
                {
                    if (!float.IsNaN(isect.intersect.x)) // check for NaN
                    {
                        /*
                         * m_ix = (float)isect.intersect.x; // show the closest
                         * m_iy = (float)isect.intersect.y;
                         * m_iz = (float)isect.intersect.z;
                         */
                        isect.poly.CalcNormal();
                        m_isectnormal.x = isect.poly.m_normal.x;
                        m_isectnormal.y = isect.poly.m_normal.y;
                        m_isectnormal.z = isect.poly.m_normal.z;

                        break;
                    }
                }

                //ISectData isect = (ISectData)isects[0]; // get the first
                // check for NaN
            }

            return(isects);
        }
Пример #4
0
        private void glControl1_MouseMove(object sender, MouseEventArgs e)
        {
            List <ISectData> hits = TestHitTest(e.X, e.Y);
            double           dx = 0, dy = 0;

            if (lmdown || rmdown || mmdown)
            {
                dx  = e.X - mdx;
                dy  = e.Y - mdy;
                mdx = e.X;
                mdy = e.Y;
            }
            dx /= 2;
            dy /= 2;

            if (lmdown)
            {
                m_camera.RotateRightFlat((float)dx);
                m_camera.RotateUp((float)dy);
            }
            else if (mmdown)
            {
                m_camera.MoveForward((float)dy);
            }
            else if (rmdown)
            {
                m_camera.Move((float)dx, (float)dy);
            }

            if (UVDLPApp.Instance().SelectedObject != null)
            {
                if (m_movingobjectmode) // if we're moving an object
                {
                    // examine the last isect data
                    foreach (ISectData dat in hits)
                    {
                        if (dat.obj.tag == Object3d.OBJ_GROUND) //found the ground plane
                        {
                            UVDLPApp.Instance().SelectedObject.Translate(
                                (float)(dat.intersect.x - UVDLPApp.Instance().SelectedObject.m_center.x),
                                (float)(dat.intersect.y - UVDLPApp.Instance().SelectedObject.m_center.y),
                                0.0f);
                        }
                    }
                    if (UVDLPApp.Instance().SelectedObject.tag == Object3d.OBJ_SUPPORT)  // if the current selected object is a support
                    {
                        Support tmpsup = (Support)UVDLPApp.Instance().SelectedObject;
                        Point3d pnt    = new Point3d();
                        pnt.Set(tmpsup.m_center.x, tmpsup.m_center.y, 0);
                        Engine3D.Vector3d vec = new Engine3D.Vector3d();
                        vec.Set(0, 0, 1); // create a vector striaght up
                        // hit test from the selected objects center x/y/0 position straight up
                        //see if it hits any object in the scene,
                        // if it does, scale the object from the ground plane to the closest intersection point
                        List <ISectData> iss = RTUtils.IntersectObjects(vec, pnt, UVDLPApp.Instance().Engine3D.m_objects, false);
                        foreach (ISectData htd in iss)
                        {
                            if (htd.obj.tag != Object3d.OBJ_SUPPORT)  // if this is not another support or the ground
                            {
                                if (htd.obj.tag != Object3d.OBJ_GROUND)
                                {
                                    // this should be it...
                                    tmpsup.ScaleToHeight(htd.intersect.z);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            //glControl1.Invalidate();
            UpdateView();
        }
        public List <Object3d> GenerateSupportObjects()
        {
            // iterate over the platform size by indicated mm step; // projected resolution in x,y
            // generate a 3d x/y point on z=0,
            // generate another on the z=zmax
            // use this ray to intersect the scene
            // foreach intersection point, generate a support
            // we gott make sure supports don't collide
            // I also have to take into account the
            // interface between the support and the model
            List <Object3d> lstsupports = new List <Object3d>();

            float ZVal = (float)UVDLPApp.Instance().m_printerinfo.m_PlatZSize;

            m_model.Update();
            float MinX = m_model.m_min.x;
            float MaxX = m_model.m_max.x;
            float MinY = m_model.m_min.y;
            float MaxY = m_model.m_max.y;

            // bool intersected = false;
            int scnt = 0; // support count
            // iterate from -HX to HX step xtep;
            double dts     = (MaxX - MinX) / m_sc.xspace;
            int    its     = (int)dts;
            int    curstep = 0;

            for (float x = (float)(MinX + (m_sc.xspace / 2.0f)); x < MaxX; x += (float)m_sc.xspace)
            {
                // say we're doing stuff
                RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eProgress, "" + curstep + "/" + its, null);
                curstep++;
                for (float y = (float)(MinY + (m_sc.yspace / 2)); y < MaxY; y += (float)m_sc.yspace)
                {
                    Point3d origin;
                    origin = new Point3d(); // bottom point
                    origin.Set(x, y, 0.0f);
                    //intersected = false; // reset the intersected flag to be false

                    Vector3d up = new Vector3d(); // the up vector
                    up.x = 0.0f;
                    up.y = 0.0f;
                    up.z = 1.0f;

                    List <ISectData> lstISects = RTUtils.IntersectObjects(up, origin, UVDLPApp.Instance().Engine3D.m_objects, false);
                    //check for cancelling
                    if (m_cancel)
                    {
                        RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eCancel, "Support Generation Cancelled", null);
                        return(lstsupports);
                    }


                    foreach (ISectData htd in lstISects)
                    {
                        if (htd.obj.tag != Object3d.OBJ_SUPPORT)    // if this is not another support or the ground
                        {
                            if (htd.obj.tag != Object3d.OBJ_GROUND) // if it's not the ground
                            {
                                if (m_sc.m_onlydownward && htd.poly.tag != Polygon.TAG_MARKDOWN)
                                {
                                    break; // not a downward facing and we're only doing downward
                                }
                                // this should be the closest intersected
                                Support s  = new Support();
                                float   lz = (float)htd.intersect.z;
                                s.Create((float)m_sc.fbrad, (float)m_sc.ftrad, (float)m_sc.hbrad, (float)m_sc.htrad, lz * .2f, lz * .6f, lz * .2f, 11);
                                s.Translate((float)x, (float)y, 0);
                                s.Name = "Support " + scnt;
                                s.SetColor(Color.Yellow);
                                scnt++;
                                lstsupports.Add(s);
                                RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eSupportGenerated, s.Name, s);
                                break; // only need to make one support
                            }
                        }
                    }
                }
            }
            // return objects;
            RaiseSupportEvent(UV_DLP_3D_Printer.SupportEvent.eCompleted, "Support Generation Completed", lstsupports);
            m_generating = false;
            return(lstsupports);
        }