use common rst syntax in doc-strings

This commit is contained in:
Andrej730
2025-11-17 14:20:54 +05:00
parent 51e2e7cd82
commit 29ab446f8c
12 changed files with 85 additions and 134 deletions
@@ -188,11 +188,9 @@ class BaseDecorator:
def get_splines(self, obj: bpy.types.Object) -> Generator[list[Vector]]:
"""Iterates through splines
Args:
obj: Blender object with Curve data
Yields:
verts: points of each spline, world coords
:param obj: Blender object with Curve data
:yield: points of each spline, world coords
"""
assert type(obj.data) is bpy.types.Curve
for spline in obj.data.splines:
@@ -204,12 +202,10 @@ class BaseDecorator:
def get_path_geom(self, obj: bpy.types.Object, topo: bool = True):
"""Parses path geometry into line segments
Args:
obj: Blender object with data of type Curve
topo: bool; if types of vertices are needed
:param obj: Blender object with data of type Curve
:param topo: if types of vertices are needed
Returns:
vertices: 3-tuples of coords
:return: vertices: 3-tuples of coords
indices: 2-tuples of each segment verices' indices
topology: types of vertices
0: internal
@@ -240,11 +236,9 @@ class BaseDecorator:
def get_mesh_geom(self, obj, check_mode=True):
"""Parses mesh geometry into line segments
Args:
obj: Blender object with data of type Mesh
:param obj: Blender object with data of type Mesh
Returns:
vertices: 3-tuples of coords
:return: vertices: 3-tuples of coords
indices: 2-tuples of each segment verices' indices
"""
if check_mode and obj.data.is_editmode:
@@ -375,11 +369,9 @@ class BaseDecorator:
):
"""Draw text label
Args:
pos: bottom-center
multiline: \n characters will be interpreted as line breaks
aligned and centered at segment middle
:param pos: bottom-center
:param multiline: ``\n`` characters will be interpreted as line breaks
aligned and centered at segment middle
NOTE: `blf.draw` seems to ignore the \n character, so we have to split the text ourselves
and use the `line_no` argument of `draw_label`
+10 -12
View File
@@ -422,8 +422,8 @@ def ortho_view_frame(
Similar to `bpy.types.Camera.view_frame`
:arg camera: camera of drawing
:arg margin: margins, in scene units
:param camera: camera of drawing
:param margin: margins, in scene units
:return: (xmin, xmax, ymin, ymax, zmin, zmax) in local camera coordinates
"""
props = tool.Drawing.get_camera_props(camera)
@@ -444,8 +444,8 @@ def almost_zero(v):
def clip_segment(bounds, segm):
"""Clipping line segment to bounds
:arg bounds: (xmin, xmax, ymin, ymax)
:arg segm: 2 vertices of the segment
:param bounds: (xmin, xmax, ymin, ymax)
:param segm: 2 vertices of the segment
:return: 2 new vertices of segment or None if segment outside the bounding box
"""
# LiangBarsky algorithm
@@ -494,8 +494,8 @@ def clip_segment(bounds, segm):
def elevate_segment(bounds, segm):
"""Elevate line xy-perpendicular segment vertically
:arg bounds: (xmin, xmax, ymin, ymax)
:arg segm: 2 vertices of the segment
:param bounds: (xmin, xmax, ymin, ymax)
:param segm: 2 vertices of the segment
:return: 2 new vertices of segment or None if segment outside the bounding box
"""
_, _, ymin, ymax, zmin, _ = bounds
@@ -545,13 +545,11 @@ def add_newline_between_words(text: str, newline_at: int) -> str:
def get_relative_z(obj: bpy.types.Object, element, abs_z: float) -> float:
"""Return relative Z of an element, accounting for its spatial container.
Args:
obj: The Blender object representing the element.
element: The IFC entity for the object.
abs_z: The absolute Z value in world coordinates.
:param obj: The Blender object representing the element.
:param element: The IFC entity for the object.
:param abs_z: The absolute Z value in world coordinates.
Returns:
Relative Z value if the element is inside a spatial container,
:return: Relative Z value if the element is inside a spatial container,
otherwise the absolute Z.
"""
z = abs_z
@@ -544,11 +544,10 @@ class Scheduler:
"""
Adds text to svg.
Args:
p_tags: list of cell's P tags from odt file
box_alignment: alignment of text in box
wrap_text: if True, text will be wrapped to fit in cell
cell_width: width of cell, used for wrapping text
:param p_tags: list of cell's P tags from odt file
:param box_alignment: alignment of text in box
:param wrap_text: if True, text will be wrapped to fit in cell
:param cell_width: width of cell, used for wrapping text
"""
text_lines = [str(p) for p in p_tags]
box_alignment_params = SvgWriter.get_box_alignment_parameters(box_alignment)
+1 -2
View File
@@ -70,8 +70,7 @@ def assign_class(
ifc_representation_class: Optional[str] = None,
) -> Optional[ifcopenshell.entity_instance]:
"""
Args:
context: is not optional if `should_add_representation` is True
:param context: is not optional if ``should_add_representation`` is True
TODO: Do NOT use should_add_representation. Because it internally calls
geometry.add_representation which is 1,000 lines of Blender -> IFC magic.
+5 -7
View File
@@ -1065,7 +1065,7 @@ class Blender(bonsai.core.tool.Blender):
"""Tries to validate the current BIM modifier parameters for the active object
Goes into path editing mode if the modifier supports it
Returns True if an action was taken, False otherwise
:return: True if an action was taken, False otherwise
"""
if cls.is_roof(element):
if cls.is_editing_roof_parameters(obj):
@@ -1089,7 +1089,7 @@ class Blender(bonsai.core.tool.Blender):
def try_canceling_editing_modifier_parameters_or_path(cls, obj: bpy.types.Object) -> bool:
"""Tries to cancel the current BIM modifier parameters or path edition for the active object
Returns True if an action was taken, False otherwise
:return: True if an action was taken, False otherwise
"""
if cls.is_editing_railing_path(obj):
bpy.ops.bim.cancel_editing_railing_path()
@@ -1672,12 +1672,10 @@ class Blender(bonsai.core.tool.Blender):
- "user_interface.wcol_menu.text" (Menu Text)
- "user_interface.wcol_menu.text_sel" (Menu Text Selected)
Args:
color_path (str, optional): The attribute path relative to bpy.context.preferences.themes[0].
threshold (float, optional): The RGB sum threshold for determining dark mode. Default is 1.671.
:param color_path: The attribute path relative to bpy.context.preferences.themes[0].
:param threshold: The RGB sum threshold for determining dark mode. Default is 1.671.
Returns:
str: 'dm' (dark mode) if the RGB sum is > threshold, otherwise 'lm' (light mode).
:return: 'dm' (dark mode) if the RGB sum is > threshold, otherwise 'lm' (light mode).
"""
full_path = f"bpy.context.preferences.themes[0].{color_path}"
+5 -6
View File
@@ -143,12 +143,11 @@ class Debug(bonsai.core.tool.Debug):
Note that Styles UI (or other UI) should be updated manually after using this method.
Args:
object_type: The type of object to merge
by_name_or_identification_only: If True, merge based only on Name attribute (or equivalent identifier).
Strips .XXX suffix patterns (e.g., 'foo.001' matches 'foo', 'foo.002').
For PERSON, uses Identification. For APPLICATION, uses ApplicationFullName.
For PERSON_AND_ORGANIZATION, uses combination of person and organization identifiers.
:param object_type: The type of object to merge
:param by_name_or_identification_only: If True, merge based only on Name attribute (or equivalent identifier).
Strips .XXX suffix patterns (e.g., 'foo.001' matches 'foo', 'foo.002').
For PERSON, uses Identification. For APPLICATION, uses ApplicationFullName.
For PERSON_AND_ORGANIZATION, uses combination of person and organization identifiers.
"""
def normalize_name(name: str) -> str:
+29 -49
View File
@@ -80,8 +80,7 @@ class Web(bonsai.core.tool.Web):
This method creates a temporary socket to bind to a free port.
It then retrieves the port number, and returns it.
Returns:
int: The port number that was generated.
:return: The port number that was generated.
"""
print("Generating port number")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
@@ -97,11 +96,9 @@ class Web(bonsai.core.tool.Web):
If the connection is refused, the port is available for use; otherwise, it is in use.
Args:
port (int): The port number to check.
:param port: The port number to check.
Returns:
bool: True if the port is available, False if it is in use.
:return: bool: True if the port is available, False if it is in use.
"""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
# connect_ex returns errno.SUCCESS (0) if the connection succeeds
@@ -116,8 +113,7 @@ class Web(bonsai.core.tool.Web):
This method sets up the environment, locates paths, and starts
the WebSocket server process.
Args:
port (int): The port number on which to start the WebSocket server.
:param port: The port number on which to start the WebSocket server.
"""
import addon_utils
@@ -156,8 +152,7 @@ class Web(bonsai.core.tool.Web):
This method sets up an asynchronous Socket.IO client with
reconnection attempts, starts an asyncio thread, connects to the WebSocket server, and sets the connection status.
Args:
port (int): The port number to connect to the WebSocket server.
:param port: The port number to connect to the WebSocket server.
"""
global ws_thread, sio
@@ -239,11 +234,9 @@ class Web(bonsai.core.tool.Web):
this method continuously checks for the existence of the WebSocket server's process ID (PID) in the running_pid JSON file.
It waits for a maximum of 5 seconds before returning False.
Args:
port (int): The port number on which the WebSocket server is expected to be running.
:param port: The port number on which the WebSocket server is expected to be running.
Returns:
bool: True if the WebSocket server has started on the specified port within the maximum time limit, False otherwise.
:return: bool: True if the WebSocket server has started on the specified port within the maximum time limit, False otherwise.
"""
pid = ws_process.pid
max_time = 5
@@ -273,12 +266,11 @@ class Web(bonsai.core.tool.Web):
"""
Sends data to the Web UI via Websocket connection.
Args:
data (Optional[Any]): The data to send. If None, just sends data from WebData.
data_key (str): The key under which to store the data in the payload. Defaults to "data".
event (str): The WebSocket event to emit. Defaults to "data".
namespace (str): The namespace for the WebSocket event. Defaults to "/blender".
use_web_data (bool): Whether to use data from WebData. Defaults to True.
:param data: The data to send. If None, just sends data from WebData.
:param data_key: The key under which to store the data in the payload. Defaults to "data".
:param event: The WebSocket event to emit. Defaults to "data".
:param namespace: The namespace for the WebSocket event. Defaults to "/blender".
:param use_web_data: Whether to use data from WebData. Defaults to True.
"""
global ws_thread
@@ -302,8 +294,7 @@ class Web(bonsai.core.tool.Web):
If the WebProperties.is_connected is False, it clears the queue and returns None to unregister the timer.
If the queue is not empty, it processes each operator by calling the corresponding handling function.
Returns:
(Optional[float]): Returns None if the WebProperties.is_connected is False, otherwise returns 1.0 to continue the timer.
:return: Returns None if the WebProperties.is_connected is False, otherwise returns 1.0 to continue the timer.
"""
if not tool.Web.get_web_props().is_connected:
with web_operator_queue.mutex:
@@ -332,8 +323,7 @@ class Web(bonsai.core.tool.Web):
"""
this method handles the Schedules page operators.
Args:
operator_data (dict): A dictionary containing the operator data.
:param operator_data: A dictionary containing the operator data.
"""
if operator_data["type"] == "selection":
bpy.ops.object.select_all(action="DESELECT")
@@ -348,8 +338,7 @@ class Web(bonsai.core.tool.Web):
"""
this method handles the Cost page operators.
Args:
operator_data (dict): A dictionary containing the operator data.
:param operator_data: A dictionary containing the operator data.
"""
ifc_file = tool.Ifc.get()
@@ -701,8 +690,7 @@ class Web(bonsai.core.tool.Web):
"""
this method handles the Sequencing page operators.
Args:
operator_data (dict): A dictionary containing the operator data.
:param operator_data: A dictionary containing the operator data.
"""
ifc_file = tool.Ifc.get()
if operator_data["type"] == "getWorkSchedules":
@@ -741,8 +729,7 @@ class Web(bonsai.core.tool.Web):
"""
this method handles the Documentation page operators.
Args:
operator_data (dict): A dictionary containing the operator data.
:param operator_data: A dictionary containing the operator data.
"""
if operator_data["type"] == "getDrawings":
drawings_data = []
@@ -778,9 +765,8 @@ class Web(bonsai.core.tool.Web):
"""
Opens a web browser and navigates to the specified URL.
Args:
port (int): The port number to be used in the URL.
page (str): The page name to be appended to the URL. Default is an empty string which points to the index page.
:param port: The port number to be used in the URL.
:param page: The page name to be appended to the URL. Default is an empty string which points to the index page.
"""
webbrowser.open(f"http://127.0.0.1:{port}/{page}")
@@ -859,8 +845,7 @@ class Web(bonsai.core.tool.Web):
This method connects to the specified URL using WebSocket transport and registers
an event listener for the `web_operator` event within the `/blender` namespace.
Args:
url (str): The URL of the WebSocket server to connect to.
:param url: The URL of the WebSocket server to connect to.
"""
await sio.connect(url, transports=["websocket"], namespaces="/blender")
sio.on("web_operator", cls.sio_listen_web_operator, namespace="/blender")
@@ -881,10 +866,9 @@ class Web(bonsai.core.tool.Web):
This method emits an event with the provided data to the WebSocket server within the specified namespace.
Args:
data (Any): The data to send to the WebSocket server.
event (Optional[str]): The WebSocket event to emit. Defaults to "data".
namespace (Optional[str]): The namespace for the WebSocket event. Defaults to "/blender".
:param data: The data to send to the WebSocket server.
:param event: The WebSocket event to emit. Defaults to "data".
:param namespace: The namespace for the WebSocket event. Defaults to "/blender".
"""
await sio.emit(event, data, namespace=namespace)
@@ -896,8 +880,7 @@ class Web(bonsai.core.tool.Web):
This method receives data from the WebSocket server and attempts to place it into the
`web_operator_queue`. If the queue is full, the data is discarded.
Args:
data (dict): The data received from the `web_operator` event.
:param data: The data received from the `web_operator` event.
"""
try:
web_operator_queue.put_nowait(data)
@@ -923,10 +906,9 @@ class AsyncioThread(threading.Thread):
This class represents a thread that runs an asyncio event loop. It is used to handle asynchronous tasks
in a separate thread from the main thread.
Args:
*args: Variable length argument list. These arguments are passed to the superclass constructor.
loop: An existing asyncio event loop. If None, a new event loop is created.
**kwargs: Arbitrary keyword arguments. These arguments are passed to the superclass constructor.
:param args: Variable length argument list. These arguments are passed to the superclass constructor.
:param loop: An existing asyncio event loop. If None, a new event loop is created.
:param kwargs: Arbitrary keyword arguments. These arguments are passed to the superclass constructor.
"""
super().__init__(*args, **kwargs)
self.loop = loop or asyncio.new_event_loop()
@@ -943,11 +925,9 @@ class AsyncioThread(threading.Thread):
"""
Run a coroutine in the asyncio event loop from a separate thread.
Args:
coro: The coroutine to be run.
:param coro: The coroutine to be run.
Returns:
The result of the coroutine.
:return: The result of the coroutine.
"""
return asyncio.run_coroutine_threadsafe(coro, loop=self.loop).result()
+1 -2
View File
@@ -411,8 +411,7 @@ class IfcCsv:
concat: str = ", ",
) -> None:
"""
Args:
table: filepath to the table.
:param table: filepath to the table.
"""
ext: FILE_FORMAT = table.split(".")[-1].lower()
@@ -319,13 +319,11 @@ def stream2(path: Union[Path, str], mmap: bool = False, page_size: int = 0):
"""Streams the content of a file path from disk, yielding each instance
as a dictionary.
Args:
path (Union[Path, str]): input file path
mmap (bool): open the file contents using memory mapping
page_size (int): open file in python and feed chunks to the parser
:param path: Input file path
:param mmap: Open the file contents using memory mapping
:param page_size: Open file in python and feed chunks to the parser.
Yields:
dict: entity instance dictionaries
:yield: Entity instance dictionaries
"""
if page_size:
import builtins
@@ -359,11 +357,8 @@ def stream2_from_string(data: str) -> Generator[dict]:
"""Streams the content of a file path from string, yielding each instance
as a dictionary.
Args:
data (str): input data
Yields:
dict: entity instance dictionaries
:param data: Input data string
:yield: entity instance dictionaries
"""
streamer = ifcopenshell_wrapper.stream_from_string(data)
while streamer:
@@ -376,9 +371,8 @@ def convert_path_to_rocksdb(ifcspf_path: Union[Path, str], rocksdb_path: Union[P
RocksDB encoding. RocksDB is an embedded key-value store that allows
partial reads and is therefore more memory efficient with larger files.
Args:
ifcspf_path (Union[Path, str]): Input file path - needs to exist
rocksdb_path (Union[Path, str]): RocksDB file path (directory) - may exist, but result may then be invalid
:param ifcspf_path: Input file path - needs to exist
:param rocksdb_path: RocksDB file path (directory) - may exist, but result may then be invalid
"""
ser = ifcopenshell_wrapper.RocksDbSerializer(str(ifcspf_path), str(rocksdb_path), True)
ser.finalize()
@@ -466,8 +466,7 @@ class entity_instance:
def is_entity(self) -> bool:
"""Tests whether the instance is an entity type as opposed to a simple data type.
Returns:
bool: True if the instance is an entity
:return: True if the instance is an entity
"""
schema_name = self.wrapped_data.is_a(True).split(".")[0]
decl = ifcopenshell_wrapper.schema_by_name(schema_name).declaration_by_name(self.is_a())
@@ -499,13 +498,11 @@ class entity_instance:
return op(a, b)
TypeError: '<' not supported between instances of 'int' and 'str'
Args:
other (_type_): Right hand side (or lhs when reverse = True)
op (_type_): The comparison operator (likely from the operator module)
reverse (bool, optional): When true swaps lhs and rhs. Defaults to False.
:param other: Right hand side (or lhs when reverse = True)
:param op: The comparison operator (likely from the operator module)
:param reverse: When true swaps lhs and rhs. Defaults to False.
Returns:
bool: The comparison predicate applied to self and other
:return: bool: The comparison predicate applied to self and other
"""
if isinstance(other, entity_instance):
@@ -189,11 +189,9 @@ def get_cost_items_for_product(product: ifcopenshell.entity_instance) -> list[if
"""
Returns a list of cost items related to the given product.
Args:
product: An object of class IfcProduct representing a product.
:param product: An object of class IfcProduct representing a product.
Returns:
A list of IfcCostItem objects representing the cost items related to the product.
:return: A list of IfcCostItem objects representing the cost items related to the product.
"""
cost_items = []
for assignment in product.HasAssignments:
@@ -367,14 +367,12 @@ def get_tasks_for_product(
"""
Get all tasks assigned to or referenced by the given product.
Args:
product: An object that is assigned tasks or references tasks.
schedule: An optional string representing the schedule name to filter tasks by.
:param product: An object that is assigned tasks or references tasks.
:param schedule: An optional string representing the schedule name to filter tasks by.
Returns:
A tuple of two lists:
- The first list contains all tasks assigned to the product.
- The second list contains all tasks referenced by the product that are part of the given schedule.
:return: A tuple of two lists:
- The first list contains all tasks assigned to the product.
- The second list contains all tasks referenced by the product that are part of the given schedule.
"""
inputs = [
assignement.RelatingProcess