Ejemplo n.º 1
0
        public static PlacementPackage ForFrontRow(RoomPackage room, PlacementPackage program)
        {
            Transform move = Transform.Translation(room.BaseAnchorLeft - room.OrientationPlane.Origin);

            program.Bounds.Transform(move);

            var stagedPlane = new Plane(room.BaseAnchorLeft, new Vector3d(room.OrientationPlane.XAxis), new Vector3d(room.OrientationPlane.YAxis));

            return(new PlacementPackage(program.Program, stagedPlane, program.Bounds));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Basic collision detection routine for single item placement.
        /// </summary>
        /// <param name="room">Room currently being populated.</param>
        /// <param name="candidate">PlacementPackaged being checked for fidelity.</param>
        /// <param name="pm"></param>
        /// <returns></returns>
        public static bool PlacementIsValid(RoomPackage room, PlacementPackage candidate, ProgramManifest pm)
        {
            //Verify placed item does not clash with previously placed items.
            foreach (PlacementPackage placedItem in room.PlacedItems)
            {
                if (Confirm.CurvesIntersect(placedItem.Bounds, candidate.Bounds, true))
                {
                    if (Confirm.CurvesIntersect(placedItem.Bounds, candidate.Bounds, false))
                    {
                        return(false);
                    }

                    CurveIntersections ccx = Intersection.CurveCurve(placedItem.Bounds, candidate.Bounds, 0.1, 0.1);

                    if (ccx.Count(x => x.IsOverlap) > 1)
                    {
                        return(false);
                    }
                }

                PointContainment insideCheck = placedItem.Bounds.Contains(candidate.Bounds.GetBoundingBox(Plane.WorldXY).Center);

                if (insideCheck == PointContainment.Inside || insideCheck == PointContainment.Coincident)
                {
                    return(false);
                }
            }

            //Verify item is completely within boundary of room.
            foreach (Curve edgeCurve in room.AllEdgeCurves)
            {
                if (Confirm.CurvesIntersect(candidate.Bounds, edgeCurve, false))
                {
                    return(false);
                }

                /*
                 * if (!Confirm.PointInRegion(room.Region, new CurveBounds(candidate.Bounds).Center))
                 * {
                 *  return false;
                 * }
                 */
            }

            //Verify program area is not larger than total room area.
            if (room.Region.GetArea() < pm.ProgramPackages[candidate.ProgramIndex].OccupationArea)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 3
0
        public static PlacementPackage ForRightLane(RoomPackage room, PlacementPackage program)
        {
            //Rotate item and move it to starting point.
            program.Bounds.Rotate(Math.PI / -2, Vector3d.ZAxis, room.OrientationPlane.Origin);

            var shiftDir = new Vector3d(room.OrientationPlane.YAxis);

            shiftDir.Reverse();
            shiftDir = shiftDir * (program.Program.Dims.Width / shiftDir.Length);

            Transform shift = Transform.Translation(shiftDir);
            Transform move  = Transform.Translation(room.BaseAnchorRight - room.OrientationPlane.Origin);

            program.Bounds.Transform(shift);
            program.Bounds.Transform(move);

            //Identify new orientation plane's origin.
            var     roomIsVertical = Math.Abs(room.OrientationPlane.YAxis.Y) > Math.Abs(room.OrientationPlane.YAxis.X);
            Point3d origin;

            if (roomIsVertical)
            {
                origin = room.OrientationPlane.YAxis.Y > 0 ? new Point3d(room.BaseAnchorRight.X, room.BaseAnchorRight.Y - program.Program.Dims.Width, 0) : new Point3d(room.BaseAnchorRight.X, room.BaseAnchorRight.Y + program.Program.Dims.Width, 0);
            }
            else
            {
                origin = room.OrientationPlane.YAxis.X > 0 ? new Point3d(room.BaseAnchorRight.X - program.Program.Dims.Width, room.BaseAnchorRight.Y, 0) : new Point3d(room.BaseAnchorRight.X + program.Program.Dims.Width, room.BaseAnchorRight.Y, 0);
            }

            //Generate new base plane.
            var stagedPlane = new Plane(origin, shiftDir, new Vector3d(room.OrientationPlane.XAxis));

            //Confirm item is still in zone. If not, compensate.
            if (Confirm.PointInRegion(room.Region, new CurveBounds(program.Bounds).Center, 0.1))
            {
                return(new PlacementPackage(program.Program, stagedPlane, program.Bounds));
            }

            //Generate mirror plane and reflect bounds.
            var mirrorPlane = new Plane(room.OrientationPlane);

            mirrorPlane.Rotate(Math.PI / 2, mirrorPlane.YAxis);
            mirrorPlane.Origin = room.BaseAnchorRight;

            Transform mirror = Transform.Mirror(mirrorPlane);

            program.Bounds.Transform(mirror);

            return(new PlacementPackage(program.Program, stagedPlane, program.Bounds));
        }
Ejemplo n.º 4
0
 public static void OrientForRoom(Curve crv, PlacementPackage item, RoomPackage room)
 {
     crv.Transform(Transform.Rotation(Vector3d.YAxis, room.OrientationPlane.XAxis, item.Dims.Center));
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Populates room in rows along its Y axis. Packs along the left (-X) edge until passing the room's midpoint, then packs along right edge until full.
        /// </summary>
        /// <param name="room"></param>
        /// <param name="zone"></param>
        /// <param name="pm"></param>
        public static void ByMostRows(RoomPackage room, ZonePackage zone, ProgramManifest pm)
        {
            var lexFull   = false;
            var rexFull   = false;
            var openZones = !lexFull || !rexFull;

            var anchor = Point3d.Unset;

            //Parent population method.
            while (room.MaxPlacement.Select(x => x > 0).Any() && openZones)
            {
                //Iterate through programs as staged.
                // (Chuck) Important: room.MaxPlacement aligns to program indices in room.FillOrder.
                // These DO NOT align to pm.ProgramPackages, and often don't even contain all programs.
                // To get data for the active program from its ProgramPackage, or to use a list that aligns with it, reference with index at room.FillOrder[i].
                for (int i = 0; i < room.MaxPlacement.Count; i++)
                {
                    var activeProgram      = pm.ProgramPackages[room.FillOrder[i]];
                    var activeProgramIndex = room.FillOrder[i];

                    //Begin packing program.
                    while (room.MaxPlacement[i] - room.NumProgramsPlaced[activeProgramIndex] > 0)
                    {
                        PlacementPackage candidate = null;

                        //Start in left half.
                        if (!lexFull)
                        {
                            candidate = Stage.Program.ForLeftLane(room, Stage.Program.InRoom(room, activeProgram));

                            //Move candidate to next position.
                            anchor = room.NextAnchor == Point3d.Unset ? room.BaseAnchorLeft : room.NextAnchor;
                            candidate.Bounds.Transform(Transform.Translation(anchor - room.BaseAnchorLeft));

                            //Verify that placement is valid and stage next anchor point accordingly.
                            if (Collision.PlacementIsValid(room, candidate, pm))
                            {
                                room.PlacedItems.Add(candidate);
                                room.NumProgramsPlaced[activeProgramIndex]++;

                                candidate.Dims = new CurveBounds(candidate.Bounds);

                                candidate.Orientation.Origin.Transform(Transform.Translation(anchor - room.BaseAnchorLeft));

                                var buffer = 0.0;

                                if (candidate.Program.AccessDirections == "1111")
                                {
                                    buffer = 3;
                                }

                                room.PrevAnchor = anchor;
                                room.NextAnchor = Stage.Room.NextAnchorRows(room, activeProgram, anchor, 1, buffer);
                            }
                            //Otherwise shift anchor slightly and retry.
                            else
                            {
                                room.PrevAnchor = anchor;
                                room.NextAnchor = Stage.Room.NextAnchorRows(room, activeProgram, anchor, 1, 0.1);
                            }

                            if (!Confirm.PointInRegion(room.Region, room.NextAnchor))
                            {
                                if (i == room.MaxPlacement.Count - 1)
                                {
                                    room.NextAnchor = Point3d.Unset;
                                    lexFull         = true;
                                    break;
                                }

                                room.NextAnchor = Point3d.Unset;
                                break;
                            }

                            continue;
                        }

                        if (!rexFull)
                        {
                            candidate = Stage.Program.ForRightLane(room, Stage.Program.InRoom(room, activeProgram));

                            //Move candidate to next position.
                            anchor = room.NextAnchor == Point3d.Unset ? room.BaseAnchorRight : room.NextAnchor;
                            candidate.Bounds.Transform(Transform.Translation(anchor - room.BaseAnchorRight));

                            //Verify that placement is valid and stage next anchor point accordingly.
                            if (Collision.PlacementIsValid(room, candidate, pm))
                            {
                                room.PlacedItems.Add(candidate);
                                room.NumProgramsPlaced[activeProgramIndex]++;

                                candidate.Dims = new CurveBounds(candidate.Bounds);

                                candidate.Orientation.Origin.Transform(Transform.Translation(anchor - room.BaseAnchorRight));

                                var buffer = 0.0;

                                if (candidate.Program.AccessDirections == "1111")
                                {
                                    buffer = 3;
                                }

                                room.PrevAnchor = anchor;
                                room.NextAnchor = Stage.Room.NextAnchorRows(room, activeProgram, anchor, 1, buffer);
                            }
                            //Otherwise shift anchor slightly and retry.
                            else
                            {
                                room.PrevAnchor = anchor;
                                room.NextAnchor = Stage.Room.NextAnchorRows(room, activeProgram, anchor, 1, 0.1);
                            }

                            if (!Confirm.PointInRegion(room.Region, room.NextAnchor))
                            {
                                if (i == room.MaxPlacement.Count - 1)
                                {
                                    room.NextAnchor = Point3d.Unset;
                                    rexFull         = true;
                                    break;
                                }

                                room.NextAnchor = Point3d.Unset;
                                break;
                            }

                            continue;
                        }

                        openZones = false;
                        break;
                    }

                    //Room has been populated.
                }
            }
        }