Ejemplo n.º 1
0
        public static CompoundSolid Crosscut_Or_Rip(CompoundSolid sol, HalfEdge he, Inches distAlongEdge, double miter, double tilt)
        {
            Face f = he.face;

            // TODO fix these names
            string[] fnames = new string[] {
                "miter_top",
                "miter_right",
                "miter_left",
                "miter_bottom",
                "miter",                                // the primary face name which gets left
                "miter_below",
            };

            xyz nrml   = f.UnitNormal();
            xyz origin = he.to + he.GetInwardNormal() * distAlongEdge;

            // vx is in the direction of the cut
            xyz vx = ut.RotateUnitVector(-he.UnitVector(), -miter, nrml);

            // now rotate nrml for tilt
            nrml = ut.RotateUnitVector(nrml, tilt, vx);

            // origin is going to be the corner of the cutter box.
            // right now it is sitting on the face.  we need to
            // move it further away.  calculate intersections with
            // the boundingbox of the compoundsolid as a whole.

            BoundingBox3d bb     = sol.GetBoundingBox();
            double        d_vx   = bb.IntersectRay_Planes_Max(origin, -vx);
            double        d_nrml = bb.IntersectRay_Planes_Max(origin, nrml);

            // TODO this approach creates a bb which is too big.  do we care?

            // now move origin far enough back behind the face
            origin.subtract_in_place((d_vx + 2) * vx);
            // and up above the face
            origin = origin + (d_nrml + 2) * nrml;

            xyz vy = xyz.cross(nrml, vx).normalize_in_place();
            xyz vz = -nrml;

            d_vx = bb.IntersectRay_Planes_Max(origin, vx);
            double d_vy = bb.IntersectRay_Planes_Max(origin, vy);
            double d_vz = bb.IntersectRay_Planes_Max(origin, vz);

            // now calculate proper sizes for the cutter
            double dx = d_vx + 2;
            double dy = d_vy + 2;
            double dz = d_vz + 2;

            Solid cutter = CreateCutter_Box(string.Format("{0}_{1}", f.name, he.Opposite().face.name), origin, vx, nrml, new xyz(dx, dy, dz), fnames);

            //sol = sol.Clone();
            //sol.AddSub(cutter);
            //return sol;
            return(bool3d.Subtract(sol, cutter));
        }
Ejemplo n.º 2
0
        private static void CreateFaceLabel(Viewport3D myVP, Face f, TranslateTransform3D ttmove)
        {
            HalfEdge he   = f.FindLongestEdge();
            xyz      p1   = he.Center();
            xyz      p2   = f.Measure(he, p1);
            xyz      v    = p2 - p1;
            double   dist = v.magnitude();
            xyz      c    = p1 + v / 2;

            c += f.UnitNormal() * .001;
            Point3D  center = wpfmisc.fixPoint(c);
            Vector3D over   = wpfmisc.fixVector(he.UnitVector());
            Vector3D up     = wpfmisc.fixVector(he.GetInwardNormal());

            double height;

            if (dist <= 1)
            {
                height = dist / 3;
            }
            else if (dist < 10)
            {
                height = 1;
            }
            else
            {
                height = 2;
            }

            // TODO the following isn't a very pretty hack
            if (f.name.Length * height > he.Length())
            {
                height = he.Length() / f.name.Length;
            }

            ModelVisual3D mv3d = wpfmisc.CreateTextLabel3D(f.name, Brushes.Black, false, height, center, over, up);

            if (ttmove != null)
            {
                mv3d.Transform = ttmove;
            }
            myVP.Children.Add(mv3d);
        }
Ejemplo n.º 3
0
        public static void Edges(IOrient s2, Face f1, Face f2, HalfEdge he1, HalfEdge he2, EdgeAlignment align, double offset1, double offset2, bool reversed)
        {
            xyz v1;
            xyz v2;

            xyz uv1 = (he1.to - he1.from).normalize_in_place();

            Debug.Assert(
                (align == EdgeAlignment.Center) ||
                (align == EdgeAlignment.Right) ||
                (align == EdgeAlignment.Left)
                );

            // move the solid to match up two points
            if (align == EdgeAlignment.Center)
            {
                v1 = he1.Center();
                if (!fp.eq_inches(offset1, 0))
                {
                    v1 += (offset1 * uv1);
                }
                v2 = he2.Center();
            }
            else if (align == EdgeAlignment.Right)
            {
                v1 = he1.to;
                if (!fp.eq_inches(offset1, 0))
                {
                    v1 -= (offset1 * uv1);
                }
                v2 = he2.from;
            }
            else // left
            {
                v1 = he1.from;
                if (!fp.eq_inches(offset1, 0))
                {
                    v1 += (offset1 * uv1);
                }
                v2 = he2.to;
            }

            if (!fp.eq_inches(offset2, 0))
            {
                xyz uv1perp = -(he1.GetInwardNormal());
                v1 += (offset2 * uv1perp);
            }

            xyz tv = v1 - v2;

            s2.Translate(tv.x, tv.y, tv.z);

            if (reversed)
            {
                RotateSoFacesAreParallelAndSameDir(s2, f1, f2, v1);
            }
            else
            {
                RotateSoFacesAreParallelAndOpposite(s2, f1, f2, v1);
            }

            // now rotate around origin = f1.MainLoop[0].to and vector = n1 to align the other points
            xyz q1 = he1.UnitVector();
            xyz q2 = he2.UnitVector();

            if (reversed)
            {
                q2 = -q2;
            }
            if (fp.eq_unitvec(q1, q2))
            {
                s2.Rotate(-1, 0, v1, f1.UnitNormal());
            }
            else if (fp.eq_unitvec(q1, -q2))
            {
                // do nothing.  this is perfect.
            }
            else
            {
                double dot = xyz.dot(q1, q2);
                xyz    kp  = xyz.cross(q2, q1).normalize_in_place();
                s2.Rotate(-dot, -Math.Sqrt(1 - dot * dot), v1, kp);
            }
        }