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)); }
/// <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); }
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)); }
public static void OrientForRoom(Curve crv, PlacementPackage item, RoomPackage room) { crv.Transform(Transform.Rotation(Vector3d.YAxis, room.OrientationPlane.XAxis, item.Dims.Center)); }
/// <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. } } }