from tdw.add_ons.proc_gen_kitchen import ProcGenKitchen
Procedurally generate a kitchen in a new scene or an existing scene.
This is an explanation of how proc_gen_kitchen.create()
works.
It is possible to explicitly set the random number generator via the rng
parameter. Doing so will allow you to recreate the exact same scene later.
If the scene
parameter is of type Room
this is straightforward. Otherwise, select a scene from the scene
parameter (which will be loaded into TDW) and get the Room
from the room_index
parameter.
Cabinetry
always visually match each other. A Cabinetry
data object is selected randomly.
A work triangle defines the overall design of the kitchen space.
A work triangle is comprised of 1 or more lateral arrangements of Arrangement
data objects along a wall, starting at a given distance from a corner.
In all lateral arrangements in ProcGenKitchen
, the following rules are always followed:
- In the wall has windows, tall
Arrangements
will be replaced with shorterArrangements
; seeProcGenKitchen.TALL_ARRANGEMENTS
. For work triangles, tallArrangements
will be replaced withKitchenCounter
. - Non-continuous walls (e.g. a wall with a doorway) will never have a lateral arrangement.
- Each wall has two corresponding corners. For example, a
north
wall has cornersnorth_west
andnorth_east
. One of these corners is selected for the start of the lateral arrangement. Unless otherwise noted, the corner is chosen randomly. - A lateral arrangement has a list of
Arrangements
. They may not all fit along the wall, in which case as manyArrangements
are added as possible.
Work triangle lateral arrangements have the following additional shared rules:
- Each work triangle lateral arrangement has secondary arrangements appended to its list to spatially lengthen it. Possibilities are: [
Basket
,Painting
,Void
,Radiator
,Stool
,Suitcase
]. The selection is random with weighted probability; seeProcGenKitchen.SECONDARY_ARRANGEMENTS["append"]
.
In TDW there are four possible work triangles:
A single lateral arrangement along one of the longer walls.
Requirements: At least one continuous longer wall.
- If one of the longer walls has windows, it will be used for the lateral arrangement. Otherwise, the wall is chosen randomly.
- There are two possible lateral arrangements, chosen randomly:
- [
Refrigerator
,Dishwasher
,Sink
,KitchenCounter
,Stove
,KitchenCounter
,Shelf
] - [
Shelf
,KitchenCounter
,Stove
,KitchenCounter
,Sink
,Dishwasher
,Refrigerator
]
Two lateral arrangements along both longer walls.
Requirements: Two continuous longer walls.
- If one of the longer walls has windows, it will be used for the lateral arrangement with the sink. Otherwise, each lateral arrangement uses a random longer wall.
- For the first lateral arrangement, there are two possibilities, chosen randomly:
- [
Refrigerator
,Dishwasher
,Sink
,KitchenCounter
,KitchenCounter
] - [
KitchenCounter
,KitchenCounter
,Sink
,Dishwasher
,Refrigerator
]
- For the second lateral arrangement, there are two possibilities, chosen randomly:
- [
KitchenCounter
,Stove
,KitchenCounter
,KitchenCounter
,KitchenCounter
] - [
KitchenCounter
,KitchenCounter
,KitchenCounter
,Stove
,KitchenCounter
]
One lateral arrangement along a longer wall and one lateral arrangement along a shorter wall. The two arrangements share a common corner.
Requirements: At least one continuous longer wall and one continuous shorter wall.
- If one of the longer walls has windows, it will be used for the longer lateral arrangement. Otherwise, the wall is chosen randomly.
- There are two possible longer lateral arrangements, each with a
KitchenCounterTop
at the end. If both shorter walls are continuous, the selected lateral arrangement is random. Otherwise,ProcGenKitchen
finds a corner shared by the longer wall and a continuous corner wall and selects the arrangement in which theKitchenCounterTop
is placed at the common corner; for example if the longer wall isnorth
and the only continuous wall iswest
then the longer arrangement is the first of the following two options because itKitchenCounterTop
will be placed at the northwest corner.
- [
KitchenCounterTop
,Sink
,Dishwasher
,Stove
,KitchenCounter
,Shelf
] - [
Shelf
,KitchenCounter
,Stove
,Dishwasher
,Sink
,KitchenCounterTop
]
- The shorter lateral arrangement is placed at the corresponding valid wall (see above). There are two possibilities, chosen randomly:
- [
Void
,KitchenCounter
,KitchenCounter
,Refrigerator
,Shelf
] - [
Void
,KitchenCounter
,Refrigerator
,KitchenCounter
,Shelf
]
One lateral arrangement along a longer wall and two lateral arrangements along both shorter walls.
Requirements: At least one continuous longer wall and two continuous shorter walls.
- If one of the longer walls has windows, it will be used for the longer lateral arrangement. Otherwise, the wall is chosen randomly.
- There are two possible longer lateral arrangements, chosen randomly:
- [
KitchenCounterTop
,Sink
,KitchenCounter
,Stove
,KitchenCounter
,KitchenCounter
] - [
KitchenCounterTop
,KitchenCounter
,Stove
,KitchenCounter
,Sink
,KitchenCounter
]
- Each of the longer lateral arrangements will have additional 20
KitchenCounters
appended. It is unlikely that there will ever actually be this many counters. Just before running out of space along the wall, the lateral arrangement will add aKitchenCounterTop
instead (to anchor the corner). - There are two possible shorter lateral arrangements. The wall on which they appear is chosen randomly:
- [
Void
,KitchenCounter
,Refrigerator
,KitchenCounter
,Shelf
] - [
Void
,KitchenCounter
,Dishwasher
,KitchenCounter
,KitchenCounter
]
Add a KitchenTable
.
The work triangles generate a list of commands and a list of used walls. This list of used walls is used as a parameter in KitchenTable
to prevent chairs from intersecting with work triangle objects.
Add secondary lateral arrangements to unused walls in the main region of the room and the walls of the alcove regions. See: ProcGenKitchen.SECONDARY_ARRANGEMENTS["main"]
and ProcGenKitchen.SECONDARY_ARRANGEMENTS["alcove"]
.
This allows objects to stop moving.
Variable | Type | Description | Value |
---|---|---|---|
SCENE_NAMES |
List[str] | The names of the default scenes. If the scene parameter in self.create() isn't set, or is set to None, a random scene from this list will be selected. |
['mm_craftroom_2a', 'mm_craftroom_2b', 'mm_craftroom_3a', 'mm_craftroom_3b', 'mm_kitchen_2a', 'mm_kitchen_2b', 'mm_kitchen_3a', 'mm_kitchen_3b'] |
SECONDARY_ARRANGEMENTS |
Dict[str, Dict[str, int]] | A dictionary of "secondary arrangements". Keys: "append" (can be appended to a work triangle lateral arrangement), "main" (can be added to a lateral arrangement along an unused wall in the main region of self.room ), and "alcove" (can be added to a lateral arrangement along an unused wall of an alcove region). Value: A dictionary of probabilities and names of arrangements; a higher value means that it is more likely for this arrangement to be randomly selected. |
loads(Path(resource_filename(__name__, "proc_gen_kitchen_data/secondary_categories.json")).read_text()) |
TALL_ARRANGEMENTS |
List[str] | Arrangements that are tall and might obscure windows. |
["refrigerator", "shelf"] |
-
rng
The random number generator. -
scene_record
TheSceneRecord
for this scene. This gets set byself.create()
and can be None if thescene
parameter is aRoom
. -
room
The kitchenRoom
. This gets set byself.create()
. -
cabinetry
TheCabinetry
. This is set randomly byself.create()
. -
commands
These commands will be appended to the commands of the nextcommunicate()
call. -
initialized
If True, this module has been initialized.
ProcGenKitchen()
(no parameters)
self.get_initialization_commands()
This function gets called exactly once per add-on. To re-initialize, set self.initialized = False
.
Returns: A list of commands that will initialize this add-on.
self.on_send(resp)
This is called within Controller.communicate(commands)
after commands are sent to the build and a response is received.
Use this function to send commands to the build on the next Controller.communicate(commands)
call, given the resp
response.
Any commands in the self.commands
list will be sent on the next Controller.communicate(commands)
call.
Parameter | Type | Default | Description |
---|---|---|---|
resp | List[bytes] | The response from the build. |
self.before_send(commands)
This is called within Controller.communicate(commands)
before sending commands to the build. By default, this function doesn't do anything.
Parameter | Type | Default | Description |
---|---|---|---|
commands | List[dict] | The commands that are about to be sent to the build. |
self.get_early_initialization_commands()
This function gets called exactly once per add-on. To re-initialize, set self.initialized = False
.
These commands are added to the list being sent on communicate()
before any other commands, including those added by the user and by other add-ons.
Usually, you shouldn't override this function. It is useful for a small number of add-ons, such as loading screens, which should initialize before anything else.
Returns: A list of commands that will initialize this add-on.
self.create(scene)
self.create(scene, room_index=0, cabinetry_type=None, rng=None)
Procedurally generate a kitchen. The kitchen will be created on the next controller.communicate()
call.
Parameter | Type | Default | Description |
---|---|---|---|
scene | Union[str, SceneRecord, Room, List[Union[str, SceneRecord] | Can be a string (the name of a scene), a SceneRecord , a list of scene names and/or SceneRecord (one will chosen randomly), a Room , or None. If this is a Room , then ProcGenKitchen will assume that the scene has already been loaded, and self.scene_record will be set to None . If scene=None , a random scene from ProcGenKitchen.SCENE_NAMES will be selected. |
|
room_index | int | 0 | The index of the room in self.scene_record.rooms (assuming self.scene_record is not None ; see above). |
cabinetry_type | CabinetryType | None | A CabinetryType value that sets which kitchen cabinets, wall cabinets, and sinks to add to the scene. If None, a CabinetryType is chosen randomly. |
rng | Union[int, np.random.RandomState] | None | The random number generator. Can be int (a random seed), np.random.RandomState , or None (a new random seed will be selected randomly). |