### Get an Example Billiards System Source: https://pooltool.readthedocs.io/en/stable/autoapi/pooltool/index Obtain a pre-configured example `pooltool.System` object for quick experimentation. This is useful for testing or demonstrating functionalities without manual setup. ```python import pooltool as pt system = pt.System.example() ``` -------------------------------- ### Create and Inspect an Example System Source: https://pooltool.readthedocs.io/en/stable/autoapi/pooltool/index Generates a predefined example system with two balls and a cue stick configured to pocket one of the balls. This serves as a starting point for simulations and testing. ```python import pooltool as pt system = pt.System.example() print(system.balls["cue"].xyz) print(system.balls["1"].xyz) print(system.cue) ``` -------------------------------- ### Install Pooltool from Source using Poetry Source: https://pooltool.readthedocs.io/en/stable/_sources/getting_started/install.md Installs Pooltool from source using Poetry, including development and documentation dependencies. It also installs the package in editable mode and sets up pre-commit hooks for code quality. ```bash poetry install --with=dev,docs pip install -e . pre-commit install ``` -------------------------------- ### Build, Simulate, and Visualize Pool System (Python) Source: https://pooltool.readthedocs.io/en/stable/getting_started/interface This Python code snippet demonstrates the fundamental steps to create an example pool system, run a simulation, and display the results using the PoolTool library. It requires the 'pooltool' library to be installed. The output is a visual representation of the simulation within the PoolTool interface. ```python import pooltool as pt system = pt.System.example() pt.simulate(system, inplace=True) pt.show(system) ``` -------------------------------- ### Verify Pooltool Installation Source: https://pooltool.readthedocs.io/en/stable/_sources/getting_started/install.md Tests the Pooltool installation by printing its version. It also shows how to verify the version if installed from source, which is expected to be '0.0.0'. ```python python -c "import pooltool; print(pooltool.__version__)" ``` -------------------------------- ### Create and Inspect an Example Pool System Source: https://pooltool.readthedocs.io/en/stable/_sources/autoapi/pooltool/system/index.rst This code snippet demonstrates how to create a default example system using `pooltool.System.example()`. It shows how to access ball properties and cue stick parameters, and how to simulate and visualize the system. Requires the 'pooltool' library. ```python import pooltool as pt system = pt.System.example() print(system.balls["cue"].xyz) print(system.balls["1"].xyz) print(system.cue) pt.simulate(system, inplace=True) pt.show(system) ``` -------------------------------- ### Example System Generation Source: https://pooltool.readthedocs.io/en/stable/_sources/autoapi/pooltool/system/index.rst Provides a method to generate a pre-configured example System object for testing or demonstration purposes. ```APIDOC ## GET /system/example ### Description Generates and returns a simple example System object. This system includes two balls and configured cue stick parameters suitable for pocketing the '1' ball. ### Method GET ### Endpoint `/system/example` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import pooltool as pt system = pt.System.example() print(system.balls["cue"].xyz) ``` ### Response #### Success Response (200) - **System** (object) - An example System object with pre-defined balls and cue settings. #### Response Example ```json { "example": "System object" } ``` ``` -------------------------------- ### Google-Style Docstring Example in Python Source: https://pooltool.readthedocs.io/en/stable/_sources/meta/developer_guide.md Demonstrates the expected Google-style docstring format for Python functions in the pooltool project. It includes sections for a brief description, detailed explanation, arguments, return values, raised exceptions, notes, examples, and related functions. ```python def function_name(arg1: str, arg2: int) -> list[str]: """Brief description of the function. More detailed description that can span multiple lines. Args: arg1: Description of arg1 arg2: Description of arg2 Returns: list[str]: Description of the return value Raises: ExceptionType: Description of when this exception is raised Notes: Additional information about implementation details Example: >>> code_example expected_output See Also: - related_function: Description of how it's related """ ``` -------------------------------- ### Install Pre-commit Hooks Source: https://pooltool.readthedocs.io/en/stable/_sources/meta/developer_guide.md Installs the pre-commit hooks for the project, which automatically check and format code according to style guidelines before each commit. This ensures code quality and consistency. ```bash pre-commit install ``` -------------------------------- ### System Example Source: https://pooltool.readthedocs.io/en/stable/autoapi/pooltool/system/index Provides a simple example System object for testing and demonstration purposes. This system includes two balls and configured cue stick parameters. ```APIDOC ## GET /System/example ### Description Creates and returns a simple example System object. This system is pre-configured with two balls and cue stick parameters designed to pocket one of the balls. ### Method GET (or a class method call like `pooltool.System.example()`) ### Endpoint `/System/example` (conceptual, actual implementation is a class method call) ### Parameters None ### Request Example ```python >>> import pooltool as pt >>> system = pt.System.example() ``` ### Response #### Success Response (200) - **System** (System) - An example System object. #### Response Example ```json { "example": "example_system_object" } ``` ``` -------------------------------- ### Example System Construction and Introspection in PoolTool Source: https://pooltool.readthedocs.io/en/stable/_sources/autoapi/pooltool/index.rst Demonstrates how to create and inspect a PoolTool system. It shows how to access ball positions and cue stick parameters. This example requires the `pooltool` library. ```python import pooltool as pt system = pt.System.example() print(system.balls["cue"].xyz) print(system.balls["1"].xyz) print(system.cue) ``` -------------------------------- ### Clone Pooltool Repository Source: https://pooltool.readthedocs.io/en/stable/_sources/getting_started/install.md Clones the Pooltool git repository to a specified directory and navigates into the cloned repository. This is the first step for installing from source. ```bash cd git clone https://github.com/ekiefl/pooltool.git cd pooltool ``` -------------------------------- ### Enter Game Logic and Scene Setup Source: https://pooltool.readthedocs.io/en/stable/_modules/pooltool/ani/animate Handles the logic for entering the game state, including creating game systems, hiding menus, setting up the visualization, and initializing game components like the HUD and collision detection. It also compiles simulation code and starts the simulation. Dependencies include Global, MenuRegistry, visual, cue_avoid, settings, hud, autils, and simulate. ```python def _enter_game(self): """Close the menu, setup the visualization, and start the game""" if not Global.game or not len(multisystem): self._create_system() MenuRegistry.hide_all() self.create_scene() visual.cue.hide_nodes() cue_avoid.init_collisions() if settings.graphics.hud: hud.init() code_comp_menu = autils.TextOverlay( title="Compiling simulation code...", frame_color=(0, 0, 0, 0.4), title_pos=(0, 0, 0), ) code_comp_menu.show() boop(2) simulate(System.example(), inplace=True) code_comp_menu.hide() Global.mode_mgr.change_mode(Mode.aim) ``` -------------------------------- ### Install Poetry Package Manager Source: https://pooltool.readthedocs.io/en/stable/getting_started/install Installs or verifies the installation of Poetry version 1.8.3 or higher, a Python package and dependency management tool. If using Conda with the provided environment file, Poetry is already included. ```shell pip install "poetry>=1.8.3" $ poetry --version Poetry (version 1.8.3) ``` -------------------------------- ### PoolTool Example System Creation Source: https://pooltool.readthedocs.io/en/stable/autoapi/pooltool/system/index Creates a simple example System object for testing and demonstration purposes. This system includes two balls and is configured for a specific shot. ```python import pooltool as pt system = pt.System.example() ``` -------------------------------- ### Start Game Execution Source: https://pooltool.readthedocs.io/en/stable/_modules/pooltool/ani/animate Starts the main task manager to run the game. Dependencies include Global. ```python [docs] def start(self): Global.task_mgr.run() ``` -------------------------------- ### Visualization Example Source: https://pooltool.readthedocs.io/en/stable/autoapi/pooltool/index Example demonstrating how to visualize a single shot in PoolTool. This involves setting up a system, simulating a shot, and then displaying the visualization. ```APIDOC ## Visualization Example ### Description This example visualizes a single shot. Make sure the shot is simulated, otherwise it will make for a boring visualization. ### Code ```python import pooltool as pt system = pt.System.example() pt.simulate(system, inplace=True) pt.show(system) # Press 'escape' to exit the interface and continue script execution ``` ### Parameters - **title** (str) - The title to display in the visualization. Defaults to an empty string. - **camera_state** - The initial camera state that the visualization is rendered with. ``` -------------------------------- ### Create Example PoolTool System Source: https://pooltool.readthedocs.io/en/stable/_sources/autoapi/pooltool/index.rst Provides a class method to generate a simple example `System` object for testing or demonstration purposes. ```python import pooltool as pt # Get an example system example_system = pt.System.example() ``` -------------------------------- ### Example: Generate and Filter Events Source: https://pooltool.readthedocs.io/en/stable/autoapi/pooltool/events/index Demonstrates generating simulation events and then filtering them using both sequential single-criterion filters and the multi-criterion `filter_events` function. This provides a practical example of event manipulation in pooltool. ```python import pooltool as pt # Setup and simulate a system system = pt.System.example() system.cue.set_state(a=0.68) pt.simulate(system, inplace=True) events = system.events # Option 1: Sequential filtering filtered_events_seq = pt.events.filter_type(events, pt.EventType.BALL_POCKET) filtered_events_seq = pt.events.filter_ball(filtered_events_seq, "cue") # Option 2: Using filter_events for combined criteria filtered_events_combined = pt.events.filter_events( events, pt.events.by_type(pt.EventType.BALL_POCKET), pt.events.by_ball("cue") ) # Both filtered_events_seq and filtered_events_combined should contain the same event(s) ``` -------------------------------- ### Vectorize Example - Plotting Trajectories (Python) Source: https://pooltool.readthedocs.io/en/stable/autoapi/pooltool/objects/index Illustrates using the `vectorize()` method to extract trajectory data (x, y coordinates from rvw) and ball spin (ss) for plotting. This example iterates through simulated ball histories and plots their paths. ```python import pooltool as pt import matplotlib.pyplot as plt system = pt.System.example() pt.simulate(system, continuous=True, inplace=True) for ball in system.balls.values(): rvw, ss, ts = ball.history_cts.vectorize() plt.plot(rvw[:, 0, 0], rvw[:, 0, 1], color=ss) ``` -------------------------------- ### Configure PoolTool Physics Resolver (YAML) Source: https://pooltool.readthedocs.io/en/stable/_sources/resources/custom_physics.md Example YAML configuration for the PoolTool physics resolver. This file, typically located at '~/.config/pooltool/physics/resolver.yaml', dictates how different collision and interaction events are resolved. ```yaml ball_ball: friction: a: 0.009951 b: 0.108 c: 1.088 model: alciatore num_iterations: 1000 model: frictional_mathavan ball_linear_cushion: model: han_2005 ball_circular_cushion: model: han_2005 ball_pocket: model: canonical stick_ball: english_throttle: 1.0 squirt_throttle: 1.0 model: instantaneous_point transition: model: canonical version: 6 ``` -------------------------------- ### Building Documentation with Sphinx Source: https://pooltool.readthedocs.io/en/stable/_sources/meta/developer_guide.md Illustrates Makefile commands for building and previewing project documentation generated with Sphinx. Options include building the documentation, enabling a live preview with auto-reloading, and executing notebooks before building. ```bash make docs make docs-live make docs-with-notebooks ``` -------------------------------- ### Install Poetry Package Manager Source: https://pooltool.readthedocs.io/en/stable/_sources/getting_started/install.md Installs or verifies the installation of the Poetry package manager, a tool for managing Python dependencies and projects. It's a requirement for installing Pooltool from source. ```bash pip install "poetry>=1.8.3" $ poetry --version ``` -------------------------------- ### Python: Create, Simulate, and Visualize a Pool System Source: https://pooltool.readthedocs.io/en/stable/_sources/getting_started/hello_world.md This script initializes a default pool table, sets up balls for a nine-ball game, creates a cue stick, and combines them into a 'System'. It then aims the cue at the '1' ball with a specified velocity, simulates the shot's evolution, and opens a graphical interface to visualize the results. Dependencies include the 'pooltool' package. ```python #! /usr/bin/env python import pooltool as pt # We need a table, some balls, and a cue stick table = pt.Table.default() balls = pt.get_rack(pt.GameType.NINEBALL, table) cue = pt.Cue(cue_ball_id="cue") # Wrap it up as a System shot = pt.System(table=table, balls=balls, cue=cue) # Aim at the head ball with a strong impact shot.cue.set_state(V0=8, phi=pt.aim.at_ball(shot, "1")) # Evolve the shot. pt.simulate(shot, inplace=True) # Open up the shot in the GUI pt.show(shot) ``` -------------------------------- ### Python: Example System Construction and Simulation Source: https://pooltool.readthedocs.io/en/stable/getting_started/hello_world Demonstrates how to construct and interact with a pooltool System object. It shows creating a system using default components, simulating it, and accessing its attributes like the number of events and cue state. It also shows how to visualize the system in the GUI. ```python import pooltool as pt # Example: Constructing a system requires a cue, a table, and a dictionary of balls: example_system_creation = pt.System( cue=pt.Cue.default(), table=pt.Table.default(), balls={"1": pt.Ball.create("1", xy=(0.2, 0.3))}, ) # Example: If you need a quick system to experiment with, call example(): system = pt.System.example() # You can simulate this system and introspect its attributes: pt.simulate(system, inplace=True) print(f"Simulated: {system.simulated}") print(f"Number of events: {len(system.events)}") print(f"Cue state: {system.cue}") # This system can also be visualized in the GUI: # pt.show(system) ``` -------------------------------- ### Install Pooltool via Pip Source: https://pooltool.readthedocs.io/en/stable/_sources/getting_started/install.md Installs Pooltool using pip. For Linux and Windows, an extra index URL for Panda3D is required until Panda3D v1.11 is released. For MacOS, a direct installation is sufficient. ```bash pip install pooltool-billiards --extra-index-url https://archive.panda3d.org/ ``` ```bash pip install pooltool-billiards ``` ```bash pip install pooltool-billiards --extra-index-url https://archive.panda3d.org/ ``` -------------------------------- ### Create and Simulate a System Source: https://pooltool.readthedocs.io/en/stable/_modules/pooltool/system/datatypes Demonstrates the creation of a default system, setting its initial state, and simulating its evolution. This is a foundational step before adding systems to a MultiSystem. ```python import pooltool as pt import numpy as np system = pt.System.example() system.strike(phi=90) pt.simulate(system, inplace=True) ``` -------------------------------- ### Create and Activate Conda Environment Source: https://pooltool.readthedocs.io/en/stable/_sources/getting_started/install.md Creates a new conda environment named 'pooltool-dev' using the 'environment.yml' file and then activates this environment. This is part of the source installation process for managing dependencies. ```bash conda env create -f environment.yml conda activate pooltool-dev ``` -------------------------------- ### Get Default Specs from Game Type Source: https://pooltool.readthedocs.io/en/stable/_modules/pooltool/objects/table/collection A function 'default_specs_from_game_type' that takes a 'GameType' enum and returns the corresponding 'TableSpecs' by utilizing the '_default_game_type_map'. This provides a convenient way to get the appropriate table setup for a chosen game. ```python from pooltool.game.datatypes import GameType from pooltool.objects.table.specs import ( BilliardTableSpecs, PocketTableSpecs, SnookerTableSpecs, TableModelDescr, TableSpecs, TableType, ) def default_specs_from_game_type(game_type: GameType) -> TableSpecs: return prebuilt_specs(_default_game_type_map[game_type]) ``` -------------------------------- ### Simulate Pool System In Place (Python) Source: https://pooltool.readthedocs.io/en/stable/_sources/autoapi/pooltool/evolution/index.rst Demonstrates how to simulate a pool system and update its state in place. This involves importing the `pooltool` library, creating an example system, and then calling `pt.simulate` with `inplace=True`. The assertions verify that the simulation has occurred and the system is marked as simulated. ```python import pooltool as pt system = pt.System.example() assert not system.simulated pt.simulate(system, inplace=True) assert system.simulated ``` -------------------------------- ### Makefile Commands for Documentation Building Source: https://pooltool.readthedocs.io/en/stable/meta/developer_guide Shows the Makefile commands used to build and preview the project's documentation. This includes standard building, live preview with auto-reloading, and building after executing notebooks. ```bash # Build documentation make docs # Live preview with auto-reload (recommended for development) make docs-live # Execute notebooks, then build docs make docs-with-notebooks ``` -------------------------------- ### Run Pooltool Application Source: https://pooltool.readthedocs.io/en/stable/_sources/getting_started/install.md Executes the Pooltool application. Successful execution will display the game window, which can be exited using the escape key. ```bash run-pooltool ``` -------------------------------- ### Get Ball IDs on Table (Python) Source: https://pooltool.readthedocs.io/en/stable/_sources/autoapi/pooltool/ruleset/index.rst Retrieves a set of ball IDs currently present on the table. This can be queried at the start of a shot or after it has concluded, with options to exclude certain balls. ```python def get_ball_ids_on_table(shot: pooltool.system.datatypes.System, at_start: bool, exclude: set[str] | None = None) -> set[str]: """ Returns the set of ball IDs on the table. """ pass ``` -------------------------------- ### Creating a Directory for a New Physics Model in PoolTool Source: https://pooltool.readthedocs.io/en/stable/_sources/resources/custom_physics.md Explains the process of creating a dedicated directory for a new physics model within the `pooltool/physics/resolve/*` structure. This involves naming the directory after the model and creating an `__init__.py` file within it. This setup allows for organizing model logic, whether simple or complex. ```file structure pooltool/ physics/ resolve/ ball_cushion/ <-- Directory for ball-cushion models __init__.py <-- Initialization file for the module unrealistic/ <-- Directory for the 'unrealistic' model __init__.py <-- Initialization file for the 'unrealistic' model # ... (model logic files if complex) ``` -------------------------------- ### Cross-referencing Python Objects in reStructuredText Source: https://pooltool.readthedocs.io/en/stable/_sources/meta/developer_guide.md Provides examples of reStructuredText directives used within pooltool's documentation to cross-reference Python elements like methods, modules, and classes. This allows linking to specific parts of the codebase directly from the documentation. ```rst * {py:meth}`pooltool.objects.Cue.set_state` (text = hyperlink) * {py:mod}`top-level API ` * {py:class}`System ` ``` -------------------------------- ### Get Ball IDs on Table (Python) Source: https://pooltool.readthedocs.io/en/stable/_modules/pooltool/ruleset/utils Returns a set of ball IDs currently on the table, either at the start or end of a shot. It filters balls based on their state and optionally excludes certain ball IDs. This is useful for determining the live balls remaining in play. ```python import pooltool.constants as const from pooltool.system.datatypes import System def get_ball_ids_on_table( shot: System, at_start: bool, exclude: set[str] | None = None ) -> set[str]: history_idx = 0 if at_start else -1 return set( ball.id for ball in shot.balls.values() if ball.history[history_idx].s in const.on_table and (exclude is None or ball.id not in exclude) ) ``` -------------------------------- ### Simulate System and Reset Balls (Python) Source: https://pooltool.readthedocs.io/en/stable/_sources/autoapi/pooltool/system/index.rst Demonstrates simulating a pool system and verifying that ball states change after simulation. It also shows how to reset the system to its initial state, confirming that the cue ball's state returns to its pre-simulation condition. The history of events and simulation time are also preserved. ```python >>> cue_ball_initial_state = system.balls["cue"].state.copy() >>> cue_ball_initial_state BallState(rvw=array([[0.4953 , 0.9906 , 0.028575], [0. , 0. , 0. ], [0. , 0. , 0. ]]), s=0, t=0.0) >>> pt.simulate(system, inplace=True) >>> assert system.balls["cue"].state != cue_ball_initial_state >>> system.reset_balls() >>> assert system.balls["cue"].state == cue_ball_initial_state >>> system.simulated True >>> len(system.events) 14 >>> system.t 5.193035203405666 ``` -------------------------------- ### Get Highest Ball on Table (Python) Source: https://pooltool.readthedocs.io/en/stable/_modules/pooltool/ruleset/utils Identifies the ball with the highest numerical ID that is on the table at either the start or end of a shot. It iterates through the balls, ignoring the cue ball and any pocketed balls at the specified time. This function is useful for tracking specific balls or game states. ```python from pooltool.objects.ball.datatypes import Ball from pooltool.system.datatypes import System class StateProbe(StrEnum): CURRENT = auto() START = auto() END = auto() def _probe_ball_state(ball: Ball, when: StateProbe, simulated: bool) -> BallState: if not simulated: return ball.state if when is StateProbe.CURRENT: return ball.state elif when is StateProbe.START: return ball.history[0] else: return ball.history[-1] def get_highest_ball(shot: System, at_start: bool) -> Ball: """Get the highest ball on the table at start or end of shot Args: at_start: If True, the highest ball on the table at t=0 is calculated. If False, the highest ball at the end of the shot (t=inf) is calculated. The latter returns a different result if the highest ball on the table was pocketed """ _dummy = "0" highest = Ball.dummy(id=_dummy) history_idx = 0 if at_start else -1 for ball in shot.balls.values(): if ball.id == "cue": continue if ball.history[history_idx].s == const.pocketed: continue ``` -------------------------------- ### PoolTool: Create and Simulate a Billiards System Source: https://pooltool.readthedocs.io/en/stable/autoapi/pooltool/system/index This example demonstrates the basic creation and simulation of a single billiards system using the PoolTool library. It initializes a system, applies a strike, simulates its evolution, and prints the elapsed time and events. ```python >>> import pooltool as pt >>> system = pt.System.example() >>> system.strike(phi=90) >>> pt.simulate(system, inplace=True) ``` -------------------------------- ### Get Lowest Ball on Table (Python) Source: https://pooltool.readthedocs.io/en/stable/_modules/pooltool/ruleset/utils Finds the ball with the lowest numerical ID that is currently on the table, either at the start or end of a shot. It iterates through all balls, skipping the cue ball and pocketed balls, and compares their IDs. An assertion ensures at least one numbered ball is present. ```python from pooltool.objects.ball.datatypes import Ball from pooltool.system.datatypes import System class StateProbe(StrEnum): CURRENT = auto() START = auto() END = auto() def _probe_ball_state(ball: Ball, when: StateProbe, simulated: bool) -> BallState: if not simulated: return ball.state if when is StateProbe.CURRENT: return ball.state elif when is StateProbe.START: return ball.history[0] else: return ball.history[-1] def get_lowest_ball(shot: System, when: StateProbe) -> Ball: """Get the lowest ball on the table at start or end of shot Args: at_start: If True, the lowest ball on the table at t=0 is calculated. If False, the lowest ball at the end of the shot (t=inf) is calculated. The latter returns a different result if the lowest ball on the table was pocketed """ _dummy = "10000" lowest = Ball.dummy(id=_dummy) for ball in shot.balls.values(): if ball.id == "cue": continue if _probe_ball_state(ball, when, shot.simulated).s == const.pocketed: continue if int(ball.id) < int(lowest.id): lowest = ball assert lowest.id != _dummy, "No numbered balls on table" return lowest ``` -------------------------------- ### PoolTool: Constructing a System Instance Source: https://pooltool.readthedocs.io/en/stable/autoapi/pooltool/system/index Provides an example of how to manually construct a PoolTool System object. This requires specifying the cue, table, and a dictionary of balls with their initial properties. ```python >>> import pooltool as pt >>> pt.System( >>> cue=pt.Cue.default(), >>> table=pt.Table.default(), >>> balls={"1": pt.Ball.create("1", xy=(0.2, 0.3))}, >>> ) ``` -------------------------------- ### Initialize Panda3D ShowBase with Configuration Source: https://pooltool.readthedocs.io/en/stable/_modules/pooltool/ani/animate Initializes the Panda3D ShowBase application with specified window properties and configures the rendering pipeline using simplepbr. It sets up the main window, background color, and enables/disables shaders based on settings. ```python class ShowBaseConfig: window_type: str | None = None window_size: tuple[int, int] | None = None fb_prop: FrameBufferProperties | None = None monitor: bool = False @classmethod def default(cls): return cls( window_type="onscreen", window_size=None, fb_prop=None, monitor=False ) @require_showbase def boop(frames=1): """Advance/render a number of frames""" for _ in range(frames): Global.base.graphicsEngine.renderFrame() @require_showbase def window_task(win=None): """Routine for managing window activity/resizing Determines whether window is active or not. If not, purgatory mode is entered, a reduced FPS state. The user can modify the game window to be whatever size they want. Ideally, they would be able to pick arbitrary aspect ratios, however this project has been hardcoded to run at a specific aspect ratio, otherwise it looks stretched/squished. With that in mind, this method is called whenever a change to the window occurs, and essentially fixes the aspect ratio. For any given window size chosen by the user, this will override their resizing, and resize the window to one with an area equal to that requested, but at the required aspect ratio. """ no_purgatory_modes = {Mode.purgatory, Mode.menu} is_window_active = Global.base.win.get_properties().foreground if not is_window_active and Global.mode_mgr.mode not in no_purgatory_modes: Global.mode_mgr.change_mode(Mode.purgatory) requested_width = Global.base.win.getXSize() requested_height = Global.base.win.getYSize() diff = abs(requested_width / requested_height - settings.system.aspect_ratio) if diff / settings.system.aspect_ratio < 0.05: # If they are within 5% of the intended ratio, just let them be. return requested_area = requested_width * requested_height # A = w*h # A = r*h*h # h = (A/r)^(1/2) height = (requested_area / settings.system.aspect_ratio) ** (1 / 2) width = height * settings.system.aspect_ratio properties = WindowProperties() properties.setSize(int(width), int(height)) Global.base.win.requestProperties(properties) def _resize_offscreen_window(size: tuple[int, int]): """Changes window size when provided the dimensions (x, y) in pixels""" Global.base.win.setSize(*[int(dim) for dim in size]) def _init_simplepbr() -> simplepbr.Pipeline: return simplepbr.init( enable_shadows=settings.graphics.shadows, max_lights=settings.graphics.max_lights, ) class Interface(ShowBase): def __init__(self, config: ShowBaseConfig): self.showbase_config = config super().__init__(self, windowType=self.showbase_config.window_type) self.openMainWindow( fbprops=self.showbase_config.fb_prop, size=self.showbase_config.window_size ) # Background doesn't apply if ran after simplepbr.init(). See # https://discourse.panda3d.org/t/cant-change-base-background-after-simplepbr-init/28945 Global.base.setBackgroundColor(0.04, 0.04, 0.04) self.simplepbr_pipeline = _init_simplepbr() if isinstance(self.win, GraphicsWindow): mouse.init() cam.init() if not settings.graphics.shader: Global.render.set_shader_off() Global.clock.setMode(ClockObject.MLimited) Global.clock.setFrameRate(settings.graphics.fps) ``` -------------------------------- ### Game Class Initialization and Setup Source: https://pooltool.readthedocs.io/en/stable/_modules/pooltool/ani/animate Initializes the Game class, sets up simulation task chains, registers game entry events, and updates the mode manager. Dependencies include Global, tasks, and Mode. ```python class Game(Interface): """This class runs the pooltool application""" def __init__(self, config=ShowBaseConfig.default()): Interface.__init__(self, config=config) # This task chain allows simulations to be run in parallel to the game processes Global.task_mgr.setupTaskChain("simulation", numThreads=1) tasks.register_event("enter-game", self._enter_game) Global.mode_mgr.update_event_baseline() Global.mode_mgr.change_mode(Mode.menu) ``` -------------------------------- ### Initialize and Populate MultiSystem Source: https://pooltool.readthedocs.io/en/stable/_modules/pooltool/system/datatypes Shows how to create an empty MultiSystem object and append a simulated system to it. It also demonstrates copying an existing system, modifying it, simulating it, and appending the new state to the MultiSystem. ```python multisystem = pt.MultiSystem() multisystem.append(system) next_system = multisystem[-1].copy() next_system.strike(phi=0) pt.simulate(next_system, inplace=True) multisystem.append(next_system) ``` -------------------------------- ### FrameStepper Iterator Setup Source: https://pooltool.readthedocs.io/en/stable/_modules/pooltool/ani/animate Prepares the system and visual elements for frame-by-frame iteration. This includes continuizing the system, resetting and appending it to multisystem, resizing the offscreen window, creating the scene, and hiding non-essential visual elements like cues and camera fixation points. Ball states are also set from history. Dependencies include Generator, System, continuize, multisystem, _resize_offscreen_window, visual, cam, ball, and Global. ```python def _iterator( self, system: System, size: tuple[int, int] = (int(1.6 * 720), 720), fps: float = 30.0, ) -> Generator: continuize(system, dt=1 / fps, inplace=True) multisystem.reset() multisystem.append(system) _resize_offscreen_window(size) self.create_scene() # We don't want the cue in this visual.cue.hide_nodes() # Or the camera fixation point object if cam.fixation_object is not None: cam.fixation_object.removeNode() # Set quaternions for each ball for ball in visual.balls.values(): ball.set_quats(ball._ball.history_cts) frames = int(system.events[-1].time * fps) + 1 yield frames for frame in range(frames): for ball in visual.balls.values(): ball.set_render_state_from_history(ball._ball.history_cts, frame) ball._ball.state = ball._ball.history_cts[frame] Global.task_mgr.step() yield frame ``` -------------------------------- ### Makefile Commands for Documentation Source: https://pooltool.readthedocs.io/en/stable/_sources/meta/developer_guide.md Provides Makefile commands for managing and building project documentation. These commands facilitate tasks such as generating documentation, previewing it live with auto-refresh, executing notebooks, and building docs with integrated notebook execution. ```bash make docs make live make notebooks make docs-with-notebooks ``` -------------------------------- ### MultiSystem Usage Example in PoolTool Source: https://pooltool.readthedocs.io/en/stable/autoapi/pooltool/index Demonstrates the creation and manipulation of a MultiSystem object, which stores a sequence of System objects representing game states or shots. Includes examples of adding systems, copying, resetting, simulating, and accessing elements within the MultiSystem. ```python import pooltool as pt import numpy as np system = pt.System.example() system.strike(phi=90) pt.simulate(system, inplace=True) multisystem = pt.MultiSystem() multisystem.append(system) next_system = multisystem[-1].copy() next_system.strike(phi=0) pt.simulate(next_system, inplace=True) multisystem.append(next_system) print(len(multisystem)) print(multisystem[0].t) for shot in multisystem: print(len(shot.events)) pt.show(multisystem, title="Press 'n' for next, 'p' for previous") ``` -------------------------------- ### Initialize and Close Visualization Window Source: https://pooltool.readthedocs.io/en/stable/_modules/pooltool/ani/animate Handles the initialization and cleanup of the visualization window and related components. `_start` opens the main window and initializes the mouse and PBR pipeline. `_stop` destroys the title node, closes the window, and stops the task manager. ```python def _start(self): self.openMainWindow(keepCamera=True) self.simplepbr_pipeline = _init_simplepbr() mouse.init() def _stop(self): self.title_node.destroy() self.closeWindow(self.win) Global.task_mgr.stop() ``` -------------------------------- ### Get Cue Stick from Event Source: https://pooltool.readthedocs.io/en/stable/_sources/autoapi/pooltool/events/index.rst Retrieves the cue stick object associated with an event using its ID. ```python event.get_stick(stick_id='cue_stick_1') ``` -------------------------------- ### Verify Python Version Source: https://pooltool.readthedocs.io/en/stable/getting_started/install Interactively checks the Python version. The expected version for development is 3.13.0. ```python python Python 3.13.0 | packaged by Anaconda, Inc. | (Oct 7 2024, 16:40:03) [Clang 14.0.6 ] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> exit() ``` -------------------------------- ### Optimize Save/Load with drop_continuized_history Source: https://pooltool.readthedocs.io/en/stable/_sources/autoapi/pooltool/system/index.rst This example illustrates how to reduce file size and improve save/load times by using the `drop_continuized_history` option when saving a system. This is particularly useful when the system has been continuized. It also shows how to reload and re-continuize the system if needed. Requires 'pooltool' and IPython's %timeit. ```python import pooltool as pt system = pt.System.example() # simulate and continuize the results pt.simulate(system, continuous=True, inplace=True) print("saving") %timeit system.save("no_drop.json") %timeit system.save("drop.json", drop_continuized_history=True) print("loading") %timeit pt.System.load("no_drop.json") %timeit pt.System.load("drop.json") # Example of reloading and re-continuizing loaded_system = pt.System.load("drop.json") assert loaded_system != system pt.continuize(loaded_system, inplace=True) assert loaded_system == system ``` -------------------------------- ### Get Ballset by Name Source: https://pooltool.readthedocs.io/en/stable/autoapi/pooltool/objects/index Retrieves a BallSet object using its unique name. This is essential for accessing predefined ball configurations. ```APIDOC ## GET /pooltool/objects/get_ballset ### Description Retrieves the ballset with the given name. ### Method GET ### Endpoint /pooltool/objects/get_ballset ### Parameters #### Query Parameters - **name** (str) - Required - The name of the ballset. To list available ballset names, call `pooltool.objects.get_ballset_names()`. ### Request Example ```json { "name": "standard" } ``` ### Response #### Success Response (200) - **BallSet** (object) - A ballset object. #### Response Example ```json { "name": "standard", "path": "/path/to/standard/ballset", "ids": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], "ball_path": "/path/to/standard/balls" } ``` #### Error Handling - **ValueError**: If Ball ID doesn’t match to the ballset. ```