From 8f558877704aefcfcf20a58e0b8c1e480f8759b4 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Thu, 23 May 2024 16:55:48 +0200 Subject: [PATCH 01/52] chore: Update package to version 30.498.0 added: - Multi Layer Cover Controller to navigation - functions in `dimension_controller` , `element_controller` , `utility_controller` - missing `ifc-type` setter getter --- docs/documentation/enums.md | 6 + .../multi_layer_cover_controller.md | 6 + docs/release_notes.md | 3628 +---------------- mkdocs.yml | 1 + pyproject.toml | 2 +- src/cadwork/ifc_2x3_element_type.pyi | 18 +- src/cadwork/multi_layer_type.pyi | 27 + src/dimension_controller/__init__.pyi | 13 +- src/element_controller/__init__.pyi | 38 + src/utility_controller/__init__.pyi | 33 + 10 files changed, 223 insertions(+), 3549 deletions(-) create mode 100644 docs/documentation/multi_layer_cover_controller.md create mode 100644 src/cadwork/multi_layer_type.pyi diff --git a/docs/documentation/enums.md b/docs/documentation/enums.md index 837761d..7591831 100644 --- a/docs/documentation/enums.md +++ b/docs/documentation/enums.md @@ -57,3 +57,9 @@ rendering: show_root_heading: false show_source: true + +## Multi Layer Cover Type +::: src.cadwork.multi_layer_type + rendering: + show_root_heading: false + show_source: true diff --git a/docs/documentation/multi_layer_cover_controller.md b/docs/documentation/multi_layer_cover_controller.md new file mode 100644 index 0000000..dc78ddf --- /dev/null +++ b/docs/documentation/multi_layer_cover_controller.md @@ -0,0 +1,6 @@ +# Multi Layer Cover Controller + +::: src.multi_layer_cover_controller + rendering: + show_root_heading: false + show_source: true diff --git a/docs/release_notes.md b/docs/release_notes.md index 955c041..4ab9ae6 100644 --- a/docs/release_notes.md +++ b/docs/release_notes.md @@ -1,3639 +1,179 @@ ---- -hide: - - navigation ---- - -# Differences from the last to the current version - -- What all counts as a change: - - New functions - - Changed function descriptions (docstrings) - - New classes - - Changed classes descriptions (docstrings) - - New enums - - Changed enums descriptions (docstrings) - - -## New Items -### Functions attribute_controller -#### is_attribute_visible_in_modify_window - -```python -def is_attribute_visible_in_modify_window(number: int) ->bool: - """is attribute visible in modify window - - Parameters: - number: number - - Returns: - bool - """ - -``` - -#### set_attribute_visibility_in_modify_window - -```python -def set_attribute_visibility_in_modify_window(number: int, visibility: bool - ) ->None: - """set attribute visibility in modify window - - Parameters: - number: number - visibility: visibility - - Returns: - None - """ - -``` - -#### set_cutting_set - -```python -def set_cutting_set(element_id_list: List[int], cutting_set_name: str) ->bool: - """set cutting set - - Parameters: - element_id_list: element_id_list - cutting_set_name: cutting_set_name - - Returns: - bool - """ - -``` - -## New Items -### Functions bim_controller -#### get_ifc_predefined_type - -```python -def get_ifc_predefined_type(element_id: int) ->ifc_predefined_type: - """Get the IfcPredefinedType of an element. - - Parameters: - element_id: element_id - - Returns: - IfcPredefinedType Wrapper - """ - -``` - -#### set_ifc_predefined_type - -```python -def set_ifc_predefined_type(element_i_ds: List[int], predefined_type: None - ) ->None: - """Set a predefined type to elements. Attention, if you change the PredefinedType of the elements, you are responsible for ensuring that valid types are set - - Parameters: - element_i_ds: element_i_ds - predefined_type: predefined_type - - Returns: - None - """ - -``` - ## New Items ### Functions dimension_controller -#### get_distance - -```python -def get_distance(element: int) ->point_3d: - """Get the distance to the dimension reference point. The point is in the plane of the dimensioning. - - Parameters: - element: element - - Returns: - point_3d - """ - -``` - -#### get_plane_normal - -```python -def get_plane_normal(element: int) ->point_3d: - """Get the plane normal - - Parameters: - element: element - - Returns: - normal - """ - -``` - -#### get_plane_xl - -```python -def get_plane_xl(element: int) ->point_3d: - """Get the plane x direction - - Parameters: - element: element - - Returns: - x direction - """ - -``` - -#### get_segment_count - -```python -def get_segment_count(element: int) ->int: - """Get count of segments - - Parameters: - element: element - - Returns: - segment count - """ - -``` - -#### get_segment_distance +#### get_segment_direction ```python -def get_segment_distance(element: int, segment_index: int) ->float: - """Get the distance from the anchor point to the dimension segment +def get_segment_direction(element: int, segment_index: int) ->point_3d: + """get segment direction Parameters: element: element segment_index: segment_index Returns: - distance + point_3d """ ``` ## New Items ### Functions element_controller -#### convert_surfaces_to_roof_surfaces - -```python -def convert_surfaces_to_roof_surfaces(elements: List[int], roof_name: str - ) ->None: - """converts surfaces to roof surfaces - - Parameters: - elements: elements - roof_name: roof_name - - Returns: - None - """ - -``` - -#### start_standard_element_dialog - -```python -def start_standard_element_dialog(standard_element_type: None) ->str: - """Starts the standard element dialogue based on the chosen element type - - Parameters: - standard_element_type: standard_element_type - - Returns: - Returns guid of selected standard element if item is valid, else null - """ - -``` - -#### remove_standard_connector_axis - -```python -def remove_standard_connector_axis(a0: str) ->None: - """remove standard connector axis - - Parameters: - a0: a0 - - Returns: - None - """ - -``` - -#### remove_standard_beam - -```python -def remove_standard_beam(guid: str) ->None: - """remove standard beam - - Parameters: - guid: guid - - Returns: - None - """ - -``` - -#### remove_standard_panel - -```python -def remove_standard_panel(guid: str) ->None: - """remove standard panel - - Parameters: - guid: guid - - Returns: - None - """ - -``` - -#### remove_standard_container - -```python -def remove_standard_container(guid: str) ->None: - """remove standard container - - Parameters: - guid: guid - - Returns: - None - """ - -``` - -#### remove_standard_export_solid - -```python -def remove_standard_export_solid(guid: str) ->None: - """remove standard export solid - - Parameters: - guid: guid - - Returns: - None - """ - -``` - -#### get_user_element_ids_with_count - -```python -def get_user_element_ids_with_count(count: int) ->List[int]: - """get user element ids with count - - Parameters: - count: count - - Returns: - List[int] - """ - -``` - -#### cut_scarf_straight - -```python -def cut_scarf_straight(elements: List[int], length: float, depth: float, - clearance_length: float, clearance_depth: float, clearance_hook: float, - drilling_count: int, drilling_diameter: float, drilling_tolerance: float - ) ->None: - """cut scarf straight - - Parameters: - elements: elements - length: length - depth: depth - clearance_length: clearance_length - clearance_depth: clearance_depth - clearance_hook: clearance_hook - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance - - Returns: - None - """ - -``` - -#### cut_scarf_diagonal +#### create_truncated_cone_beam_points ```python -def cut_scarf_diagonal(elements: List[int], length: float, depth: float, - clearance_length: float, clearance_depth: float, drilling_count: int, - drilling_diameter: float, drilling_tolerance: float) ->None: - """cut scarf diagonal +def create_truncated_cone_beam_points(start_diameter: float, end_diameter: + float, p1: point_3d, p2: point_3d, p3: point_3d) ->int: + """create truncated cone beam points Parameters: - elements: elements - length: length - depth: depth - clearance_length: clearance_length - clearance_depth: clearance_depth - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance + start_diameter: start_diameter + end_diameter: end_diameter + p1: p1 + p2: p2 + p3: p3 Returns: - None + int """ ``` -#### cut_scarf_with_wedge +#### create_truncated_cone_beam_vectors ```python -def cut_scarf_with_wedge(elements: List[int], length: float, depth: float, - clearance_length: float, clearance_depth: float, wedge_width: float, - drilling_count: int, drilling_diameter: float, drilling_tolerance: float - ) ->None: - """cut scarf with wedge +def create_truncated_cone_beam_vectors(start_diameter: float, end_diameter: + float, length: float, p1: point_3d, xl: point_3d, zl: point_3d) ->int: + """create truncated cone beam vectors Parameters: - elements: elements + start_diameter: start_diameter + end_diameter: end_diameter length: length - depth: depth - clearance_length: clearance_length - clearance_depth: clearance_depth - wedge_width: wedge_width - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance + p1: p1 + xl: xl + zl: zl Returns: - None + int """ ``` -#### cut_beam_end_profile +#### create_spline_line ```python -def cut_beam_end_profile(elements: List[int], profile_name: str, - on_start_face: bool, on_end_face: bool) ->None: - """cut beam end profile +def create_spline_line(spline_points: None) ->int: + """create spline line Parameters: - elements: elements - profile_name: profile_name - on_start_face: on_start_face - on_end_face: on_end_face + spline_points: spline_points Returns: - None + int """ ``` ## New Items -### Functions geometry_controller -#### get_round_machine_rough_part_negative_width - -```python -def get_round_machine_rough_part_negative_width(element_id: int) ->bool: - """get round machine rough part negative width - - Parameters: - element_id: element_id - - Returns: - bool - """ - -``` - -#### set_round_machine_rough_part_negative_width +### Functions utility_controller +#### get_user_int_with_default_value ```python -def set_round_machine_rough_part_negative_width(elements: List[int], value: - bool) ->None: - """set round machine rough part negative width +def get_user_int_with_default_value(message: str, default_value: int) ->int: + """get user int with default value Parameters: - elements: elements - value: value + message: message + default_value: default_value Returns: - None + int """ ``` -#### get_round_machine_rough_part_positive_width +#### get_user_double_with_default_value ```python -def get_round_machine_rough_part_positive_width(element_id: int) ->bool: - """get round machine rough part positive width +def get_user_double_with_default_value(message: str, default_value: float + ) ->float: + """get user double with default value Parameters: - element_id: element_id + message: message + default_value: default_value Returns: - bool + float """ ``` -#### set_round_machine_rough_part_positive_width +#### get_user_string_with_default_value ```python -def set_round_machine_rough_part_positive_width(elements: List[int], value: - bool) ->None: - """set round machine rough part positive width +def get_user_string_with_default_value(message: str, default_value: str) ->str: + """get user string with default value Parameters: - elements: elements - value: value + message: message + default_value: default_value Returns: - None + str """ ``` -#### get_round_machine_rough_part_negative_height +## New Items +### Classes cadwork +#### multi_layer_type ```python -def get_round_machine_rough_part_negative_height(element_id: int) ->bool: - """get round machine rough part negative height - - Parameters: - element_id: element_id +@unique +class multi_layer_type(IntEnum): + """multi layer type - Returns: - bool + Examples: + >>> cadwork.multi_layer_type.undefined + undefined """ + undefined = 0 + """""" + structure = 1 + """""" + panel = 2 + """""" + lathing = 3 + """""" + air = 4 + """""" + covering = 5 + """""" -``` - -#### set_round_machine_rough_part_negative_height - -```python -def set_round_machine_rough_part_negative_height(elements: List[int], value: - bool) ->None: - """set round machine rough part negative height - - Parameters: - elements: elements - value: value - - Returns: - None - """ + def __int__(self) ->int: + return self.value ``` -#### get_round_machine_rough_part_positive_height +## New Items +### Classes cadwork +#### ifc_2x3_element_type ```python -def get_round_machine_rough_part_positive_height(element_id: int) ->bool: - """get round machine rough part positive height - - Parameters: - element_id: element_id - - Returns: - bool - """ +class ifc_2x3_element_type: + def is_ifc_element_assembly(self) ->bool: + """is ifc element assembly -``` + Returns: + bool + """ -#### set_round_machine_rough_part_positive_height - -```python -def set_round_machine_rough_part_positive_height(elements: List[int], value: - bool) ->None: - """set round machine rough part positive height - - Parameters: - elements: elements - value: value - - Returns: - None - """ - -``` - -#### get_round_machine_rough_part_negative_length - -```python -def get_round_machine_rough_part_negative_length(element_id: int) ->bool: - """get round machine rough part negative length - - Parameters: - element_id: element_id - - Returns: - bool - """ - -``` - -#### set_round_machine_rough_part_negative_length - -```python -def set_round_machine_rough_part_negative_length(elements: List[int], value: - bool) ->None: - """set round machine rough part negative length - - Parameters: - elements: elements - value: value - - Returns: - None - """ - -``` - -#### get_round_machine_rough_part_positive_length - -```python -def get_round_machine_rough_part_positive_length(element_id: int) ->bool: - """get round machine rough part positive length - - Parameters: - element_id: element_id - - Returns: - bool - """ - -``` - -#### set_round_machine_rough_part_positive_length - -```python -def set_round_machine_rough_part_positive_length(elements: List[int], value: - bool) ->None: - """set round machine rough part positive length - - Parameters: - elements: elements - value: value - - Returns: - None - """ - -``` - -#### get_standard_element_width_from_guid - -```python -def get_standard_element_width_from_guid(standard_element_guid: str) ->float: - """get standard element width from guid - - Parameters: - standard_element_guid: standard_element_guid - - Returns: - float - """ - -``` - -#### get_standard_element_height_from_guid - -```python -def get_standard_element_height_from_guid(standard_element_guid: str) ->float: - """get standard element height from guid - - Parameters: - standard_element_guid: standard_element_guid - - Returns: - float - """ - -``` - -#### get_standard_element_length_from_guid - -```python -def get_standard_element_length_from_guid(standard_element_guid: str) ->float: - """get standard element length from guid - - Parameters: - standard_element_guid: standard_element_guid - - Returns: - float - """ - -``` - -#### get_standard_element_width_from_name - -```python -def get_standard_element_width_from_name(standard_element_name: str) ->float: - """get standard element width from name - - Parameters: - standard_element_name: standard_element_name - - Returns: - float - """ - -``` - -#### get_standard_element_height_from_name - -```python -def get_standard_element_height_from_name(standard_element_name: str) ->float: - """get standard element height from name - - Parameters: - standard_element_name: standard_element_name - - Returns: - float - """ - -``` - -#### get_standard_element_length_from_name - -```python -def get_standard_element_length_from_name(standard_element_name: str) ->float: - """get standard element length from name - - Parameters: - standard_element_name: standard_element_name - - Returns: - float - """ - -``` - -## New Items -### Functions list_controller -#### export_cover_list - -```python -def export_cover_list(element_id_list: List[int], file_path: str) ->None: - """Exports a Wall/Roof/Floor list - - Parameters: - element_id_list: element_id_list - file_path: file_path - - Returns: - None - """ - -``` - -#### export_cover_list_with_settings - -```python -def export_cover_list_with_settings(element_id_list: List[int], file_path: - str, settings_file_path: str) ->None: - """Exports a Wall/Roof/Floor list with settings file - - Parameters: - element_id_list: element_id_list - file_path: file_path - settings_file_path: settings_file_path - - Returns: - None - """ - -``` - -## New Items -### Functions material_controller -#### get_material_color_assignment_for_nodes - -```python -def get_material_color_assignment_for_nodes(a0: int) ->int: - """get material color assignment for nodes - - Parameters: - a0: a0 - - Returns: - int - """ - -``` - -#### set_material_color_assignment_for_nodes - -```python -def set_material_color_assignment_for_nodes(a0: int, a1: int) ->None: - """set material color assignment for nodes - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_material_color_assignment_for_standard_axes - -```python -def get_material_color_assignment_for_standard_axes(a0: int) ->int: - """get material color assignment for standard axes - - Parameters: - a0: a0 - - Returns: - int - """ - -``` - -#### set_material_color_assignment_for_standard_axes - -```python -def set_material_color_assignment_for_standard_axes(a0: int, a1: int) ->None: - """set material color assignment for standard axes - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_material_color_assignment_for_drillings - -```python -def get_material_color_assignment_for_drillings(a0: int) ->int: - """get material color assignment for drillings - - Parameters: - a0: a0 - - Returns: - int - """ - -``` - -#### set_material_color_assignment_for_drillings - -```python -def set_material_color_assignment_for_drillings(a0: int, a1: int) ->None: - """set material color assignment for drillings - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_material_color_assignment_for_mep_axes - -```python -def get_material_color_assignment_for_mep_axes(a0: int) ->int: - """get material color assignment for mep axes - - Parameters: - a0: a0 - - Returns: - int - """ - -``` - -#### set_material_color_assignment_for_mep_axes - -```python -def set_material_color_assignment_for_mep_axes(a0: int, a1: int) ->None: - """set material color assignment for mep axes - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_material_color_assignment_for_beams - -```python -def get_material_color_assignment_for_beams(a0: int) ->int: - """get material color assignment for beams - - Parameters: - a0: a0 - - Returns: - int - """ - -``` - -#### set_material_color_assignment_for_beams - -```python -def set_material_color_assignment_for_beams(a0: int, a1: int) ->None: - """set material color assignment for beams - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_material_color_assignment_for_panels - -```python -def get_material_color_assignment_for_panels(a0: int) ->int: - """get material color assignment for panels - - Parameters: - a0: a0 - - Returns: - int - """ - -``` - -#### set_material_color_assignment_for_panels - -```python -def set_material_color_assignment_for_panels(a0: int, a1: int) ->None: - """set material color assignment for panels - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_material_color_assignment_for_auxiliary_elements - -```python -def get_material_color_assignment_for_auxiliary_elements(a0: int) ->int: - """get material color assignment for auxiliary elements - - Parameters: - a0: a0 - - Returns: - int - """ - -``` - -#### set_material_color_assignment_for_auxiliary_elements - -```python -def set_material_color_assignment_for_auxiliary_elements(a0: int, a1: int - ) ->None: - """set material color assignment for auxiliary elements - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_material_color_assignment_for_surfaces - -```python -def get_material_color_assignment_for_surfaces(a0: int) ->int: - """get material color assignment for surfaces - - Parameters: - a0: a0 - - Returns: - int - """ - -``` - -#### set_material_color_assignment_for_surfaces - -```python -def set_material_color_assignment_for_surfaces(a0: int, a1: int) ->None: - """set material color assignment for surfaces - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_texture_color - -```python -def get_texture_color(a0: int) ->int: - """get texture color - - Parameters: - a0: a0 - - Returns: - int - """ - -``` - -#### set_texture_color - -```python -def set_texture_color(a0: int, a1: int) ->None: - """set texture color - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_texture_transparency - -```python -def get_texture_transparency(a0: int) ->int: - """get texture transparency - - Parameters: - a0: a0 - - Returns: - int - """ - -``` - -#### set_texture_transparency - -```python -def set_texture_transparency(a0: int, a1: int) ->None: - """set texture transparency - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_texture_rotation_angle - -```python -def get_texture_rotation_angle(a0: int) ->float: - """get texture rotation angle - - Parameters: - a0: a0 - - Returns: - float - """ - -``` - -#### set_texture_rotation_angle - -```python -def set_texture_rotation_angle(a0: int, a1: float) ->None: - """set texture rotation angle - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_texture_length_alignment - -```python -def get_texture_length_alignment(a0: int) ->bool: - """get texture length alignment - - Parameters: - a0: a0 - - Returns: - bool - """ - -``` - -#### set_texture_length_alignment - -```python -def set_texture_length_alignment(a0: int, a1: bool) ->None: - """set texture length alignment - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_texture_zoom_x - -```python -def get_texture_zoom_x(a0: int) ->float: - """get texture zoom x - - Parameters: - a0: a0 - - Returns: - float - """ - -``` - -#### set_texture_zoom_x - -```python -def set_texture_zoom_x(a0: int, a1: float) ->None: - """set texture zoom x - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -#### get_texture_zoom_y - -```python -def get_texture_zoom_y(a0: int) ->float: - """get texture zoom y - - Parameters: - a0: a0 - - Returns: - float - """ - -``` - -#### set_texture_zoom_y - -```python -def set_texture_zoom_y(a0: int, a1: float) ->None: - """set texture zoom y - - Parameters: - a0: a0 - a1: a1 - - Returns: - None - """ - -``` - -## New Items -### Functions scene_controller -#### is_scene_present - -```python -def is_scene_present(name: str) ->bool: - """Queries of scene with name is present - - Parameters: - name: name - - Returns: - presence of scene - """ - -``` - -#### set_group_tab_color - -```python -def set_group_tab_color(scene_group_name: str, red: int, green: int, blue: int - ) ->None: - """set group tab color - - Parameters: - scene_group_name: scene_group_name - red: red - green: green - blue: blue - - Returns: - None - """ - -``` - -#### rename_scene_group - -```python -def rename_scene_group(old_name: str, new_name: str) ->None: - """rename scene group - - Parameters: - old_name: old_name - new_name: new_name - - Returns: - None - """ - -``` - -#### get_group_index_by_name - -```python -def get_group_index_by_name(scene_group_name: str) ->int: - """get group index by name - - Parameters: - scene_group_name: scene_group_name - - Returns: - int - """ - -``` - -#### rename_scene_group_by_index - -```python -def rename_scene_group_by_index(group_index: int, new_name: str) ->None: - """rename scene group by index - - Parameters: - group_index: group_index - new_name: new_name - - Returns: - None - """ - -``` - -#### group_scences_with_name - -```python -def group_scences_with_name(a0: List[str], a1: str) ->int: - """group scences with name - - Parameters: - a0: a0 - a1: a1 - - Returns: - int - """ - -``` - -## New Items -### Functions utility_controller -#### get_3d_main_window_geometry - -```python -def get_3d_main_window_geometry() ->'window_geometry': - """get 3d main window geometry - - Returns: - window geometry - """ - -``` - -#### get_project_data_keys - -```python -def get_project_data_keys() ->List[str]: - """get project data keys - - Returns: - List[str] - """ - -``` - -## New Items -### Classes cadwork -#### coordinate_system_data - -```python -class coordinate_system_data: - - def get_p1(self) ->point_3d: - """get p1 - - Returns: - point_3d - """ - - def get_p2(self) ->point_3d: - """get p2 - - Returns: - point_3d - """ - - def get_p3(self) ->point_3d: - """get p3 - - Returns: - point_3d - """ - -``` - -## New Items -### Classes cadwork -#### ifc_predefined_type - -```python -class ifc_predefined_type: - - def is_none(self) ->bool: - """is none - - Returns: - bool - """ - - def is_ceiling(self) ->bool: - """is ceiling - - Returns: - bool - """ - - def is_cladding(self) ->bool: - """is cladding - - Returns: - bool - """ - - def is_flooring(self) ->bool: - """is flooring - - Returns: - bool - """ - - def is_insulation(self) ->bool: - """is insulation - - Returns: - bool - """ - - def is_membrane(self) ->bool: - """is membrane - - Returns: - bool - """ - - def is_roofing(self) ->bool: - """is roofing - - Returns: - bool - """ - - def is_sleeving(self) ->bool: - """is sleeving - - Returns: - bool - """ - - def is_wrapping(self) ->bool: - """is wrapping - - Returns: - bool - """ - - def is_footing_beam(self) ->bool: - """is footing beam - - Returns: - bool - """ - - def is_pad_footing(self) ->bool: - """is pad footing - - Returns: - bool - """ - - def is_pile_cap(self) ->bool: - """is pile cap - - Returns: - bool - """ - - def is_strip_footing(self) ->bool: - """is strip footing - - Returns: - bool - """ - - def is_cohesion(self) ->bool: - """is cohesion - - Returns: - bool - """ - - def is_friction(self) ->bool: - """is friction - - Returns: - bool - """ - - def is_support(self) ->bool: - """is support - - Returns: - bool - """ - - def is_balustrade(self) ->bool: - """is balustrade - - Returns: - bool - """ - - def is_guardrail(self) ->bool: - """is guardrail - - Returns: - bool - """ - - def is_handrail(self) ->bool: - """is handrail - - Returns: - bool - """ - - def is_baseslab(self) ->bool: - """is baseslab - - Returns: - bool - """ - - def is_floor(self) ->bool: - """is floor - - Returns: - bool - """ - - def is_landing(self) ->bool: - """is landing - - Returns: - bool - """ - - def is_roof(self) ->bool: - """is roof - - Returns: - bool - """ - - def is_beam(self) ->bool: - """is beam - - Returns: - bool - """ - - def is_spandrel(self) ->bool: - """is spandrel - - Returns: - bool - """ - - def is_tbeam(self) ->bool: - """is tbeam - - Returns: - bool - """ - - def is_complex(self) ->bool: - """is complex - - Returns: - bool - """ - - def is_element(self) ->bool: - """is element - - Returns: - bool - """ - - def is_partial(self) ->bool: - """is partial - - Returns: - bool - """ - - def is_provision_for_space(self) ->bool: - """is provision for space - - Returns: - bool - """ - - def is_provision_for_void(self) ->bool: - """is provision for void - - Returns: - bool - """ - - def is_column(self) ->bool: - """is column - - Returns: - bool - """ - - def is_pilaster(self) ->bool: - """is pilaster - - Returns: - bool - """ - - def is_molding(self) ->bool: - """is molding - - Returns: - bool - """ - - def is_skirtingboard(self) ->bool: - """is skirtingboard - - Returns: - bool - """ - - def is_door(self) ->bool: - """is door - - Returns: - bool - """ - - def is_gate(self) ->bool: - """is gate - - Returns: - bool - """ - - def is_trap_door(self) ->bool: - """is trap door - - Returns: - bool - """ - - def is_caisson_foundation(self) ->bool: - """is caisson foundation - - Returns: - bool - """ - - def is_brace(self) ->bool: - """is brace - - Returns: - bool - """ - - def is_chord(self) ->bool: - """is chord - - Returns: - bool - """ - - def is_collar(self) ->bool: - """is collar - - Returns: - bool - """ - - def is_member(self) ->bool: - """is member - - Returns: - bool - """ - - def is_mullion(self) ->bool: - """is mullion - - Returns: - bool - """ - - def is_plate(self) ->bool: - """is plate - - Returns: - bool - """ - - def is_post(self) ->bool: - """is post - - Returns: - bool - """ - - def is_purlin(self) ->bool: - """is purlin - - Returns: - bool - """ - - def is_rafter(self) ->bool: - """is rafter - - Returns: - bool - """ - - def is_stringer(self) ->bool: - """is stringer - - Returns: - bool - """ - - def is_strut(self) ->bool: - """is strut - - Returns: - bool - """ - - def is_stud(self) ->bool: - """is stud - - Returns: - bool - """ - - def is_bored(self) ->bool: - """is bored - - Returns: - bool - """ - - def is_driven(self) ->bool: - """is driven - - Returns: - bool - """ - - def is_jetgrouting(self) ->bool: - """is jetgrouting - - Returns: - bool - """ - - def is_curtain_panel(self) ->bool: - """is curtain panel - - Returns: - bool - """ - - def is_sheet(self) ->bool: - """is sheet - - Returns: - bool - """ - - def is_half_turn_ramp(self) ->bool: - """is half turn ramp - - Returns: - bool - """ - - def is_quarter_turn_ramp(self) ->bool: - """is quarter turn ramp - - Returns: - bool - """ - - def is_spiral_ramp(self) ->bool: - """is spiral ramp - - Returns: - bool - """ - - def is_straight_run_ramp(self) ->bool: - """is straight run ramp - - Returns: - bool - """ - - def is_two_quarter_turn_ramp(self) ->bool: - """is two quarter turn ramp - - Returns: - bool - """ - - def is_two_straight_run_ramp(self) ->bool: - """is two straight run ramp - - Returns: - bool - """ - - def is_barrel_roof(self) ->bool: - """is barrel roof - - Returns: - bool - """ - - def is_butterfly_roof(self) ->bool: - """is butterfly roof - - Returns: - bool - """ - - def is_dome_roof(self) ->bool: - """is dome roof - - Returns: - bool - """ - - def is_flat_roof(self) ->bool: - """is flat roof - - Returns: - bool - """ - - def is_freeform(self) ->bool: - """is freeform - - Returns: - bool - """ - - def is_gable_roof(self) ->bool: - """is gable roof - - Returns: - bool - """ - - def is_gambrel_roof(self) ->bool: - """is gambrel roof - - Returns: - bool - """ - - def is_hipped_gable_roof(self) ->bool: - """is hipped gable roof - - Returns: - bool - """ - - def is_hip_roof(self) ->bool: - """is hip roof - - Returns: - bool - """ - - def is_mansard_roof(self) ->bool: - """is mansard roof - - Returns: - bool - """ - - def is_pavilion_roof(self) ->bool: - """is pavilion roof - - Returns: - bool - """ - - def is_rainbow_roof(self) ->bool: - """is rainbow roof - - Returns: - bool - """ - - def is_shed_roof(self) ->bool: - """is shed roof - - Returns: - bool - """ - - def is_curved_run_stair(self) ->bool: - """is curved run stair - - Returns: - bool - """ - - def is_double_return_stair(self) ->bool: - """is double return stair - - Returns: - bool - """ - - def is_half_turn_stair(self) ->bool: - """is half turn stair - - Returns: - bool - """ - - def is_half_winding_stair(self) ->bool: - """is half winding stair - - Returns: - bool - """ - - def is_quarter_turn_stair(self) ->bool: - """is quarter turn stair - - Returns: - bool - """ - - def is_quarter_winding_stair(self) ->bool: - """is quarter winding stair - - Returns: - bool - """ - - def is_spiral_stair(self) ->bool: - """is spiral stair - - Returns: - bool - """ - - def is_straight_run_stair(self) ->bool: - """is straight run stair - - Returns: - bool - """ - - def is_three_quarter_turn_stair(self) ->bool: - """is three quarter turn stair - - Returns: - bool - """ - - def is_three_quarter_winding_stair(self) ->bool: - """is three quarter winding stair - - Returns: - bool - """ - - def is_two_curved_run_stair(self) ->bool: - """is two curved run stair - - Returns: - bool - """ - - def is_two_quarter_turn_stair(self) ->bool: - """is two quarter turn stair - - Returns: - bool - """ - - def is_two_quarter_winding_stair(self) ->bool: - """is two quarter winding stair - - Returns: - bool - """ - - def is_two_straight_run_stair(self) ->bool: - """is two straight run stair - - Returns: - bool - """ - - def is_curved(self) ->bool: - """is curved - - Returns: - bool - """ - - def is_spiral(self) ->bool: - """is spiral - - Returns: - bool - """ - - def is_straight(self) ->bool: - """is straight - - Returns: - bool - """ - - def is_winder(self) ->bool: - """is winder - - Returns: - bool - """ - - def is_elemented_wall(self) ->bool: - """is elemented wall - - Returns: - bool - """ - - def is_movable(self) ->bool: - """is movable - - Returns: - bool - """ - - def is_parapet(self) ->bool: - """is parapet - - Returns: - bool - """ - - def is_partitioning(self) ->bool: - """is partitioning - - Returns: - bool - """ - - def is_plumbing_wall(self) ->bool: - """is plumbing wall - - Returns: - bool - """ - - def is_polygonal(self) ->bool: - """is polygonal - - Returns: - bool - """ - - def is_shear(self) ->bool: - """is shear - - Returns: - bool - """ - - def is_solid_wall(self) ->bool: - """is solid wall - - Returns: - bool - """ - - def is_standard(self) ->bool: - """is standard - - Returns: - bool - """ - - def is_lightdome(self) ->bool: - """is lightdome - - Returns: - bool - """ - - def is_skylight(self) ->bool: - """is skylight - - Returns: - bool - """ - - def is_window(self) ->bool: - """is window - - Returns: - bool - """ - - def is_opening(self) ->bool: - """is opening - - Returns: - bool - """ - - def is_recess(self) ->bool: - """is recess - - Returns: - bool - """ - - def is_anchorbolt(self) ->bool: - """is anchorbolt - - Returns: - bool - """ - - def is_bolt(self) ->bool: - """is bolt - - Returns: - bool - """ - - def is_dowel(self) ->bool: - """is dowel - - Returns: - bool - """ - - def is_nail(self) ->bool: - """is nail - - Returns: - bool - """ - - def is_nail_plate(self) ->bool: - """is nail plate - - Returns: - bool - """ - - def is_rivet(self) ->bool: - """is rivet - - Returns: - bool - """ - - def is_screw(self) ->bool: - """is screw - - Returns: - bool - """ - - def is_shear_connector(self) ->bool: - """is shear connector - - Returns: - bool - """ - - def is_staple(self) ->bool: - """is staple - - Returns: - bool - """ - - def is_stud_shear_connector(self) ->bool: - """is stud shear connector - - Returns: - bool - """ - - def is_glue(self) ->bool: - """is glue - - Returns: - bool - """ - - def is_mortar(self) ->bool: - """is mortar - - Returns: - bool - """ - - def is_weld(self) ->bool: - """is weld - - Returns: - bool - """ - - def is_external(self) ->bool: - """is external - - Returns: - bool - """ - - def is_gfa(self) ->bool: - """is gfa - - Returns: - bool - """ - - def is_internal(self) ->bool: - """is internal - - Returns: - bool - """ - - def is_parking(self) ->bool: - """is parking - - Returns: - bool - """ - - def is_space(self) ->bool: - """is space - - Returns: - bool - """ - - def is_accessory_assembly(self) ->bool: - """is accessory assembly - - Returns: - bool - """ - - def is_arch(self) ->bool: - """is arch - - Returns: - bool - """ - - def is_beam_grid(self) ->bool: - """is beam grid - - Returns: - bool - """ - - def is_braced_frame(self) ->bool: - """is braced frame - - Returns: - bool - """ - - def is_girder(self) ->bool: - """is girder - - Returns: - bool - """ - - def is_reinforcement_unit(self) ->bool: - """is reinforcement unit - - Returns: - bool - """ - - def is_rigid_frame(self) ->bool: - """is rigid frame - - Returns: - bool - """ - - def is_slab_field(self) ->bool: - """is slab field - - Returns: - bool - """ - - def is_truss(self) ->bool: - """is truss - - Returns: - bool - """ - - def is_cable_ladder_segment(self) ->bool: - """is cable ladder segment - - Returns: - bool - """ - - def is_cable_tray_segment(self) ->bool: - """is cable tray segment - - Returns: - bool - """ - - def is_cable_trunking_segment(self) ->bool: - """is cable trunking segment - - Returns: - bool - """ - - def is_conduit_segment(self) ->bool: - """is conduit segment - - Returns: - bool - """ - - def is_busbar_segment(self) ->bool: - """is busbar segment - - Returns: - bool - """ - - def is_cable_segment(self) ->bool: - """is cable segment - - Returns: - bool - """ - - def is_conductor_segment(self) ->bool: - """is conductor segment - - Returns: - bool - """ - - def is_core_segment(self) ->bool: - """is core segment - - Returns: - bool - """ - - def is_flexible_segment(self) ->bool: - """is flexible segment - - Returns: - bool - """ - - def is_rigid_segment(self) ->bool: - """is rigid segment - - Returns: - bool - """ - - def is_culvert(self) ->bool: - """is culvert - - Returns: - bool - """ - - def is_gutter(self) ->bool: - """is gutter - - Returns: - bool - """ - - def is_spool(self) ->bool: - """is spool - - Returns: - bool - """ - - def is_audio_visual_outlet(self) ->bool: - """is audio visual outlet - - Returns: - bool - """ - - def is_communications_outlet(self) ->bool: - """is communications outlet - - Returns: - bool - """ - - def is_power_outlet(self) ->bool: - """is power outlet - - Returns: - bool - """ - - def is_data_outlet(self) ->bool: - """is data outlet - - Returns: - bool - """ - - def is_telephone_outlet(self) ->bool: - """is telephone outlet - - Returns: - bool - """ - - def is_anchoring(self) ->bool: - """is anchoring - - Returns: - bool - """ - - def is_edge(self) ->bool: - """is edge - - Returns: - bool - """ - - def is_ligature(self) ->bool: - """is ligature - - Returns: - bool - """ - - def is_main(self) ->bool: - """is main - - Returns: - bool - """ - - def is_punching(self) ->bool: - """is punching - - Returns: - bool - """ - - def is_ring(self) ->bool: - """is ring - - Returns: - bool - """ - - def set_none(self) ->None: - """set none - - Returns: - None - """ - - def set_ceiling(self) ->None: - """set ceiling - - Returns: - None - """ - - def set_cladding(self) ->None: - """set cladding - - Returns: - None - """ - - def set_flooring(self) ->None: - """set flooring - - Returns: - None - """ - - def set_insulation(self) ->None: - """set insulation - - Returns: - None - """ - - def set_membrane(self) ->None: - """set membrane - - Returns: - None - """ - - def set_roofing(self) ->None: - """set roofing - - Returns: - None - """ - - def set_sleeving(self) ->None: - """set sleeving - - Returns: - None - """ - - def set_wrapping(self) ->None: - """set wrapping - - Returns: - None - """ - - def set_footing_beam(self) ->None: - """set footing beam - - Returns: - None - """ - - def set_pad_footing(self) ->None: - """set pad footing - - Returns: - None - """ - - def set_pile_cap(self) ->None: - """set pile cap - - Returns: - None - """ - - def set_strip_footing(self) ->None: - """set strip footing - - Returns: - None - """ - - def set_cohesion(self) ->None: - """set cohesion - - Returns: - None - """ - - def set_friction(self) ->None: - """set friction - - Returns: - None - """ - - def set_support(self) ->None: - """set support - - Returns: - None - """ - - def set_balustrade(self) ->None: - """set balustrade - - Returns: - None - """ - - def set_guardrail(self) ->None: - """set guardrail - - Returns: - None - """ - - def set_handrail(self) ->None: - """set handrail - - Returns: - None - """ - - def set_baseslab(self) ->None: - """set baseslab - - Returns: - None - """ - - def set_floor(self) ->None: - """set floor - - Returns: - None - """ - - def set_landing(self) ->None: - """set landing - - Returns: - None - """ - - def set_roof(self) ->None: - """set roof - - Returns: - None - """ - - def set_beam(self) ->None: - """set beam - - Returns: - None - """ - - def set_hollowcore(self) ->None: - """set hollowcore - - Returns: - None - """ - - def set_joist(self) ->None: - """set joist - - Returns: - None - """ - - def set_lintel(self) ->None: - """set lintel - - Returns: - None - """ - - def set_spandrel(self) ->None: - """set spandrel - - Returns: - None - """ - - def set_tbeam(self) ->None: - """set tbeam - - Returns: - None - """ - - def set_complex(self) ->None: - """set complex - - Returns: - None - """ - - def set_element(self) ->None: - """set element - - Returns: - None - """ - - def set_partial(self) ->None: - """set partial - - Returns: - None - """ - - def set_provision_for_space(self) ->None: - """set provision for space - - Returns: - None - """ - - def set_provision_for_void(self) ->None: - """set provision for void - - Returns: - None - """ - - def set_column(self) ->None: - """set column - - Returns: - None - """ - - def set_pilaster(self) ->None: - """set pilaster - - Returns: - None - """ - - def set_molding(self) ->None: - """set molding - - Returns: - None - """ - - def set_skirtingboard(self) ->None: - """set skirtingboard - - Returns: - None - """ - - def set_door(self) ->None: - """set door - - Returns: - None - """ - - def set_gate(self) ->None: - """set gate - - Returns: - None - """ - - def set_trap_door(self) ->None: - """set trap door - - Returns: - None - """ - - def set_caisson_foundation(self) ->None: - """set caisson foundation - - Returns: - None - """ - - def set_brace(self) ->None: - """set brace - - Returns: - None - """ - - def set_chord(self) ->None: - """set chord - - Returns: - None - """ - - def set_collar(self) ->None: - """set collar - - Returns: - None - """ - - def set_member(self) ->None: - """set member - - Returns: - None - """ - - def set_mullion(self) ->None: - """set mullion - - Returns: - None - """ - - def set_plate(self) ->None: - """set plate - - Returns: - None - """ - - def set_post(self) ->None: - """set post - - Returns: - None - """ - - def set_purlin(self) ->None: - """set purlin - - Returns: - None - """ - - def set_rafter(self) ->None: - """set rafter - - Returns: - None - """ - - def set_stringer(self) ->None: - """set stringer - - Returns: - None - """ - - def set_strut(self) ->None: - """set strut - - Returns: - None - """ - - def set_stud(self) ->None: - """set stud - - Returns: - None - """ - - def set_bored(self) ->None: - """set bored - - Returns: - None - """ - - def set_driven(self) ->None: - """set driven - - Returns: - None - """ - - def set_jetgrouting(self) ->None: - """set jetgrouting - - Returns: - None - """ - - def set_curtain_panel(self) ->None: - """set curtain panel - - Returns: - None - """ - - def set_sheet(self) ->None: - """set sheet - - Returns: - None - """ - - def set_half_turn_ramp(self) ->None: - """set half turn ramp - - Returns: - None - """ - - def set_quarter_turn_ramp(self) ->None: - """set quarter turn ramp - - Returns: - None - """ - - def set_spiral_ramp(self) ->None: - """set spiral ramp - - Returns: - None - """ - - def set_straight_run_ramp(self) ->None: - """set straight run ramp - - Returns: - None - """ - - def set_two_quarter_turn_ramp(self) ->None: - """set two quarter turn ramp - - Returns: - None - """ - - def set_two_straight_run_ramp(self) ->None: - """set two straight run ramp - - Returns: - None - """ - - def set_barrel_roof(self) ->None: - """set barrel roof - - Returns: - None - """ - - def set_butterfly_roof(self) ->None: - """set butterfly roof - - Returns: - None - """ - - def set_dome_roof(self) ->None: - """set dome roof - - Returns: - None - """ - - def set_flat_roof(self) ->None: - """set flat roof - - Returns: - None - """ - - def set_freeform(self) ->None: - """set freeform - - Returns: - None - """ - - def set_gable_roof(self) ->None: - """set gable roof - - Returns: - None - """ - - def set_gambrel_roof(self) ->None: - """set gambrel roof - - Returns: - None - """ - - def set_hipped_gable_roof(self) ->None: - """set hipped gable roof - - Returns: - None - """ - - def set_hip_roof(self) ->None: - """set hip roof - - Returns: - None - """ - - def set_mansard_roof(self) ->None: - """set mansard roof - - Returns: - None - """ - - def set_pavilion_roof(self) ->None: - """set pavilion roof - - Returns: - None - """ - - def set_rainbow_roof(self) ->None: - """set rainbow roof - - Returns: - None - """ - - def set_shed_roof(self) ->None: - """set shed roof - - Returns: - None - """ - - def set_curved_run_stair(self) ->None: - """set curved run stair - - Returns: - None - """ - - def set_double_return_stair(self) ->None: - """set double return stair - - Returns: - None - """ - - def set_half_turn_stair(self) ->None: - """set half turn stair - - Returns: - None - """ - - def set_half_winding_stair(self) ->None: - """set half winding stair - - Returns: - None - """ - - def set_quarter_turn_stair(self) ->None: - """set quarter turn stair - - Returns: - None - """ - - def set_quarter_winding_stair(self) ->None: - """set quarter winding stair - - Returns: - None - """ - - def set_spiral_stair(self) ->None: - """set spiral stair - - Returns: - None - """ - - def set_straight_run_stair(self) ->None: - """set straight run stair - - Returns: - None - """ - - def set_three_quarter_turn_stair(self) ->None: - """set three quarter turn stair - - Returns: - None - """ - - def set_three_quarter_winding_stair(self) ->None: - """set three quarter winding stair - - Returns: - None - """ - - def set_two_curved_run_stair(self) ->None: - """set two curved run stair - - Returns: - None - """ - - def set_two_quarter_turn_stair(self) ->None: - """set two quarter turn stair - - Returns: - None - """ - - def set_two_quarter_winding_stair(self) ->None: - """set two quarter winding stair - - Returns: - None - """ - - def set_two_straight_run_stair(self) ->None: - """set two straight run stair - - Returns: - None - """ - - def set_curved(self) ->None: - """set curved - - Returns: - None - """ - - def set_spiral(self) ->None: - """set spiral - - Returns: - None - """ - - def set_straight(self) ->None: - """set straight - - Returns: - None - """ - - def set_winder(self) ->None: - """set winder - - Returns: - None - """ - - def set_elemented_wall(self) ->None: - """set elemented wall - - Returns: - None - """ - - def set_movable(self) ->None: - """set movable - - Returns: - None - """ - - def set_parapet(self) ->None: - """set parapet - - Returns: - None - """ - - def set_partitioning(self) ->None: - """set partitioning - - Returns: - None - """ - - def set_plumbing_wall(self) ->None: - """set plumbing wall - - Returns: - None - """ - - def set_polygonal(self) ->None: - """set polygonal - - Returns: - None - """ - - def set_shear(self) ->None: - """set shear - - Returns: - None - """ - - def set_solid_wall(self) ->None: - """set solid wall - - Returns: - None - """ - - def set_standard(self) ->None: - """set standard - - Returns: - None - """ - - def set_lightdome(self) ->None: - """set lightdome - - Returns: - None - """ - - def set_skylight(self) ->None: - """set skylight - - Returns: - None - """ - - def set_window(self) ->None: - """set window - - Returns: - None - """ - - def set_opening(self) ->None: - """set opening - - Returns: - None - """ - - def set_recess(self) ->None: - """set recess - - Returns: - None - """ - - def set_anchorbolt(self) ->None: - """set anchorbolt - - Returns: - None - """ - - def set_bolt(self) ->None: - """set bolt - - Returns: - None - """ - - def set_dowel(self) ->None: - """set dowel - - Returns: - None - """ - - def set_nail(self) ->None: - """set nail - - Returns: - None - """ - - def set_nailplate(self) ->None: - """set nailplate - - Returns: - None - """ - - def set_rivet(self) ->None: - """set rivet - - Returns: - None - """ - - def set_screw(self) ->None: - """set screw - - Returns: - None - """ - - def set_shearconnector(self) ->None: - """set shearconnector - - Returns: - None - """ - - def set_staple(self) ->None: - """set staple - - Returns: - None - """ - - def set_studshearconnector(self) ->None: - """set studshearconnector - - Returns: - None - """ - - def set_glue(self) ->None: - """set glue - - Returns: - None - """ - - def set_mortar(self) ->None: - """set mortar - - Returns: - None - """ - - def set_weld(self) ->None: - """set weld - - Returns: - None - """ - - def set_external(self) ->None: - """set external - - Returns: - None - """ - - def set_gfa(self) ->None: - """set gfa - - Returns: - None - """ - - def set_internal(self) ->None: - """set internal - - Returns: - None - """ - - def set_parking(self) ->None: - """set parking - - Returns: - None - """ - - def set_space(self) ->None: - """set space - - Returns: - None - """ - - def set_accessory_assembly(self) ->None: - """set accessory assembly - - Returns: - None - """ - - def set_arch(self) ->None: - """set arch - - Returns: - None - """ - - def set_beam_grid(self) ->None: - """set beam grid - - Returns: - None - """ - - def set_braced_frame(self) ->None: - """set braced frame - - Returns: - None - """ - - def set_girder(self) ->None: - """set girder - - Returns: - None - """ - - def set_reinforcement_unit(self) ->None: - """set reinforcement unit - - Returns: - None - """ - - def set_rigid_frame(self) ->None: - """set rigid frame - - Returns: - None - """ - - def set_slab_field(self) ->None: - """set slab field - - Returns: - None - """ - - def set_truss(self) ->None: - """set truss - - Returns: - None - """ - - def set_cable_ladder_segment(self) ->None: - """set cable ladder segment - - Returns: - None - """ - - def set_cable_tray_segment(self) ->None: - """set cable tray segment - - Returns: - None - """ - - def set_cable_trunking_segment(self) ->None: - """set cable trunking segment - - Returns: - None - """ - - def set_conduit_segment(self) ->None: - """set conduit segment - - Returns: - None - """ - - def set_busbar_segment(self) ->None: - """set busbar segment - - Returns: - None - """ - - def set_cable_segment(self) ->None: - """set cable segment - - Returns: - None - """ - - def set_conductor_segment(self) ->None: - """set conductor segment - - Returns: - None - """ - - def set_core_segment(self) ->None: - """set core segment - - Returns: - None - """ - - def set_flexible_segment(self) ->None: - """set flexible segment - - Returns: - None - """ - - def set_rigid_segment(self) ->None: - """set rigid segment - - Returns: - None - """ - - def set_culvert(self) ->None: - """set culvert - - Returns: - None - """ - - def set_gutter(self) ->None: - """set gutter - - Returns: - None - """ - - def set_spool(self) ->None: - """set spool - - Returns: - None - """ - - def set_audio_visual_outlet(self) ->None: - """set audio visual outlet - - Returns: - None - """ - - def set_communications_outlet(self) ->None: - """set communications outlet - - Returns: - None - """ - - def set_power_outlet(self) ->None: - """set power outlet - - Returns: - None - """ - - def set_data_outlet(self) ->None: - """set data outlet - - Returns: - None - """ - - def set_telephone_outlet(self) ->None: - """set telephone outlet - - Returns: - None - """ - - def set_anchoring(self) ->None: - """set anchoring - - Returns: - None - """ - - def set_edge(self) ->None: - """set edge - - Returns: - None - """ - - def set_ligature(self) ->None: - """set ligature - - Returns: - None - """ - - def set_main(self) ->None: - """set main - - Returns: - None - """ - - def set_punching(self) ->None: - """set punching - - Returns: - None - """ - - def set_ring(self) ->None: - """set ring + def set_ifc_element_assembly(self) ->None: + """set ifc element assembly Returns: None """ -``` - -## New Items -### Classes cadwork -#### multi_layer_type - -```python -@unique -class multi_layer_type(IntEnum): - """multi layer type - - Examples: - >>> cadwork.multi_layer_type.undefined - undefined - """ - undefined = 0 - """""" - structure = 1 - """""" - panel = 2 - """""" - lathing = 3 - """""" - air = 4 - """""" - covering = 5 - """""" - - def __int__(self) ->int: - return self.value - -``` - -## New Items -## New Items -### Classes cadwork -#### standard_element_type - -```python -@unique -class standard_element_type(IntEnum): - """standard element type - - Examples: - >>> cadwork.standard_element_type.beam - beam - """ - beam = 0 - """""" - panel = 2 - """""" - vba = 3 - """""" - exportSolid = 4 - """""" - container = 5 - """""" - metal = 6 - """""" - - def __int__(self) ->int: - return self.value - -``` - -## New Items -### Classes cadwork -#### window_geometry - -```python -class window_geometry: - - - class point: - - def __init__(self, x, y): - self.x = x - self.y = y - - def __init__(self): - self.bottom_left = self.point(0, 0) - self.bottom_right = self.point(0, 0) - self.top_left = self.point(0, 0) - self.top_right = self.point(0, 0) - -``` - - - - +``` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 04e4840..0254640 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -62,6 +62,7 @@ nav: - Machine Controller: documentation/machine_controller.md - Material Controller: documentation/material_controller.md - Menu Controller: documentation/menu_controller.md + - Multi Layer Cover Controller: documentation/multi_layer_cover_controller.md - Roof Controller: documentation/roof_controller.md - Scene Controller: documentation/scene_controller.md - Shop Drawing Controller: documentation/shop_drawing_controller.md diff --git a/pyproject.toml b/pyproject.toml index 742f889..3d993c6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "30.444.0" +version = "30.498.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.10" description = 'Python bindings for CwAPI3D' diff --git a/src/cadwork/ifc_2x3_element_type.pyi b/src/cadwork/ifc_2x3_element_type.pyi index 396b883..741b053 100644 --- a/src/cadwork/ifc_2x3_element_type.pyi +++ b/src/cadwork/ifc_2x3_element_type.pyi @@ -1,5 +1,5 @@ class ifc_2x3_element_type: - + def is_none(self) -> bool: """is none @@ -407,9 +407,23 @@ class ifc_2x3_element_type: """ def __repr__(self) -> str: - """ repr + """ repr Returns: str """ + def is_ifc_element_assembly(self) -> bool: + """is ifc element assembly + + Returns: + bool + """ + + def set_ifc_element_assembly(self) -> None: + """set ifc element assembly + + Returns: + None + """ + diff --git a/src/cadwork/multi_layer_type.pyi b/src/cadwork/multi_layer_type.pyi new file mode 100644 index 0000000..a0128f1 --- /dev/null +++ b/src/cadwork/multi_layer_type.pyi @@ -0,0 +1,27 @@ +from enum import IntEnum, unique + + +@unique +class multi_layer_type(IntEnum): + """multi layer type + + Examples: + >>> cadwork.multi_layer_type.undefined + undefined + """ + undefined = 0 + """""" + structure = 1 + """""" + panel = 2 + """""" + lathing = 3 + """""" + air = 4 + """""" + covering = 5 + """""" + + def __int__(self) -> int: + return self.value + diff --git a/src/dimension_controller/__init__.pyi b/src/dimension_controller/__init__.pyi index 3543327..1fb805e 100644 --- a/src/dimension_controller/__init__.pyi +++ b/src/dimension_controller/__init__.pyi @@ -156,8 +156,6 @@ def get_default_anchor_length(element: int) -> float: double """ -from cadwork import point_3d - def get_distance(element: int) -> point_3d: """Get the distance to the dimension reference point. The point is in the plane of the dimensioning. @@ -209,3 +207,14 @@ def get_segment_distance(element: int, segment_index: int) -> float: distance """ +def get_segment_direction(element: int, segment_index: int) -> point_3d: + """get segment direction + + Parameters: + element: element + segment_index: segment_index + + Returns: + point_3d + """ + diff --git a/src/element_controller/__init__.pyi b/src/element_controller/__init__.pyi index 270b1a5..3296bb1 100644 --- a/src/element_controller/__init__.pyi +++ b/src/element_controller/__init__.pyi @@ -1924,4 +1924,42 @@ def cut_beam_end_profile(elements: List[int], profile_name: str, on_start_face: None """ +def create_truncated_cone_beam_points(start_diameter: float, end_diameter: float, p1: point_3d, p2: point_3d, p3: point_3d) -> int: + """create truncated cone beam points + + Parameters: + start_diameter: start_diameter + end_diameter: end_diameter + p1: p1 + p2: p2 + p3: p3 + + Returns: + int + """ + +def create_truncated_cone_beam_vectors(start_diameter: float, end_diameter: float, length: float, p1: point_3d, xl: point_3d, zl: point_3d) -> int: + """create truncated cone beam vectors + + Parameters: + start_diameter: start_diameter + end_diameter: end_diameter + length: length + p1: p1 + xl: xl + zl: zl + + Returns: + int + """ + +def create_spline_line(spline_points: None) -> int: + """create spline line + + Parameters: + spline_points: spline_points + + Returns: + int + """ diff --git a/src/utility_controller/__init__.pyi b/src/utility_controller/__init__.pyi index a6249ad..43ddc4a 100644 --- a/src/utility_controller/__init__.pyi +++ b/src/utility_controller/__init__.pyi @@ -1057,3 +1057,36 @@ def get_project_data_keys() -> List[str]: List[str] """ +def get_user_int_with_default_value(message: str, default_value: int) -> int: + """get user int with default value + + Parameters: + message: message + default_value: default_value + + Returns: + int + """ + +def get_user_double_with_default_value(message: str, default_value: float) -> float: + """get user double with default value + + Parameters: + message: message + default_value: default_value + + Returns: + float + """ + +def get_user_string_with_default_value(message: str, default_value: str) -> str: + """get user string with default value + + Parameters: + message: message + default_value: default_value + + Returns: + str + """ + From f0d2c82118366330f8eb18583032377a2cefcaff Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Thu, 23 May 2024 17:12:39 +0200 Subject: [PATCH 02/52] chore: format markdown --- docs/documentation/enums.md | 3 +++ docs/release_notes.md | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/docs/documentation/enums.md b/docs/documentation/enums.md index 7591831..225f593 100644 --- a/docs/documentation/enums.md +++ b/docs/documentation/enums.md @@ -1,3 +1,5 @@ +# Enum types + ## Node symbols ::: src.cadwork.node_symbol @@ -59,6 +61,7 @@ show_source: true ## Multi Layer Cover Type + ::: src.cadwork.multi_layer_type rendering: show_root_heading: false diff --git a/docs/release_notes.md b/docs/release_notes.md index 4ab9ae6..c2de160 100644 --- a/docs/release_notes.md +++ b/docs/release_notes.md @@ -1,5 +1,9 @@ +# change log build 30.498.0 + ## New Items + ### Functions dimension_controller + #### get_segment_direction ```python @@ -17,7 +21,9 @@ def get_segment_direction(element: int, segment_index: int) ->point_3d: ``` ## New Items + ### Functions element_controller + #### create_truncated_cone_beam_points ```python @@ -75,7 +81,9 @@ def create_spline_line(spline_points: None) ->int: ``` ## New Items + ### Functions utility_controller + #### get_user_int_with_default_value ```python @@ -126,7 +134,9 @@ def get_user_string_with_default_value(message: str, default_value: str) ->str: ``` ## New Items + ### Classes cadwork + #### multi_layer_type ```python @@ -157,7 +167,9 @@ class multi_layer_type(IntEnum): ``` ## New Items + ### Classes cadwork + #### ifc_2x3_element_type ```python From e846be49854af0030995a1f978645ff95fbfd0f7 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Wed, 10 Jul 2024 15:21:20 +0200 Subject: [PATCH 03/52] chore: Update package to 30.0.533 --- docs/documentation/window_geometry.md | 6 + docs/release_notes.md | 170 ++++------------------ mkdocs.yml | 1 + pyproject.toml | 2 +- src/cadwork/point_3d.pyi | 14 +- src/cadwork/projection_type.pyi | 4 +- src/cadwork/window_geometry.pyi | 42 +++--- src/element_controller/__init__.pyi | 33 +++++ src/visualization_controller/__init__.pyi | 14 +- 9 files changed, 116 insertions(+), 170 deletions(-) create mode 100644 docs/documentation/window_geometry.md diff --git a/docs/documentation/window_geometry.md b/docs/documentation/window_geometry.md new file mode 100644 index 0000000..659170d --- /dev/null +++ b/docs/documentation/window_geometry.md @@ -0,0 +1,6 @@ +# window_geometry + +::: src.cadwork.window_geometry + rendering: + show_root_heading: true + show_source: true \ No newline at end of file diff --git a/docs/release_notes.md b/docs/release_notes.md index c2de160..b3eaa13 100644 --- a/docs/release_notes.md +++ b/docs/release_notes.md @@ -1,191 +1,73 @@ -# change log build 30.498.0 - -## New Items - -### Functions dimension_controller - -#### get_segment_direction - -```python -def get_segment_direction(element: int, segment_index: int) ->point_3d: - """get segment direction - - Parameters: - element: element - segment_index: segment_index - - Returns: - point_3d - """ - -``` - ## New Items - ### Functions element_controller - -#### create_truncated_cone_beam_points +#### unjoin_elements ```python -def create_truncated_cone_beam_points(start_diameter: float, end_diameter: - float, p1: point_3d, p2: point_3d, p3: point_3d) ->int: - """create truncated cone beam points +def unjoin_elements(element_id_list: List[int]) ->bool: + """unjoin elements Parameters: - start_diameter: start_diameter - end_diameter: end_diameter - p1: p1 - p2: p2 - p3: p3 + element_id_list: element_id_list Returns: - int + bool """ ``` -#### create_truncated_cone_beam_vectors +#### unjoin_top_level_elements ```python -def create_truncated_cone_beam_vectors(start_diameter: float, end_diameter: - float, length: float, p1: point_3d, xl: point_3d, zl: point_3d) ->int: - """create truncated cone beam vectors +def unjoin_top_level_elements(element_id_list: List[int]) ->bool: + """unjoin top level elements Parameters: - start_diameter: start_diameter - end_diameter: end_diameter - length: length - p1: p1 - xl: xl - zl: zl + element_id_list: element_id_list Returns: - int + bool """ ``` -#### create_spline_line - -```python -def create_spline_line(spline_points: None) ->int: - """create spline line - - Parameters: - spline_points: spline_points - - Returns: - int - """ - -``` - -## New Items - -### Functions utility_controller - -#### get_user_int_with_default_value +#### set_element_group_single_select_mode ```python -def get_user_int_with_default_value(message: str, default_value: int) ->int: - """get user int with default value - - Parameters: - message: message - default_value: default_value +def set_element_group_single_select_mode() ->None: + """set element group single select mode Returns: - int + None """ ``` -#### get_user_double_with_default_value +#### set_element_group_multi_select_mode ```python -def get_user_double_with_default_value(message: str, default_value: float - ) ->float: - """get user double with default value - - Parameters: - message: message - default_value: default_value +def set_element_group_multi_select_mode() ->None: + """set element group multi select mode Returns: - float + None """ ``` -#### get_user_string_with_default_value +## New Items +### Functions visualization_controller +#### enter_working_plane ```python -def get_user_string_with_default_value(message: str, default_value: str) ->str: - """get user string with default value +def enter_working_plane(plane_normal: point_3d, plane_origin: point_3d) ->None: + """enter working plane Parameters: - message: message - default_value: default_value + plane_normal: plane_normal + plane_origin: plane_origin Returns: - str + None """ ``` - -## New Items - -### Classes cadwork - -#### multi_layer_type - -```python -@unique -class multi_layer_type(IntEnum): - """multi layer type - - Examples: - >>> cadwork.multi_layer_type.undefined - undefined - """ - undefined = 0 - """""" - structure = 1 - """""" - panel = 2 - """""" - lathing = 3 - """""" - air = 4 - """""" - covering = 5 - """""" - - def __int__(self) ->int: - return self.value - -``` - -## New Items - -### Classes cadwork - -#### ifc_2x3_element_type - -```python -class ifc_2x3_element_type: - def is_ifc_element_assembly(self) ->bool: - """is ifc element assembly - - Returns: - bool - """ - - def set_ifc_element_assembly(self) ->None: - """set ifc element assembly - - Returns: - None - """ - -``` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 0254640..8d1f11f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -52,6 +52,7 @@ nav: - Camera: documentation/camera_data.md - Layer Settings: documentation/layer_settings.md - Text Object Options: documentation/text_object_options.md + - Window Geometry: documentation/window_geometry.md - Connector Axis Controller: documentation/connector_axis_controller.md - Dimension Controller: documentation/dimension_controller.md - Element Controller: documentation/element_controller.md diff --git a/pyproject.toml b/pyproject.toml index 3d993c6..8c7a2b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "30.498.0" +version = "30.0.533" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.10" description = 'Python bindings for CwAPI3D' diff --git a/src/cadwork/point_3d.pyi b/src/cadwork/point_3d.pyi index d782233..45c5cf9 100644 --- a/src/cadwork/point_3d.pyi +++ b/src/cadwork/point_3d.pyi @@ -1,7 +1,17 @@ class point_3d: + def __init__(self, x: float, y: float, z: float): + """ + Initialize an instance of a point_3d. + + Parameters: + x (float): The x-coordinate of the point. + y (float): The y-coordinate of the point. + z (float): The z-coordinate of the point. + """ + self.x = x + self.y = y + self.z = z - def __init__(self, x: float, y: float, z: float) -> None: ... - def dot(self, p: 'point_3d') -> float: """dot diff --git a/src/cadwork/projection_type.pyi b/src/cadwork/projection_type.pyi index 7edbd64..1ddb0f2 100644 --- a/src/cadwork/projection_type.pyi +++ b/src/cadwork/projection_type.pyi @@ -9,9 +9,9 @@ class projection_type(IntEnum): >>> cadwork.projection_type.Perspective Perspective """ - Perspective = 1 + Perspective = 0 """""" - Orthographic = 2 + Orthographic = 1 """""" def __int__(self) -> int: diff --git a/src/cadwork/window_geometry.pyi b/src/cadwork/window_geometry.pyi index 82f83c2..97c12d2 100644 --- a/src/cadwork/window_geometry.pyi +++ b/src/cadwork/window_geometry.pyi @@ -1,23 +1,27 @@ -class point: - def __init__(self, x, y): +class Point: + def __init__(self, x: float, y: float): + """ + Initialize a point with x and y coordinates. + + Args: + x (float): The x-coordinate. + y (float): The y-coordinate. + """ self.x = x self.y = y -class window_geometry: - def __init__(self): - self.bottom_left = self.point(0, 0) - self.bottom_right = self.point(0, 0) - self.top_left = self.point(0, 0) - self.top_right = self.point(0, 0) - - @property - def bottom_left(self) -> point: ... - - @property - def bottom_right(self) -> point: ... - - @property - def top_left(self) -> point: ... +class WindowGeometry: + def __init__(self, bottom_left: Point, bottom_right: Point, top_left: Point, top_right: Point): + """ + Initialize window geometry with points defining the window corners. - @property - def top_right(self) -> point: ... \ No newline at end of file + Args: + bottom_left (Point): The bottom left corner of the window. + bottom_right (Point): The bottom right corner of the window. + top_left (Point): The top left corner of the window. + top_right (Point): The top right corner of the window. + """ + self.bottom_left = bottom_left + self.bottom_right = bottom_right + self.top_left = top_left + self.top_right = top_right \ No newline at end of file diff --git a/src/element_controller/__init__.pyi b/src/element_controller/__init__.pyi index 3296bb1..7ba197f 100644 --- a/src/element_controller/__init__.pyi +++ b/src/element_controller/__init__.pyi @@ -1963,3 +1963,36 @@ def create_spline_line(spline_points: None) -> int: int """ +def unjoin_elements(element_id_list: List[int]) ->bool: + """unjoin elements + + Parameters: + element_id_list: element_id_list + + Returns: + bool + """ + +def unjoin_top_level_elements(element_id_list: List[int]) ->bool: + """unjoin top level elements + + Parameters: + element_id_list: element_id_list + + Returns: + bool + """ + +def set_element_group_single_select_mode() ->None: + """set element group single select mode + + Returns: + None + """ + +def set_element_group_multi_select_mode() ->None: + """set element group multi select mode + + Returns: + None + """ \ No newline at end of file diff --git a/src/visualization_controller/__init__.pyi b/src/visualization_controller/__init__.pyi index e8b63d7..a9afc60 100644 --- a/src/visualization_controller/__init__.pyi +++ b/src/visualization_controller/__init__.pyi @@ -171,7 +171,7 @@ def set_material(element_id_list: List[int], element_id: int) -> None: None """ -def save_visibility_state() -> visibility_state: +def save_visibility_state() -> "visibility_state": """Saves the visibility state Returns: @@ -188,7 +188,7 @@ def restore_visibility_state(state: None) -> None: None """ -def save_activation_state() -> activation_state: +def save_activation_state() -> "activation_state": """Saves the activation state Returns: @@ -501,3 +501,13 @@ def is_cadwork_window_in_dark_mode() -> bool: window is in dark mode """ +def enter_working_plane(plane_normal: point_3d, plane_origin: point_3d) ->None: + """enter working plane + + Parameters: + plane_normal: plane_normal + plane_origin: plane_origin + + Returns: + None + """ From dd37c6015582709e34772768e369ff2998294f41 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Mon, 22 Jul 2024 08:42:03 +0200 Subject: [PATCH 04/52] refact: argument descriptions in `element_controller`, and `geometry_controller` --- src/element_controller/__init__.pyi | 307 +++++++++++----------- src/geometry_controller/__init__.pyi | 365 +++++++++++++++++---------- 2 files changed, 377 insertions(+), 295 deletions(-) diff --git a/src/element_controller/__init__.pyi b/src/element_controller/__init__.pyi index 7ba197f..79253e5 100644 --- a/src/element_controller/__init__.pyi +++ b/src/element_controller/__init__.pyi @@ -4,17 +4,7 @@ from cadwork import element_module_properties from cadwork import facet_list from cadwork import point_3d from cadwork import text_object_options -from cadwork import coordinate_system_data - -def get_last_error(error_code: int) -> str: - """Gets the last error - - Parameters: - error_code: error_code - - Returns: - error string - """ +from cadwork.coordinate_system_data import coordinate_system_data def delete_elements(element_id_list: List[int]) -> None: """delete elements @@ -563,7 +553,7 @@ def clear_errors() -> None: """ def glide_elements(element_i_ds: List[int], glide_point: point_3d) -> None: - """Glides elements + """glide elements Parameters: element_i_ds: element_i_ds @@ -669,18 +659,6 @@ def create_auto_container_from_standard_with_reference(elements: List[int], outp int """ -def slice_elements_with_plane_and_get_new_elements(a0: int, a1: point_3d, a2: float) -> List[int]: - """slice elements with plane and get new elements - - Parameters: - a0: a0 - a1: a1 - a2: a2 - - Returns: - List[int] - """ - def create_surface(surface_vertices: List[point_3d]) -> int: """create surface @@ -691,66 +669,56 @@ def create_surface(surface_vertices: List[point_3d]) -> int: int """ -def convert_circular_beam_to_drilling(elements: List[int]) -> None: - """converts circular/round beams into drillings - - Parameters: - elements: elements - - Returns: - None - """ - -def stretch_start_facet(a0: List[int], a1: point_3d) -> None: +def stretch_start_facet(elements: List[int], stretch_vector: point_3d) -> None: """stretch start facet Parameters: - a0: a0 - a1: a1 + elements: elements + stretch_vector: a vector that defines the stretch direction and distance Returns: None """ -def stretch_end_facet(a0: List[int], a1: point_3d) -> None: +def stretch_end_facet(elements: List[int], stretch_vector: point_3d) -> None: """stretch end facet Parameters: - a0: a0 - a1: a1 + elements: elements + stretch_vector: a vector that defines the stretch direction and distance Returns: None """ -def set_export_solid_contents(a0: int, a1: List[int]) -> None: +def set_export_solid_contents(export_solid_id: int, element_i_ds: List[int]) -> None: """set export solid contents Parameters: - a0: a0 - a1: a1 + export_solid_id: export_solid_id + element_i_ds: element_i_ds Returns: None """ -def set_container_contents(a0: int, a1: List[int]) -> None: +def set_container_contents(container_id: int, element_i_ds: List[int]) -> None: """set container contents Parameters: - a0: a0 - a1: a1 + container_id: container_id + element_i_ds: element_i_ds Returns: None """ -def set_parent_opening_variants_opening_angle(a0: List[int], a1: float) -> None: +def set_parent_opening_variants_opening_angle(element_i_ds: List[int], angle: float) -> None: """set parent opening variants opening angle Parameters: - a0: a0 - a1: a1 + element_i_ds: element_i_ds + angle: angle Returns: None @@ -781,7 +749,7 @@ def mirror_copy_elements(elements: List[int], plane: point_3d, plane_distance: f """ def reset_element_cadwork_guid(element_id: int) -> None: - """sets the Cadwork Guid of an element to NULL + """reset element cadwork guid Parameters: element_id: element_id @@ -959,86 +927,86 @@ def convert_container_to_container_block(elements: List[int]) -> None: None """ -def create_bounding_box_local(a0: int, a1: List[int]) -> int: +def create_bounding_box_local(reference_element: int, elements: List[int]) -> int: """create bounding box local Parameters: - a0: a0 - a1: a1 + reference_element: reference_element + elements: elements Returns: int """ -def create_bounding_box_global(a1: List[int]) -> int: +def create_bounding_box_global(elements: List[int]) -> int: """create bounding box global Parameters: - a1: a1 + elements: elements Returns: int """ -def convert_auxiliary_to_panel(a0: List[int]) -> None: +def convert_auxiliary_to_panel(elements: List[int]) -> None: """convert auxiliary to panel Parameters: - a0: a0 + elements: elements Returns: None """ -def convert_auxiliary_to_beam(a0: List[int]) -> None: +def convert_auxiliary_to_beam(elements: List[int]) -> None: """convert auxiliary to beam Parameters: - a0: a0 + elements: elements Returns: None """ -def auto_set_rough_volume_situation(a0: List[int]) -> None: +def auto_set_rough_volume_situation(elements: List[int]) -> None: """auto set rough volume situation Parameters: - a0: a0 + elements: elements Returns: None """ -def rough_volume_situation_manual(a0: int, a1: List[int], a2: List[int]) -> None: +def rough_volume_situation_manual(cover: int, add_partner: List[int], remove_partner: List[int]) -> None: """rough volume situation manual Parameters: - a0: a0 - a1: a1 - a2: a2 + cover: cover + add_partner: add_partner + remove_partner: remove_partner Returns: None """ -def auto_set_parts_situation(a0: List[int]) -> None: +def auto_set_parts_situation(elements: List[int]) -> None: """auto set parts situation Parameters: - a0: a0 + elements: elements Returns: None """ -def parts_situation_manual(a0: int, a1: List[int], a2: List[int]) -> None: +def parts_situation_manual(cover: int, add_childs: List[int], remove_childs: List[int]) -> None: """parts situation manual Parameters: - a0: a0 - a1: a1 - a2: a2 + cover: cover + add_childs: add_childs + remove_childs: remove_childs Returns: None @@ -1058,12 +1026,12 @@ def activate_parts_without_situation() -> List[int]: List[int] """ -def add_elements_to_detail(a0: List[int], a1: int) -> None: +def add_elements_to_detail(elements: List[int], detail: int) -> None: """add elements to detail Parameters: - a0: a0 - a1: a1 + elements: The list of elements to be added to the detail + detail: The ID of the detail Returns: None @@ -1107,70 +1075,70 @@ def start_element_module_calculation_silently(covers: List[int]) -> None: None """ -def replace_physical_drillings_with_drilling_axes(a0: List[int], a1: float, a2: float) -> List[int]: +def replace_physical_drillings_with_drilling_axes(elements: List[int], mininum_diameter: float, maximum_diameter: float) -> List[int]: """replace physical drillings with drilling axes Parameters: - a0: a0 - a1: a1 - a2: a2 + elements: elements + mininum_diameter: mininum_diameter + maximum_diameter: maximum_diameter Returns: List[int] """ -def cut_element_with_processing_group(a0: int, a1: int) -> None: +def cut_element_with_processing_group(soft_element: int, processing: int) -> None: """cut element with processing group Parameters: - a0: a0 - a1: a1 + soft_element: soft_element + processing: processing Returns: None """ -def add_element_to_detail(a0: List[int], a1: int) -> None: +def add_element_to_detail(elements: List[int], detail: int) -> None: """add element to detail Parameters: - a0: a0 - a1: a1 + elements: elements + detail: detail Returns: None """ -def convert_elements_to_auxiliary_elements(a0: List[int]) -> None: +def convert_elements_to_auxiliary_elements(elements: List[int]) -> None: """convert elements to auxiliary elements Parameters: - a0: a0 + elements: elements Returns: None """ -def create_circular_axis_points(a0: float, a1: point_3d, a2: point_3d) -> int: +def create_circular_axis_points(diameter: float, p1: point_3d, p2: point_3d) -> int: """create circular axis points Parameters: - a0: a0 - a1: a1 - a2: a2 + diameter: diameter + p1: p1 + p2: p2 Returns: int """ -def create_circular_axis_vector(a0: float, a1: float, a2: point_3d, a3: point_3d) -> int: +def create_circular_axis_vector(diameter: float, length: float, p1: point_3d, xl: point_3d) -> int: """create circular axis vector Parameters: - a0: a0 - a1: a1 - a2: a2 - a3: a3 + diameter: diameter + length: length + p1: p1 + xl: xl Returns: int @@ -1189,96 +1157,96 @@ def create_polygon_panel(polygon_vertices: List[point_3d], thickness: float, xl: int """ -def cut_elements_with_overmeasure(a0: List[int], a1: List[int]) -> None: +def cut_elements_with_overmeasure(hard_elements: List[int], soft_elements: List[int]) -> None: """cut elements with overmeasure Parameters: - a0: a0 - a1: a1 + hard_elements: hard_elements + soft_elements: soft_elements Returns: None """ -def cut_log_corner_joint(a0: str, a1: List[int]) -> None: +def cut_log_corner_joint(settings_name: str, elements: List[int]) -> None: """cut log corner joint Parameters: - a0: a0 - a1: a1 + settings_name: settings_name + elements: elements Returns: None """ -def get_edge_selection(a0: List[int]) -> edge_list: +def get_edge_selection(elements: List[int]) -> edge_list: """get edge selection Parameters: - a0: a0 + elements: elements Returns: edge_list """ -def get_facets_with_lasso(a0: List[int]) -> facet_list: +def get_facets_with_lasso(elements: List[int]) -> facet_list: """get facets with lasso Parameters: - a0: a0 + elements: elements Returns: facet_list """ -def create_standard_element_from_guid_points(a0: str, a1: point_3d, a2: point_3d, a3: point_3d) -> int: +def create_standard_element_from_guid_points(guid: str, p1: point_3d, p2: point_3d, p3: point_3d) -> int: """create standard element from guid points Parameters: - a0: a0 - a1: a1 - a2: a2 - a3: a3 + guid: guid + p1: p1 + p2: p2 + p3: p3 Returns: int """ -def create_standard_element_from_guid_vectors(a0: str, a1: float, a2: point_3d, a3: point_3d, a4: point_3d) -> int: +def create_standard_element_from_guid_vectors(guid: str, length: float, p1: point_3d, xl: point_3d, zl: point_3d) -> int: """create standard element from guid vectors Parameters: - a0: a0 - a1: a1 - a2: a2 - a3: a3 - a4: a4 + guid: guid + length: length + p1: p1 + xl: xl + zl: zl Returns: int """ -def fillet_edge(a0: int, a1: point_3d, a2: point_3d, a3: float) -> None: +def fillet_edge(element_id: int, edge_start: point_3d, edge_end: point_3d, radius: float) -> None: """fillet edge Parameters: - a0: a0 - a1: a1 - a2: a2 - a3: a3 + element_id: element_id + edge_start: edge_start + edge_end: edge_end + radius: radius Returns: None """ -def chamfer_edge(a0: int, a1: point_3d, a2: point_3d, a3: float) -> None: +def chamfer_edge(element_id: int, edge_start: point_3d, edge_end: point_3d, length: float) -> None: """chamfer edge Parameters: - a0: a0 - a1: a1 - a2: a2 - a3: a3 + element_id: element_id + edge_start: edge_start + edge_end: edge_end + length: length Returns: None @@ -1315,7 +1283,7 @@ def convert_surfaces_to_volume(elements: List[int]) -> int: """ def cut_corner_lap(elements: List[int], depth: float, clearance_base: float, clearance_side: float, backcut: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cuts a corner-lap with specific parameters + """cut corner lap Parameters: elements: elements @@ -1332,7 +1300,7 @@ def cut_corner_lap(elements: List[int], depth: float, clearance_base: float, cle """ def cut_t_lap(elements: List[int], depth: float, clearance_base: float, clearance_side: float, backcut: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cuts a t-lap with specific parameters + """cut t lap Parameters: elements: elements @@ -1349,7 +1317,7 @@ def cut_t_lap(elements: List[int], depth: float, clearance_base: float, clearanc """ def cut_cross_lap(elements: List[int], depth: float, clearance_base: float, clearance_side: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cuts a cross-lap with specific parameters + """cut cross lap Parameters: elements: elements @@ -1365,7 +1333,7 @@ def cut_cross_lap(elements: List[int], depth: float, clearance_base: float, clea """ def delete_processes_keep_cutting_bodies(elements: List[int], keep_cutting_elements_only: bool) -> List[int]: - """Gets the cutting bodies of all processes (and deletes processes), like Ctrl+D Action + """delete processes keep cutting bodies Parameters: elements: elements @@ -1376,7 +1344,7 @@ def delete_processes_keep_cutting_bodies(elements: List[int], keep_cutting_eleme """ def cut_double_tenon(elements: List[int], depth1: float, depth2: float, clearance: float, backcut: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cuts a double tenon with specific parameters + """cut double tenon Parameters: elements: elements @@ -1392,19 +1360,19 @@ def cut_double_tenon(elements: List[int], depth1: float, depth2: float, clearanc None """ -def get_coordinate_system_data_nesting_child(nesting_parent_id: int, nesting_child_id: int) -> coordinate_system_data: - """Get the coordinate system of nesting child +def get_coordinate_system_data_nesting_child(nesting_parent_id: int, nesting_child_id: int) -> 'coordinate_system_data': + """get coordinate system data nesting child Parameters: nesting_parent_id: nesting_parent_id nesting_child_id: nesting_child_id Returns: - A global element coordinate-system of the nested child element consisting of a Point1, a Point2 and a Point3. You can get the local placement by subtracting the parent coordinate-system with child coordinate-system + coordinate_system_data """ def cut_half_lap(elements: List[int], length: float, clearance_length: float, clearance_depth: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cuts a half lap joint with specific parameters + """cut half lap Parameters: elements: elements @@ -1420,7 +1388,7 @@ def cut_half_lap(elements: List[int], length: float, clearance_length: float, cl """ def cut_simple_scarf(elements: List[int], length: float, depth: float, clearance_length: float, clearance_depth: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cuts a simple scarf joint with specific parameters + """cut simple scarf Parameters: elements: elements @@ -1437,7 +1405,7 @@ def cut_simple_scarf(elements: List[int], length: float, depth: float, clearance """ def cut_diagonal_cut(elements: List[int], length: float, clearance_length: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cuts a diagonal cut joint with specific parameters + """cut diagonal cut Parameters: elements: elements @@ -1565,11 +1533,11 @@ def get_standard_panel_list() -> List[str]: List[str] """ -def get_variant_sibling_element_ids(a0: int) -> List[int]: +def get_variant_sibling_element_ids(element_id: int) -> List[int]: """get variant sibling element ids Parameters: - a0: a0 + element_id: element_id Returns: List[int] @@ -1706,22 +1674,22 @@ def get_element_cadwork_guid(element_id: int) -> str: str """ -def get_bounding_box_vertices_local(a0: int, a1: List[int]) -> List[point_3d]: +def get_bounding_box_vertices_local(reference_element: int, elements: List[int]) -> List[point_3d]: """get bounding box vertices local Parameters: - a0: a0 - a1: a1 + reference_element: reference_element + elements: elements Returns: List[point_3d] """ -def get_bounding_box_vertices_global(a0: List[int]) -> List[point_3d]: +def get_bounding_box_vertices_global(elements: List[int]) -> List[point_3d]: """get bounding box vertices global Parameters: - a0: a0 + elements: elements Returns: List[point_3d] @@ -1734,11 +1702,11 @@ def get_all_nesting_raw_parts() -> List[int]: List[int] """ -def get_joined_elements(a0: int) -> List[int]: +def get_joined_elements(element_id: int) -> List[int]: """get joined elements Parameters: - a0: a0 + element_id: element_id Returns: List[int] @@ -1754,11 +1722,11 @@ def check_element_duplicates(elements: List[int]) -> List[int]: List[int] """ -def get_elements_in_contact(a0: int) -> List[int]: +def get_elements_in_contact(element: int) -> List[int]: """get elements in contact Parameters: - a0: a0 + element: element Returns: List[int] @@ -1778,7 +1746,7 @@ def create_text_object_with_options(position: point_3d, xl: point_3d, zl: point_ """ def convert_surfaces_to_roof_surfaces(elements: List[int], roof_name: str) -> None: - """converts surfaces to roof surfaces + """convert surfaces to roof surfaces Parameters: elements: elements @@ -1789,20 +1757,20 @@ def convert_surfaces_to_roof_surfaces(elements: List[int], roof_name: str) -> No """ def start_standard_element_dialog(standard_element_type: None) -> str: - """Starts the standard element dialogue based on the chosen element type + """start standard element dialog Parameters: standard_element_type: standard_element_type Returns: - Returns guid of selected standard element if item is valid, else null + str """ -def remove_standard_connector_axis(a0: str) -> None: +def remove_standard_connector_axis(guid: str) -> None: """remove standard connector axis Parameters: - a0: a0 + guid: guid Returns: None @@ -1963,7 +1931,7 @@ def create_spline_line(spline_points: None) -> int: int """ -def unjoin_elements(element_id_list: List[int]) ->bool: +def unjoin_elements(element_id_list: List[int]) -> bool: """unjoin elements Parameters: @@ -1973,7 +1941,7 @@ def unjoin_elements(element_id_list: List[int]) ->bool: bool """ -def unjoin_top_level_elements(element_id_list: List[int]) ->bool: +def unjoin_top_level_elements(element_id_list: List[int]) -> bool: """unjoin top level elements Parameters: @@ -1983,16 +1951,39 @@ def unjoin_top_level_elements(element_id_list: List[int]) ->bool: bool """ -def set_element_group_single_select_mode() ->None: +def set_element_group_single_select_mode() -> None: """set element group single select mode Returns: None """ -def set_element_group_multi_select_mode() ->None: +def set_element_group_multi_select_mode() -> None: """set element group multi select mode Returns: None - """ \ No newline at end of file + """ + +def convert_circular_beam_to_drilling(elements: List[int]) -> None: + """convert circular beam to drilling + + Parameters: + elements: elements + + Returns: + None + """ + +def slice_elements_with_plane_and_get_new_elements(element: int, cut_plane_normal_vector: point_3d, distance_from_global_origin: float) -> List[int]: + """slice elements with plane and get new elements + + Parameters: + element: The ID of the element to be sliced + cut_plane_normal_vector: The normal vector of the cutting plane + distance_from_global_origin: list of IDs of the new elements created by the slicing operation + + Returns: + List[int] + """ + diff --git a/src/geometry_controller/__init__.pyi b/src/geometry_controller/__init__.pyi index 516f4de..7140043 100644 --- a/src/geometry_controller/__init__.pyi +++ b/src/geometry_controller/__init__.pyi @@ -2,18 +2,9 @@ from typing import List from cadwork import facet_list from cadwork import point_3d -def get_last_error(error_code: int) -> str: - """Gets the last error - - Parameters: - error_code: error_code - - Returns: - error string - """ def rotate_height_axis_90(element_id_list: List[int]) -> None: - """Rotates the element height axis 90 degrees + """rotate height axis 90 Parameters: element_id_list: element_id_list @@ -22,8 +13,9 @@ def rotate_height_axis_90(element_id_list: List[int]) -> None: None """ + def rotate_height_axis_180(element_id_list: List[int]) -> None: - """Rotates the element height axis 180 degrees + """rotate height axis 180 Parameters: element_id_list: element_id_list @@ -32,8 +24,9 @@ def rotate_height_axis_180(element_id_list: List[int]) -> None: None """ + def set_over_width(element_id_list: List[int], value: float) -> None: - """Sets the element overwidth + """set over width Parameters: element_id_list: element_id_list @@ -43,8 +36,9 @@ def set_over_width(element_id_list: List[int], value: float) -> None: None """ + def set_over_height(element_id_list: List[int], value: float) -> None: - """Sets the element overheight + """set over height Parameters: element_id_list: element_id_list @@ -54,8 +48,9 @@ def set_over_height(element_id_list: List[int], value: float) -> None: None """ + def set_over_length(element_id_list: List[int], value: float) -> None: - """Sets the element overlength + """set over length Parameters: element_id_list: element_id_list @@ -65,8 +60,9 @@ def set_over_length(element_id_list: List[int], value: float) -> None: None """ + def set_rounding_width(element_id_list: List[int], value: float) -> None: - """Sets the element rounding width + """set rounding width Parameters: element_id_list: element_id_list @@ -76,8 +72,9 @@ def set_rounding_width(element_id_list: List[int], value: float) -> None: None """ + def set_rounding_height(element_id_list: List[int], value: float) -> None: - """Sets the element rounding height + """set rounding height Parameters: element_id_list: element_id_list @@ -87,8 +84,9 @@ def set_rounding_height(element_id_list: List[int], value: float) -> None: None """ + def set_rounding_length(element_id_list: List[int], value: float) -> None: - """Sets the element rounding length + """set rounding length Parameters: element_id_list: element_id_list @@ -98,8 +96,9 @@ def set_rounding_length(element_id_list: List[int], value: float) -> None: None """ + def set_cross_correction_negative_width(element_id_list: List[int], value: float) -> None: - """Sets the element negative width cross correction + """set cross correction negative width Parameters: element_id_list: element_id_list @@ -109,8 +108,9 @@ def set_cross_correction_negative_width(element_id_list: List[int], value: float None """ + def set_cross_correction_positive_width(element_id_list: List[int], value: float) -> None: - """Sets the element positive width cross correction + """set cross correction positive width Parameters: element_id_list: element_id_list @@ -120,8 +120,9 @@ def set_cross_correction_positive_width(element_id_list: List[int], value: float None """ + def set_cross_correction_negative_height(element_id_list: List[int], value: float) -> None: - """Sets the element negative height cross correction + """set cross correction negative height Parameters: element_id_list: element_id_list @@ -131,8 +132,9 @@ def set_cross_correction_negative_height(element_id_list: List[int], value: floa None """ + def set_cross_correction_positive_height(element_id_list: List[int], value: float) -> None: - """Sets the element positive height cross correction + """set cross correction positive height Parameters: element_id_list: element_id_list @@ -142,8 +144,9 @@ def set_cross_correction_positive_height(element_id_list: List[int], value: floa None """ + def set_cross_correction_negative_length(element_id_list: List[int], value: float) -> None: - """Sets the element negative length cross correction + """set cross correction negative length Parameters: element_id_list: element_id_list @@ -153,8 +156,9 @@ def set_cross_correction_negative_length(element_id_list: List[int], value: floa None """ + def set_cross_correction_positive_length(element_id_list: List[int], value: float) -> None: - """Sets the element positive length cross correction + """set cross correction positive length Parameters: element_id_list: element_id_list @@ -164,8 +168,9 @@ def set_cross_correction_positive_length(element_id_list: List[int], value: floa None """ + def apply_global_scale(element_id_list: List[int], scale: float, origin: point_3d) -> None: - """Applies a global scale to element + """apply global scale Parameters: element_id_list: element_id_list @@ -176,8 +181,9 @@ def apply_global_scale(element_id_list: List[int], scale: float, origin: point_3 None """ + def auto_regenerate_axes(element_id_list: List[int]) -> None: - """Automatically regenerates axes on element + """auto regenerate axes Parameters: element_id_list: element_id_list @@ -186,8 +192,9 @@ def auto_regenerate_axes(element_id_list: List[int]) -> None: None """ + def rotate_length_axis_90(element_id_list: List[int]) -> None: - """Rotates element length axis 90 degrees + """rotate length axis 90 Parameters: element_id_list: element_id_list @@ -196,8 +203,9 @@ def rotate_length_axis_90(element_id_list: List[int]) -> None: None """ + def rotate_length_axis_180(element_id_list: List[int]) -> None: - """Rotates element length axis 180 degrees + """rotate length axis 180 Parameters: element_id_list: element_id_list @@ -206,8 +214,9 @@ def rotate_length_axis_180(element_id_list: List[int]) -> None: None """ + def invert_model(element_id_list: List[int]) -> None: - """Inverts element model + """invert model Parameters: element_id_list: element_id_list @@ -216,8 +225,9 @@ def invert_model(element_id_list: List[int]) -> None: None """ + def set_width_real(elements: List[int], width: float) -> None: - """Sets the element real width + """set width real Parameters: elements: elements @@ -227,8 +237,9 @@ def set_width_real(elements: List[int], width: float) -> None: None """ + def set_height_real(elements: List[int], height: float) -> None: - """Sets the element real height + """set height real Parameters: elements: elements @@ -238,8 +249,9 @@ def set_height_real(elements: List[int], height: float) -> None: None """ + def set_length_real(elements: List[int], length: float) -> None: - """Gets the element real length + """set length real Parameters: elements: elements @@ -249,8 +261,9 @@ def set_length_real(elements: List[int], length: float) -> None: None """ + def rotate_height_axis_2_points(elements: List[int], point1: point_3d, point2: point_3d) -> None: - """Rotates the element height axis via 2 points + """rotate height axis 2 points Parameters: elements: elements @@ -261,6 +274,7 @@ def rotate_height_axis_2_points(elements: List[int], point1: point_3d, point2: p None """ + def clear_errors() -> None: """clear errors @@ -268,8 +282,9 @@ def clear_errors() -> None: None """ + def set_drilling_tolerance(elements: List[int], tolerance: float) -> None: - """Gets the division zone points + """set drilling tolerance Parameters: elements: elements @@ -279,18 +294,20 @@ def set_drilling_tolerance(elements: List[int], tolerance: float) -> None: None """ -def auto_regenerate_axes_silently(a0: List[int]) -> None: + +def auto_regenerate_axes_silently(element_id_list: List[int]) -> None: """auto regenerate axes silently Parameters: - a0: a0 + element_id_list: element_id_list Returns: None """ + def rotate_length_axis_2_points(elements: List[int], point1: point_3d, point2: point_3d) -> None: - """Rotates the element length axis via 2 points + """rotate length axis 2 points Parameters: elements: elements @@ -301,468 +318,516 @@ def rotate_length_axis_2_points(elements: List[int], point1: point_3d, point2: p None """ + def get_width(element_id: int) -> float: - """Gets the element width + """get width Parameters: element_id: element_id Returns: - element width + float """ + def get_height(element_id: int) -> float: - """Gets the element height + """get height Parameters: element_id: element_id Returns: - element height + float """ + def get_length(element_id: int) -> float: - """Gets the element length + """get length Parameters: element_id: element_id Returns: - element length + float """ + def get_p1(element_id: int) -> point_3d: - """Gets the element P1 + """get p1 Parameters: element_id: element_id Returns: - element P1 + point_3d """ + def get_p2(element_id: int) -> point_3d: - """Gets the element P2 + """get p2 Parameters: element_id: element_id Returns: - element P2 + point_3d """ + def get_p3(element_id: int) -> point_3d: - """Gets the element P3 + """get p3 Parameters: element_id: element_id Returns: - element P3 + point_3d """ + def get_start_height_cut_angle(element_id: int) -> float: - """Gets the element start height cut angle + """get start height cut angle Parameters: element_id: element_id Returns: - element start height cut angle + float """ + def get_start_width_cut_angle(element_id: int) -> float: - """Gets the element start width cut angle + """get start width cut angle Parameters: element_id: element_id Returns: - element start width cut angle + float """ + def get_end_height_cut_angle(element_id: int) -> float: - """Gets the element end height cut angle + """get end height cut angle Parameters: element_id: element_id Returns: - element end height cut angle + float """ + def get_end_width_cut_angle(element_id: int) -> float: - """Gets the element end width cut angle + """get end width cut angle Parameters: element_id: element_id Returns: - element end width cut angle + float """ + def get_over_width(element_id: int) -> float: - """Gets the element overwidth + """get over width Parameters: element_id: element_id Returns: - element overwidth + float """ + def get_over_height(element_id: int) -> float: - """Gets the element overheight + """get over height Parameters: element_id: element_id Returns: - element overheight + float """ + def get_over_length(element_id: int) -> float: - """Gets the element overlength + """get over length Parameters: element_id: element_id Returns: - element overlength + float """ + def get_rounding_width(element_id: int) -> float: - """Gets the element rounding width + """get rounding width Parameters: element_id: element_id Returns: - element rounding width + float """ + def get_rounding_height(element_id: int) -> float: - """Gets the element rounding height + """get rounding height Parameters: element_id: element_id Returns: - element rounding height + float """ + def get_rounding_length(element_id: int) -> float: - """Gets the element rounding length + """get rounding length Parameters: element_id: element_id Returns: - element rounding length + float """ + def get_cross_correction_negative_width(element_id: int) -> float: - """Gets the element negative width cross correction + """get cross correction negative width Parameters: element_id: element_id Returns: - element negative width cross correction + float """ + def get_cross_correction_positive_width(element_id: int) -> float: - """Gets the element positive width cross correction + """get cross correction positive width Parameters: element_id: element_id Returns: - element positive width cross correction + float """ + def get_cross_correction_negative_height(element_id: int) -> float: - """Gets the element negative height cross correction + """get cross correction negative height Parameters: element_id: element_id Returns: - element negative height cross correction + float """ + def get_cross_correction_positive_height(element_id: int) -> float: - """Gets the element positive height cross correction + """get cross correction positive height Parameters: element_id: element_id Returns: - element positive height cross correction + float """ + def get_cross_correction_negative_length(element_id: int) -> float: - """Gets the element negative length cross correction + """get cross correction negative length Parameters: element_id: element_id Returns: - element negative length cross correction + float """ + def get_cross_correction_positive_length(element_id: int) -> float: - """Gets the element positive length cross correction + """get cross correction positive length Parameters: element_id: element_id Returns: - element positive length cross correction + float """ + def get_weight(element_id: int) -> float: - """Gets the element real weight + """get weight Parameters: element_id: element_id Returns: - element real weight + float """ + def get_list_weight(element_id: int) -> float: - """Gets the element list weight + """get list weight Parameters: element_id: element_id Returns: - element list weight + float """ + def get_volume(element_id: int) -> float: - """Gets the element rough volume (does not include negative geometry operations, such as end-types, drillings, connectors, openings, and MEP elements) + """get volume Parameters: element_id: element_id Returns: - element rough volume + float """ + def get_list_volume(element_id: int) -> float: - """Gets the element list volume + """get list volume Parameters: element_id: element_id Returns: - element list volume + float """ + def get_xl(element_id: int) -> point_3d: - """Gets the element XL vector + """get xl Parameters: element_id: element_id Returns: - element XL vector + point_3d """ + def get_yl(element_id: int) -> point_3d: - """Gets the element YL vector + """get yl Parameters: element_id: element_id Returns: - element YL vector + point_3d """ + def get_zl(element_id: int) -> point_3d: - """Gets the element ZL vector + """get zl Parameters: element_id: element_id Returns: - element ZL vector + point_3d """ + def get_center_of_gravity(element_id: int) -> point_3d: - """Gets the element center of gravity + """get center of gravity Parameters: element_id: element_id Returns: - element center of gravity + point_3d """ + def get_reference_side(element_id: int) -> int: - """Gets the element reference side + """get reference side Parameters: element_id: element_id Returns: - element reference side + int """ + def get_element_vertices(element_id: int) -> List[point_3d]: - """Gets the element vertices + """get element vertices Parameters: element_id: element_id Returns: - element vertices + List[point_3d] """ + def get_element_facets(element_id: int) -> facet_list: - """Gets the element facets + """get element facets Parameters: element_id: element_id Returns: - element facets + facet_list """ + def get_list_width(element_id: int) -> float: - """Get the element list width + """get list width Parameters: element_id: element_id Returns: - element list width + float """ + def get_list_height(element_id: int) -> float: - """Gets the element list height + """get list height Parameters: element_id: element_id Returns: - element list height + float """ + def get_list_length(element_id: int) -> float: - """Gets the element list length + """get list length Parameters: element_id: element_id Returns: - element list length + float """ + def get_minimum_distance_between_elements(first_id: int, second_id: int) -> float: - """Gets the minimum distance between 2 elements + """get minimum distance between elements Parameters: first_id: first_id second_id: second_id Returns: - minimum distance + float """ + def get_total_area_of_all_faces(element: int) -> float: - """Gets the total area of all faces for element + """get total area of all faces Parameters: element: element Returns: - element total faces area + float """ + def get_area_of_front_face(element: int) -> float: - """Gets the front face are for element + """get area of front face Parameters: element: element Returns: - element front face area + float """ + def get_door_surface(elements: List[int]) -> float: - """Gets the element door surface + """get door surface Parameters: elements: elements Returns: - element door surface + float """ + def get_window_surface(elements: List[int]) -> float: - """Gets the element window surface + """get window surface Parameters: elements: elements Returns: - element window surface + float """ + def get_local_x() -> point_3d: - """Gets the local X vector + """get local x Returns: - local X vector + point_3d """ + def get_local_z() -> point_3d: - """Gets the local Y vector + """get local z Returns: - local Y vector + point_3d """ + def get_local_y() -> point_3d: - """Gets the local Z vector + """get local y Returns: - local Z vector + point_3d """ + def get_drilling_tolerance(element: int) -> float: - """Gets the drilling tolerance of an axis + """get drilling tolerance Parameters: element: element Returns: - the drilling tolerance + float """ + def get_element_reference_face_vertices(element_id: int) -> List[point_3d]: - """Gets the vertices of the reference side + """get element reference face vertices Parameters: element_id: element_id Returns: - vertexlist of all points + List[point_3d] """ + def get_element_reference_face_area(element_id: int) -> float: - """Gets the area of the reference side + """get element reference face area Parameters: element_id: element_id Returns: - area(size) of reference face + float """ + def get_center_of_gravity_for_list(elements: List[int]) -> point_3d: """get center of gravity for list @@ -773,6 +838,7 @@ def get_center_of_gravity_for_list(elements: List[int]) -> point_3d: point_3d """ + def get_center_of_gravity_for_list_considering_materials(elements: List[int]) -> point_3d: """get center of gravity for list considering materials @@ -783,6 +849,7 @@ def get_center_of_gravity_for_list_considering_materials(elements: List[int]) -> point_3d """ + def get_element_facet_count(element_id: int) -> int: """get element facet count @@ -793,6 +860,7 @@ def get_element_facet_count(element_id: int) -> int: int """ + def get_weight_real(element_id: int) -> float: """get weight real @@ -803,37 +871,44 @@ def get_weight_real(element_id: int) -> float: float """ -def get_actual_physical_weight(a0: int) -> float: + +def get_actual_physical_weight(element: int) -> float: """get actual physical weight Parameters: - a0: a0 + element: element Returns: float """ + def get_actual_physical_volume(element_id: int) -> float: - """Gets actual physical volume (includes negative geometry operations, such as end-types, drillings, connectors, openings, and MEP elements) (it might also take into account different drilling bodies and counterbores in a connector) + """Gets actual physical volume (includes negative geometry operations, such as end-types, drillings, connectors, + openings, and MEP elements) (it might also take into account different drilling + bodies and counterbores in a connector) + Parameters: element_id: element_id Returns: - actual physical volume + float """ + def are_facets_coplanar(first_facet: List[point_3d], second_facet: List[point_3d]) -> bool: - """Tests if facets are coplanar + """are facets coplanar Parameters: first_facet: first_facet second_facet: second_facet Returns: - facet coplanarity + bool """ + def get_round_machine_rough_part_negative_width(element_id: int) -> bool: """get round machine rough part negative width @@ -844,6 +919,7 @@ def get_round_machine_rough_part_negative_width(element_id: int) -> bool: bool """ + def set_round_machine_rough_part_negative_width(elements: List[int], value: bool) -> None: """set round machine rough part negative width @@ -855,6 +931,7 @@ def set_round_machine_rough_part_negative_width(elements: List[int], value: bool None """ + def get_round_machine_rough_part_positive_width(element_id: int) -> bool: """get round machine rough part positive width @@ -865,6 +942,7 @@ def get_round_machine_rough_part_positive_width(element_id: int) -> bool: bool """ + def set_round_machine_rough_part_positive_width(elements: List[int], value: bool) -> None: """set round machine rough part positive width @@ -876,6 +954,7 @@ def set_round_machine_rough_part_positive_width(elements: List[int], value: bool None """ + def get_round_machine_rough_part_negative_height(element_id: int) -> bool: """get round machine rough part negative height @@ -886,6 +965,7 @@ def get_round_machine_rough_part_negative_height(element_id: int) -> bool: bool """ + def set_round_machine_rough_part_negative_height(elements: List[int], value: bool) -> None: """set round machine rough part negative height @@ -897,6 +977,7 @@ def set_round_machine_rough_part_negative_height(elements: List[int], value: boo None """ + def get_round_machine_rough_part_positive_height(element_id: int) -> bool: """get round machine rough part positive height @@ -907,6 +988,7 @@ def get_round_machine_rough_part_positive_height(element_id: int) -> bool: bool """ + def set_round_machine_rough_part_positive_height(elements: List[int], value: bool) -> None: """set round machine rough part positive height @@ -918,6 +1000,7 @@ def set_round_machine_rough_part_positive_height(elements: List[int], value: boo None """ + def get_round_machine_rough_part_negative_length(element_id: int) -> bool: """get round machine rough part negative length @@ -928,6 +1011,7 @@ def get_round_machine_rough_part_negative_length(element_id: int) -> bool: bool """ + def set_round_machine_rough_part_negative_length(elements: List[int], value: bool) -> None: """set round machine rough part negative length @@ -939,6 +1023,7 @@ def set_round_machine_rough_part_negative_length(elements: List[int], value: boo None """ + def get_round_machine_rough_part_positive_length(element_id: int) -> bool: """get round machine rough part positive length @@ -949,6 +1034,7 @@ def get_round_machine_rough_part_positive_length(element_id: int) -> bool: bool """ + def set_round_machine_rough_part_positive_length(elements: List[int], value: bool) -> None: """set round machine rough part positive length @@ -960,6 +1046,7 @@ def set_round_machine_rough_part_positive_length(elements: List[int], value: boo None """ + def get_standard_element_width_from_guid(standard_element_guid: str) -> float: """get standard element width from guid @@ -970,6 +1057,7 @@ def get_standard_element_width_from_guid(standard_element_guid: str) -> float: float """ + def get_standard_element_height_from_guid(standard_element_guid: str) -> float: """get standard element height from guid @@ -980,6 +1068,7 @@ def get_standard_element_height_from_guid(standard_element_guid: str) -> float: float """ + def get_standard_element_length_from_guid(standard_element_guid: str) -> float: """get standard element length from guid @@ -990,6 +1079,7 @@ def get_standard_element_length_from_guid(standard_element_guid: str) -> float: float """ + def get_standard_element_width_from_name(standard_element_name: str) -> float: """get standard element width from name @@ -1000,6 +1090,7 @@ def get_standard_element_width_from_name(standard_element_name: str) -> float: float """ + def get_standard_element_height_from_name(standard_element_name: str) -> float: """get standard element height from name @@ -1010,6 +1101,7 @@ def get_standard_element_height_from_name(standard_element_name: str) -> float: float """ + def get_standard_element_length_from_name(standard_element_name: str) -> float: """get standard element length from name @@ -1019,4 +1111,3 @@ def get_standard_element_length_from_name(standard_element_name: str) -> float: Returns: float """ - From 7e9d0e27073537f6e5f91cd1755ac7b8b12da339 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Wed, 2 Oct 2024 09:42:42 +0200 Subject: [PATCH 05/52] - add new cwapi3d functions for build >= 30.0.593 --- docs/documentation/bim_team_upload_result.md | 6 + docs/documentation/enums.md | 7 + docs/release_notes.md | 75 ++++++++++ mkdocs.yml | 1 + src/cadwork/bim_team_upload_result.pyi | 17 +++ src/cadwork/bim_team_upload_result_code.pyi | 26 ++++ src/element_controller/__init__.pyi | 11 ++ src/file_controller/__init__.pyi | 93 ++++++++++++- src/utility_controller/__init__.pyi | 139 +++++++++++++++++++ 9 files changed, 370 insertions(+), 5 deletions(-) create mode 100644 docs/documentation/bim_team_upload_result.md create mode 100644 src/cadwork/bim_team_upload_result.pyi create mode 100644 src/cadwork/bim_team_upload_result_code.pyi diff --git a/docs/documentation/bim_team_upload_result.md b/docs/documentation/bim_team_upload_result.md new file mode 100644 index 0000000..9480cff --- /dev/null +++ b/docs/documentation/bim_team_upload_result.md @@ -0,0 +1,6 @@ +# BIMteam upload + +::: src.cadwork.bim_team_upload_result + rendering: + show_root_heading: false + show_source: true \ No newline at end of file diff --git a/docs/documentation/enums.md b/docs/documentation/enums.md index 225f593..f760e3a 100644 --- a/docs/documentation/enums.md +++ b/docs/documentation/enums.md @@ -66,3 +66,10 @@ rendering: show_root_heading: false show_source: true + +## BIMteam upload + +::: src.cadwork.bim_team_upload_result_code + rendering: + show_root_heading: false + show_source: true diff --git a/docs/release_notes.md b/docs/release_notes.md index b3eaa13..b3e5697 100644 --- a/docs/release_notes.md +++ b/docs/release_notes.md @@ -54,6 +54,80 @@ def set_element_group_multi_select_mode() ->None: ``` +#### get_elements_in_collision + +```python +def get_elements_in_collision(element: int) ->List[int]: + """get elements in collision + + Parameters: + element: element + + Returns: + List[int] + """ + +``` + +## New Items +### Functions file_controller +#### export_step_file_cut_drillings + +```python +def export_step_file_cut_drillings(elements: List[int], file_path: str, scale_factor: float, version: int, + text_mode: bool, imperial_units: bool) -> None: + """Exports a STEP file with extruded drillings + + Parameters: + elements: elements + file_path: file_path + scale_factor: scale_factor + version: version + text_mode: text_mode + imperial_units: imperial_units + + Returns: + None + """ + +``` + +#### export_sat_file_cut_drillings + +```python +def export_sat_file_cut_drillings(elements: List[int], file_path: str, + scale_factor: float, binary: bool, version: int) ->None: + """export sat file cut drillings + + Parameters: + elements: elements + file_path: file_path + scale_factor: scale_factor + binary: binary + version: version + + Returns: + None + """ + +``` + +#### upload_to_bim_team_and_create_share_link + +```python +def upload_to_bim_team_and_create_share_link(elements: None + ) ->bim_team_upload_result: + """upload to bim team and create share link + + Parameters: + elements: elements + + Returns: + bim_team_upload_result + """ + +``` + ## New Items ### Functions visualization_controller #### enter_working_plane @@ -71,3 +145,4 @@ def enter_working_plane(plane_normal: point_3d, plane_origin: point_3d) ->None: """ ``` + diff --git a/mkdocs.yml b/mkdocs.yml index 8d1f11f..d6a52bd 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -53,6 +53,7 @@ nav: - Layer Settings: documentation/layer_settings.md - Text Object Options: documentation/text_object_options.md - Window Geometry: documentation/window_geometry.md + - BIMteam Upload Result: documentation/bim_team_upload_result.md - Connector Axis Controller: documentation/connector_axis_controller.md - Dimension Controller: documentation/dimension_controller.md - Element Controller: documentation/element_controller.md diff --git a/src/cadwork/bim_team_upload_result.pyi b/src/cadwork/bim_team_upload_result.pyi new file mode 100644 index 0000000..56f41ab --- /dev/null +++ b/src/cadwork/bim_team_upload_result.pyi @@ -0,0 +1,17 @@ +from src.cadwork.bim_team_upload_result_code import bim_team_upload_result_code + + +class bim_team_upload_result: + """bim team upload result + """ + + def __init__(self): + """ + Instance of the bim_team_upload_result class. + + Attributes: + upload_result_code (bim_team_upload_result_code): The result code of the upload. + share_link (str): The share link for the uploaded BIM team result. + """ + self.upload_result_code = bim_team_upload_result_code.ok + self.share_link = "" diff --git a/src/cadwork/bim_team_upload_result_code.pyi b/src/cadwork/bim_team_upload_result_code.pyi new file mode 100644 index 0000000..344d7f2 --- /dev/null +++ b/src/cadwork/bim_team_upload_result_code.pyi @@ -0,0 +1,26 @@ +from enum import IntEnum, unique + + +@unique +class bim_team_upload_result_code(IntEnum): + """bim team upload result code + + Examples: + >>> cadwork.bim_team_upload_result_code.ok + ok + """ + ok = 0 + """""" + error_general_error = 1 + """""" + error_too_many_models = 2 + """""" + error_insufficient_storage = 3 + """""" + error_invalid_project_id = 4 + """""" + error_authentication_failed = 5 + """""" + + def __int__(self) -> int: + return self.value diff --git a/src/element_controller/__init__.pyi b/src/element_controller/__init__.pyi index 79253e5..1aff9ee 100644 --- a/src/element_controller/__init__.pyi +++ b/src/element_controller/__init__.pyi @@ -1987,3 +1987,14 @@ def slice_elements_with_plane_and_get_new_elements(element: int, cut_plane_norma List[int] """ +def get_elements_in_collision(element: int) ->List[int]: + """get elements in collision + + Parameters: + element: element + + Returns: + List[int] + """ + + diff --git a/src/file_controller/__init__.pyi b/src/file_controller/__init__.pyi index c719900..c6ba66a 100644 --- a/src/file_controller/__init__.pyi +++ b/src/file_controller/__init__.pyi @@ -1,5 +1,7 @@ from typing import List from cadwork import point_3d +from cadwork.bim_team_upload_result import bim_team_upload_result + def get_last_error(error_code: int) -> str: """Gets the last error @@ -11,6 +13,7 @@ def get_last_error(error_code: int) -> str: error string """ + def export_stl_file(element_id_list: List[int], file_path: str) -> None: """Exports an STL file @@ -22,6 +25,7 @@ def export_stl_file(element_id_list: List[int], file_path: str) -> None: None """ + def import_step_file(file_path: str, scale_factor: float) -> List[int]: """Imports a STEP file @@ -33,6 +37,7 @@ def import_step_file(file_path: str, scale_factor: float) -> List[int]: imported element ID list """ + def import_step_file_with_message_option(file_path: str, scale_factor: float, hide_message: bool) -> List[int]: """Imports a STEP file @@ -45,6 +50,7 @@ def import_step_file_with_message_option(file_path: str, scale_factor: float, hi imported element ID list """ + def export_webgl(element_id_list: List[int], file_path: str) -> bool: """Exports a WebGL file @@ -56,6 +62,7 @@ def export_webgl(element_id_list: List[int], file_path: str) -> bool: did operation succeed """ + def export_3d_file(element_id_list: List[int], file_path: str) -> bool: """Exports a 3D file @@ -67,6 +74,7 @@ def export_3d_file(element_id_list: List[int], file_path: str) -> bool: did operation succeed """ + def import_sat_file(file_path: str, scale_factor: float, binary: bool) -> List[int]: """Imports an SAT file @@ -79,6 +87,7 @@ def import_sat_file(file_path: str, scale_factor: float, binary: bool) -> List[i imported element ID list """ + def import_3dc_file(file_path: str) -> List[int]: """Imports a 3DC file @@ -89,6 +98,7 @@ def import_3dc_file(file_path: str) -> List[int]: imported element ID list """ + def import_rhino_file(file_path: str, without_dialog: bool) -> List[int]: """Imports a Rhino file @@ -100,7 +110,9 @@ def import_rhino_file(file_path: str, without_dialog: bool) -> List[int]: imported element ID list """ -def export_step_file(element_list: List[int], file_path: str, scale_factor: float, version: int, text_mode: bool) -> None: + +def export_step_file(element_list: List[int], file_path: str, scale_factor: float, version: int, + text_mode: bool) -> None: """Exports a STEP file Parameters: @@ -114,6 +126,7 @@ def export_step_file(element_list: List[int], file_path: str, scale_factor: floa None """ + def import_3dz_file(file_path: str) -> None: """Imports a 3DZ file @@ -124,6 +137,7 @@ def import_3dz_file(file_path: str) -> None: None """ + def export_obj_file(elements: List[int], file_path: str) -> None: """Exports a OBJ file @@ -135,6 +149,7 @@ def export_obj_file(elements: List[int], file_path: str) -> None: None """ + def import_sat_file_silently(file_path: str, scale_factor: float, binary: bool) -> List[int]: """Imports a SAT File without messages @@ -147,6 +162,7 @@ def import_sat_file_silently(file_path: str, scale_factor: float, binary: bool) List[int] """ + def export_fbx_file(elements: List[int], file_path: str, fbx_format: int) -> None: """Exports a FBX file @@ -159,6 +175,7 @@ def export_fbx_file(elements: List[int], file_path: str, fbx_format: int) -> Non None """ + def clear_errors() -> None: """clear errors @@ -166,6 +183,7 @@ def clear_errors() -> None: None """ + def import_3dc_file_with_glide(file_path: str) -> List[int]: """Imports a 3DC file with glide @@ -176,6 +194,7 @@ def import_3dc_file_with_glide(file_path: str) -> List[int]: imported element ID list """ + def import_btl_file(file_path: str) -> None: """Imports a BTL file @@ -186,6 +205,7 @@ def import_btl_file(file_path: str) -> None: None """ + def export_3dc_file(element_id_list: List[int], file_path: str) -> None: """Exports a 3D file @@ -197,6 +217,7 @@ def export_3dc_file(element_id_list: List[int], file_path: str) -> None: None """ + def import_btl_file_for_nesting(file_path: str) -> None: """Imports a BTL file for nesting @@ -207,6 +228,7 @@ def import_btl_file_for_nesting(file_path: str) -> None: None """ + def export_btl_file_for_nesting(file_path: str) -> None: """Exports a BTL file for nesting @@ -217,7 +239,9 @@ def export_btl_file_for_nesting(file_path: str) -> None: None """ -def export_rhino_file(element_id_list: List[int], file_path: str, version: int, use_default_assignment: bool, write_standard_attributes: bool) -> None: + +def export_rhino_file(element_id_list: List[int], file_path: str, version: int, use_default_assignment: bool, + write_standard_attributes: bool) -> None: """Exports a 3dm rhino file Parameters: @@ -231,6 +255,7 @@ def export_rhino_file(element_id_list: List[int], file_path: str, version: int, None """ + def import_bxf_file(file_path: str, insert_position: point_3d) -> List[int]: """import bxf file @@ -242,6 +267,7 @@ def import_bxf_file(file_path: str, insert_position: point_3d) -> List[int]: List[int] """ + def get_blum_export_path() -> str: """get blum export path @@ -249,6 +275,7 @@ def get_blum_export_path() -> str: str """ + def set_blum_export_path(path: str) -> None: """set blum export path @@ -259,6 +286,7 @@ def set_blum_export_path(path: str) -> None: None """ + def export_sat_file(elements: List[int], file_path: str, scale_factor: float, binary: bool, version: int) -> None: """exports a SAT File @@ -273,6 +301,7 @@ def export_sat_file(elements: List[int], file_path: str, scale_factor: float, bi None """ + def export_glb_file(elements: List[int], file_path: str) -> None: """exports a GLB File @@ -284,6 +313,7 @@ def export_glb_file(elements: List[int], file_path: str) -> None: None """ + def import_variant_file(file_path: str, insert_position: point_3d) -> List[int]: """imports a variant by .val-File @@ -295,6 +325,7 @@ def import_variant_file(file_path: str, insert_position: point_3d) -> List[int]: imported element ID list """ + def import_element_light(a0: str, a1: point_3d) -> int: """import element light @@ -306,7 +337,10 @@ def import_element_light(a0: str, a1: point_3d) -> int: int """ -def export_rhino_file_with_options(element_id_list: List[int], file_path: str, version: int, use_default_assignment: bool, write_standard_attributes: bool, rhino_options: None) -> None: + +def export_rhino_file_with_options(element_id_list: List[int], file_path: str, version: int, + use_default_assignment: bool, write_standard_attributes: bool, + rhino_options: None) -> None: """exports elements to a rhino 3dm file based on the export options Parameters: @@ -321,6 +355,7 @@ def export_rhino_file_with_options(element_id_list: List[int], file_path: str, v None """ + def import_3dc_file_with_options(file_path: str, import3dc_options: None) -> List[int]: """imports a 3d or a 3dc file depending on the import options @@ -332,13 +367,15 @@ def import_3dc_file_with_options(file_path: str, import3dc_options: None) -> Lis imported element ID list """ -def get_import_3dc_options() -> import_3dc_options: + +def get_import_3dc_options() -> 'import_3dc_options': """get import 3dc options Returns: import_3dc_options """ + def load_webgl_preset_file(file_path: str) -> None: """loads a preset file for the WebGl export @@ -349,7 +386,26 @@ def load_webgl_preset_file(file_path: str) -> None: None """ -def export_step_file_extrude_drillings(elements: List[int], file_path: str, scale_factor: float, version: int, text_mode: bool, imperial_units: bool) -> None: + +def export_step_file_extrude_drillings(elements: List[int], file_path: str, scale_factor: float, version: int, + text_mode: bool, imperial_units: bool) -> None: + """Exports a STEP file with extruded drillings + + Parameters: + elements: elements + file_path: file_path + scale_factor: scale_factor + version: version + text_mode: text_mode + imperial_units: imperial_units + + Returns: + None + """ + + +def export_step_file_cut_drillings(elements: List[int], file_path: str, scale_factor: float, version: int, + text_mode: bool, imperial_units: bool) -> None: """Exports a STEP file with extruded drillings Parameters: @@ -364,3 +420,30 @@ def export_step_file_extrude_drillings(elements: List[int], file_path: str, scal None """ + +def export_sat_file_cut_drillings(elements: List[int], file_path: str, + scale_factor: float, binary: bool, version: int) -> None: + """export sat file cut drillings + + Parameters: + elements: elements + file_path: file_path + scale_factor: scale_factor + binary: binary + version: version + + Returns: + None + """ + + +def upload_to_bim_team_and_create_share_link(elements: None + ) -> bim_team_upload_result: + """upload to bim team and create share link + + Parameters: + elements: elements + + Returns: + bim_team_upload_result + """ diff --git a/src/utility_controller/__init__.pyi b/src/utility_controller/__init__.pyi index 43ddc4a..fc804c2 100644 --- a/src/utility_controller/__init__.pyi +++ b/src/utility_controller/__init__.pyi @@ -3,6 +3,7 @@ from typing import Tuple from cadwork import point_3d from cadwork import window_geometry + def get_last_error(error_code: int) -> str: """Gets the last error @@ -13,6 +14,7 @@ def get_last_error(error_code: int) -> str: error string """ + def get_3d_version() -> int: """Gets the 3D version @@ -20,6 +22,7 @@ def get_3d_version() -> int: 3D version """ + def get_3d_build() -> int: """Gets the 3D build @@ -27,6 +30,7 @@ def get_3d_build() -> int: 3D build """ + def get_3d_file_path() -> str: """Gets the 3D file path @@ -34,6 +38,7 @@ def get_3d_file_path() -> str: 3D file path """ + def set_project_data(element_id: str, data: str) -> None: """Sets the project data @@ -45,6 +50,7 @@ def set_project_data(element_id: str, data: str) -> None: None """ + def print_error(message: str) -> None: """Prints an error @@ -55,6 +61,7 @@ def print_error(message: str) -> None: None """ + def get_language() -> str: """Gets the 3D language @@ -62,6 +69,7 @@ def get_language() -> str: 3D language """ + def print_message(message: str, column: int) -> None: """Prints a message @@ -73,6 +81,7 @@ def print_message(message: str, column: int) -> None: None """ + def get_user_int(message: str) -> int: """Prompts the user for an integer @@ -83,6 +92,7 @@ def get_user_int(message: str) -> int: user integer """ + def get_user_double(message: str) -> float: """Prompts the user for a double @@ -93,6 +103,7 @@ def get_user_double(message: str) -> float: user double """ + def get_user_bool(message: str, default_yes: bool) -> bool: """Prompts the user for a boolean @@ -104,6 +115,7 @@ def get_user_bool(message: str, default_yes: bool) -> bool: user boolean """ + def get_user_string(message: str) -> str: """Prompts the user for a string @@ -114,6 +126,7 @@ def get_user_string(message: str) -> str: user string """ + def set_project_name(project_name: str) -> None: """Sets the project name @@ -124,6 +137,7 @@ def set_project_name(project_name: str) -> None: None """ + def set_project_number(project_number: str) -> None: """Sets the project number @@ -134,6 +148,7 @@ def set_project_number(project_number: str) -> None: None """ + def set_project_part(project_part: str) -> None: """Sets the project part @@ -144,6 +159,7 @@ def set_project_part(project_part: str) -> None: None """ + def set_project_architect(project_architect: str) -> None: """Sets the project architect @@ -154,6 +170,7 @@ def set_project_architect(project_architect: str) -> None: None """ + def set_project_customer(project_customer: str) -> None: """Sets the project customer @@ -164,6 +181,7 @@ def set_project_customer(project_customer: str) -> None: None """ + def set_project_designer(project_designer: str) -> None: """Sets the project designer @@ -174,6 +192,7 @@ def set_project_designer(project_designer: str) -> None: None """ + def set_project_deadline(project_deadline: str) -> None: """Sets the project deadline @@ -184,6 +203,7 @@ def set_project_deadline(project_deadline: str) -> None: None """ + def set_project_user_attribute(number: int, user_attribute: str) -> None: """Sets the project user attribute @@ -195,6 +215,7 @@ def set_project_user_attribute(number: int, user_attribute: str) -> None: None """ + def set_project_user_attribute_name(number: int, user_attribute_name: str) -> None: """Sets the project user attribute name @@ -206,6 +227,7 @@ def set_project_user_attribute_name(number: int, user_attribute_name: str) -> No None """ + def set_project_latitude(latitude: float) -> None: """Sets the project latitude @@ -216,6 +238,7 @@ def set_project_latitude(latitude: float) -> None: None """ + def set_project_longitude(longitude: float) -> None: """Sets the project longitude @@ -226,6 +249,7 @@ def set_project_longitude(longitude: float) -> None: None """ + def set_project_address(address: str) -> None: """Sets the project address @@ -236,6 +260,7 @@ def set_project_address(address: str) -> None: None """ + def set_project_postal_code(postal_code: str) -> None: """Sets the project postal code @@ -246,6 +271,7 @@ def set_project_postal_code(postal_code: str) -> None: None """ + def set_project_city(city: str) -> None: """Sets the project city @@ -256,6 +282,7 @@ def set_project_city(city: str) -> None: None """ + def set_project_country(country: str) -> None: """Sets the project country @@ -266,6 +293,7 @@ def set_project_country(country: str) -> None: None """ + def get_user_file_from_dialog(name_filter: str) -> str: """Gets a file with a dialog @@ -276,6 +304,7 @@ def get_user_file_from_dialog(name_filter: str) -> str: file path """ + def get_client_number() -> str: """Gets the client number @@ -283,6 +312,7 @@ def get_client_number() -> str: client number """ + def get_user_point() -> point_3d: """Gets a point from the user @@ -290,6 +320,7 @@ def get_user_point() -> point_3d: user point """ + def disable_auto_display_refresh() -> None: """Disables automatic display refresh @@ -297,6 +328,7 @@ def disable_auto_display_refresh() -> None: None """ + def enable_auto_display_refresh() -> None: """Enables automatic display refresh @@ -304,6 +336,7 @@ def enable_auto_display_refresh() -> None: None """ + def create_new_guid() -> str: """Creates a new GUID @@ -311,6 +344,7 @@ def create_new_guid() -> str: GUID """ + def print_to_console(message: str) -> None: """Prints a message to the console @@ -321,6 +355,7 @@ def print_to_console(message: str) -> None: None """ + def export_screen_to_image(file_path: str, factor: int) -> None: """Exports the screen to an image @@ -332,6 +367,7 @@ def export_screen_to_image(file_path: str, factor: int) -> None: None """ + def get_new_user_file_from_dialog(name_filter: str) -> str: """Gets a new file with a dialog @@ -342,6 +378,7 @@ def get_new_user_file_from_dialog(name_filter: str) -> str: file path """ + def api_autostart(api_name: str, option: int) -> int: """api autostart @@ -353,6 +390,7 @@ def api_autostart(api_name: str, option: int) -> int: int """ + def enable_autostart(api_name: str) -> None: """enable autostart @@ -363,6 +401,7 @@ def enable_autostart(api_name: str) -> None: None """ + def disable_autostart(api_name: str) -> None: """disable autostart @@ -373,6 +412,7 @@ def disable_autostart(api_name: str) -> None: None """ + def check_autostart(api_name: str) -> bool: """check autostart @@ -383,6 +423,7 @@ def check_autostart(api_name: str) -> bool: bool """ + def delete_project_data(element_id: str) -> None: """Deletes the project data @@ -393,6 +434,7 @@ def delete_project_data(element_id: str) -> None: None """ + def run_external_program(name: str) -> bool: """Runs a 3D external program @@ -403,6 +445,7 @@ def run_external_program(name: str) -> bool: external program return """ + def save_3d_file_silently() -> None: """Saves the 3D file silently @@ -410,6 +453,7 @@ def save_3d_file_silently() -> None: None """ + def get_licence_first_part() -> str: """Gets the first part of the licence @@ -417,6 +461,7 @@ def get_licence_first_part() -> str: first part of licence """ + def get_licence_second_part() -> str: """Gets the second part of the licence @@ -424,6 +469,7 @@ def get_licence_second_part() -> str: second part of licence """ + def show_progress_bar() -> None: """Shows a ProgressBar in the CommandBar @@ -431,6 +477,7 @@ def show_progress_bar() -> None: None """ + def update_progress_bar(value: int) -> None: """Updates the ProgressBar with a value @@ -441,6 +488,7 @@ def update_progress_bar(value: int) -> None: None """ + def hide_progress_bar() -> None: """Hides the ProgressBar @@ -448,6 +496,7 @@ def hide_progress_bar() -> None: None """ + def get_user_color(initial_color: int) -> int: """Gets a color choosen by the user @@ -458,6 +507,7 @@ def get_user_color(initial_color: int) -> int: the colornumber """ + def get_3d_linear_units() -> str: """Gets the current linear units @@ -465,6 +515,7 @@ def get_3d_linear_units() -> str: str """ + def get_3d_linear_display_units() -> str: """Gets the current display units @@ -472,6 +523,7 @@ def get_3d_linear_display_units() -> str: str """ + def get_3d_angular_units() -> str: """Gets the current angular units @@ -479,6 +531,7 @@ def get_3d_angular_units() -> str: str """ + def get_3d_angular_display_units() -> str: """Gets the current angular display units @@ -486,6 +539,7 @@ def get_3d_angular_display_units() -> str: str """ + def get_3d_build_date() -> str: """Gets the current build date @@ -493,6 +547,7 @@ def get_3d_build_date() -> str: str """ + def set_project_elevation(elevation: float) -> None: """Sets the project elevation @@ -503,6 +558,7 @@ def set_project_elevation(elevation: float) -> None: None """ + def clear_errors() -> None: """clear errors @@ -510,6 +566,7 @@ def clear_errors() -> None: None """ + def push_check_and_query_data() -> None: """push check and query data @@ -517,6 +574,7 @@ def push_check_and_query_data() -> None: None """ + def pop_check_and_query_data() -> None: """pop check and query data @@ -524,6 +582,7 @@ def pop_check_and_query_data() -> None: None """ + def change_check_and_query_data_to_no_queries() -> None: """change check and query data to no queries @@ -531,6 +590,7 @@ def change_check_and_query_data_to_no_queries() -> None: None """ + def change_check_and_query_data_to_queries() -> None: """change check and query data to queries @@ -538,6 +598,7 @@ def change_check_and_query_data_to_queries() -> None: None """ + def is_direct_info_enabled() -> bool: """is direct info enabled @@ -545,6 +606,7 @@ def is_direct_info_enabled() -> bool: bool """ + def enable_direct_info() -> None: """enable direct info @@ -552,6 +614,7 @@ def enable_direct_info() -> None: None """ + def disable_direct_info() -> None: """disable direct info @@ -559,6 +622,7 @@ def disable_direct_info() -> None: None """ + def load_attribute_display_settings(file_path: str) -> None: """load attribute display settings @@ -569,6 +633,7 @@ def load_attribute_display_settings(file_path: str) -> None: None """ + def set_project_description(description: str) -> None: """set project description @@ -579,6 +644,7 @@ def set_project_description(description: str) -> None: None """ + def start_project_data_dialog() -> None: """start project data dialog @@ -586,6 +652,7 @@ def start_project_data_dialog() -> None: None """ + def init_LxSDK() -> None: """init LxSDK @@ -593,6 +660,7 @@ def init_LxSDK() -> None: None """ + def load_element_attribute_display_settings(file_path: str, elements: List[int]) -> None: """load element attribute display settings @@ -604,6 +672,7 @@ def load_element_attribute_display_settings(file_path: str, elements: List[int]) None """ + def get_global_x_offset() -> float: """get global x offset @@ -611,6 +680,7 @@ def get_global_x_offset() -> float: float """ + def set_global_x_offset(offset: float) -> None: """set global x offset @@ -621,6 +691,7 @@ def set_global_x_offset(offset: float) -> None: None """ + def get_global_y_offset() -> float: """get global y offset @@ -628,6 +699,7 @@ def get_global_y_offset() -> float: float """ + def set_global_y_offset(offset: float) -> None: """set global y offset @@ -638,6 +710,7 @@ def set_global_y_offset(offset: float) -> None: None """ + def get_global_z_offset() -> float: """get global z offset @@ -645,6 +718,7 @@ def get_global_z_offset() -> float: float """ + def set_global_z_offset(offset: float) -> None: """set global z offset @@ -655,6 +729,7 @@ def set_global_z_offset(offset: float) -> None: None """ + def show_north_arrow() -> None: """show north arrow @@ -662,6 +737,7 @@ def show_north_arrow() -> None: None """ + def hide_north_arrow() -> None: """hide north arrow @@ -669,6 +745,7 @@ def hide_north_arrow() -> None: None """ + def is_north_arrow_visible() -> bool: """is north arrow visible @@ -676,6 +753,7 @@ def is_north_arrow_visible() -> bool: bool """ + def get_north_angle() -> float: """get north angle @@ -683,6 +761,7 @@ def get_north_angle() -> float: float """ + def set_north_angle(north_angle: float) -> None: """set north angle @@ -693,6 +772,7 @@ def set_north_angle(north_angle: float) -> None: None """ + def get_user_file_from_dialog_in_path(name_filter: str, path: str) -> str: """get user file from dialog in path @@ -704,6 +784,7 @@ def get_user_file_from_dialog_in_path(name_filter: str, path: str) -> str: str """ + def get_new_user_file_from_dialog_in_path(name_filter: str, path: str) -> str: """get new user file from dialog in path @@ -715,6 +796,7 @@ def get_new_user_file_from_dialog_in_path(name_filter: str, path: str) -> str: str """ + def enable_update_variant() -> None: """enable update variant @@ -722,6 +804,7 @@ def enable_update_variant() -> None: None """ + def disable_update_variant() -> None: """disable update variant @@ -729,6 +812,7 @@ def disable_update_variant() -> None: None """ + def get_user_points() -> List[point_3d]: """get user points @@ -736,6 +820,7 @@ def get_user_points() -> List[point_3d]: List[point_3d] """ + def get_user_points_with_count(a0: int) -> List[point_3d]: """get user points with count @@ -746,6 +831,7 @@ def get_user_points_with_count(a0: int) -> List[point_3d]: List[point_3d] """ + def get_user_path_from_dialog() -> str: """get user path from dialog @@ -753,6 +839,7 @@ def get_user_path_from_dialog() -> str: str """ + def get_user_path_from_dialog_in_path(a0: str) -> str: """get user path from dialog in path @@ -763,6 +850,7 @@ def get_user_path_from_dialog_in_path(a0: str) -> str: str """ + def execute_shortcut(a0: int, a1: int) -> None: """execute shortcut @@ -774,6 +862,7 @@ def execute_shortcut(a0: int, a1: int) -> None: None """ + def run_external_program_from_custom_directory(file_path: str) -> bool: """Runs a 3D external program from a custom file path @@ -784,6 +873,7 @@ def run_external_program_from_custom_directory(file_path: str) -> bool: external program return """ + def get_3d_file_name() -> str: """Gets the 3D file name @@ -791,6 +881,7 @@ def get_3d_file_name() -> str: 3D file name """ + def get_project_data(element_id: str) -> str: """Gets the project data @@ -801,6 +892,7 @@ def get_project_data(element_id: str) -> str: project data """ + def get_project_name() -> str: """Gets the project name @@ -808,6 +900,7 @@ def get_project_name() -> str: project name """ + def get_project_part() -> str: """Sets the project part @@ -815,6 +908,7 @@ def get_project_part() -> str: project part """ + def get_project_architect() -> str: """Gets the project architect @@ -822,6 +916,7 @@ def get_project_architect() -> str: project architect """ + def get_project_number() -> str: """Gets the project number @@ -829,6 +924,7 @@ def get_project_number() -> str: project number """ + def get_project_customer() -> str: """Gets the project customer @@ -836,6 +932,7 @@ def get_project_customer() -> str: project customer """ + def get_project_designer() -> str: """Gets the project designer @@ -843,6 +940,7 @@ def get_project_designer() -> str: project designer """ + def get_project_deadline() -> str: """Gets the project deadline @@ -850,6 +948,7 @@ def get_project_deadline() -> str: project deadline """ + def get_project_user_attribute(number: int) -> str: """Gets the project user attribute @@ -860,6 +959,7 @@ def get_project_user_attribute(number: int) -> str: project user attribute """ + def get_project_user_attribute_name(number: int) -> str: """Gets the project user attribute name @@ -870,6 +970,7 @@ def get_project_user_attribute_name(number: int) -> str: project user attribute name """ + def get_project_latitude() -> float: """Gets the project latitude @@ -877,6 +978,7 @@ def get_project_latitude() -> float: project latitude """ + def get_project_longitude() -> float: """Gets the project longitude @@ -884,6 +986,7 @@ def get_project_longitude() -> float: project longitude """ + def get_project_postal_code() -> str: """Gets the project postal code @@ -891,6 +994,7 @@ def get_project_postal_code() -> str: project postal code """ + def get_project_address() -> str: """Gets the project address @@ -898,6 +1002,7 @@ def get_project_address() -> str: project address """ + def get_project_city() -> str: """Gets the project city @@ -905,6 +1010,7 @@ def get_project_city() -> str: project city """ + def get_project_country() -> str: """Gets the project country @@ -912,6 +1018,7 @@ def get_project_country() -> str: project country """ + def get_project_elevation() -> float: """Gets the project elevation @@ -919,6 +1026,7 @@ def get_project_elevation() -> float: project elevation """ + def get_project_description() -> str: """get project description @@ -926,6 +1034,7 @@ def get_project_description() -> str: str """ + def get_project_guid() -> str: """Gets the project GUID @@ -933,6 +1042,7 @@ def get_project_guid() -> str: project GUID """ + def get_3d_userprofil_path() -> str: """Gets the 3D userprofil path @@ -940,6 +1050,7 @@ def get_3d_userprofil_path() -> str: the 3D userprofil path """ + def get_plugin_path() -> str: """get plugin path @@ -947,6 +1058,7 @@ def get_plugin_path() -> str: str """ + def get_millimetre_from_imperial_string(value: str) -> float: """get millimetre from imperial string @@ -957,6 +1069,7 @@ def get_millimetre_from_imperial_string(value: str) -> float: float """ + def get_imperial_string_from_millimetre(value: float) -> str: """get imperial string from millimetre @@ -967,6 +1080,7 @@ def get_imperial_string_from_millimetre(value: float) -> str: str """ + def get_user_catalog_path() -> str: """get user catalog path @@ -974,6 +1088,7 @@ def get_user_catalog_path() -> str: str """ + def get_3d_hwnd() -> int: """Gets the 3D HWND @@ -981,6 +1096,7 @@ def get_3d_hwnd() -> int: 3D HWND """ + def close_cadwork_document_saved() -> None: """close cadwork saved @@ -988,6 +1104,7 @@ def close_cadwork_document_saved() -> None: None """ + def close_cadwork_document_unsaved() -> None: """close cadwork document unsaved @@ -995,6 +1112,7 @@ def close_cadwork_document_unsaved() -> None: None """ + def get_use_of_global_coordinates() -> bool: """get use of global coordinates @@ -1002,6 +1120,7 @@ def get_use_of_global_coordinates() -> bool: bool """ + def set_use_of_global_coordinates(use_of_global_coordinates: bool) -> None: """Sets the use of global coordinates @@ -1012,6 +1131,7 @@ def set_use_of_global_coordinates(use_of_global_coordinates: bool) -> None: None """ + def get_global_origin() -> point_3d: """Gets the global origin @@ -1019,6 +1139,7 @@ def get_global_origin() -> point_3d: global origin """ + def set_global_origin(global_origin: point_3d) -> None: """Sets the global origin @@ -1029,6 +1150,7 @@ def set_global_origin(global_origin: point_3d) -> None: None """ + def create_snapshot() -> str: """get snapshot from screen @@ -1036,6 +1158,7 @@ def create_snapshot() -> str: snapshot """ + def get_3d_gui_upper_left_screen_coordinates() -> Tuple[int, int]: """get 3d gui upper left screen coordinates @@ -1043,6 +1166,7 @@ def get_3d_gui_upper_left_screen_coordinates() -> Tuple[int, int]: coordinates of the upper left corner of the 3D GUI """ + def get_3d_main_window_geometry() -> 'window_geometry': """get 3d main window geometry @@ -1050,6 +1174,7 @@ def get_3d_main_window_geometry() -> 'window_geometry': window geometry """ + def get_project_data_keys() -> List[str]: """get project data keys @@ -1057,6 +1182,7 @@ def get_project_data_keys() -> List[str]: List[str] """ + def get_user_int_with_default_value(message: str, default_value: int) -> int: """get user int with default value @@ -1068,6 +1194,7 @@ def get_user_int_with_default_value(message: str, default_value: int) -> int: int """ + def get_user_double_with_default_value(message: str, default_value: float) -> float: """get user double with default value @@ -1079,6 +1206,7 @@ def get_user_double_with_default_value(message: str, default_value: float) -> fl float """ + def get_user_string_with_default_value(message: str, default_value: str) -> str: """get user string with default value @@ -1090,3 +1218,14 @@ def get_user_string_with_default_value(message: str, default_value: str) -> str: str """ + +def enter_working_plane(plane_normal: point_3d, plane_origin: point_3d) -> None: + """enter working plane + + Parameters: + plane_normal: plane_normal + plane_origin: plane_origin + + Returns: + None + """ From ebbb10d99dd478afe8d5169388850e2b9693b2d2 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Wed, 2 Oct 2024 09:46:12 +0200 Subject: [PATCH 06/52] - remove `enter_working_plane`function from wrong controller --- src/utility_controller/__init__.pyi | 11 ----------- src/visualization_controller/__init__.pyi | 1 + 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/utility_controller/__init__.pyi b/src/utility_controller/__init__.pyi index fc804c2..d0e9387 100644 --- a/src/utility_controller/__init__.pyi +++ b/src/utility_controller/__init__.pyi @@ -1218,14 +1218,3 @@ def get_user_string_with_default_value(message: str, default_value: str) -> str: str """ - -def enter_working_plane(plane_normal: point_3d, plane_origin: point_3d) -> None: - """enter working plane - - Parameters: - plane_normal: plane_normal - plane_origin: plane_origin - - Returns: - None - """ diff --git a/src/visualization_controller/__init__.pyi b/src/visualization_controller/__init__.pyi index a9afc60..63ca42e 100644 --- a/src/visualization_controller/__init__.pyi +++ b/src/visualization_controller/__init__.pyi @@ -511,3 +511,4 @@ def enter_working_plane(plane_normal: point_3d, plane_origin: point_3d) ->None: Returns: None """ + From 18678d8d963bc7ce1c573843b2c9d3a80a0a8cba Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Wed, 2 Oct 2024 10:55:32 +0200 Subject: [PATCH 07/52] - update cwapi3d package version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8c7a2b5..971f472 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "30.0.533" +version = "30.0.593" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.10" description = 'Python bindings for CwAPI3D' From 405aac35fba893d797bdf90cc897ef6dcf912bf0 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Tue, 18 Feb 2025 16:26:30 +0100 Subject: [PATCH 08/52] Bump cwapi3d version to 30.0.693 and add recent functions --- docs/documentation/shoulder_options.md | 16 + docs/release_notes.md | 1601 ++++++++++++++++- mkdocs.yml | 1 + pyproject.toml | 2 +- src/attribute_controller/__init__.pyi | 10 + src/cadwork/double_shoulder_options.pyi | 274 +++ src/cadwork/extended_settings.pyi | 67 + src/cadwork/heel_shoulder_beam_geometry.pyi | 19 + src/cadwork/heel_shoulder_options.pyi | 206 +++ src/cadwork/ifc_material_definition.pyi | 21 + src/cadwork/ifc_options_aggregation.pyi | 19 +- src/cadwork/shoulder_beam_geometry.pyi | 23 + src/cadwork/shoulder_drilling_orientation.pyi | 23 + src/cadwork/shoulder_options.pyi | 342 ++++ src/dimension_controller/__init__.pyi | 9 + src/element_controller/__init__.pyi | 101 ++ src/visualization_controller/__init__.pyi | 61 + 17 files changed, 2784 insertions(+), 11 deletions(-) create mode 100644 docs/documentation/shoulder_options.md create mode 100644 src/cadwork/double_shoulder_options.pyi create mode 100644 src/cadwork/heel_shoulder_beam_geometry.pyi create mode 100644 src/cadwork/heel_shoulder_options.pyi create mode 100644 src/cadwork/ifc_material_definition.pyi create mode 100644 src/cadwork/shoulder_beam_geometry.pyi create mode 100644 src/cadwork/shoulder_drilling_orientation.pyi create mode 100644 src/cadwork/shoulder_options.pyi diff --git a/docs/documentation/shoulder_options.md b/docs/documentation/shoulder_options.md new file mode 100644 index 0000000..b0ca2c8 --- /dev/null +++ b/docs/documentation/shoulder_options.md @@ -0,0 +1,16 @@ +# Shoulder options + +::: src.cadwork.double_shoulder_options + rendering: + show_root_heading: false + show_source: true + +::: src.cadwork.heel_shoulder_beam_geometry + rendering: + show_root_heading: false + show_source: true + +::: src.cadwork.heel_shoulder_options + rendering: + show_root_heading: false + show_source: true \ No newline at end of file diff --git a/docs/release_notes.md b/docs/release_notes.md index b3e5697..f475b60 100644 --- a/docs/release_notes.md +++ b/docs/release_notes.md @@ -1,3 +1,37 @@ +## New Items +### Functions attribute_controller +#### get_standard_element_material_id + +```python +def get_standard_element_material_id(element_id: int) ->int: + """get standard element material id + + Parameters: + element_id: element_id + + Returns: + int + """ + +``` + +## New Items +### Functions dimension_controller +#### get_total_dimension + +```python +def get_total_dimension(element: int) ->bool: + """get total dimension + + Parameters: + element: element + + Returns: + bool + """ + +``` + ## New Items ### Functions element_controller #### unjoin_elements @@ -69,22 +103,176 @@ def get_elements_in_collision(element: int) ->List[int]: ``` +#### get_text_object_options + +```python +def get_text_object_options(element: int) ->text_object_options: + """get text object options + + Parameters: + element: element + + Returns: + text_object_options + """ + +``` + +#### get_is_element_group_single_select_mode + +```python +def get_is_element_group_single_select_mode() ->bool: + """get is element group single select mode + + Returns: + bool + """ + +``` + +#### get_is_element_group_multi_select_mode + +```python +def get_is_element_group_multi_select_mode() ->bool: + """get is element group multi select mode + + Returns: + bool + """ + +``` + +#### apply_image_to_surface + +```python +def apply_image_to_surface(element: int, image_file_path: str, p1: point_3d, + p2: point_3d) ->bool: + """apply image to surface + + Parameters: + element: element + image_file_path: image_file_path + p1: p1 + p2: p2 + + Returns: + bool + """ + +``` + +#### set_shoulder_options + +```python +def set_shoulder_options(options: None) ->None: + """set shoulder options + + Parameters: + options: options + + Returns: + None + """ + +``` + +#### set_heel_shoulder_options + +```python +def set_heel_shoulder_options(options: None) ->None: + """set heel shoulder options + + Parameters: + options: options + + Returns: + None + """ + +``` + +#### set_double_shoulder_options + +```python +def set_double_shoulder_options(options: None) ->None: + """set double shoulder options + + Parameters: + options: options + + Returns: + None + """ + +``` + +#### cut_shoulder + +```python +def cut_shoulder(element_id_list: List[int], connecting_element_id_list: + List[int]) ->None: + """cut shoulder + + Parameters: + element_id_list: element_id_list + connecting_element_id_list: connecting_element_id_list + + Returns: + None + """ + +``` + +#### cut_heel_shoulder + +```python +def cut_heel_shoulder(element_id_list: List[int], + connecting_element_id_list: List[int]) ->None: + """cut heel shoulder + + Parameters: + element_id_list: element_id_list + connecting_element_id_list: connecting_element_id_list + + Returns: + None + """ + +``` + +#### cut_double_shoulder + +```python +def cut_double_shoulder(element_id_list: List[int], + connecting_element_id_list: List[int]) ->None: + """cut double shoulder + + Parameters: + element_id_list: element_id_list + connecting_element_id_list: connecting_element_id_list + + Returns: + None + """ + +``` + ## New Items ### Functions file_controller #### export_step_file_cut_drillings ```python -def export_step_file_cut_drillings(elements: List[int], file_path: str, scale_factor: float, version: int, - text_mode: bool, imperial_units: bool) -> None: - """Exports a STEP file with extruded drillings +def export_step_file_cut_drillings(a0: List[int], a1: str, a2: float, a3: + int, a4: bool, a5: bool) ->None: + """export step file cut drillings Parameters: - elements: elements - file_path: file_path - scale_factor: scale_factor - version: version - text_mode: text_mode - imperial_units: imperial_units + a0: a0 + a1: a1 + a2: a2 + a3: a3 + a4: a4 + a5: a5 Returns: None @@ -146,3 +334,1398 @@ def enter_working_plane(plane_normal: point_3d, plane_origin: point_3d) ->None: ``` +#### get_element_transparency + +```python +def get_element_transparency(element_id: int) ->int: + """get element transparency + + Parameters: + element_id: element_id + + Returns: + int + """ + +``` + +#### set_element_transparency + +```python +def set_element_transparency(element_id_list: List[int], value: int) ->None: + """set element transparency + + Parameters: + element_id_list: element_id_list + value: value + + Returns: + None + """ + +``` + +#### get_use_material_texture + +```python +def get_use_material_texture(element_id: int) ->bool: + """get use material texture + + Parameters: + element_id: element_id + + Returns: + bool + """ + +``` + +#### set_use_material_texture + +```python +def set_use_material_texture(element_id_list: List[int], value: bool) ->None: + """set use material texture + + Parameters: + element_id_list: element_id_list + value: value + + Returns: + None + """ + +``` + +#### display_bitmaps_as_texture_representation_in_shaded1 + +```python +def display_bitmaps_as_texture_representation_in_shaded1(a0: bool) ->None: + """display bitmaps as texture representation in shaded1 + + Parameters: + a0: a0 + + Returns: + None + """ + +``` + +#### display_bitmaps_as_texture_representation_in_shaded2 + +```python +def display_bitmaps_as_texture_representation_in_shaded2(a0: bool) ->None: + """display bitmaps as texture representation in shaded2 + + Parameters: + a0: a0 + + Returns: + None + """ + +``` + +## New Items +### Classes cadwork +#### double_shoulder_options + +```python +class double_shoulder_options: + + def get_add_drilling_axis(self) ->bool: + """get add drilling axis + + Returns: + bool + """ + + def set_add_drilling_axis(self, value: bool) ->None: + """set add drilling axis + + Parameters: + value: value + + Returns: + None + """ + + def get_add_drilling_axis_query_user_flag(self) ->bool: + """get add drilling axis query user flag + + Returns: + bool + """ + + def set_add_drilling_axis_query_user_flag(self, flag: bool) ->None: + """set add drilling axis query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_diameter(self) ->float: + """get drilling diameter + + Returns: + float + """ + + def set_drilling_diameter(self, value: float) ->None: + """set drilling diameter + + Parameters: + value: value + + Returns: + None + """ + + def get_drilling_diameter_query_user_flag(self) ->bool: + """get drilling diameter query user flag + + Returns: + bool + """ + + def set_drilling_diameter_query_user_flag(self, flag: bool) ->None: + """set drilling diameter query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_tolerance(self) ->float: + """get drilling tolerance + + Returns: + float + """ + + def set_drilling_tolerance(self, value: float) ->None: + """set drilling tolerance + + Parameters: + value: value + + Returns: + None + """ + + def get_drilling_tolerance_query_user_flag(self) ->bool: + """get drilling tolerance query user flag + + Returns: + bool + """ + + def set_drilling_tolerance_query_user_flag(self, flag: bool) ->None: + """set drilling tolerance query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_orientation_query_user_flag(self) ->bool: + """get drilling orientation query user flag + + Returns: + bool + """ + + def set_drilling_orientation_query_user_flag(self, flag: bool) ->None: + """set drilling orientation query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_beam_geometry(self) ->shoulder_beam_geometry: + """get beam geometry + + Returns: + shoulder_beam_geometry + """ + + def set_beam_geometry(self, value: shoulder_beam_geometry) ->None: + """set beam geometry + + Parameters: + value: value + + Returns: + None + """ + + def get_beam_geometry_query_user_flag(self) ->bool: + """get beam geometry query user flag + + Returns: + bool + """ + + def set_beam_geometry_query_user_flag(self, flag: bool) ->None: + """set beam geometry query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_double_shoulder_depth(self) ->float: + """get double shoulder depth + + Returns: + float + """ + + def set_double_shoulder_depth(self, value: float) ->None: + """set double shoulder depth + + Parameters: + value: value + + Returns: + None + """ + + def get_double_shoulder_depth_query_user_flag(self) ->bool: + """get double shoulder depth query user flag + + Returns: + bool + """ + + def set_double_shoulder_depth_query_user_flag(self, flag: bool) ->None: + """set double shoulder depth query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_heel_shoulder_depth(self) ->float: + """get heel shoulder depth + + Returns: + float + """ + + def set_heel_shoulder_depth(self, value: float) ->None: + """set heel shoulder depth + + Parameters: + value: value + + Returns: + None + """ + + def get_heel_shoulder_depth_query_user_flag(self) ->bool: + """get heel shoulder depth query user flag + + Returns: + bool + """ + + def set_heel_shoulder_depth_query_user_flag(self, flag: bool) ->None: + """set heel shoulder depth query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_cut_counter_part_through_whole_width(self) ->bool: + """get cut counter part through whole width + + Returns: + bool + """ + + def set_cut_counter_part_through_whole_width(self, value: bool) ->None: + """set cut counter part through whole width + + Parameters: + value: value + + Returns: + None + """ + + def get_cut_counter_part_through_whole_width_query_user_flag(self) ->bool: + """get cut counter part through whole width query user flag + + Returns: + bool + """ + + def set_cut_counter_part_through_whole_width_query_user_flag(self, flag: + bool) ->None: + """set cut counter part through whole width query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_orientation(self) ->shoulder_drilling_orientation: + """get drilling orientation + + Returns: + shoulder_drilling_orientation + """ + + def set_drilling_orientation(self, value: shoulder_drilling_orientation + ) ->None: + """set drilling orientation + + Parameters: + value: value + + Returns: + None + """ + +``` + +## New Items +### Classes cadwork +#### extended_settings + +```python +class extended_settings: + + def get_btl_wall_export(self) ->bool: + """get btl wall export + + Returns: + bool + """ + + def get_chief_element(self) ->bool: + """get chief element + + Returns: + bool + """ + + def get_group_export(self) ->bool: + """get group export + + Returns: + bool + """ + + def get_ignore_for_connector_axis(self) ->bool: + """get ignore for connector axis + + Returns: + bool + """ + + def get_log_home_export(self) ->bool: + """get log home export + + Returns: + bool + """ + + def get_log_macro_export(self) ->bool: + """get log macro export + + Returns: + bool + """ + + def get_mfb_export(self) ->bool: + """get mfb export + + Returns: + bool + """ + + def get_outline(self) ->bool: + """get outline + + Returns: + bool + """ + + def get_piece_by_piece_export_with_dimensions(self) ->bool: + """get piece by piece export with dimensions + + Returns: + bool + """ + + def get_piece_by_piece_export_without_dimensions(self) ->bool: + """get piece by piece export without dimensions + + Returns: + bool + """ + + def get_wall_export(self) ->bool: + """get wall export + + Returns: + bool + """ + + def set_btl_wall_export(self, value: bool) ->None: + """set btl wall export + + Parameters: + value: value + + Returns: + None + """ + + def set_chief_element(self, value: bool) ->None: + """set chief element + + Parameters: + value: value + + Returns: + None + """ + + def set_group_export(self, value: bool) ->None: + """set group export + + Parameters: + value: value + + Returns: + None + """ + + def set_ignore_for_connector_axis(self, value: bool) ->None: + """set ignore for connector axis + + Parameters: + value: value + + Returns: + None + """ + + def set_log_home_export(self, value: bool) ->None: + """set log home export + + Parameters: + value: value + + Returns: + None + """ + + def set_mfb_export(self, value: bool) ->None: + """set mfb export + + Parameters: + value: value + + Returns: + None + """ + + def set_outline(self, value: bool) ->None: + """set outline + + Parameters: + value: value + + Returns: + None + """ + + def set_piece_by_piece_export_with_dimensions(self, value: bool) ->None: + """set piece by piece export with dimensions + + Parameters: + value: value + + Returns: + None + """ + + def set_piece_by_piece_export_without_dimensions(self, value: bool) ->None: + """set piece by piece export without dimensions + + Parameters: + value: value + + Returns: + None + """ + + def set_wall_export(self, value: bool) ->None: + """set wall export + + Parameters: + value: value + + Returns: + None + """ + + def get_ignore_processing(self) ->bool: + """get ignore processing + + Returns: + bool + """ + + def set_ignore_processing(self, value: bool) ->None: + """set ignore processing + + Parameters: + value: value + + Returns: + None + """ + + def get_single_piece(self) ->bool: + """get single piece + + Returns: + bool + """ + + def set_single_piece(self, value: bool) ->None: + """set single piece + + Parameters: + value: value + + Returns: + None + """ + + def get_composite(self) ->bool: + """get composite + + Returns: + bool + """ + + def set_composite(self, value: bool) ->None: + """set composite + + Parameters: + value: value + + Returns: + None + """ + + def get_drilling_create_notches(self) ->bool: + """get drilling create notches + + Returns: + bool + """ + + def set_drilling_create_notches(self, value: bool) ->None: + """set drilling create notches + + Parameters: + value: value + + Returns: + None + """ + +``` + +## New Items +### Classes cadwork +#### heel_shoulder_beam_geometry + +```python +@unique +class heel_shoulder_beam_geometry(IntEnum): + """heel shoulder beam geometry + + Examples: + >>> cadwork.heel_shoulder_beam_geometry.normal + normal + """ + normal = 0 + """""" + straight = 1 + """""" + + def __int__(self) ->int: + return self.value + +``` + +## New Items +### Classes cadwork +#### heel_shoulder_options + +```python +class heel_shoulder_options: + + def get_beam_geometry(self) ->shoulder_beam_geometry: + """get beam geometry + + Returns: + shoulder_beam_geometry + """ + + def set_beam_geometry(self, value: shoulder_beam_geometry) ->None: + """set beam geometry + + Parameters: + value: value + + Returns: + None + """ + + def get_beam_geometry_query_user_flag(self) ->bool: + """get beam geometry query user flag + + Returns: + bool + """ + + def set_beam_geometry_query_user_flag(self, flag: bool) ->None: + """set beam geometry query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_shoulder_depth(self) ->float: + """get shoulder depth + + Returns: + float + """ + + def set_shoulder_depth(self, value: float) ->None: + """set shoulder depth + + Parameters: + value: value + + Returns: + None + """ + + def get_shoulder_depth_query_user_flag(self) ->bool: + """get shoulder depth query user flag + + Returns: + bool + """ + + def set_shoulder_depth_query_user_flag(self, flag: bool) ->None: + """set shoulder depth query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_gap(self) ->float: + """get gap + + Returns: + float + """ + + def set_gap(self, value: float) ->None: + """set gap + + Parameters: + value: value + + Returns: + None + """ + + def get_gap_query_user_flag(self) ->bool: + """get gap query user flag + + Returns: + bool + """ + + def set_gap_query_user_flag(self, flag: bool) ->None: + """set gap query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_cut_counter_part_through_whole_width(self) ->bool: + """get cut counter part through whole width + + Returns: + bool + """ + + def set_cut_counter_part_through_whole_width(self, value: bool) ->None: + """set cut counter part through whole width + + Parameters: + value: value + + Returns: + None + """ + + def get_cut_counter_part_through_whole_width_query_user_flag(self) ->bool: + """get cut counter part through whole width query user flag + + Returns: + bool + """ + + def set_cut_counter_part_through_whole_width_query_user_flag(self, flag: + bool) ->None: + """set cut counter part through whole width query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_add_end_type(self) ->bool: + """get add end type + + Returns: + bool + """ + + def set_add_end_type(self, value: bool) ->None: + """set add end type + + Parameters: + value: value + + Returns: + None + """ + + def get_add_end_type_query_user_flag(self) ->bool: + """get add end type query user flag + + Returns: + bool + """ + + def set_add_end_type_query_user_flag(self, flag: bool) ->None: + """set add end type query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_end_type_name(self) ->str: + """get end type name + + Returns: + str + """ + + def set_end_type_name(self, value: str) ->None: + """set end type name + + Parameters: + value: value + + Returns: + None + """ + + def get_end_type_name_query_user_flag(self) ->bool: + """get end type name query user flag + + Returns: + bool + """ + + def set_end_type_name_query_user_flag(self, flag: bool) ->None: + """set end type name query user flag + + Parameters: + flag: flag + + Returns: + None + """ + +``` + +## New Items +### Classes cadwork +#### ifc_material_definition + +```python +@unique +class ifc_material_definition(IntEnum): + """ifc material definition + + Examples: + >>> cadwork.ifc_material_definition.ignore + ignore + """ + ignore = 1 + """""" + material_layer_set = 2 + """""" + material_constituent_set = 3 + """""" + + def __int__(self) ->int: + return self.value + +``` + +## New Items +### Classes cadwork +#### ifc_options_aggregation + +```python +class ifc_options_aggregation: + + def set_consider_element_aggregation(self, consider_element_aggregation: + bool) ->None: + """set consider element aggregation + + Parameters: + consider_element_aggregation: consider_element_aggregation + + Returns: + None + """ + + def get_element_aggregation_attribute(self) ->int: + """get element aggregation attribute + + Returns: + int + """ + + def set_export_cover_geometry(self, export_cover_geometry: bool) ->None: + """set export cover geometry + + Parameters: + export_cover_geometry: export_cover_geometry + + Returns: + None + """ + + def set_element_aggregation_attribute(self, + element_aggregation_attribute: element_grouping_type) ->None: + """set element aggregation attribute + + Parameters: + element_aggregation_attribute: element_aggregation_attribute + + Returns: + None + """ + + def set_element_combine_type(self, element_combine_type: + ifc_element_combine_behaviour) ->None: + """set element combine type + + Parameters: + element_combine_type: element_combine_type + + Returns: + None + """ + + def get_consider_element_aggregation(self) ->bool: + """get consider element aggregation + + Returns: + bool + """ + + def get_export_cover_geometry(self) ->bool: + """get export cover geometry + + Returns: + bool + """ + + def get_element_combine_type(self) ->ifc_element_combine_behaviour: + """get element combine type + + Returns: + ifc_element_combine_behaviour + """ + + def set_multi_layer_material_definition_type(self, + ifc_material_definition: ifc_material_definition) ->None: + """set multi layer material definition type + + Parameters: + ifc_material_definition: ifc_material_definition + + Returns: + None + """ + + def get_multi_layer_material_definition_type(self + ) ->ifc_material_definition: + """get multi layer material definition type + + Returns: + ifc_material_definition + """ + +``` + +## New Items +### Classes cadwork +#### shoulder_beam_geometry + +```python +@unique +class shoulder_beam_geometry(IntEnum): + """shoulder beam geometry + + Examples: + >>> cadwork.shoulder_beam_geometry.bisector + bisector + """ + bisector = 0 + """""" + perpendicular_to_strut = 1 + """""" + perpendicular_to_counter_part = 2 + """""" + birdsmouth = 3 + """""" + + def __int__(self) ->int: + return self.value + +``` + +## New Items +### Classes cadwork +#### shoulder_drilling_orientation + +```python +@unique +class shoulder_drilling_orientation(IntEnum): + """shoulder drilling orientation + + Examples: + >>> cadwork.shoulder_drilling_orientation.perpendicular_to_bisector + perpendicular_to_bisector + """ + perpendicular_to_bisector = 1 + """""" + perpendicular_to_counter_part = 2 + """""" + perpendicular_to_strut = 3 + """""" + perpendicular_to_contact_surface = 4 + """""" + + def __int__(self) ->int: + return self.value + +``` + +## New Items +### Classes cadwork +#### shoulder_options + +```python +class shoulder_options: + + def get_add_drilling_axis(self) ->bool: + """get add drilling axis + + Returns: + bool + """ + + def set_add_drilling_axis(self, value: bool) ->None: + """set add drilling axis + + Parameters: + value: value + + Returns: + None + """ + + def get_add_drilling_axis_query_user_flag(self) ->bool: + """get add drilling axis query user flag + + Returns: + bool + """ + + def set_add_drilling_axis_query_user_flag(self, flag: bool) ->None: + """set add drilling axis query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_diameter(self) ->float: + """get drilling diameter + + Returns: + float + """ + + def set_drilling_diameter(self, value: float) ->None: + """set drilling diameter + + Parameters: + value: value + + Returns: + None + """ + + def get_drilling_diameter_query_user_flag(self) ->bool: + """get drilling diameter query user flag + + Returns: + bool + """ + + def set_drilling_diameter_query_user_flag(self, flag: bool) ->None: + """set drilling diameter query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_tolerance(self) ->float: + """get drilling tolerance + + Returns: + float + """ + + def set_drilling_tolerance(self, value: float) ->None: + """set drilling tolerance + + Parameters: + value: value + + Returns: + None + """ + + def get_drilling_tolerance_query_user_flag(self) ->bool: + """get drilling tolerance query user flag + + Returns: + bool + """ + + def set_drilling_tolerance_query_user_flag(self, flag: bool) ->None: + """set drilling tolerance query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_orientation_query_user_flag(self) ->bool: + """get drilling orientation query user flag + + Returns: + bool + """ + + def set_drilling_orientation_query_user_flag(self, flag: bool) ->None: + """set drilling orientation query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_beam_geometry(self) ->shoulder_beam_geometry: + """get beam geometry + + Returns: + shoulder_beam_geometry + """ + + def set_beam_geometry(self, value: shoulder_beam_geometry) ->None: + """set beam geometry + + Parameters: + value: value + + Returns: + None + """ + + def get_beam_geometry_query_user_flag(self) ->bool: + """get beam geometry query user flag + + Returns: + bool + """ + + def set_beam_geometry_query_user_flag(self, flag: bool) ->None: + """set beam geometry query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_shoulder_depth(self) ->float: + """get shoulder depth + + Returns: + float + """ + + def set_shoulder_depth(self, value: float) ->None: + """set shoulder depth + + Parameters: + value: value + + Returns: + None + """ + + def get_shoulder_depth_query_user_flag(self) ->bool: + """get shoulder depth query user flag + + Returns: + bool + """ + + def set_shoulder_depth_query_user_flag(self, flag: bool) ->None: + """set shoulder depth query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_toe_offset(self) ->float: + """get toe offset + + Returns: + float + """ + + def set_toe_offset(self, value: float) ->None: + """set toe offset + + Parameters: + value: value + + Returns: + None + """ + + def get_toe_offset_query_user_flag(self) ->bool: + """get toe offset query user flag + + Returns: + bool + """ + + def set_toe_offset_query_user_flag(self, flag: bool) ->None: + """set toe offset query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_cut_counter_part_through_whole_width(self) ->bool: + """get cut counter part through whole width + + Returns: + bool + """ + + def set_cut_counter_part_through_whole_width(self, value: bool) ->None: + """set cut counter part through whole width + + Parameters: + value: value + + Returns: + None + """ + + def get_cut_counter_part_through_whole_width_query_user_flag(self) ->bool: + """get cut counter part through whole width query user flag + + Returns: + bool + """ + + def set_cut_counter_part_through_whole_width_query_user_flag(self, flag: + bool) ->None: + """set cut counter part through whole width query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_add_end_type(self) ->bool: + """get add end type + + Returns: + bool + """ + + def set_add_end_type(self, value: bool) ->None: + """set add end type + + Parameters: + value: value + + Returns: + None + """ + + def get_add_end_type_query_user_flag(self) ->bool: + """get add end type query user flag + + Returns: + bool + """ + + def set_add_end_type_query_user_flag(self, flag: bool) ->None: + """set add end type query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_end_type_name(self) ->str: + """get end type name + + Returns: + str + """ + + def set_end_type_name(self, value: str) ->None: + """set end type name + + Parameters: + value: value + + Returns: + None + """ + + def get_end_type_name_query_user_flag(self) ->bool: + """get end type name query user flag + + Returns: + bool + """ + + def set_end_type_name_query_user_flag(self, flag: bool) ->None: + """set end type name query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_orientation(self) ->shoulder_drilling_orientation: + """get drilling orientation + + Returns: + shoulder_drilling_orientation + """ + + def set_drilling_orientation(self, value: shoulder_drilling_orientation + ) ->None: + """set drilling orientation + + Parameters: + value: value + + Returns: + None + """ + +``` + diff --git a/mkdocs.yml b/mkdocs.yml index d6a52bd..9ac8078 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -54,6 +54,7 @@ nav: - Text Object Options: documentation/text_object_options.md - Window Geometry: documentation/window_geometry.md - BIMteam Upload Result: documentation/bim_team_upload_result.md + - Shoulder cut options: documentation/shoulder_options.md - Connector Axis Controller: documentation/connector_axis_controller.md - Dimension Controller: documentation/dimension_controller.md - Element Controller: documentation/element_controller.md diff --git a/pyproject.toml b/pyproject.toml index 971f472..df88b72 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "30.0.593" +version = "30.0.693" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.10" description = 'Python bindings for CwAPI3D' diff --git a/src/attribute_controller/__init__.pyi b/src/attribute_controller/__init__.pyi index cf9bc85..958099e 100644 --- a/src/attribute_controller/__init__.pyi +++ b/src/attribute_controller/__init__.pyi @@ -1781,3 +1781,13 @@ def set_cutting_set(element_id_list: List[int], cutting_set_name: str) -> bool: Returns: bool """ + +def get_standard_element_material_id(element_id: int) ->int: + """get standard element material id + + Parameters: + element_id: element_id + + Returns: + int + """ \ No newline at end of file diff --git a/src/cadwork/double_shoulder_options.pyi b/src/cadwork/double_shoulder_options.pyi new file mode 100644 index 0000000..95b96c3 --- /dev/null +++ b/src/cadwork/double_shoulder_options.pyi @@ -0,0 +1,274 @@ +class double_shoulder_options: + + def get_add_drilling_axis(self) -> bool: + """get add drilling axis + + Returns: + bool + """ + + def set_add_drilling_axis(self, value: bool) -> None: + """set add drilling axis + + Parameters: + value: value + + Returns: + None + """ + + def get_add_drilling_axis_query_user_flag(self) -> bool: + """get add drilling axis query user flag + + Returns: + bool + """ + + def set_add_drilling_axis_query_user_flag(self, flag: bool) -> None: + """set add drilling axis query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_diameter(self) -> float: + """get drilling diameter + + Returns: + float + """ + + def set_drilling_diameter(self, value: float) -> None: + """set drilling diameter + + Parameters: + value: value + + Returns: + None + """ + + def get_drilling_diameter_query_user_flag(self) -> bool: + """get drilling diameter query user flag + + Returns: + bool + """ + + def set_drilling_diameter_query_user_flag(self, flag: bool) -> None: + """set drilling diameter query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_tolerance(self) -> float: + """get drilling tolerance + + Returns: + float + """ + + def set_drilling_tolerance(self, value: float) -> None: + """set drilling tolerance + + Parameters: + value: value + + Returns: + None + """ + + def get_drilling_tolerance_query_user_flag(self) -> bool: + """get drilling tolerance query user flag + + Returns: + bool + """ + + def set_drilling_tolerance_query_user_flag(self, flag: bool) -> None: + """set drilling tolerance query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_orientation_query_user_flag(self) -> bool: + """get drilling orientation query user flag + + Returns: + bool + """ + + def set_drilling_orientation_query_user_flag(self, flag: bool) -> None: + """set drilling orientation query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_beam_geometry(self) -> 'shoulder_beam_geometry': + """get beam geometry + + Returns: + shoulder_beam_geometry + """ + + def set_beam_geometry(self, value: 'shoulder_beam_geometry') -> None: + """set beam geometry + + Parameters: + value: value + + Returns: + None + """ + + def get_beam_geometry_query_user_flag(self) -> bool: + """get beam geometry query user flag + + Returns: + bool + """ + + def set_beam_geometry_query_user_flag(self, flag: bool) -> None: + """set beam geometry query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_double_shoulder_depth(self) -> float: + """get double shoulder depth + + Returns: + float + """ + + def set_double_shoulder_depth(self, value: float) -> None: + """set double shoulder depth + + Parameters: + value: value + + Returns: + None + """ + + def get_double_shoulder_depth_query_user_flag(self) -> bool: + """get double shoulder depth query user flag + + Returns: + bool + """ + + def set_double_shoulder_depth_query_user_flag(self, flag: bool) -> None: + """set double shoulder depth query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_heel_shoulder_depth(self) -> float: + """get heel shoulder depth + + Returns: + float + """ + + def set_heel_shoulder_depth(self, value: float) -> None: + """set heel shoulder depth + + Parameters: + value: value + + Returns: + None + """ + + def get_heel_shoulder_depth_query_user_flag(self) -> bool: + """get heel shoulder depth query user flag + + Returns: + bool + """ + + def set_heel_shoulder_depth_query_user_flag(self, flag: bool) -> None: + """set heel shoulder depth query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_cut_counter_part_through_whole_width(self) -> bool: + """get cut counter part through whole width + + Returns: + bool + """ + + def set_cut_counter_part_through_whole_width(self, value: bool) -> None: + """set cut counter part through whole width + + Parameters: + value: value + + Returns: + None + """ + + def get_cut_counter_part_through_whole_width_query_user_flag(self) -> bool: + """get cut counter part through whole width query user flag + + Returns: + bool + """ + + def set_cut_counter_part_through_whole_width_query_user_flag(self, flag: bool) -> None: + """set cut counter part through whole width query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_orientation(self) -> 'shoulder_drilling_orientation': + """get drilling orientation + + Returns: + shoulder_drilling_orientation + """ + + def set_drilling_orientation(self, value: 'shoulder_drilling_orientation') -> None: + """set drilling orientation + + Parameters: + value: value + + Returns: + None + """ + diff --git a/src/cadwork/extended_settings.pyi b/src/cadwork/extended_settings.pyi index 4658f37..80745a5 100644 --- a/src/cadwork/extended_settings.pyi +++ b/src/cadwork/extended_settings.pyi @@ -176,4 +176,71 @@ class extended_settings: Returns: None """ + + def get_ignore_processing(self) ->bool: + """get ignore processing + + Returns: + bool + """ + + def set_ignore_processing(self, value: bool) ->None: + """set ignore processing + + Parameters: + value: value + + Returns: + None + """ + + def get_single_piece(self) -> bool: + """get single piece + + Returns: + bool + """ + + def set_single_piece(self, value: bool) -> None: + """set single piece + + Parameters: + value: value + + Returns: + None + """ + + def get_composite(self) -> bool: + """get composite + + Returns: + bool + """ + + def set_composite(self, value: bool) -> None: + """set composite + + Parameters: + value: value + + Returns: + None + """ + + def get_drilling_create_notches(self) -> bool: + """get drilling create notches + Returns: + bool + """ + + def set_drilling_create_notches(self, value: bool) -> None: + """set drilling create notches + + Parameters: + value: value + + Returns: + None + """ \ No newline at end of file diff --git a/src/cadwork/heel_shoulder_beam_geometry.pyi b/src/cadwork/heel_shoulder_beam_geometry.pyi new file mode 100644 index 0000000..a0789d9 --- /dev/null +++ b/src/cadwork/heel_shoulder_beam_geometry.pyi @@ -0,0 +1,19 @@ +from enum import IntEnum, unique + + +@unique +class heel_shoulder_beam_geometry(IntEnum): + """heel shoulder beam geometry + + Examples: + >>> cadwork.heel_shoulder_beam_geometry.normal + normal + """ + normal = 0 + """""" + straight = 1 + """""" + + def __int__(self) -> int: + return self.value + diff --git a/src/cadwork/heel_shoulder_options.pyi b/src/cadwork/heel_shoulder_options.pyi new file mode 100644 index 0000000..93773e3 --- /dev/null +++ b/src/cadwork/heel_shoulder_options.pyi @@ -0,0 +1,206 @@ +class heel_shoulder_options: + + def get_beam_geometry(self) -> 'shoulder_beam_geometry': + """get beam geometry + + Returns: + shoulder_beam_geometry + """ + + def set_beam_geometry(self, value: 'shoulder_beam_geometry') -> None: + """set beam geometry + + Parameters: + value: value + + Returns: + None + """ + + def get_beam_geometry_query_user_flag(self) -> bool: + """get beam geometry query user flag + + Returns: + bool + """ + + def set_beam_geometry_query_user_flag(self, flag: bool) -> None: + """set beam geometry query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_shoulder_depth(self) -> float: + """get shoulder depth + + Returns: + float + """ + + def set_shoulder_depth(self, value: float) -> None: + """set shoulder depth + + Parameters: + value: value + + Returns: + None + """ + + def get_shoulder_depth_query_user_flag(self) -> bool: + """get shoulder depth query user flag + + Returns: + bool + """ + + def set_shoulder_depth_query_user_flag(self, flag: bool) -> None: + """set shoulder depth query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_gap(self) -> float: + """get gap + + Returns: + float + """ + + def set_gap(self, value: float) -> None: + """set gap + + Parameters: + value: value + + Returns: + None + """ + + def get_gap_query_user_flag(self) -> bool: + """get gap query user flag + + Returns: + bool + """ + + def set_gap_query_user_flag(self, flag: bool) -> None: + """set gap query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_cut_counter_part_through_whole_width(self) -> bool: + """get cut counter part through whole width + + Returns: + bool + """ + + def set_cut_counter_part_through_whole_width(self, value: bool) -> None: + """set cut counter part through whole width + + Parameters: + value: value + + Returns: + None + """ + + def get_cut_counter_part_through_whole_width_query_user_flag(self) -> bool: + """get cut counter part through whole width query user flag + + Returns: + bool + """ + + def set_cut_counter_part_through_whole_width_query_user_flag(self, flag: bool) -> None: + """set cut counter part through whole width query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_add_end_type(self) -> bool: + """get add end type + + Returns: + bool + """ + + def set_add_end_type(self, value: bool) -> None: + """set add end type + + Parameters: + value: value + + Returns: + None + """ + + def get_add_end_type_query_user_flag(self) -> bool: + """get add end type query user flag + + Returns: + bool + """ + + def set_add_end_type_query_user_flag(self, flag: bool) -> None: + """set add end type query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_end_type_name(self) -> str: + """get end type name + + Returns: + str + """ + + def set_end_type_name(self, value: str) -> None: + """set end type name + + Parameters: + value: value + + Returns: + None + """ + + def get_end_type_name_query_user_flag(self) -> bool: + """get end type name query user flag + + Returns: + bool + """ + + def set_end_type_name_query_user_flag(self, flag: bool) -> None: + """set end type name query user flag + + Parameters: + flag: flag + + Returns: + None + """ + diff --git a/src/cadwork/ifc_material_definition.pyi b/src/cadwork/ifc_material_definition.pyi new file mode 100644 index 0000000..e23941a --- /dev/null +++ b/src/cadwork/ifc_material_definition.pyi @@ -0,0 +1,21 @@ +from enum import IntEnum, unique + + +@unique +class ifc_material_definition(IntEnum): + """ifc material definition + + Examples: + >>> cadwork.ifc_material_definition.ignore + ignore + """ + ignore = 1 + """""" + material_layer_set = 2 + """""" + material_constituent_set = 3 + """""" + + def __int__(self) -> int: + return self.value + diff --git a/src/cadwork/ifc_options_aggregation.pyi b/src/cadwork/ifc_options_aggregation.pyi index d0e2811..ceb8622 100644 --- a/src/cadwork/ifc_options_aggregation.pyi +++ b/src/cadwork/ifc_options_aggregation.pyi @@ -1,4 +1,4 @@ -from cadwork import element_grouping_type +from cadwork import element_grouping_type, ifc_material_definition from cadwork import ifc_element_combine_behaviour class ifc_options_aggregation: @@ -71,3 +71,20 @@ class ifc_options_aggregation: None """ + def set_multi_layer_material_definition_type(self, ifc_material_definition: ifc_material_definition) -> None: + """set multi layer material definition type + + Parameters: + ifc_material_definition: ifc_material_definition + + Returns: + None + """ + + def get_multi_layer_material_definition_type(self) -> ifc_material_definition: + """get multi layer material definition type + + Returns: + ifc_material_definition + """ + diff --git a/src/cadwork/shoulder_beam_geometry.pyi b/src/cadwork/shoulder_beam_geometry.pyi new file mode 100644 index 0000000..9f31c6f --- /dev/null +++ b/src/cadwork/shoulder_beam_geometry.pyi @@ -0,0 +1,23 @@ +from enum import IntEnum, unique + + +@unique +class shoulder_beam_geometry(IntEnum): + """shoulder beam geometry + + Examples: + >>> cadwork.shoulder_beam_geometry.bisector + bisector + """ + bisector = 0 + """""" + perpendicular_to_strut = 1 + """""" + perpendicular_to_counter_part = 2 + """""" + birdsmouth = 3 + """""" + + def __int__(self) -> int: + return self.value + diff --git a/src/cadwork/shoulder_drilling_orientation.pyi b/src/cadwork/shoulder_drilling_orientation.pyi new file mode 100644 index 0000000..b2d60d2 --- /dev/null +++ b/src/cadwork/shoulder_drilling_orientation.pyi @@ -0,0 +1,23 @@ +from enum import IntEnum, unique + + +@unique +class shoulder_drilling_orientation(IntEnum): + """shoulder drilling orientation + + Examples: + >>> cadwork.shoulder_drilling_orientation.perpendicular_to_bisector + perpendicular_to_bisector + """ + perpendicular_to_bisector = 1 + """""" + perpendicular_to_counter_part = 2 + """""" + perpendicular_to_strut = 3 + """""" + perpendicular_to_contact_surface = 4 + """""" + + def __int__(self) -> int: + return self.value + diff --git a/src/cadwork/shoulder_options.pyi b/src/cadwork/shoulder_options.pyi new file mode 100644 index 0000000..f79be86 --- /dev/null +++ b/src/cadwork/shoulder_options.pyi @@ -0,0 +1,342 @@ +class shoulder_options: + + def get_add_drilling_axis(self) -> bool: + """get add drilling axis + + Returns: + bool + """ + + def set_add_drilling_axis(self, value: bool) -> None: + """set add drilling axis + + Parameters: + value: value + + Returns: + None + """ + + def get_add_drilling_axis_query_user_flag(self) -> bool: + """get add drilling axis query user flag + + Returns: + bool + """ + + def set_add_drilling_axis_query_user_flag(self, flag: bool) -> None: + """set add drilling axis query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_diameter(self) -> float: + """get drilling diameter + + Returns: + float + """ + + def set_drilling_diameter(self, value: float) -> None: + """set drilling diameter + + Parameters: + value: value + + Returns: + None + """ + + def get_drilling_diameter_query_user_flag(self) -> bool: + """get drilling diameter query user flag + + Returns: + bool + """ + + def set_drilling_diameter_query_user_flag(self, flag: bool) -> None: + """set drilling diameter query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_tolerance(self) -> float: + """get drilling tolerance + + Returns: + float + """ + + def set_drilling_tolerance(self, value: float) -> None: + """set drilling tolerance + + Parameters: + value: value + + Returns: + None + """ + + def get_drilling_tolerance_query_user_flag(self) -> bool: + """get drilling tolerance query user flag + + Returns: + bool + """ + + def set_drilling_tolerance_query_user_flag(self, flag: bool) -> None: + """set drilling tolerance query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_orientation_query_user_flag(self) -> bool: + """get drilling orientation query user flag + + Returns: + bool + """ + + def set_drilling_orientation_query_user_flag(self, flag: bool) -> None: + """set drilling orientation query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_beam_geometry(self) -> 'shoulder_beam_geometry': + """get beam geometry + + Returns: + shoulder_beam_geometry + """ + + def set_beam_geometry(self, value: 'shoulder_beam_geometry') -> None: + """set beam geometry + + Parameters: + value: value + + Returns: + None + """ + + def get_beam_geometry_query_user_flag(self) -> bool: + """get beam geometry query user flag + + Returns: + bool + """ + + def set_beam_geometry_query_user_flag(self, flag: bool) -> None: + """set beam geometry query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_shoulder_depth(self) -> float: + """get shoulder depth + + Returns: + float + """ + + def set_shoulder_depth(self, value: float) -> None: + """set shoulder depth + + Parameters: + value: value + + Returns: + None + """ + + def get_shoulder_depth_query_user_flag(self) -> bool: + """get shoulder depth query user flag + + Returns: + bool + """ + + def set_shoulder_depth_query_user_flag(self, flag: bool) -> None: + """set shoulder depth query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_toe_offset(self) -> float: + """get toe offset + + Returns: + float + """ + + def set_toe_offset(self, value: float) -> None: + """set toe offset + + Parameters: + value: value + + Returns: + None + """ + + def get_toe_offset_query_user_flag(self) -> bool: + """get toe offset query user flag + + Returns: + bool + """ + + def set_toe_offset_query_user_flag(self, flag: bool) -> None: + """set toe offset query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_cut_counter_part_through_whole_width(self) -> bool: + """get cut counter part through whole width + + Returns: + bool + """ + + def set_cut_counter_part_through_whole_width(self, value: bool) -> None: + """set cut counter part through whole width + + Parameters: + value: value + + Returns: + None + """ + + def get_cut_counter_part_through_whole_width_query_user_flag(self) -> bool: + """get cut counter part through whole width query user flag + + Returns: + bool + """ + + def set_cut_counter_part_through_whole_width_query_user_flag(self, flag: bool) -> None: + """set cut counter part through whole width query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_add_end_type(self) -> bool: + """get add end type + + Returns: + bool + """ + + def set_add_end_type(self, value: bool) -> None: + """set add end type + + Parameters: + value: value + + Returns: + None + """ + + def get_add_end_type_query_user_flag(self) -> bool: + """get add end type query user flag + + Returns: + bool + """ + + def set_add_end_type_query_user_flag(self, flag: bool) -> None: + """set add end type query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_end_type_name(self) -> str: + """get end type name + + Returns: + str + """ + + def set_end_type_name(self, value: str) -> None: + """set end type name + + Parameters: + value: value + + Returns: + None + """ + + def get_end_type_name_query_user_flag(self) -> bool: + """get end type name query user flag + + Returns: + bool + """ + + def set_end_type_name_query_user_flag(self, flag: bool) -> None: + """set end type name query user flag + + Parameters: + flag: flag + + Returns: + None + """ + + def get_drilling_orientation(self) -> 'shoulder_drilling_orientation': + """get drilling orientation + + Returns: + shoulder_drilling_orientation + """ + + def set_drilling_orientation(self, value: 'shoulder_drilling_orientation') -> None: + """set drilling orientation + + Parameters: + value: value + + Returns: + None + """ + diff --git a/src/dimension_controller/__init__.pyi b/src/dimension_controller/__init__.pyi index 1fb805e..7f53aed 100644 --- a/src/dimension_controller/__init__.pyi +++ b/src/dimension_controller/__init__.pyi @@ -218,3 +218,12 @@ def get_segment_direction(element: int, segment_index: int) -> point_3d: point_3d """ +def get_total_dimension(element: int) ->bool: + """get total dimension + + Parameters: + element: element + + Returns: + bool + """ diff --git a/src/element_controller/__init__.pyi b/src/element_controller/__init__.pyi index 1aff9ee..445bd22 100644 --- a/src/element_controller/__init__.pyi +++ b/src/element_controller/__init__.pyi @@ -1997,4 +1997,105 @@ def get_elements_in_collision(element: int) ->List[int]: List[int] """ +def get_text_object_options(element: int) ->'text_object_options': + """get text object options + Parameters: + element: element + + Returns: + text_object_options + """ + +def get_is_element_group_single_select_mode() ->bool: + """get is element group single select mode + + Returns: + bool + """ + +def get_is_element_group_multi_select_mode() ->bool: + """get is element group multi select mode + + Returns: + bool + """ + +def apply_image_to_surface(element: int, image_file_path: str, p1: point_3d, p2: point_3d) ->bool: + """apply image to surface + + Parameters: + element: element + image_file_path: image_file_path + p1: p1 + p2: p2 + + Returns: + bool + """ + +def set_shoulder_options(options: None) ->None: + """set shoulder options + + Parameters: + options: options + + Returns: + None + """ + +def set_heel_shoulder_options(options: None) ->None: + """set heel shoulder options + + Parameters: + options: options + + Returns: + None + """ + +def set_double_shoulder_options(options: None) ->None: + """set double shoulder options + + Parameters: + options: options + + Returns: + None + """ + +def cut_shoulder(element_id_list: List[int], connecting_element_id_list: + List[int]) ->None: + """cut shoulder + + Parameters: + element_id_list: element_id_list + connecting_element_id_list: connecting_element_id_list + + Returns: + None + """ + +def cut_heel_shoulder(element_id_list: List[int], + connecting_element_id_list: List[int]) ->None: + """cut heel shoulder + + Parameters: + element_id_list: element_id_list + connecting_element_id_list: connecting_element_id_list + + Returns: + None + """ + +def cut_double_shoulder(element_id_list: List[int], + connecting_element_id_list: List[int]) ->None: + """cut double shoulder + + Parameters: + element_id_list: element_id_list + connecting_element_id_list: connecting_element_id_list + + Returns: + None + """ \ No newline at end of file diff --git a/src/visualization_controller/__init__.pyi b/src/visualization_controller/__init__.pyi index 63ca42e..3c30f5c 100644 --- a/src/visualization_controller/__init__.pyi +++ b/src/visualization_controller/__init__.pyi @@ -512,3 +512,64 @@ def enter_working_plane(plane_normal: point_3d, plane_origin: point_3d) ->None: None """ +def get_element_transparency(element_id: int) ->int: + """get element transparency + + Parameters: + element_id: element_id + + Returns: + int + """ + +def set_element_transparency(element_id_list: List[int], value: int) -> None: + """set element transparency + + Parameters: + element_id_list: element_id_list + value: value + + Returns: + None + """ + +def get_use_material_texture(element_id: int) -> bool: + """get use material texture + + Parameters: + element_id: element_id + + Returns: + bool + """ + +def set_use_material_texture(element_id_list: List[int], value: bool) -> None: + """set use material texture + + Parameters: + element_id_list: element_id_list + value: value + + Returns: + None + """ + +def display_bitmaps_as_texture_representation_in_shaded1(a0: bool) -> None: + """display bitmaps as texture representation in shaded1 + + Parameters: + a0: a0 + + Returns: + None + """ + +def display_bitmaps_as_texture_representation_in_shaded2(a0: bool) -> None: + """display bitmaps as texture representation in shaded2 + + Parameters: + a0: a0 + + Returns: + None + """ From 3bed7446af18b3bb0048ace4f3ae876d3eef9e7b Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Thu, 27 Feb 2025 15:16:36 +0100 Subject: [PATCH 09/52] Update cwapi3d version format to follow semantic versioning --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index df88b72..cb2803f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "30.0.693" +version = "30.693.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.10" description = 'Python bindings for CwAPI3D' From a63bc797caa30f926a57ccdad92680e6f2b379a6 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Fri, 25 Apr 2025 11:15:07 +0200 Subject: [PATCH 10/52] Add new classes and methods for cadwork v2025 build >=245, update documentation Signed-off-by: Michael Brunner --- dockerfile => Dockerfile | 0 docs/debug.md | 2 +- docs/documentation/element_filter.md | 6 + docs/documentation/element_map_query.md | 6 + docs/documentation/enums.md | 21 + docs/documentation/hit_result.md | 6 + docs/examples/utility_example.md | 2 +- docs/release_notes.md | 1736 +++----------------- mkdocs.yml | 127 +- pyproject.toml | 6 +- src/attribute_controller/__init__.pyi | 287 ++-- src/bim_controller/__init__.pyi | 25 +- src/cadwork/__init__.pyi | 76 + src/cadwork/dimension_base_format.pyi | 24 + src/cadwork/dxf_export_version.pyi | 18 + src/cadwork/dxf_layer_format_type.pyi | 26 + src/cadwork/element_filter.pyi | 82 + src/cadwork/element_map_query.pyi | 74 + src/cadwork/hit_result.pyi | 22 + src/cadwork/ifc_options_properties.pyi | 16 + src/cadwork/point.pyi | 11 + src/cadwork/projection_type.pyi | 4 +- src/cadwork/text_object_options.pyi | 16 + src/cadwork/window_geometry.pyi | 23 +- src/connector_axis_controller/__init__.pyi | 288 +++- src/dimension_controller/__init__.pyi | 12 + src/element_controller/__init__.pyi | 83 +- src/endtype_controller/__init__.pyi | 32 +- src/file_controller/__init__.pyi | 33 +- src/geometry_controller/__init__.pyi | 15 +- src/list_controller/__init__.pyi | 55 +- src/material_controller/__init__.pyi | 210 ++- src/menu_controller/__init__.pyi | 3 + src/scene_controller/__init__.pyi | 17 +- src/shop_drawing_controller/__init__.pyi | 2 +- src/utility_controller/__init__.pyi | 100 +- src/visualization_controller/__init__.pyi | 40 +- 37 files changed, 1623 insertions(+), 1883 deletions(-) rename dockerfile => Dockerfile (100%) create mode 100644 docs/documentation/element_filter.md create mode 100644 docs/documentation/element_map_query.md create mode 100644 docs/documentation/hit_result.md create mode 100644 src/cadwork/dimension_base_format.pyi create mode 100644 src/cadwork/dxf_export_version.pyi create mode 100644 src/cadwork/dxf_layer_format_type.pyi create mode 100644 src/cadwork/element_filter.pyi create mode 100644 src/cadwork/element_map_query.pyi create mode 100644 src/cadwork/hit_result.pyi create mode 100644 src/cadwork/point.pyi diff --git a/dockerfile b/Dockerfile similarity index 100% rename from dockerfile rename to Dockerfile diff --git a/docs/debug.md b/docs/debug.md index 6bafe8d..9c55bde 100644 --- a/docs/debug.md +++ b/docs/debug.md @@ -6,7 +6,7 @@ hide: **Debugging python script in cadwork**
This section refers to calling the plugins from the Plugin Bar. If you want to debug a script in cadwork, then you can enable the console in User Test in the user settings. When cadwork is restarted, the console opens. -In the console you will see the screen output, or errors. +In the console you will see the screen output or errors. User Test -> Userprofile -> Test Options... -> Console diff --git a/docs/documentation/element_filter.md b/docs/documentation/element_filter.md new file mode 100644 index 0000000..6560517 --- /dev/null +++ b/docs/documentation/element_filter.md @@ -0,0 +1,6 @@ +# element_filter + +::: src.cadwork.element_filter +rendering: +show_root_heading: false +show_source: true diff --git a/docs/documentation/element_map_query.md b/docs/documentation/element_map_query.md new file mode 100644 index 0000000..48e1c63 --- /dev/null +++ b/docs/documentation/element_map_query.md @@ -0,0 +1,6 @@ +# element_map_query + +::: src.cadwork.element_map_query +rendering: +show_root_heading: false +show_source: true diff --git a/docs/documentation/enums.md b/docs/documentation/enums.md index f760e3a..6c3f0e3 100644 --- a/docs/documentation/enums.md +++ b/docs/documentation/enums.md @@ -73,3 +73,24 @@ rendering: show_root_heading: false show_source: true + +### Dimenson base format + +::: src.cadwork.dimension_base_format +rendering: +show_root_heading: false +show_source: true + +### DXF export version + +::: src.cadwork.dxf_export_version +rendering: +show_root_heading: false +show_source: true + +### DXF layer format type + +::: src.cadwork.dxf_layer_format_type +rendering: +show_root_heading: false +show_source: true diff --git a/docs/documentation/hit_result.md b/docs/documentation/hit_result.md new file mode 100644 index 0000000..6fae9fb --- /dev/null +++ b/docs/documentation/hit_result.md @@ -0,0 +1,6 @@ +# hit_result + +::: src.cadwork.hit_result +rendering: +show_root_heading: false +show_source: true diff --git a/docs/examples/utility_example.md b/docs/examples/utility_example.md index ea40c95..93d09d8 100644 --- a/docs/examples/utility_example.md +++ b/docs/examples/utility_example.md @@ -28,7 +28,7 @@ for p in points_range: vc.set_color(drillings, 5) uc.enable_auto_display_refresh() -# ec.ec.recreate_elements(element_ids) +ec.recreate_elements(drillings) end = timer() print(timedelta(seconds=end-start)) diff --git a/docs/release_notes.md b/docs/release_notes.md index f475b60..2f918e5 100644 --- a/docs/release_notes.md +++ b/docs/release_notes.md @@ -1,101 +1,43 @@ -## New Items -### Functions attribute_controller -#### get_standard_element_material_id +# Newly added functions, classes, and enums in cadwork 3D API 2025.0.245 -```python -def get_standard_element_material_id(element_id: int) ->int: - """get standard element material id - - Parameters: - element_id: element_id - - Returns: - int - """ - -``` - -## New Items ### Functions dimension_controller -#### get_total_dimension + +#### get_dimension_base_format ```python -def get_total_dimension(element: int) ->bool: - """get total dimension +def get_dimension_base_format(element: int) -> dimension_base_format: + """get dimension base format Parameters: element: element Returns: - bool + dimension_base_format """ ``` -## New Items -### Functions element_controller -#### unjoin_elements - -```python -def unjoin_elements(element_id_list: List[int]) ->bool: - """unjoin elements - - Parameters: - element_id_list: element_id_list - - Returns: - bool - """ -``` +### Functions element_controller -#### unjoin_top_level_elements +#### filter_elements ```python -def unjoin_top_level_elements(element_id_list: List[int]) ->bool: - """unjoin top level elements +def filter_elements(elements: List[int], element_filter: element_filter + ) -> List[int]: + """filter elements Parameters: - element_id_list: element_id_list - - Returns: - bool - """ - -``` - -#### set_element_group_single_select_mode - -```python -def set_element_group_single_select_mode() ->None: - """set element group single select mode - - Returns: - None - """ - -``` - -#### set_element_group_multi_select_mode - -```python -def set_element_group_multi_select_mode() ->None: - """set element group multi select mode - - Returns: - None - """ - -``` - -#### get_elements_in_collision - -```python -def get_elements_in_collision(element: int) ->List[int]: - """get elements in collision + elements: elements + element_filter: name_filter - Parameters: - element: element + Example: + >>> import cadwork + >>> import element_controller as ec + >>> your_element_filter = cadwork.element_filter() + >>> your_element_filter.set_name("beam") + >>> filtered_elements = ec.filter_elements(ec.get_active_identifiable_element_ids(), your_element_filter) + >>> print(filtered_elements) Returns: List[int] @@ -103,57 +45,76 @@ def get_elements_in_collision(element: int) ->List[int]: ``` -#### get_text_object_options +#### map_elements ```python -def get_text_object_options(element: int) ->text_object_options: - """get text object options +def map_elements(elements: List[int], map_query: element_map_query) -> Dict[ + str, List[int]]: + """map elements Parameters: - element: element + elements: elements + map_query: map_query + + Example: + >>> import cadwork + >>> import element_controller as ec + >>> your_map_query = cadwork.element_map_query() + >>> your_map_query.set_by_subgroup() + >>> mapped_items = ec.map_elements(ec.get_active_identifiable_element_ids(), your_map_query) + >>> print(mapped_items) Returns: - text_object_options + Dict[str, List[int]] """ ``` -#### get_is_element_group_single_select_mode +#### cast_ray_and_get_element_intersections ```python -def get_is_element_group_single_select_mode() ->bool: - """get is element group single select mode +def cast_ray_and_get_element_intersections(elements: List[int], + ray_start_position: point_3d, ray_end_position: point_3d, radius: float + ) -> hit_result: + """cast ray and get element intersections + Parameters: + elements: elements + ray_start_position: ray_start_position + ray_end_position: ray_end_position + radius: radius + + Example: + >>> import cadwork + >>> import element_controller as ec + >>> ray_start = cadwork.point_3d(0, 0, 0) + >>> ray_end = cadwork.point_3d(1000, 0, 0) + >>> hit_result = ec.cast_ray_and_get_element_intersections(ec.get_active_identifiable_element_ids(), ray_start, ray_end, 40.0) + >>> print(hits.get_hit_element_ids()) + >>> for element in hits.get_hit_element_ids(): + >>> print(f"ElementID {element}: {hits.get_hit_vertices_by_element(element)}") + >>> for pos in hits.get_hit_vertices_by_element(element): + >>> ec.create_node(pos) Returns: - bool + hit_result """ ``` -#### get_is_element_group_multi_select_mode - -```python -def get_is_element_group_multi_select_mode() ->bool: - """get is element group multi select mode - - Returns: - bool - """ -``` +### Functions file_controller -#### apply_image_to_surface +#### export_dxf_file ```python -def apply_image_to_surface(element: int, image_file_path: str, p1: point_3d, - p2: point_3d) ->bool: - """apply image to surface +def export_dxf_file(file_path: str, dxf_layer_format_type: +dxf_layer_format_type, dxf_export_version: dxf_export_version) -> bool: + """export dxf file Parameters: - element: element - image_file_path: image_file_path - p1: p1 - p2: p2 + file_path: file_path + dxf_layer_format_type: dxf_layer_format_type + dxf_export_version: dxf_export_version Returns: bool @@ -161,61 +122,42 @@ def apply_image_to_surface(element: int, image_file_path: str, p1: point_3d, ``` -#### set_shoulder_options +#### export_dstv_file ```python -def set_shoulder_options(options: None) ->None: - """set shoulder options +def export_dstv_file(file_path: str) -> bool: + """export dstv file Parameters: - options: options + file_path: file_path Returns: - None + bool """ ``` -#### set_heel_shoulder_options - -```python -def set_heel_shoulder_options(options: None) ->None: - """set heel shoulder options - - Parameters: - options: options - - Returns: - None - """ - -``` +### Functions utility_controller -#### set_double_shoulder_options +#### get_3d_version_name ```python -def set_double_shoulder_options(options: None) ->None: - """set double shoulder options - - Parameters: - options: options +def get_3d_version_name() -> str: + """get 3d version name Returns: - None + str """ ``` -#### cut_shoulder +#### redirect_python_output_to_logger ```python -def cut_shoulder(element_id_list: List[int], connecting_element_id_list: - List[int]) ->None: - """cut shoulder - - Parameters: - element_id_list: element_id_list - connecting_element_id_list: connecting_element_id_list +def redirect_python_output_to_logger() -> None: + """redirect python output to logger. + This function is used to redirect the output of the Python interpreter to the logger. + This is useful for debugging and logging purposes. Returns: None @@ -223,1509 +165,339 @@ def cut_shoulder(element_id_list: List[int], connecting_element_id_list: ``` -#### cut_heel_shoulder - -```python -def cut_heel_shoulder(element_id_list: List[int], - connecting_element_id_list: List[int]) ->None: - """cut heel shoulder - - Parameters: - element_id_list: element_id_list - connecting_element_id_list: connecting_element_id_list - - Returns: - None - """ - -``` +### Classes cadwork -#### cut_double_shoulder +#### bim_team_upload_result ```python -def cut_double_shoulder(element_id_list: List[int], - connecting_element_id_list: List[int]) ->None: - """cut double shoulder - - Parameters: - element_id_list: element_id_list - connecting_element_id_list: connecting_element_id_list - - Returns: - None +class bim_team_upload_result: + """bim team upload result """ -``` - -## New Items -### Functions file_controller -#### export_step_file_cut_drillings - -```python -def export_step_file_cut_drillings(a0: List[int], a1: str, a2: float, a3: - int, a4: bool, a5: bool) ->None: - """export step file cut drillings - - Parameters: - a0: a0 - a1: a1 - a2: a2 - a3: a3 - a4: a4 - a5: a5 + def __init__(self): + """ + Instance of the bim_team_upload_result class. - Returns: - None - """ + Attributes: + upload_result_code (bim_team_upload_result_code): The result code of the upload. + share_link (str): The share link for the uploaded BIM team result. + """ + self.upload_result_code = bim_team_upload_result_code.ok + self.share_link = '' ``` -#### export_sat_file_cut_drillings - -```python -def export_sat_file_cut_drillings(elements: List[int], file_path: str, - scale_factor: float, binary: bool, version: int) ->None: - """export sat file cut drillings - - Parameters: - elements: elements - file_path: file_path - scale_factor: scale_factor - binary: binary - version: version - - Returns: - None - """ - -``` +### Classes cadwork -#### upload_to_bim_team_and_create_share_link +#### bim_team_upload_result_code ```python -def upload_to_bim_team_and_create_share_link(elements: None - ) ->bim_team_upload_result: - """upload to bim team and create share link - - Parameters: - elements: elements +@unique +class bim_team_upload_result_code(IntEnum): + """bim team upload result code - Returns: - bim_team_upload_result + Examples: + >>> cadwork.bim_team_upload_result_code.ok + ok """ + ok = 0 + """""" + error_general_error = 1 + """""" + error_too_many_models = 2 + """""" + error_insufficient_storage = 3 + """""" + error_invalid_project_id = 4 + """""" + error_authentication_failed = 5 + """""" -``` - -## New Items -### Functions visualization_controller -#### enter_working_plane - -```python -def enter_working_plane(plane_normal: point_3d, plane_origin: point_3d) ->None: - """enter working plane - - Parameters: - plane_normal: plane_normal - plane_origin: plane_origin - - Returns: - None - """ + def __int__(self) -> int: + return self.value ``` -#### get_element_transparency - -```python -def get_element_transparency(element_id: int) ->int: - """get element transparency - - Parameters: - element_id: element_id - - Returns: - int - """ - -``` +### Classes cadwork -#### set_element_transparency +#### dimension_base_format ```python -def set_element_transparency(element_id_list: List[int], value: int) ->None: - """set element transparency +@unique +class dimension_base_format(IntEnum): + """ Enumeration for dimension base format. - Parameters: - element_id_list: element_id_list - value: value + Examples: + >>> cadwork.dimension_base_format.sum_only - Returns: - None """ + none = 0 + """""" + distance_only = 1 + """""" + sum_only = 2 + """""" + distance_and_sum = 3 + """""" + sum_moved = 4 + """""" -``` - -#### get_use_material_texture - -```python -def get_use_material_texture(element_id: int) ->bool: - """get use material texture - - Parameters: - element_id: element_id - - Returns: - bool - """ + def __int__(self) -> int: + return self.value ``` -#### set_use_material_texture - -```python -def set_use_material_texture(element_id_list: List[int], value: bool) ->None: - """set use material texture - - Parameters: - element_id_list: element_id_list - value: value - - Returns: - None - """ - -``` +### Classes cadwork -#### display_bitmaps_as_texture_representation_in_shaded1 +#### dxf_export_version ```python -def display_bitmaps_as_texture_representation_in_shaded1(a0: bool) ->None: - """display bitmaps as texture representation in shaded1 +@unique +class dxf_export_version(IntEnum): + """ Enumeration for DXF export version. - Parameters: - a0: a0 + Examples: + >>> cadwork.dxf_export_version.auto_cad_r27 - Returns: - None """ + auto_cad_r10 = 0 + """""" + auto_cad_r27 = 1 + """""" + + def __int__(self) -> int: + return self.value ``` -#### display_bitmaps_as_texture_representation_in_shaded2 +### Classes cadwork + +#### dxf_layer_format_type ```python -def display_bitmaps_as_texture_representation_in_shaded2(a0: bool) ->None: - """display bitmaps as texture representation in shaded2 +@unique +class dxf_layer_format_type(IntEnum): + """ Enumeration for DXF layer format type. - Parameters: - a0: a0 + Examples: + >>> cadwork.dxf_layer_format_type.color - Returns: - None """ + all_in_no_1 = 0 + """""" + color = 1 + """""" + material = 2 + """""" + name = 3 + """""" + group = 4 + """""" + subgroup = 5 + """""" + + def __int__(self) -> int: + return self.value ``` -## New Items -### Classes cadwork -#### double_shoulder_options -```python -class double_shoulder_options: +### Classes cadwork - def get_add_drilling_axis(self) ->bool: - """get add drilling axis +#### element_filter - Returns: - bool - """ +```python +class element_filter: - def set_add_drilling_axis(self, value: bool) ->None: - """set add drilling axis + def set_name(self, name: str) -> None: + """set name Parameters: - value: value + name: name Returns: None """ - def get_add_drilling_axis_query_user_flag(self) ->bool: - """get add drilling axis query user flag - - Returns: - bool - """ - - def set_add_drilling_axis_query_user_flag(self, flag: bool) ->None: - """set add drilling axis query user flag + def set_group(self, group: str) -> None: + """set group Parameters: - flag: flag + group: group Returns: None """ - def get_drilling_diameter(self) ->float: - """get drilling diameter + def set_subgroup(self, subgroup: str) -> None: + """set subgroup + + Parameters: + subgroup: subgroup Returns: - float + None """ - def set_drilling_diameter(self, value: float) ->None: - """set drilling diameter + def set_comment(self, comment: str) -> None: + """set comment Parameters: - value: value + comment: comment Returns: None """ - def get_drilling_diameter_query_user_flag(self) ->bool: - """get drilling diameter query user flag + def set_user_attribute(self, number: int, user_attribute: str) -> None: + """set user attribute + + Parameters: + number: number + user_attribute: user_attribute Returns: - bool + None """ - def set_drilling_diameter_query_user_flag(self, flag: bool) ->None: - """set drilling diameter query user flag + def set_sku(self, sku: str) -> None: + """set sku Parameters: - flag: flag + sku: sku Returns: None """ - def get_drilling_tolerance(self) ->float: - """get drilling tolerance + def set_production_number(self, production_number: int) -> None: + """set production number + + Parameters: + production_number: production_number Returns: - float + None """ - def set_drilling_tolerance(self, value: float) ->None: - """set drilling tolerance + def set_part_number(self, part_number: int) -> None: + """set part number Parameters: - value: value + part_number: part_number Returns: None """ - def get_drilling_tolerance_query_user_flag(self) ->bool: - """get drilling tolerance query user flag +``` - Returns: - bool - """ - def set_drilling_tolerance_query_user_flag(self, flag: bool) ->None: - """set drilling tolerance query user flag +### Classes cadwork - Parameters: - flag: flag +#### element_map_query + +```python +class element_map_query: + + def set_by_name(self) -> None: + """set by name Returns: None """ - def get_drilling_orientation_query_user_flag(self) ->bool: - """get drilling orientation query user flag + def set_by_group(self) -> None: + """set by group Returns: - bool + None """ - def set_drilling_orientation_query_user_flag(self, flag: bool) ->None: - """set drilling orientation query user flag - - Parameters: - flag: flag + def set_by_subgroup(self) -> None: + """set by subgroup Returns: None """ - def get_beam_geometry(self) ->shoulder_beam_geometry: - """get beam geometry + def set_by_comment(self) -> None: + """set by comment Returns: - shoulder_beam_geometry + None """ - def set_beam_geometry(self, value: shoulder_beam_geometry) ->None: - """set beam geometry + def set_by_user_attribute(self, number: int) -> None: + """set by user attribute Parameters: - value: value + number: number Returns: None """ - def get_beam_geometry_query_user_flag(self) ->bool: - """get beam geometry query user flag + def set_by_sku(self) -> None: + """set by sku Returns: - bool + None """ - def set_beam_geometry_query_user_flag(self, flag: bool) ->None: - """set beam geometry query user flag - - Parameters: - flag: flag + def set_by_production_number(self) -> None: + """set by production number Returns: None """ - def get_double_shoulder_depth(self) ->float: - """get double shoulder depth + def set_by_part_number(self) -> None: + """set by part number Returns: - float + None """ - def set_double_shoulder_depth(self, value: float) ->None: - """set double shoulder depth - - Parameters: - value: value + def set_by_building(self) -> None: + """set by building Returns: None """ - def get_double_shoulder_depth_query_user_flag(self) ->bool: - """get double shoulder depth query user flag + def set_by_storey(self) -> None: + """set by storey Returns: - bool + None """ - def set_double_shoulder_depth_query_user_flag(self, flag: bool) ->None: - """set double shoulder depth query user flag +``` - Parameters: - flag: flag - Returns: - None - """ - - def get_heel_shoulder_depth(self) ->float: - """get heel shoulder depth - - Returns: - float - """ - - def set_heel_shoulder_depth(self, value: float) ->None: - """set heel shoulder depth - - Parameters: - value: value - - Returns: - None - """ - - def get_heel_shoulder_depth_query_user_flag(self) ->bool: - """get heel shoulder depth query user flag - - Returns: - bool - """ - - def set_heel_shoulder_depth_query_user_flag(self, flag: bool) ->None: - """set heel shoulder depth query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_cut_counter_part_through_whole_width(self) ->bool: - """get cut counter part through whole width - - Returns: - bool - """ - - def set_cut_counter_part_through_whole_width(self, value: bool) ->None: - """set cut counter part through whole width - - Parameters: - value: value - - Returns: - None - """ - - def get_cut_counter_part_through_whole_width_query_user_flag(self) ->bool: - """get cut counter part through whole width query user flag - - Returns: - bool - """ - - def set_cut_counter_part_through_whole_width_query_user_flag(self, flag: - bool) ->None: - """set cut counter part through whole width query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_drilling_orientation(self) ->shoulder_drilling_orientation: - """get drilling orientation - - Returns: - shoulder_drilling_orientation - """ - - def set_drilling_orientation(self, value: shoulder_drilling_orientation - ) ->None: - """set drilling orientation - - Parameters: - value: value - - Returns: - None - """ - -``` - -## New Items -### Classes cadwork -#### extended_settings - -```python -class extended_settings: - - def get_btl_wall_export(self) ->bool: - """get btl wall export - - Returns: - bool - """ - - def get_chief_element(self) ->bool: - """get chief element - - Returns: - bool - """ - - def get_group_export(self) ->bool: - """get group export - - Returns: - bool - """ - - def get_ignore_for_connector_axis(self) ->bool: - """get ignore for connector axis - - Returns: - bool - """ - - def get_log_home_export(self) ->bool: - """get log home export - - Returns: - bool - """ - - def get_log_macro_export(self) ->bool: - """get log macro export - - Returns: - bool - """ - - def get_mfb_export(self) ->bool: - """get mfb export - - Returns: - bool - """ - - def get_outline(self) ->bool: - """get outline - - Returns: - bool - """ - - def get_piece_by_piece_export_with_dimensions(self) ->bool: - """get piece by piece export with dimensions - - Returns: - bool - """ - - def get_piece_by_piece_export_without_dimensions(self) ->bool: - """get piece by piece export without dimensions - - Returns: - bool - """ - - def get_wall_export(self) ->bool: - """get wall export - - Returns: - bool - """ - - def set_btl_wall_export(self, value: bool) ->None: - """set btl wall export - - Parameters: - value: value - - Returns: - None - """ - - def set_chief_element(self, value: bool) ->None: - """set chief element - - Parameters: - value: value - - Returns: - None - """ - - def set_group_export(self, value: bool) ->None: - """set group export - - Parameters: - value: value - - Returns: - None - """ - - def set_ignore_for_connector_axis(self, value: bool) ->None: - """set ignore for connector axis - - Parameters: - value: value - - Returns: - None - """ - - def set_log_home_export(self, value: bool) ->None: - """set log home export - - Parameters: - value: value - - Returns: - None - """ - - def set_mfb_export(self, value: bool) ->None: - """set mfb export - - Parameters: - value: value - - Returns: - None - """ - - def set_outline(self, value: bool) ->None: - """set outline - - Parameters: - value: value - - Returns: - None - """ - - def set_piece_by_piece_export_with_dimensions(self, value: bool) ->None: - """set piece by piece export with dimensions - - Parameters: - value: value - - Returns: - None - """ - - def set_piece_by_piece_export_without_dimensions(self, value: bool) ->None: - """set piece by piece export without dimensions - - Parameters: - value: value - - Returns: - None - """ - - def set_wall_export(self, value: bool) ->None: - """set wall export - - Parameters: - value: value - - Returns: - None - """ - - def get_ignore_processing(self) ->bool: - """get ignore processing - - Returns: - bool - """ - - def set_ignore_processing(self, value: bool) ->None: - """set ignore processing - - Parameters: - value: value - - Returns: - None - """ - - def get_single_piece(self) ->bool: - """get single piece - - Returns: - bool - """ - - def set_single_piece(self, value: bool) ->None: - """set single piece - - Parameters: - value: value - - Returns: - None - """ - - def get_composite(self) ->bool: - """get composite - - Returns: - bool - """ - - def set_composite(self, value: bool) ->None: - """set composite - - Parameters: - value: value - - Returns: - None - """ - - def get_drilling_create_notches(self) ->bool: - """get drilling create notches - - Returns: - bool - """ - - def set_drilling_create_notches(self, value: bool) ->None: - """set drilling create notches - - Parameters: - value: value - - Returns: - None - """ - -``` - -## New Items -### Classes cadwork -#### heel_shoulder_beam_geometry - -```python -@unique -class heel_shoulder_beam_geometry(IntEnum): - """heel shoulder beam geometry - - Examples: - >>> cadwork.heel_shoulder_beam_geometry.normal - normal - """ - normal = 0 - """""" - straight = 1 - """""" - - def __int__(self) ->int: - return self.value - -``` - -## New Items -### Classes cadwork -#### heel_shoulder_options - -```python -class heel_shoulder_options: - - def get_beam_geometry(self) ->shoulder_beam_geometry: - """get beam geometry - - Returns: - shoulder_beam_geometry - """ - - def set_beam_geometry(self, value: shoulder_beam_geometry) ->None: - """set beam geometry - - Parameters: - value: value - - Returns: - None - """ - - def get_beam_geometry_query_user_flag(self) ->bool: - """get beam geometry query user flag - - Returns: - bool - """ - - def set_beam_geometry_query_user_flag(self, flag: bool) ->None: - """set beam geometry query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_shoulder_depth(self) ->float: - """get shoulder depth - - Returns: - float - """ - - def set_shoulder_depth(self, value: float) ->None: - """set shoulder depth - - Parameters: - value: value - - Returns: - None - """ - - def get_shoulder_depth_query_user_flag(self) ->bool: - """get shoulder depth query user flag - - Returns: - bool - """ - - def set_shoulder_depth_query_user_flag(self, flag: bool) ->None: - """set shoulder depth query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_gap(self) ->float: - """get gap - - Returns: - float - """ - - def set_gap(self, value: float) ->None: - """set gap - - Parameters: - value: value - - Returns: - None - """ - - def get_gap_query_user_flag(self) ->bool: - """get gap query user flag - - Returns: - bool - """ - - def set_gap_query_user_flag(self, flag: bool) ->None: - """set gap query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_cut_counter_part_through_whole_width(self) ->bool: - """get cut counter part through whole width - - Returns: - bool - """ - - def set_cut_counter_part_through_whole_width(self, value: bool) ->None: - """set cut counter part through whole width - - Parameters: - value: value - - Returns: - None - """ - - def get_cut_counter_part_through_whole_width_query_user_flag(self) ->bool: - """get cut counter part through whole width query user flag - - Returns: - bool - """ - - def set_cut_counter_part_through_whole_width_query_user_flag(self, flag: - bool) ->None: - """set cut counter part through whole width query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_add_end_type(self) ->bool: - """get add end type - - Returns: - bool - """ - - def set_add_end_type(self, value: bool) ->None: - """set add end type - - Parameters: - value: value - - Returns: - None - """ - - def get_add_end_type_query_user_flag(self) ->bool: - """get add end type query user flag - - Returns: - bool - """ - - def set_add_end_type_query_user_flag(self, flag: bool) ->None: - """set add end type query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_end_type_name(self) ->str: - """get end type name - - Returns: - str - """ - - def set_end_type_name(self, value: str) ->None: - """set end type name - - Parameters: - value: value - - Returns: - None - """ - - def get_end_type_name_query_user_flag(self) ->bool: - """get end type name query user flag - - Returns: - bool - """ - - def set_end_type_name_query_user_flag(self, flag: bool) ->None: - """set end type name query user flag - - Parameters: - flag: flag - - Returns: - None - """ - -``` - -## New Items -### Classes cadwork -#### ifc_material_definition - -```python -@unique -class ifc_material_definition(IntEnum): - """ifc material definition - - Examples: - >>> cadwork.ifc_material_definition.ignore - ignore - """ - ignore = 1 - """""" - material_layer_set = 2 - """""" - material_constituent_set = 3 - """""" - - def __int__(self) ->int: - return self.value - -``` - -## New Items -### Classes cadwork -#### ifc_options_aggregation - -```python -class ifc_options_aggregation: - - def set_consider_element_aggregation(self, consider_element_aggregation: - bool) ->None: - """set consider element aggregation - - Parameters: - consider_element_aggregation: consider_element_aggregation - - Returns: - None - """ - - def get_element_aggregation_attribute(self) ->int: - """get element aggregation attribute - - Returns: - int - """ - - def set_export_cover_geometry(self, export_cover_geometry: bool) ->None: - """set export cover geometry - - Parameters: - export_cover_geometry: export_cover_geometry - - Returns: - None - """ - - def set_element_aggregation_attribute(self, - element_aggregation_attribute: element_grouping_type) ->None: - """set element aggregation attribute - - Parameters: - element_aggregation_attribute: element_aggregation_attribute - - Returns: - None - """ - - def set_element_combine_type(self, element_combine_type: - ifc_element_combine_behaviour) ->None: - """set element combine type - - Parameters: - element_combine_type: element_combine_type - - Returns: - None - """ - - def get_consider_element_aggregation(self) ->bool: - """get consider element aggregation - - Returns: - bool - """ - - def get_export_cover_geometry(self) ->bool: - """get export cover geometry - - Returns: - bool - """ - - def get_element_combine_type(self) ->ifc_element_combine_behaviour: - """get element combine type - - Returns: - ifc_element_combine_behaviour - """ - - def set_multi_layer_material_definition_type(self, - ifc_material_definition: ifc_material_definition) ->None: - """set multi layer material definition type - - Parameters: - ifc_material_definition: ifc_material_definition - - Returns: - None - """ - - def get_multi_layer_material_definition_type(self - ) ->ifc_material_definition: - """get multi layer material definition type - - Returns: - ifc_material_definition - """ - -``` - -## New Items -### Classes cadwork -#### shoulder_beam_geometry - -```python -@unique -class shoulder_beam_geometry(IntEnum): - """shoulder beam geometry - - Examples: - >>> cadwork.shoulder_beam_geometry.bisector - bisector - """ - bisector = 0 - """""" - perpendicular_to_strut = 1 - """""" - perpendicular_to_counter_part = 2 - """""" - birdsmouth = 3 - """""" - - def __int__(self) ->int: - return self.value - -``` - -## New Items ### Classes cadwork -#### shoulder_drilling_orientation - -```python -@unique -class shoulder_drilling_orientation(IntEnum): - """shoulder drilling orientation - Examples: - >>> cadwork.shoulder_drilling_orientation.perpendicular_to_bisector - perpendicular_to_bisector - """ - perpendicular_to_bisector = 1 - """""" - perpendicular_to_counter_part = 2 - """""" - perpendicular_to_strut = 3 - """""" - perpendicular_to_contact_surface = 4 - """""" - - def __int__(self) ->int: - return self.value - -``` - -## New Items -### Classes cadwork -#### shoulder_options +#### hit_result ```python -class shoulder_options: - - def get_add_drilling_axis(self) ->bool: - """get add drilling axis - - Returns: - bool - """ - - def set_add_drilling_axis(self, value: bool) ->None: - """set add drilling axis - - Parameters: - value: value - - Returns: - None - """ - - def get_add_drilling_axis_query_user_flag(self) ->bool: - """get add drilling axis query user flag - - Returns: - bool - """ - - def set_add_drilling_axis_query_user_flag(self, flag: bool) ->None: - """set add drilling axis query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_drilling_diameter(self) ->float: - """get drilling diameter - - Returns: - float - """ - - def set_drilling_diameter(self, value: float) ->None: - """set drilling diameter - - Parameters: - value: value - - Returns: - None - """ - - def get_drilling_diameter_query_user_flag(self) ->bool: - """get drilling diameter query user flag - - Returns: - bool - """ - - def set_drilling_diameter_query_user_flag(self, flag: bool) ->None: - """set drilling diameter query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_drilling_tolerance(self) ->float: - """get drilling tolerance - - Returns: - float - """ - - def set_drilling_tolerance(self, value: float) ->None: - """set drilling tolerance - - Parameters: - value: value - - Returns: - None - """ - - def get_drilling_tolerance_query_user_flag(self) ->bool: - """get drilling tolerance query user flag - - Returns: - bool - """ - - def set_drilling_tolerance_query_user_flag(self, flag: bool) ->None: - """set drilling tolerance query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_drilling_orientation_query_user_flag(self) ->bool: - """get drilling orientation query user flag - - Returns: - bool - """ - - def set_drilling_orientation_query_user_flag(self, flag: bool) ->None: - """set drilling orientation query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_beam_geometry(self) ->shoulder_beam_geometry: - """get beam geometry - - Returns: - shoulder_beam_geometry - """ - - def set_beam_geometry(self, value: shoulder_beam_geometry) ->None: - """set beam geometry - - Parameters: - value: value +class hit_result: - Returns: - None - """ - - def get_beam_geometry_query_user_flag(self) ->bool: - """get beam geometry query user flag - - Returns: - bool - """ - - def set_beam_geometry_query_user_flag(self, flag: bool) ->None: - """set beam geometry query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_shoulder_depth(self) ->float: - """get shoulder depth - - Returns: - float - """ - - def set_shoulder_depth(self, value: float) ->None: - """set shoulder depth - - Parameters: - value: value - - Returns: - None - """ - - def get_shoulder_depth_query_user_flag(self) ->bool: - """get shoulder depth query user flag - - Returns: - bool - """ - - def set_shoulder_depth_query_user_flag(self, flag: bool) ->None: - """set shoulder depth query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_toe_offset(self) ->float: - """get toe offset - - Returns: - float - """ - - def set_toe_offset(self, value: float) ->None: - """set toe offset - - Parameters: - value: value - - Returns: - None - """ - - def get_toe_offset_query_user_flag(self) ->bool: - """get toe offset query user flag - - Returns: - bool - """ - - def set_toe_offset_query_user_flag(self, flag: bool) ->None: - """set toe offset query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_cut_counter_part_through_whole_width(self) ->bool: - """get cut counter part through whole width - - Returns: - bool - """ - - def set_cut_counter_part_through_whole_width(self, value: bool) ->None: - """set cut counter part through whole width - - Parameters: - value: value - - Returns: - None - """ - - def get_cut_counter_part_through_whole_width_query_user_flag(self) ->bool: - """get cut counter part through whole width query user flag - - Returns: - bool - """ - - def set_cut_counter_part_through_whole_width_query_user_flag(self, flag: - bool) ->None: - """set cut counter part through whole width query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_add_end_type(self) ->bool: - """get add end type - - Returns: - bool - """ - - def set_add_end_type(self, value: bool) ->None: - """set add end type - - Parameters: - value: value - - Returns: - None - """ - - def get_add_end_type_query_user_flag(self) ->bool: - """get add end type query user flag - - Returns: - bool - """ - - def set_add_end_type_query_user_flag(self, flag: bool) ->None: - """set add end type query user flag - - Parameters: - flag: flag - - Returns: - None - """ - - def get_end_type_name(self) ->str: - """get end type name - - Returns: - str - """ - - def set_end_type_name(self, value: str) ->None: - """set end type name - - Parameters: - value: value - - Returns: - None - """ - - def get_end_type_name_query_user_flag(self) ->bool: - """get end type name query user flag - - Returns: - bool - """ - - def set_end_type_name_query_user_flag(self, flag: bool) ->None: - """set end type name query user flag - - Parameters: - flag: flag + def get_hit_element_ids(self) -> List[int]: + """get hit element ids Returns: - None - """ - - def get_drilling_orientation(self) ->shoulder_drilling_orientation: - """get drilling orientation - - Returns: - shoulder_drilling_orientation + List[int] """ - def set_drilling_orientation(self, value: shoulder_drilling_orientation - ) ->None: - """set drilling orientation + def get_hit_vertices_by_element(self, element_id: int) -> List[point_3d]: + """get hit vertices by element Parameters: - value: value + element_id: element_id Returns: - None + List[point_3d] """ -``` - +``` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 9ac8078..53111d9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -11,7 +11,7 @@ theme: name: material logo: cw_logo.svg favicon: cw_logo.svg - version: V30 + version: V2025 palette: - scheme: default toggle: @@ -29,69 +29,72 @@ theme: nav: - Home: - - index.md - - Getting Started: get_started.md - - Packages and Modules: modules.md - - Debugging: debug.md - - Community: community.md + - index.md + - Getting Started: get_started.md + - Packages and Modules: modules.md + - Debugging: debug.md + - Community: community.md - Reference: - - Attribute Controller: documentation/attribute_controller.md - - BIM Controller: documentation/bim_controller.md - - Cadwork: - - Element Module Properties: documentation/element_module_properties.md - - Element Type: documentation/element_type.md - - Process Type: documentation/process_type.md - - Point 3D: documentation/point_3d.md - - Enumerations: documentation/enums.md - - Extended Settings: documentation/extended_settings.md - - Rhino Export Options: documentation/rhino_export_options.md - - BREP data: documentation/brep_data.md - - IFC: - - IFC2x3 Element Type: documentation/ifc_2x3_element_type.md - - IFC Options: documentation/ifc_options.md - - Camera: documentation/camera_data.md - - Layer Settings: documentation/layer_settings.md - - Text Object Options: documentation/text_object_options.md - - Window Geometry: documentation/window_geometry.md - - BIMteam Upload Result: documentation/bim_team_upload_result.md - - Shoulder cut options: documentation/shoulder_options.md - - Connector Axis Controller: documentation/connector_axis_controller.md - - Dimension Controller: documentation/dimension_controller.md - - Element Controller: documentation/element_controller.md - - End-Type Controller: documentation/endtype_controller.md - - File Controller: documentation/file_controller.md - - Geometry Controller: documentation/geometry_controller.md - - List Controller: documentation/list_controller.md - - Machine Controller: documentation/machine_controller.md - - Material Controller: documentation/material_controller.md - - Menu Controller: documentation/menu_controller.md - - Multi Layer Cover Controller: documentation/multi_layer_cover_controller.md - - Roof Controller: documentation/roof_controller.md - - Scene Controller: documentation/scene_controller.md - - Shop Drawing Controller: documentation/shop_drawing_controller.md - - Utility Controller: documentation/utility_controller.md - - Visualization Controller: documentation/visualization_controller.md + - Attribute Controller: documentation/attribute_controller.md + - BIM Controller: documentation/bim_controller.md + - Cadwork: + - Element Module Properties: documentation/element_module_properties.md + - Element Type: documentation/element_type.md + - Process Type: documentation/process_type.md + - Point 3D: documentation/point_3d.md + - Enumerations: documentation/enums.md + - Extended Settings: documentation/extended_settings.md + - Rhino Export Options: documentation/rhino_export_options.md + - BREP data: documentation/brep_data.md + - IFC: + - IFC2x3 Element Type: documentation/ifc_2x3_element_type.md + - IFC Options: documentation/ifc_options.md + - Camera: documentation/camera_data.md + - Layer Settings: documentation/layer_settings.md + - Text Object Options: documentation/text_object_options.md + - Window Geometry: documentation/window_geometry.md + - BIMteam Upload Result: documentation/bim_team_upload_result.md + - Shoulder cut options: documentation/shoulder_options.md + - Element Filter: documentation/element_filter.md + - Element Map Query: documentation/element_map_query.md + - Hit Result: documentation/hit_result.md + - Connector Axis Controller: documentation/connector_axis_controller.md + - Dimension Controller: documentation/dimension_controller.md + - Element Controller: documentation/element_controller.md + - End-Type Controller: documentation/endtype_controller.md + - File Controller: documentation/file_controller.md + - Geometry Controller: documentation/geometry_controller.md + - List Controller: documentation/list_controller.md + - Machine Controller: documentation/machine_controller.md + - Material Controller: documentation/material_controller.md + - Menu Controller: documentation/menu_controller.md + - Multi Layer Cover Controller: documentation/multi_layer_cover_controller.md + - Roof Controller: documentation/roof_controller.md + - Scene Controller: documentation/scene_controller.md + - Shop Drawing Controller: documentation/shop_drawing_controller.md + - Utility Controller: documentation/utility_controller.md + - Visualization Controller: documentation/visualization_controller.md - Examples: - - Geometry: examples/geometry.md - - Attribute Controller: examples/attribute_example.md - - BIM Controller: examples/bim_example.md - - Cadwork: examples/cadwork.md - - Connector Axis Controller: examples/connector_example.md - - Element Controller: examples/element_example.md - - End-Type Controller: examples/endtype_example.md - - File Controller: examples/file_example.md - - Geometry Controller: examples/geometry_example.md - - List Controller: examples/list_example.md - - Machine Controller: examples/machine_example.md - - Material Controller: examples/material_example.md - - Menu Controller: examples/menu_example.md - - Roof Controller: examples/roof_example.md - - Scene Controller: examples/scene_example.md - - Shop Drawing Controller: examples/shop_drawing_example.md - - Utility Controller: examples/utility_example.md - - Visualization Controller: examples/visualization_example.md - - GUI: examples/tk_gui.md - - Compare: examples/compare.md + - Geometry: examples/geometry.md + - Attribute Controller: examples/attribute_example.md + - BIM Controller: examples/bim_example.md + - Cadwork: examples/cadwork.md + - Connector Axis Controller: examples/connector_example.md + - Element Controller: examples/element_example.md + - End-Type Controller: examples/endtype_example.md + - File Controller: examples/file_example.md + - Geometry Controller: examples/geometry_example.md + - List Controller: examples/list_example.md + - Machine Controller: examples/machine_example.md + - Material Controller: examples/material_example.md + - Menu Controller: examples/menu_example.md + - Roof Controller: examples/roof_example.md + - Scene Controller: examples/scene_example.md + - Shop Drawing Controller: examples/shop_drawing_example.md + - Utility Controller: examples/utility_example.md + - Visualization Controller: examples/visualization_example.md + - GUI: examples/tk_gui.md + - Compare: examples/compare.md - Videos: - videos.md - Auto Attributes: diff --git a/pyproject.toml b/pyproject.toml index cb2803f..abe22df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,8 @@ [project] name = "cwapi3d" -version = "30.693.0" +version = "32.246.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] -requires-python = ">= 3.10" +requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' readme = "README.md" license = { file = "LICENSE" } @@ -14,7 +14,7 @@ classifiers = [ "License :: OSI Approved :: MIT License", "Operating System :: Microsoft :: Windows", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.12", "Topic :: Software Development :: Libraries", ] diff --git a/src/attribute_controller/__init__.pyi b/src/attribute_controller/__init__.pyi index 958099e..0bdfaf4 100644 --- a/src/attribute_controller/__init__.pyi +++ b/src/attribute_controller/__init__.pyi @@ -1,9 +1,9 @@ from typing import List -from cadwork import attribute_display_settings -from cadwork import element_grouping_type -from cadwork import element_type -from cadwork import extended_settings -from cadwork import process_type +from cadwork.attribute_display_settings import attribute_display_settings +from cadwork.element_grouping_type import element_grouping_type +from cadwork.element_type import element_type +from cadwork.extended_settings import extended_settings +from cadwork.process_type import process_type def get_last_error(error_code: int) -> str: """Gets the last error @@ -192,21 +192,23 @@ def set_extended_settings(element_id_list: List[int], extended_settings: None) - None """ -def set_wall(a0: List[int]) -> None: + +def set_wall(element_ids: List[int]) -> None: """set wall Parameters: - a0: a0 + element_ids: element_ids Returns: None """ -def set_floor(a0: List[int]) -> None: + +def set_floor(element_ids: List[int]) -> None: """set floor Parameters: - a0: a0 + element_ids: element_ids Returns: None @@ -353,11 +355,12 @@ def set_solid_floor(elements: List[int]) -> None: None """ -def set_roof(a0: List[int]) -> None: + +def set_roof(elements: List[int]) -> None: """set roof Parameters: - a0: a0 + elements: elements Returns: None @@ -422,75 +425,82 @@ def update_auto_attribute() -> None: None """ -def set_additional_guid(a0: List[int], a1: str, a2: str) -> None: + +def set_additional_guid(elements: List[int], data_id: str, guid: str) -> None: """set additional guid Parameters: - a0: a0 - a1: a1 - a2: a2 + elements: elements + data_id: data_id + guid: guid Returns: None """ -def add_item_to_group_list(a0: str) -> None: + +def add_item_to_group_list(item: str) -> None: """add item to group list Parameters: - a0: a0 + item: item Returns: None """ -def add_item_to_subgroup_list(a0: str) -> None: + +def add_item_to_subgroup_list(item: str) -> None: """add item to subgroup list Parameters: - a0: a0 + item: item Returns: None """ -def add_item_to_comment_list(a0: str) -> None: + +def add_item_to_comment_list(item: str) -> None: """add item to comment list Parameters: - a0: a0 + item: item Returns: None """ -def add_item_to_sku_list(a0: str) -> None: + +def add_item_to_sku_list(item: str) -> None: """add item to sku list Parameters: - a0: a0 + item: item Returns: None """ -def add_item_to_user_attribute_list(a0: int, a1: str) -> None: + +def add_item_to_user_attribute_list(attribute_number: int, item: str) -> None: """add item to user attribute list Parameters: - a0: a0 - a1: a1 + attribute_number: attribute_number + item: item Returns: None """ -def set_container_number(a0: List[int], a1: int) -> None: + +def set_container_number(elements: List[int], number: int) -> None: """set container number Parameters: - a0: a0 - a1: a1 + elements: elements + number: number Returns: None @@ -503,272 +513,299 @@ def get_name_list_items() -> List[str]: List[str] """ -def add_item_to_name_list(a0: str) -> None: + +def add_item_to_name_list(item: str) -> None: """add item to name list Parameters: - a0: a0 + item: item Returns: None """ -def delete_item_from_comment_list(a0: str) -> bool: + +def delete_item_from_comment_list(item: str) -> bool: """delete item from comment list Parameters: - a0: a0 + item: item Returns: bool """ -def delete_item_from_group_list(a0: str) -> bool: + +def delete_item_from_group_list(item: str) -> bool: """delete item from group list Parameters: - a0: a0 + item: item Returns: bool """ -def delete_item_from_sku_list(a0: str) -> bool: + +def delete_item_from_sku_list(item: str) -> bool: """delete item from sku list Parameters: - a0: a0 + item: item Returns: bool """ -def delete_item_from_subgroup_list(a0: str) -> bool: + +def delete_item_from_subgroup_list(item: str) -> bool: """delete item from subgroup list Parameters: - a0: a0 + item: item Returns: bool """ -def delete_item_from_user_attribute_list(a0: int, a1: str) -> bool: + +def delete_item_from_user_attribute_list(attribute_number: int, item: str) -> bool: """delete item from user attribute list Parameters: - a0: a0 - a1: a1 + attribute_number: attribute_number + item: item Returns: bool """ -def set_attribute_display_settings_for_2d(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_2d(settings: attribute_display_settings) -> None: """set attribute display settings for 2d Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_2d_with_layout(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_2d_with_layout(settings: attribute_display_settings) -> None: """set attribute display settings for 2d with layout Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_2d_without_layout(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_2d_without_layout(settings: attribute_display_settings) -> None: """set attribute display settings for 2d without layout Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_3d(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_3d(settings: attribute_display_settings) -> None: """set attribute display settings for 3d Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_container(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_container(settings: attribute_display_settings) -> None: """set attribute display settings for container Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_export_solid(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_export_solid(settings: attribute_display_settings) -> None: """set attribute display settings for export solid Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_framed_wall_axis(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_framed_wall_axis(settings: attribute_display_settings) -> None: """set attribute display settings for framed wall axis Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_framed_wall_beam(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_framed_wall_beam(settings: attribute_display_settings) -> None: """set attribute display settings for framed wall beam Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_framed_wall_opening(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_framed_wall_opening(settings: attribute_display_settings) -> None: """set attribute display settings for framed wall opening Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_framed_wall_panel(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_framed_wall_panel(settings: attribute_display_settings) -> None: """set attribute display settings for framed wall panel Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_log_wall_axis(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_log_wall_axis(settings: attribute_display_settings) -> None: """set attribute display settings for log wall axis Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_log_wall_beam(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_log_wall_beam(settings: attribute_display_settings) -> None: """set attribute display settings for log wall beam Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_log_wall_opening(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_log_wall_opening(settings: attribute_display_settings) -> None: """set attribute display settings for log wall opening Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_log_wall_panel(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_log_wall_panel(settings: attribute_display_settings) -> None: """set attribute display settings for log wall panel Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_machine(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_machine(settings: attribute_display_settings) -> None: """set attribute display settings for machine Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_nesting_element(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_nesting_element(settings: attribute_display_settings) -> None: """set attribute display settings for nesting element Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_nesting_volume(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_nesting_volume(settings: attribute_display_settings) -> None: """set attribute display settings for nesting volume Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_solid_wall_axis(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_solid_wall_axis(settings: attribute_display_settings) -> None: """set attribute display settings for solid wall axis Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_solid_wall_beam(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_solid_wall_beam(settings: attribute_display_settings) -> None: """set attribute display settings for solid wall beam Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_solid_wall_opening(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_solid_wall_opening(settings: attribute_display_settings) -> None: """set attribute display settings for solid wall opening Parameters: - a0: a0 + settings: settings Returns: None """ -def set_attribute_display_settings_for_solid_wall_panel(a0: attribute_display_settings) -> None: + +def set_attribute_display_settings_for_solid_wall_panel(settings: attribute_display_settings) -> None: """set attribute display settings for solid wall panel Parameters: - a0: a0 + settings: settings Returns: None @@ -804,11 +841,12 @@ def set_framed_wall(element_id_list: List[int]) -> None: None """ -def get_name_list_items_by_element_type(a0: element_type) -> List[str]: + +def get_name_list_items_by_element_type(element_tpye: element_type) -> List[str]: """get name list items by element type Parameters: - a0: a0 + element_tpye: element_tpye Returns: List[str] @@ -1367,82 +1405,90 @@ def is_solid_roof(element_id: int) -> bool: bool """ -def get_additional_guid(a0: int, a1: str) -> str: + +def get_additional_guid(element_id: int, data_id: str) -> str: """get additional guid Parameters: - a0: a0 - a1: a1 + element_id: element_id + data_id: data_id Returns: str """ -def get_prefab_layer_all_assigned(a0: int) -> List[int]: + +def get_prefab_layer_all_assigned(element_id: int) -> List[int]: """get prefab layer all assigned Parameters: - a0: a0 + element_id: element_id Returns: List[int] """ -def get_prefab_layer_with_dimensions(a0: int) -> List[int]: + +def get_prefab_layer_with_dimensions(element_id: int) -> List[int]: """get prefab layer with dimensions Parameters: - a0: a0 + element_id: element_id Returns: List[int] """ -def get_prefab_layer_without_dimensions(a0: int) -> List[int]: + +def get_prefab_layer_without_dimensions(element_id: int) -> List[int]: """get prefab layer without dimensions Parameters: - a0: a0 + element_id: element_id Returns: List[int] """ -def is_nesting_parent(a0: int) -> bool: + +def is_nesting_parent(element_id: int) -> bool: """is nesting parent Parameters: - a0: a0 + element_id: element_id Returns: bool """ -def is_nesting_raw_part(a0: int) -> bool: + +def is_nesting_raw_part(element_id: int) -> bool: """is nesting raw part Parameters: - a0: a0 + element_id: element_id Returns: bool """ -def get_container_number(a0: int) -> int: + +def get_container_number(element_id: int) -> int: """get container number Parameters: - a0: a0 + element_id: element_id Returns: int """ -def get_container_number_with_prefix(a0: int) -> str: + +def get_container_number_with_prefix(element_id: int) -> str: """get container number with prefix Parameters: - a0: a0 + element_id: element_id Returns: str @@ -1476,71 +1522,78 @@ def get_sku_list_items() -> List[str]: List[str] """ -def get_user_attribute_list_items(a0: int) -> List[str]: + +def get_user_attribute_list_items(element_id: int) -> List[str]: """get user attribute list items Parameters: - a0: a0 + element_id: element_id Returns: List[str] """ -def is_circular_mep(a0: int) -> bool: + +def is_circular_mep(element_id: int) -> bool: """is circular mep Parameters: - a0: a0 + element_id: element_id Returns: bool """ -def is_rectangular_mep(a0: int) -> bool: + +def is_rectangular_mep(element_id: int) -> bool: """is rectangular mep Parameters: - a0: a0 + element_id: element_id Returns: bool """ -def get_machine_calculation_state(a0: int) -> str: + +def get_machine_calculation_state(element_id: int) -> str: """get machine calculation state Parameters: - a0: a0 + element_id: element_id Returns: str """ -def get_machine_calculation_set_machine_type(a0: int) -> str: + +def get_machine_calculation_set_machine_type(element_id: int) -> str: """get machine calculation set machine type Parameters: - a0: a0 + element_id: element_id Returns: str """ -def is_btl_processing_group(a0: int) -> bool: + +def is_btl_processing_group(element_id: int) -> bool: """is btl processing group Parameters: - a0: a0 + element_id: element_id Returns: bool """ -def is_hundegger_processing_group(a0: int) -> bool: + +def is_hundegger_processing_group(element_id: int) -> bool: """is hundegger processing group Parameters: - a0: a0 + element_id: element_id Returns: bool diff --git a/src/bim_controller/__init__.pyi b/src/bim_controller/__init__.pyi index 23e8981..bf8b46b 100644 --- a/src/bim_controller/__init__.pyi +++ b/src/bim_controller/__init__.pyi @@ -1,7 +1,8 @@ from typing import List -from cadwork import ifc_2x3_element_type -from cadwork import ifc_options -from cadwork import ifc_predefined_type +from cadwork.ifc_2x3_element_type import ifc_2x3_element_type +from cadwork.ifc_options import ifc_options +from cadwork.ifc_predefined_type import ifc_predefined_type +from cadwork.element_type import element_type def get_last_error(a0: int) -> str: """get last error @@ -40,7 +41,8 @@ def get_ifc2x3_element_type(element_id: int) -> ifc_2x3_element_type: ifc_2x3_element_type """ -def set_ifc2x3_element_type(element_i_ds: List[int], element_type: None) -> None: + +def set_ifc2x3_element_type(element_i_ds: List[int], element_type: element_type) -> None: """set ifc2x3 element type Parameters: @@ -191,10 +193,10 @@ def update_bmt_structure_building_storey(element_i_ds: List[int]) -> None: """ def get_ifc_options() -> ifc_options: - """Get the IfcOptions with the settings used in the document // * + """Get the IfcOptions with the settings used in the document Returns: - IfcOptions // + ifc_options """ def set_building_and_storey(element_id_list: List[int], building: str, storey: str) -> None: @@ -240,7 +242,8 @@ def get_storey_height(building: str, storey: str) -> float: float """ -def get_ifc2x3_element_type_string(element_type: None) -> str: + +def get_ifc2x3_element_type_string(element_type: element_type) -> str: """get ifc2x3 element type string Parameters: @@ -250,7 +253,8 @@ def get_ifc2x3_element_type_string(element_type: None) -> str: str """ -def get_ifc2x3_element_type_display_string(element_type: None) -> str: + +def get_ifc2x3_element_type_display_string(element_type: element_type) -> str: """get ifc2x3 element type display string Parameters: @@ -277,11 +281,12 @@ def get_all_storeys(building: str) -> List[str]: List[str] """ -def get_element_id_from_base64_ifc_guid(a1: str) -> int: + +def get_element_id_from_base64_ifc_guid(base_64_ifc_guid: str) -> int: """get element id from base64 ifc guid Parameters: - a1: a1 + base_64_ifc_guid: base_64_ifc_guid Returns: int diff --git a/src/cadwork/__init__.pyi b/src/cadwork/__init__.pyi index 1372526..1aa50c0 100644 --- a/src/cadwork/__init__.pyi +++ b/src/cadwork/__init__.pyi @@ -1,8 +1,11 @@ from .attribute_display_settings import attribute_display_settings +from .bim_team_upload_result import bim_team_upload_result +from .bim_team_upload_result_code import bim_team_upload_result_code from .btl_version import btl_version from .camera_data import camera_data from .coordinate_system_data import coordinate_system_data from .division_zone_direction import division_zone_direction +from .double_shoulder_options import double_shoulder_options from .edge_list import edge_list from .element_grouping_type import element_grouping_type from .element_module_detail import element_module_detail @@ -10,9 +13,12 @@ from .element_module_properties import element_module_properties from .element_type import element_type from .extended_settings import extended_settings from .facet_list import facet_list +from .heel_shoulder_beam_geometry import heel_shoulder_beam_geometry +from .heel_shoulder_options import heel_shoulder_options from .hundegger_machine_type import hundegger_machine_type from .ifc_2x3_element_type import ifc_2x3_element_type from .ifc_element_combine_behaviour import ifc_element_combine_behaviour +from .ifc_material_definition import ifc_material_definition from .ifc_options import ifc_options from .ifc_options_aggregation import ifc_options_aggregation from .ifc_options_level_of_detail import ifc_options_level_of_detail @@ -21,6 +27,7 @@ from .ifc_options_properties import ifc_options_properties from .ifc_predefined_type import ifc_predefined_type from .import_3dc_options import import_3dc_options from .layer_settings import layer_settings +from .multi_layer_type import multi_layer_type from .node_symbol import node_symbol from .point_3d import point_3d from .polygon_list import polygon_list @@ -29,14 +36,83 @@ from .projection_type import projection_type from .rhino_options import rhino_options from .shortcut_key import shortcut_key from .shortcut_key_modifier import shortcut_key_modifier +from .shoulder_beam_geometry import shoulder_beam_geometry +from .shoulder_drilling_orientation import shoulder_drilling_orientation +from .shoulder_options import shoulder_options from .standard_element_type import standard_element_type from .text_element_type import text_element_type from .text_object_options import text_object_options from .vertex_list import vertex_list from .weinmann_mfb_version import weinmann_mfb_version from .window_geometry import window_geometry +from .element_map_query import element_map_query +from .element_filter import element_filter +from .hit_result import hit_result +from .dimension_base_format import dimension_base_format +from .dxf_layer_format_type import dxf_layer_format_type +from .dxf_export_version import dxf_export_version from typing import List +# These assignments make each type accessible through both import styles: +# 1. Direct import: from cadwork import point_3d +# 2. Module access: import cadwork; cadwork.point_3d(...) +# Without these assignments, the classes would be imported but not exposed as callable attributes +# of the cadwork module, resulting in "not callable" errors/warnings when using the module access style. + +attribute_display_settings = attribute_display_settings +bim_team_upload_result = bim_team_upload_result +bim_team_upload_result_code = bim_team_upload_result_code +btl_version = btl_version +camera_data = camera_data +coordinate_system_data = coordinate_system_data +division_zone_direction = division_zone_direction +double_shoulder_options = double_shoulder_options +edge_list = edge_list +element_grouping_type = element_grouping_type +element_module_detail = element_module_detail +element_module_properties = element_module_properties +element_type = element_type +extended_settings = extended_settings +facet_list = facet_list +heel_shoulder_beam_geometry = heel_shoulder_beam_geometry +heel_shoulder_options = heel_shoulder_options +hundegger_machine_type = hundegger_machine_type +ifc_2x3_element_type = ifc_2x3_element_type +ifc_element_combine_behaviour = ifc_element_combine_behaviour +ifc_material_definition = ifc_material_definition +ifc_options = ifc_options +ifc_options_aggregation = ifc_options_aggregation +ifc_options_level_of_detail = ifc_options_level_of_detail +ifc_options_project_data = ifc_options_project_data +ifc_options_properties = ifc_options_properties +ifc_predefined_type = ifc_predefined_type +import_3dc_options = import_3dc_options +layer_settings = layer_settings +multi_layer_type = multi_layer_type +node_symbol = node_symbol +point_3d = point_3d +polygon_list = polygon_list +process_type = process_type +projection_type = projection_type +rhino_options = rhino_options +shortcut_key = shortcut_key +shortcut_key_modifier = shortcut_key_modifier +shoulder_beam_geometry = shoulder_beam_geometry +shoulder_drilling_orientation = shoulder_drilling_orientation +shoulder_options = shoulder_options +standard_element_type = standard_element_type +text_element_type = text_element_type +text_object_options = text_object_options +vertex_list = vertex_list +weinmann_mfb_version = weinmann_mfb_version +window_geometry = window_geometry +element_map_query = element_map_query +element_filter = element_filter +hit_result = hit_result +dimension_base_format = dimension_base_format +dxf_layer_format_type = dxf_layer_format_type +dxf_export_version = dxf_export_version + def get_auto_attribute_elements() -> List[int]: """Get ontly the elements of the selected types in the attribute manager dialog. All other elements will diff --git a/src/cadwork/dimension_base_format.pyi b/src/cadwork/dimension_base_format.pyi new file mode 100644 index 0000000..af5d8d1 --- /dev/null +++ b/src/cadwork/dimension_base_format.pyi @@ -0,0 +1,24 @@ +from enum import IntEnum, unique + + +@unique +class dimension_base_format(IntEnum): + """ Enumeration for dimension base format. + + Examples: + >>> cadwork.dimension_base_format.sum_only + + """ + none = 0 + """""" + distance_only = 1 + """""" + sum_only = 2 + """""" + distance_and_sum = 3 + """""" + sum_moved = 4 + """""" + + def __int__(self) -> int: + return self.value diff --git a/src/cadwork/dxf_export_version.pyi b/src/cadwork/dxf_export_version.pyi new file mode 100644 index 0000000..8bceba1 --- /dev/null +++ b/src/cadwork/dxf_export_version.pyi @@ -0,0 +1,18 @@ +from enum import IntEnum, unique + + +@unique +class dxf_export_version(IntEnum): + """ Enumeration for DXF export version. + + Examples: + >>> cadwork.dxf_export_version.auto_cad_r27 + + """ + auto_cad_r10 = 0 + """""" + auto_cad_r27 = 1 + """""" + + def __int__(self) -> int: + return self.value diff --git a/src/cadwork/dxf_layer_format_type.pyi b/src/cadwork/dxf_layer_format_type.pyi new file mode 100644 index 0000000..74bf6eb --- /dev/null +++ b/src/cadwork/dxf_layer_format_type.pyi @@ -0,0 +1,26 @@ +from enum import IntEnum, unique + + +@unique +class dxf_layer_format_type(IntEnum): + """ Enumeration for DXF layer format type. + + Examples: + >>> cadwork.dxf_layer_format_type.color + + """ + all_in_no_1 = 0 + """""" + color = 1 + """""" + material = 2 + """""" + name = 3 + """""" + group = 4 + """""" + subgroup = 5 + """""" + + def __int__(self) -> int: + return self.value diff --git a/src/cadwork/element_filter.pyi b/src/cadwork/element_filter.pyi new file mode 100644 index 0000000..d8af660 --- /dev/null +++ b/src/cadwork/element_filter.pyi @@ -0,0 +1,82 @@ +class element_filter: + + def set_name(self, name: str) -> None: + """set name + + Parameters: + name: name + + Returns: + None + """ + + def set_group(self, group: str) -> None: + """set group + + Parameters: + group: group + + Returns: + None + """ + + def set_subgroup(self, subgroup: str) -> None: + """set subgroup + + Parameters: + subgroup: subgroup + + Returns: + None + """ + + def set_comment(self, comment: str) -> None: + """set comment + + Parameters: + comment: comment + + Returns: + None + """ + + def set_user_attribute(self, number: int, user_attribute: str) -> None: + """set user attribute + + Parameters: + number: number + user_attribute: user_attribute + + Returns: + None + """ + + def set_sku(self, sku: str) -> None: + """set sku + + Parameters: + sku: sku + + Returns: + None + """ + + def set_production_number(self, production_number: int) -> None: + """set production number + + Parameters: + production_number: production_number + + Returns: + None + """ + + def set_part_number(self, part_number: int) -> None: + """set part number + + Parameters: + part_number: part_number + + Returns: + None + """ diff --git a/src/cadwork/element_map_query.pyi b/src/cadwork/element_map_query.pyi new file mode 100644 index 0000000..c187566 --- /dev/null +++ b/src/cadwork/element_map_query.pyi @@ -0,0 +1,74 @@ +class element_map_query: + + def set_by_name(self) -> None: + """set by name + + Returns: + None + """ + + def set_by_group(self) -> None: + """set by group + + Returns: + None + """ + + def set_by_subgroup(self) -> None: + """set by subgroup + + Returns: + None + """ + + def set_by_comment(self) -> None: + """set by comment + + Returns: + None + """ + + def set_by_user_attribute(self, number: int) -> None: + """set by user attribute + + Parameters: + number: number + + Returns: + None + """ + + def set_by_sku(self) -> None: + """set by sku + + Returns: + None + """ + + def set_by_production_number(self) -> None: + """set by production number + + Returns: + None + """ + + def set_by_part_number(self) -> None: + """set by part number + + Returns: + None + """ + + def set_by_building(self) -> None: + """set by building + + Returns: + None + """ + + def set_by_storey(self) -> None: + """set by storey + + Returns: + None + """ diff --git a/src/cadwork/hit_result.pyi b/src/cadwork/hit_result.pyi new file mode 100644 index 0000000..ab4918d --- /dev/null +++ b/src/cadwork/hit_result.pyi @@ -0,0 +1,22 @@ +from typing import List +from cadwork import point_3d + + +class hit_result: + + def get_hit_element_ids(self) -> List[int]: + """get hit element ids + + Returns: + List[int] + """ + + def get_hit_vertices_by_element(self, element_id: int) -> List[point_3d]: + """get hit vertices by element + + Parameters: + element_id: element_id + + Returns: + List[point_3d] + """ diff --git a/src/cadwork/ifc_options_properties.pyi b/src/cadwork/ifc_options_properties.pyi index 909ea58..c13697f 100644 --- a/src/cadwork/ifc_options_properties.pyi +++ b/src/cadwork/ifc_options_properties.pyi @@ -102,3 +102,19 @@ class ifc_options_properties: bool """ + def get_export_quantity_sets(self) -> bool: + """get export quantity sets + + Returns: + bool + """ + + def set_export_quantity_sets(self, export_quantity_sets: bool) -> None: + """set export quantity sets + + Parameters: + export_quantity_sets: export_quantity_sets + + Returns: + None + """ diff --git a/src/cadwork/point.pyi b/src/cadwork/point.pyi new file mode 100644 index 0000000..555350e --- /dev/null +++ b/src/cadwork/point.pyi @@ -0,0 +1,11 @@ +class point: + def __init__(self, x: float, y: float): + """ + Initialize a point with x and y coordinates. + + Args: + x (float): The x-coordinate. + y (float): The y-coordinate. + """ + self.x = x + self.y = y diff --git a/src/cadwork/projection_type.pyi b/src/cadwork/projection_type.pyi index 1ddb0f2..7edbd64 100644 --- a/src/cadwork/projection_type.pyi +++ b/src/cadwork/projection_type.pyi @@ -9,9 +9,9 @@ class projection_type(IntEnum): >>> cadwork.projection_type.Perspective Perspective """ - Perspective = 0 + Perspective = 1 """""" - Orthographic = 1 + Orthographic = 2 """""" def __int__(self) -> int: diff --git a/src/cadwork/text_object_options.pyi b/src/cadwork/text_object_options.pyi index 4aaac5a..61bce78 100644 --- a/src/cadwork/text_object_options.pyi +++ b/src/cadwork/text_object_options.pyi @@ -155,3 +155,19 @@ class text_object_options: bool """ + def set_draw_on_top(self, value: bool) -> None: + """set draw on top + + Parameters: + value: value + + Returns: + None + """ + + def get_draw_on_top(self) -> bool: + """get draw on top + + Returns: + bool + """ diff --git a/src/cadwork/window_geometry.pyi b/src/cadwork/window_geometry.pyi index 97c12d2..faec5ea 100644 --- a/src/cadwork/window_geometry.pyi +++ b/src/cadwork/window_geometry.pyi @@ -1,25 +1,16 @@ -class Point: - def __init__(self, x: float, y: float): - """ - Initialize a point with x and y coordinates. +from cadwork import point - Args: - x (float): The x-coordinate. - y (float): The y-coordinate. - """ - self.x = x - self.y = y -class WindowGeometry: - def __init__(self, bottom_left: Point, bottom_right: Point, top_left: Point, top_right: Point): +class window_geometry: + def __init__(self, bottom_left: point, bottom_right: point, top_left: point, top_right: point): """ Initialize window geometry with points defining the window corners. Args: - bottom_left (Point): The bottom left corner of the window. - bottom_right (Point): The bottom right corner of the window. - top_left (Point): The top left corner of the window. - top_right (Point): The top right corner of the window. + bottom_left (point): The bottom left corner of the window. + bottom_right (point): The bottom right corner of the window. + top_left (point): The top left corner of the window. + top_right (point): The top right corner of the window. """ self.bottom_left = bottom_left self.bottom_right = bottom_right diff --git a/src/connector_axis_controller/__init__.pyi b/src/connector_axis_controller/__init__.pyi index 642481a..0695469 100644 --- a/src/connector_axis_controller/__init__.pyi +++ b/src/connector_axis_controller/__init__.pyi @@ -1,5 +1,6 @@ from typing import List -from cadwork import point_3d +from cadwork.point_3d import point_3d + def get_last_error(error_code: int) -> str: """get last error @@ -11,6 +12,7 @@ def get_last_error(error_code: int) -> str: str """ + def create_standard_connector(axis_name: str, point1: point_3d, point2: point_3d) -> int: """Creates a standard connector axis between two points. @@ -23,6 +25,7 @@ def create_standard_connector(axis_name: str, point1: point_3d, point2: point_3d int """ + def set_bolt_length(axis_id: int, length: float) -> None: """Sets the Bolt Length @@ -34,6 +37,7 @@ def set_bolt_length(axis_id: int, length: float) -> None: None """ + def set_bolt_length_automatic(axis_id: int, length_automatic: bool) -> None: """Sets the Bolt Length Automatic @@ -45,6 +49,7 @@ def set_bolt_length_automatic(axis_id: int, length_automatic: bool) -> None: None """ + def set_diameter(axis_id: int, diameter: float) -> None: """Sets the Drilling Diameter for all Sections @@ -56,6 +61,7 @@ def set_diameter(axis_id: int, diameter: float) -> None: None """ + def set_section_diameter(axis_id: int, section_nr: int, diameter: float) -> None: """Sets the Drilling Diameter for a specific Sections @@ -68,6 +74,7 @@ def set_section_diameter(axis_id: int, section_nr: int, diameter: float) -> None None """ + def check_axis(axis_id: int) -> bool: """Returns if the axis is valid. @@ -78,6 +85,7 @@ def check_axis(axis_id: int) -> bool: bool """ + def clear_errors() -> None: """clear errors @@ -85,6 +93,7 @@ def clear_errors() -> None: None """ + def update_axis_cutting_ability(axis_i_ds: List[int]) -> None: """updates the Connection Config (CuttingAbility) of Axis/VBAs @@ -95,6 +104,7 @@ def update_axis_cutting_ability(axis_i_ds: List[int]) -> None: None """ + def set_bolt_item(axis_id: int, item_guid: str) -> None: """Sets the Bolt Item @@ -106,28 +116,31 @@ def set_bolt_item(axis_id: int, item_guid: str) -> None: None """ -def create_blank_connector(a0: float, a1: point_3d, a2: point_3d) -> int: + +def create_blank_connector(diameter: float, start_point: point_3d, end_point: point_3d) -> int: """create blank connector Parameters: - a0: a0 - a1: a1 - a2: a2 + diameter: diameter + start_point: start_point + end_point: end_point Returns: int """ -def import_from_file(a0: str) -> None: + +def import_from_file(file_path: str) -> None: """import from file Parameters: - a0: a0 + file_path: file_path Returns: None """ + def start_configuration_dialog() -> None: """Starts the ConnectorAxis configuration dialog. @@ -135,6 +148,7 @@ def start_configuration_dialog() -> None: None """ + def get_item_guid_by_name(name: str, item_type: int) -> str: """get item guid by name @@ -146,6 +160,7 @@ def get_item_guid_by_name(name: str, item_type: int) -> str: str """ + def get_bolt_length(axis_id: int) -> float: """Gets the Bolt Length @@ -156,6 +171,7 @@ def get_bolt_length(axis_id: int) -> float: float """ + def get_bolt_over_length(axis_id: int) -> float: """Gets the Bolt OverLength @@ -166,6 +182,7 @@ def get_bolt_over_length(axis_id: int) -> float: float """ + def set_bolt_over_length(axis_id: int, over_length: float) -> None: """Sets the Bolt OverLength @@ -177,6 +194,7 @@ def set_bolt_over_length(axis_id: int, over_length: float) -> None: None """ + def get_bolt_length_automatic(axis_id: int) -> bool: """Returns if Bolt Length Automatic is set @@ -187,6 +205,7 @@ def get_bolt_length_automatic(axis_id: int) -> bool: bool """ + def get_bolt_item_guid(axis_id: int) -> str: """Gets the Guid of the Bolt Item @@ -197,6 +216,7 @@ def get_bolt_item_guid(axis_id: int) -> str: str """ + def get_section_diameter(axis_id: int, section_nr: int) -> float: """Gets the Drilling Diameter of a specific Sections @@ -208,6 +228,7 @@ def get_section_diameter(axis_id: int, section_nr: int) -> float: float """ + def get_axis_items_guids(axis_id: int) -> List[str]: """Returns a list of GUIDs of all axis items. @@ -218,6 +239,7 @@ def get_axis_items_guids(axis_id: int) -> List[str]: List[str] """ + def get_axis_item_name(guid: str) -> str: """Returns the name of an axis item. @@ -228,6 +250,7 @@ def get_axis_item_name(guid: str) -> str: str """ + def get_axis_item_material(guid: str) -> str: """Returns the material of an axis item. @@ -238,6 +261,7 @@ def get_axis_item_material(guid: str) -> str: str """ + def get_axis_item_norm(guid: str) -> str: """Returns the norm of an axis item. @@ -248,6 +272,7 @@ def get_axis_item_norm(guid: str) -> str: str """ + def get_axis_item_strength_category(guid: str) -> str: """Returns the strength category of an axis item. @@ -258,6 +283,7 @@ def get_axis_item_strength_category(guid: str) -> str: str """ + def get_axis_item_user_field(guid: str, user_item_nr: int) -> str: """Returns an userfield value of an axis item. @@ -269,6 +295,7 @@ def get_axis_item_user_field(guid: str, user_item_nr: int) -> str: str """ + def get_axis_item_order_number(guid: str) -> str: """Returns the strength category of an axis item. @@ -279,6 +306,7 @@ def get_axis_item_order_number(guid: str) -> str: str """ + def get_bolt_order_number(axis_id: int) -> str: """Returns the ordernumber of a bolt item. @@ -289,6 +317,7 @@ def get_bolt_order_number(axis_id: int) -> str: str """ + def get_section_count(axis_id: int) -> int: """Returns the number of sections. @@ -299,6 +328,7 @@ def get_section_count(axis_id: int) -> int: int """ + def get_section_material_name(axis_id: int, section_nr: int) -> str: """Returns material of a section contact element. @@ -310,27 +340,30 @@ def get_section_material_name(axis_id: int, section_nr: int) -> str: str """ -def get_section_contact_element(a0: float, a1: int) -> int: + +def get_section_contact_element(axis_id: float, section_nr: int) -> int: """get section contact element Parameters: - a0: a0 - a1: a1 + axis_id: axis_id + section_nr: section_nr Returns: int """ -def get_bolt_diameter(a0: int) -> float: + +def get_bolt_diameter(axis_id: int) -> float: """get bolt diameter Parameters: - a0: a0 + axis_id: axis_id Returns: float """ + def get_standard_connector_list() -> List[str]: """Returns a list of all standard connectors. @@ -338,3 +371,234 @@ def get_standard_connector_list() -> List[str]: List[str] """ + +def get_counterbore_diameter_for_start_side(axis_id: int, section_index: int, diameter: float, depth: float, + is_conical: bool) -> float: + """get counterbore diameter for start side + + Parameters: + axis_id: axis_id + section_index: section_index + diameter: diameter + depth: depth + is_conical: is_conical + + Returns: + float + """ + + +def get_counterbore_diameter_for_end_side(axis_id: int, section_index: int) -> float: + """Gets the counterbore diameter for the end side of a section. + + Parameters: + axis_id: The ID of the axis. + section_index: The index of the section. + + Returns: + float: The counterbore diameter for the end side. + """ + + +def get_counterbore_depth_for_start_side(axis_id: int, section_index: int) -> float: + """get counterbore depth for start side + + Parameters: + axis_id: The ID of the axis. + section_index: The index of the section. + + Returns: + float + """ + + +def get_counterbore_depth_for_end_side(axis_id: int, section_index: int) -> float: + """get counterbore depth for end side + + Parameters: + axis_id: The ID of the axis. + section_index: The index of the section + + Returns: + float + """ + + +def get_counterbore_is_conical_for_start_side(axis_id: int, section_index: int) -> bool: + """get counterbore is conical for start side + + Parameters: + axis_id: The ID of the axis. + section_index: The index of the section + + Returns: + bool + """ + + +def get_counterbore_is_conical_for_end_side(axis_id: int, section_index: int) -> bool: + """get counterbore is conical for end side + + Parameters: + axis_id: The ID of the axis. + section_index: The index of the section + + Returns: + bool + """ + + +def set_counterbore_for_start_side(axis_id: int, section_index: int, diameter: float, depth: float, + is_conical: bool) -> None: + """set counterbore for start side + + Parameters: + axis_id: axis_id + section_index: section_index + diameter: diameter + depth: depth + is_conical: is_conical + + Returns: + None + """ + + +def set_counterbore_for_end_side(axis_id: int, section_index: int, diameter: float, depth: float, + is_conical: bool) -> None: + """set counterbore for end side + + Parameters: + axis_id: axis_id + section_index: section_index + diameter: diameter + depth: depth + is_conical: is_conical + + Returns: + None + """ + + +def get_intersection_count(intersection_index: int) -> int: + """get intersection count + + Parameters: + intersection_index: intersection_index + + Returns: + int + """ + + +def get_item_guids_at_intersection(axis_id: int, intersection_index: int) -> List[str]: + """get item guids at intersection + + Parameters: + axis_id: axis_id + intersection_index: intersection_index + + Returns: + List[str] + """ + + +def set_item_guids_at_intersection(axis_id: int, intersection_index: int, item_guids: List[str]) -> None: + """set item guids at intersection + + Parameters: + axis_id: axis_id + intersection_index: intersection_index + item_guids: item_guids + + Returns: + None + """ + + +def get_section_length(axis_id: int, section_index: int) -> float: + """get section length + + Parameters: + axis_id: axis_id + section_index: section_index + + Returns: + float + """ + + +def get_section_oblong_drilling_is_enabled(axis_id: int, section_index: int) -> bool: + """get section oblong drilling is enabled + + Parameters: + axis_id: axis_id + section_index: section_index + + Returns: + bool + """ + + +def get_section_oblong_drilling_positive_value(axis_id: int, section_index: int) -> float: + """get section oblong drilling positive value + + Parameters: + axis_id: axis_id + section_index: section_index + + Returns: + float + """ + + +def get_section_oblong_drilling_negative_value(axis_id: int, section_index: int) -> float: + """get section oblong drilling negative value + + Parameters: + axis_id: axis_id + section_index: section_index + + Returns: + float + """ + + +def get_section_oblong_drilling_angle(axis_id: int, section_index: int) -> float: + """get section oblong drilling angle + + Parameters: + axis_id: axis_id + section_index: section_index + + Returns: + float + """ + + +def set_section_oblong_drilling_is_disabled(axis_id: int, section_index: int) -> None: + """set section oblong drilling is disabled + + Parameters: + axis_id: axis_id + section_index: section_index + + Returns: + None + """ + + +def set_section_oblong_drilling_is_enabled(axis_id: int, section_index: int, positive_value: float, + negative_value: float, angle: float) -> None: + """set section oblong drilling is enabled + + Parameters: + axis_id: axis_id + section_index: section_index + positive_value: positive_value + negative_value: negative_value + angle: angle + + Returns: + None + """ diff --git a/src/dimension_controller/__init__.pyi b/src/dimension_controller/__init__.pyi index 7f53aed..cfe689d 100644 --- a/src/dimension_controller/__init__.pyi +++ b/src/dimension_controller/__init__.pyi @@ -1,5 +1,6 @@ from typing import List from cadwork import point_3d +from cadwork.dimension_base_format import dimension_base_format def create_dimension(xl: point_3d, plane_normal: point_3d, distance: point_3d, dimension_points: List[point_3d]) -> int: """creates a dimension element @@ -227,3 +228,14 @@ def get_total_dimension(element: int) ->bool: Returns: bool """ + + +def get_dimension_base_format(element: int) -> dimension_base_format: + """get dimension base format + + Parameters: + element: element + + Returns: + dimension_base_format + """ diff --git a/src/element_controller/__init__.pyi b/src/element_controller/__init__.pyi index 445bd22..354ba8a 100644 --- a/src/element_controller/__init__.pyi +++ b/src/element_controller/__init__.pyi @@ -1,10 +1,13 @@ -from typing import List -from cadwork import edge_list -from cadwork import element_module_properties -from cadwork import facet_list -from cadwork import point_3d -from cadwork import text_object_options +from typing import List, Dict +from cadwork.edge_list import edge_list +from cadwork.element_module_properties import element_module_properties +from cadwork.facet_list import facet_list +from cadwork.point_3d import point_3d +from cadwork.text_object_options import text_object_options from cadwork.coordinate_system_data import coordinate_system_data +from cadwork.element_map_query import element_map_query +from cadwork.element_filter import element_filter +from cadwork.hit_result import hit_result def delete_elements(element_id_list: List[int]) -> None: """delete elements @@ -2098,4 +2101,70 @@ def cut_double_shoulder(element_id_list: List[int], Returns: None - """ \ No newline at end of file + """ + + +def filter_elements(elements: List[int], element_filter: element_filter) -> List[int]: + """filter elements + + Parameters: + elements: elements + element_filter: name_filter + + Example: + >>> import cadwork + >>> import element_controller as ec + >>> your_element_filter = cadwork.element_filter() + >>> your_element_filter.set_name("beam") + >>> filtered_elements = ec.filter_elements(ec.get_active_identifiable_element_ids(), your_element_filter) + >>> print(filtered_elements) + + Returns: + List[int] + """ + + +def map_elements(elements: List[int], map_query: element_map_query) -> Dict[str, List[int]]: + """map elements + + Parameters: + elements: elements + map_query: map_query + + Example: + >>> import cadwork + >>> import element_controller as ec + >>> your_map_query = cadwork.element_map_query() + >>> your_map_query.set_by_subgroup() + >>> mapped_items = ec.map_elements(ec.get_active_identifiable_element_ids(), your_map_query) + >>> print(mapped_items) + + Returns: + Dict[str, List[int]] + """ + + +def cast_ray_and_get_element_intersections(elements: List[int], ray_start_position: point_3d, + ray_end_position: point_3d, radius: float) -> hit_result: + """cast ray and get element intersections + Parameters: + elements: elements + ray_start_position: ray_start_position + ray_end_position: ray_end_position + radius: radius + + Example: + >>> from cadwork import point_3d + >>> import element_controller as ec + >>> ray_start = point_3d(0, 0, 0) + >>> ray_end = point_3d(1000, 0, 0) + >>> hit_result = ec.cast_ray_and_get_element_intersections(ec.get_active_identifiable_element_ids(), ray_start, ray_end, 40.0) + >>> print(hits.get_hit_element_ids()) + >>> for element in hits.get_hit_element_ids(): + >>> print(f"ElementID {element}: {hits.get_hit_vertices_by_element(element)}") + >>> for pos in hits.get_hit_vertices_by_element(element): + >>> ec.create_node(pos) + + Returns: + hit_result + """ diff --git a/src/endtype_controller/__init__.pyi b/src/endtype_controller/__init__.pyi index 4a7d315..109e05a 100644 --- a/src/endtype_controller/__init__.pyi +++ b/src/endtype_controller/__init__.pyi @@ -40,12 +40,13 @@ def get_endtype_id_end(element_id: int) -> int: int """ -def get_endtype_id_facet(a0: int, a1: int) -> int: + +def get_endtype_id_facet(element_id: int, face_number: int) -> int: """get endtype id facet Parameters: - a0: a0 - a1: a1 + element_id: element_id + face_number: face_number Returns: int @@ -73,13 +74,14 @@ def set_endtype_name_end(element_id: int, name: str) -> None: None """ -def set_endtype_name_facet(a0: int, a1: str, a2: int) -> None: + +def set_endtype_name_facet(element_id: int, name: str, face_number: int) -> None: """set endtype name facet Parameters: - a0: a0 - a1: a1 - a2: a2 + element_id: element_id + name: name + face_number: face_number Returns: None @@ -107,13 +109,14 @@ def set_endtype_id_end(element_id: int, endtype_id: int) -> None: None """ -def set_endtype_id_facet(a0: int, a1: int, a2: int) -> None: + +def set_endtype_id_facet(element_id: int, endtype_id: int, face_number: int) -> None: """set endtype id facet Parameters: - a0: a0 - a1: a1 - a2: a2 + element_id: element_id + endtype_id: endtype_id + face_number: face_number Returns: None @@ -168,12 +171,13 @@ def get_endtype_name_end(element_id: int) -> str: str """ -def get_endtype_name_facet(a0: int, a1: int) -> str: + +def get_endtype_name_facet(element_id: int, face_number: int) -> str: """get endtype name facet Parameters: - a0: a0 - a1: a1 + element_id: element_id + face_number: face_number Returns: str diff --git a/src/file_controller/__init__.pyi b/src/file_controller/__init__.pyi index c6ba66a..410fc01 100644 --- a/src/file_controller/__init__.pyi +++ b/src/file_controller/__init__.pyi @@ -1,6 +1,8 @@ from typing import List from cadwork import point_3d from cadwork.bim_team_upload_result import bim_team_upload_result +from cadwork.dxf_layer_format_type import dxf_layer_format_type +from cadwork.dxf_export_version import dxf_export_version def get_last_error(error_code: int) -> str: @@ -326,12 +328,12 @@ def import_variant_file(file_path: str, insert_position: point_3d) -> List[int]: """ -def import_element_light(a0: str, a1: point_3d) -> int: +def import_element_light(file_path: str, insert_position: point_3d) -> int: """import element light Parameters: - a0: a0 - a1: a1 + file_path: file_path + insert_position: insert_position Returns: int @@ -447,3 +449,28 @@ def upload_to_bim_team_and_create_share_link(elements: None Returns: bim_team_upload_result """ + + +def export_dxf_file(file_path: str, dxf_layer_format_type: dxf_layer_format_type, + dxf_export_version: dxf_export_version) -> bool: + """export dxf file + + Parameters: + file_path: file_path + dxf_layer_format_type: dxf_layer_format_type + dxf_export_version: dxf_export_version + + Returns: + bool + """ + + +def export_dstv_file(file_path: str) -> bool: + """export dstv file + + Parameters: + file_path: file_path + + Returns: + bool + """ diff --git a/src/geometry_controller/__init__.pyi b/src/geometry_controller/__init__.pyi index 7140043..de9fdbb 100644 --- a/src/geometry_controller/__init__.pyi +++ b/src/geometry_controller/__init__.pyi @@ -1,6 +1,6 @@ from typing import List -from cadwork import facet_list -from cadwork import point_3d +from cadwork.facet_list import facet_list +from cadwork.point_3d import point_3d def rotate_height_axis_90(element_id_list: List[int]) -> None: @@ -1111,3 +1111,14 @@ def get_standard_element_length_from_name(standard_element_name: str) -> float: Returns: float """ + + +def get_last_error(error_code: int) -> str: + """get last error + + Parameters: + error_code: error_code + + Returns: + str + """ diff --git a/src/list_controller/__init__.pyi b/src/list_controller/__init__.pyi index 6ec68f8..710163d 100644 --- a/src/list_controller/__init__.pyi +++ b/src/list_controller/__init__.pyi @@ -1,5 +1,6 @@ from typing import List + def get_last_error(error_code: int) -> str: """Gets the last error @@ -10,6 +11,7 @@ def get_last_error(error_code: int) -> str: error string """ + def export_production_list(element_id_list: List[int], file_path: str) -> None: """Exports a production list @@ -21,6 +23,7 @@ def export_production_list(element_id_list: List[int], file_path: str) -> None: None """ + def export_part_list(element_id_list: List[int], file_path: str) -> None: """Exports a part list @@ -32,6 +35,7 @@ def export_part_list(element_id_list: List[int], file_path: str) -> None: None """ + def check_position_numbers_production_list() -> List[int]: """Checks the production list numbers and returns the element ids with discrepancies @@ -39,6 +43,7 @@ def check_position_numbers_production_list() -> List[int]: element ids with discrepancies """ + def check_position_numbers_part_list() -> List[int]: """Checks the part list numbers and returns the element ids with discrepancies @@ -46,6 +51,7 @@ def check_position_numbers_part_list() -> List[int]: element ids with discrepancies """ + def clear_errors() -> None: """clear errors @@ -53,6 +59,7 @@ def clear_errors() -> None: None """ + def export_production_list_with_settings(element_id_list: List[int], file_path: str, settings_file_path: str) -> None: """export production list with settings @@ -65,6 +72,7 @@ def export_production_list_with_settings(element_id_list: List[int], file_path: None """ + def export_part_list_with_settings(element_id_list: List[int], file_path: str, settings_file_path: str) -> None: """export part list with settings @@ -77,72 +85,81 @@ def export_part_list_with_settings(element_id_list: List[int], file_path: str, s None """ -def generate_new_production_list_numbers(a0: List[int]) -> None: + +def generate_new_production_list_numbers(elements: List[int]) -> None: """generate new production list numbers Parameters: - a0: a0 + elements: elements Returns: None """ -def generate_new_part_list_numbers(a0: List[int]) -> None: + +def generate_new_part_list_numbers(elements: List[int]) -> None: """generate new part list numbers Parameters: - a0: a0 + elements: elements Returns: None """ -def load_production_list_calculation_settings(a0: str) -> None: + +def load_production_list_calculation_settings(settings_file_path: str) -> None: """load production list calculation settings Parameters: - a0: a0 + settings_file_path: settings_file_path Returns: None """ -def load_part_list_calculation_settings(a0: str) -> None: + +def load_part_list_calculation_settings(settings_file_path: str) -> None: """load part list calculation settings Parameters: - a0: a0 + settings_file_path: settings_file_path Returns: None """ -def generate_new_production_list_silently(a0: List[int], a1: int, a2: bool, a3: bool) -> None: + +def generate_new_production_list_silently(elements: List[int], starting_number: int, keep_existing_numbers: bool, + with_containers: bool) -> None: """generate new production list silently Parameters: - a0: a0 - a1: a1 - a2: a2 - a3: a3 + elements: elements + starting_number: starting_number + keep_existing_numbers: keep_existing_numbers + with_containers: with_containers Returns: None """ -def generate_new_part_list_silently(a0: List[int], a1: int, a2: bool, a3: bool) -> None: + +def generate_new_part_list_silently(elements: List[int], starting_number: int, keep_existing_numbers: bool, + with_containers: bool) -> None: """generate new part list silently Parameters: - a0: a0 - a1: a1 - a2: a2 - a3: a3 + elements: elements + starting_number: starting_number + keep_existing_numbers: keep_existing_numbers + with_containers: with_containers Returns: None """ + def export_cover_list(element_id_list: List[int], file_path: str) -> None: """Exports a Wall/Roof/Floor list @@ -154,6 +171,7 @@ def export_cover_list(element_id_list: List[int], file_path: str) -> None: None """ + def export_cover_list_with_settings(element_id_list: List[int], file_path: str, settings_file_path: str) -> None: """Exports a Wall/Roof/Floor list with settings file @@ -165,4 +183,3 @@ def export_cover_list_with_settings(element_id_list: List[int], file_path: str, Returns: None """ - diff --git a/src/material_controller/__init__.pyi b/src/material_controller/__init__.pyi index aad072c..9044e5c 100644 --- a/src/material_controller/__init__.pyi +++ b/src/material_controller/__init__.pyi @@ -247,34 +247,37 @@ def clear_errors() -> None: None """ -def set_grade(a0: int, a1: str) -> None: + +def set_grade(material_id: int, grade: str) -> None: """set grade Parameters: - a0: a0 - a1: a1 + material_id: material_id + grade: grade Returns: None """ -def set_quality(a0: int, a1: str) -> None: + +def set_quality(material_id: int, quality: str) -> None: """set quality Parameters: - a0: a0 - a1: a1 + material_id: material_id + quality: quality Returns: None """ -def set_composition(a0: int, a1: str) -> None: + +def set_composition(material_id: int, composition: str) -> None: """set composition Parameters: - a0: a0 - a1: a1 + material_id: material_id + composition: composition Returns: None @@ -497,41 +500,45 @@ def get_all_materials() -> List[int]: material ID list """ -def get_grade(a0: int) -> str: + +def get_grade(material_id: int) -> str: """get grade Parameters: - a0: a0 + material_id: material_id Returns: str """ -def get_quality(a0: int) -> str: + +def get_quality(material_id: int) -> str: """get quality Parameters: - a0: a0 + material_id: material_id Returns: str """ -def get_composition(a0: int) -> str: + +def get_composition(material_id: int) -> str: """get composition Parameters: - a0: a0 + material_id: material_id Returns: str """ -def get_short_name(a0: int) -> str: + +def get_short_name(material_id: int) -> str: """get short name Parameters: - a0: a0 + material_id: material_id Returns: str @@ -554,297 +561,324 @@ def get_parent_group(group: str) -> str: parent group name """ -def get_material_color_assignment_for_nodes(a0: int) -> int: + +def get_material_color_assignment_for_nodes(color_nr: int) -> int: """get material color assignment for nodes Parameters: - a0: a0 + color_nr: color_nr Returns: int """ -def set_material_color_assignment_for_nodes(a0: int, a1: int) -> None: + +def set_material_color_assignment_for_nodes(color_nr: int, material_id: int) -> None: """set material color assignment for nodes Parameters: - a0: a0 - a1: a1 + color_nr: color_nr + material_id: material_id Returns: None """ -def get_material_color_assignment_for_standard_axes(a0: int) -> int: + +def get_material_color_assignment_for_standard_axes(color_nr: int) -> int: """get material color assignment for standard axes Parameters: - a0: a0 + color_nr: color_nr Returns: int """ -def set_material_color_assignment_for_standard_axes(a0: int, a1: int) -> None: + +def set_material_color_assignment_for_standard_axes(color_nr: int, material_id: int) -> None: """set material color assignment for standard axes Parameters: - a0: a0 - a1: a1 + color_nr: color_nr + material_id: material_id Returns: None """ -def get_material_color_assignment_for_drillings(a0: int) -> int: + +def get_material_color_assignment_for_drillings(color_nr: int) -> int: """get material color assignment for drillings Parameters: - a0: a0 + color_nr: color_nr Returns: int """ -def set_material_color_assignment_for_drillings(a0: int, a1: int) -> None: + +def set_material_color_assignment_for_drillings(color_nr: int, material_id: int) -> None: """set material color assignment for drillings Parameters: - a0: a0 - a1: a1 + color_nr: color_nr + material_id: material_id Returns: None """ -def get_material_color_assignment_for_mep_axes(a0: int) -> int: + +def get_material_color_assignment_for_mep_axes(color_nr: int) -> int: """get material color assignment for mep axes Parameters: - a0: a0 + color_nr: color_nr Returns: int """ -def set_material_color_assignment_for_mep_axes(a0: int, a1: int) -> None: + +def set_material_color_assignment_for_mep_axes(color_nr: int, material_id: int) -> None: """set material color assignment for mep axes Parameters: - a0: a0 - a1: a1 + color_nr: color_nr + material_id: material_id Returns: None """ -def get_material_color_assignment_for_beams(a0: int) -> int: + +def get_material_color_assignment_for_beams(color_nr: int) -> int: """get material color assignment for beams Parameters: - a0: a0 + color_nr: color_nr Returns: int """ -def set_material_color_assignment_for_beams(a0: int, a1: int) -> None: + +def set_material_color_assignment_for_beams(color_nr: int, material_id: int) -> None: """set material color assignment for beams Parameters: - a0: a0 - a1: a1 + color_nr: color_nr + material_id: material_id Returns: None """ -def get_material_color_assignment_for_panels(a0: int) -> int: + +def get_material_color_assignment_for_panels(color_nr: int) -> int: """get material color assignment for panels Parameters: - a0: a0 + color_nr: color_nr Returns: int """ -def set_material_color_assignment_for_panels(a0: int, a1: int) -> None: + +def set_material_color_assignment_for_panels(color_nr: int, material_id: int) -> None: """set material color assignment for panels Parameters: - a0: a0 - a1: a1 + color_nr: color_nr + material_id: material_id Returns: None """ -def get_material_color_assignment_for_auxiliary_elements(a0: int) -> int: + +def get_material_color_assignment_for_auxiliary_elements(color_nr: int) -> int: """get material color assignment for auxiliary elements Parameters: - a0: a0 + color_nr: color_nr Returns: int """ -def set_material_color_assignment_for_auxiliary_elements(a0: int, a1: int) -> None: + +def set_material_color_assignment_for_auxiliary_elements(color_nr: int, material_id: int) -> None: """set material color assignment for auxiliary elements Parameters: - a0: a0 - a1: a1 + color_nr: color_nr + material_id: material_id Returns: None """ -def get_material_color_assignment_for_surfaces(a0: int) -> int: + +def get_material_color_assignment_for_surfaces(color_nr: int) -> int: """get material color assignment for surfaces Parameters: - a0: a0 + color_nr: color_nr Returns: int """ -def set_material_color_assignment_for_surfaces(a0: int, a1: int) -> None: + +def set_material_color_assignment_for_surfaces(color_nr: int, material_id: int) -> None: """set material color assignment for surfaces Parameters: - a0: a0 - a1: a1 + color_nr: color_nr + material_id: material_id Returns: None """ -def get_texture_color(a0: int) -> int: + +def get_texture_color(material_id: int) -> int: """get texture color Parameters: - a0: a0 + material_id: material_id Returns: int """ -def set_texture_color(a0: int, a1: int) -> None: + +def set_texture_color(color_nr: int, material_id: int) -> None: """set texture color Parameters: - a0: a0 - a1: a1 + color_nr: color_nr + material_id: material_id Returns: None """ -def get_texture_transparency(a0: int) -> int: + +def get_texture_transparency(material_id: int) -> int: """get texture transparency Parameters: - a0: a0 + material_id: material_id Returns: int """ -def set_texture_transparency(a0: int, a1: int) -> None: + +def set_texture_transparency(color_nr: int, material_id: int) -> None: """set texture transparency Parameters: - a0: a0 - a1: a1 + color_nr: color_nr + material_id: material_id Returns: None """ -def get_texture_rotation_angle(a0: int) -> float: + +def get_texture_rotation_angle(material_id: int) -> float: """get texture rotation angle Parameters: - a0: a0 + material_id: material_id Returns: float """ -def set_texture_rotation_angle(a0: int, a1: float) -> None: + +def set_texture_rotation_angle(material_id: int, angle: float) -> None: """set texture rotation angle Parameters: - a0: a0 - a1: a1 + material_id: material_id + angle: angle Returns: None """ -def get_texture_length_alignment(a0: int) -> bool: + +def get_texture_length_alignment(material_id: int) -> bool: """get texture length alignment Parameters: - a0: a0 + material_id: material_id Returns: bool """ -def set_texture_length_alignment(a0: int, a1: bool) -> None: + +def set_texture_length_alignment(material_id: int, flag: bool) -> None: """set texture length alignment Parameters: - a0: a0 - a1: a1 + material_id: material_id + flag: flag Returns: None """ -def get_texture_zoom_x(a0: int) -> float: + +def get_texture_zoom_x(material_id: int) -> float: """get texture zoom x Parameters: - a0: a0 + material_id: material_id Returns: float """ -def set_texture_zoom_x(a0: int, a1: float) -> None: + +def set_texture_zoom_x(material_id: int, value: float) -> None: """set texture zoom x Parameters: - a0: a0 - a1: a1 + material_id: material_id + value: value Returns: None """ -def get_texture_zoom_y(a0: int) -> float: + +def get_texture_zoom_y(material_id: int) -> float: """get texture zoom y Parameters: - a0: a0 + material_id: material_id Returns: float """ -def set_texture_zoom_y(a0: int, a1: float) -> None: + +def set_texture_zoom_y(material_id: int, value: float) -> None: """set texture zoom y Parameters: - a0: a0 - a1: a1 + material_id: material_id + value: value Returns: None """ - diff --git a/src/menu_controller/__init__.pyi b/src/menu_controller/__init__.pyi index 7e6614a..20a125e 100644 --- a/src/menu_controller/__init__.pyi +++ b/src/menu_controller/__init__.pyi @@ -1,3 +1,6 @@ +from typing import List + + def display_simple_menu(menu_items: List[str]) -> str: """display simple menu diff --git a/src/scene_controller/__init__.pyi b/src/scene_controller/__init__.pyi index ad1cee5..a9ce1d3 100644 --- a/src/scene_controller/__init__.pyi +++ b/src/scene_controller/__init__.pyi @@ -97,21 +97,23 @@ def get_scene_list() -> List[str]: List[str] """ -def group_scences(a0: List[str]) -> int: + +def group_scences(scene_names: List[str]) -> int: """group scences Parameters: - a0: a0 + scene_names: scene_names Returns: int """ -def ungroup_scences(a0: int) -> None: + +def ungroup_scences(group_index: int) -> None: """ungroup scences Parameters: - a0: a0 + group_index: group_index Returns: None @@ -172,12 +174,13 @@ def rename_scene_group_by_index(group_index: int, new_name: str) -> None: None """ -def group_scences_with_name(a0: List[str], a1: str) -> int: + +def group_scences_with_name(scene_names: List[str], group_name: str) -> int: """group scences with name Parameters: - a0: a0 - a1: a1 + scene_names: scene_names + group_name: group_name Returns: int diff --git a/src/shop_drawing_controller/__init__.pyi b/src/shop_drawing_controller/__init__.pyi index fdf444f..2e2015f 100644 --- a/src/shop_drawing_controller/__init__.pyi +++ b/src/shop_drawing_controller/__init__.pyi @@ -1,5 +1,5 @@ from typing import List -from cadwork import point_3d +from cadwork.point_3d import point_3d def get_last_error(error_code: int) -> str: """Gets the last error diff --git a/src/utility_controller/__init__.pyi b/src/utility_controller/__init__.pyi index d0e9387..a5c7058 100644 --- a/src/utility_controller/__init__.pyi +++ b/src/utility_controller/__init__.pyi @@ -1,7 +1,9 @@ from typing import List from typing import Tuple -from cadwork import point_3d -from cadwork import window_geometry +from cadwork.point_3d import point_3d +from cadwork.window_geometry import window_geometry +from cadwork.shortcut_key import shortcut_key +from cadwork.shortcut_key_modifier import shortcut_key_modifier def get_last_error(error_code: int) -> str: @@ -322,7 +324,13 @@ def get_user_point() -> point_3d: def disable_auto_display_refresh() -> None: - """Disables automatic display refresh + """ + Disables the automatic refresh of the display. + + This function prevents the display from updating automatically, which can + significantly improve performance during operations that involve multiple + changes or computations. The display will remain static until explicitly + refreshed by the user. Returns: None @@ -330,7 +338,30 @@ def disable_auto_display_refresh() -> None: def enable_auto_display_refresh() -> None: - """Enables automatic display refresh + """ + Enables the automatic refresh of the display. + This function restores the default behavior where the display updates + automatically after each operation. Use this function to resume normal + display updates after previously disabling them with disable_auto_display_refresh(). + It's recommended to call this function after completing operations that required + disabled display refreshing. + + + Examples: + >>> import cadwork + >>> import utility_controller as uc + >>> import element_controller as ec + >>> uc.disable_auto_display_refresh() + >>> # Perform operations that require disabled display refresh + >>> your_list_of_elements: List[int] = [] + >>> uc.enable_auto_display_refresh() + >>> ec.recreate_elements(your_list_of_elements) + + + Note: + If elements were created while display refresh was disabled, it's important + to recreate these elements after enabling the display refresh to ensure they + are properly visualized in cadwork. Returns: None @@ -380,14 +411,28 @@ def get_new_user_file_from_dialog(name_filter: str) -> str: def api_autostart(api_name: str, option: int) -> int: - """api autostart + """Manages the autostart configuration for a specified API. Parameters: - api_name: api_name - option: option + api_name: Name of the API to be managed. + option: Determines the operation mode: + + - -1: Checks if API is configured for autostart without making changes. Returns 1 if API is found, 0 if not, or -1 in case of errors. + - 1: Enables autostart for the specified API. + - 0: Disables autostart for the specified API. + + Note: + This function reads and updates alias and module configuration files + to manage the autostart state of the API. + + Examples: + + >>> api_autostart("my_api", 1) # Enable autostart + >>> api_autostart("my_api", 0) # Disable autostart + >>> api_autostart("my_api", -1) # Check current autostart state Returns: - int + The value of option if the operation is successful, or -1 in case of errors. """ @@ -455,18 +500,18 @@ def save_3d_file_silently() -> None: def get_licence_first_part() -> str: - """Gets the first part of the licence + """Gets the first part of the license Returns: - first part of licence + first part of license """ def get_licence_second_part() -> str: - """Gets the second part of the licence + """Gets the second part of the license Returns: - second part of licence + second part of license """ @@ -821,11 +866,11 @@ def get_user_points() -> List[point_3d]: """ -def get_user_points_with_count(a0: int) -> List[point_3d]: +def get_user_points_with_count(count: int) -> List[point_3d]: """get user points with count Parameters: - a0: a0 + count: count Returns: List[point_3d] @@ -840,23 +885,23 @@ def get_user_path_from_dialog() -> str: """ -def get_user_path_from_dialog_in_path(a0: str) -> str: +def get_user_path_from_dialog_in_path(path: str) -> str: """get user path from dialog in path Parameters: - a0: a0 + path: path Returns: str """ -def execute_shortcut(a0: int, a1: int) -> None: +def execute_shortcut(shortcut_key_modifier: shortcut_key_modifier, shortcut_key: shortcut_key) -> None: """execute shortcut Parameters: - a0: a0 - a1: a1 + shortcut_key_modifier: shortcut_key_modifier + shortcut_key: shortcut_key Returns: None @@ -1218,3 +1263,20 @@ def get_user_string_with_default_value(message: str, default_value: str) -> str: str """ + +def get_3d_version_name() -> str: + """get 3d version name + + Returns: + str + """ + + +def redirect_python_output_to_logger() -> None: + """redirect python output to logger. + This function is used to redirect the output of the Python interpreter to the logger. + This is useful for debugging and logging purposes. + + Returns: + None + """ diff --git a/src/visualization_controller/__init__.pyi b/src/visualization_controller/__init__.pyi index 3c30f5c..f0d653b 100644 --- a/src/visualization_controller/__init__.pyi +++ b/src/visualization_controller/__init__.pyi @@ -1,7 +1,6 @@ from typing import List -from cadwork import camera_data -from cadwork import point_3d -from cadwork import rgb_color +from cadwork.camera_data import camera_data +from cadwork.point_3d import point_3d def get_last_error(error_code: int) -> str: """Gets the last error @@ -361,23 +360,25 @@ def show_perspective_central() -> None: None """ -def set_color_without_material(a0: List[int], a1: int) -> None: + +def set_color_without_material(elements: List[int], color_id: int) -> None: """set color without material Parameters: - a0: a0 - a1: a1 + elements: elements + color_id: color_id Returns: None """ -def set_texture_rotated(a0: List[int], a1: bool) -> None: + +def set_texture_rotated(elements: List[int], flag: bool) -> None: """set texture rotated Parameters: - a0: a0 - a1: a1 + elements: elements + flag: flag Returns: None @@ -430,7 +431,8 @@ def get_color(element_id: int) -> int: color ID """ -def get_opengl_color(element_id: int) -> rgb_color: + +def get_opengl_color(element_id: int) -> 'rgb_color': """Gets the element OpenGL color Parameters: @@ -450,7 +452,8 @@ def get_material(element_id: int) -> int: material ID """ -def get_rgb_from_cadwork_color_id(color_id: None) -> rgb_color: + +def get_rgb_from_cadwork_color_id(color_id: None) -> 'rgb_color': """get rgb from cadwork color id Parameters: @@ -460,11 +463,12 @@ def get_rgb_from_cadwork_color_id(color_id: None) -> rgb_color: colorRGB """ -def is_texture_rotated(a0: int) -> bool: + +def is_texture_rotated(element_id: int) -> bool: """is texture rotated Parameters: - a0: a0 + element_id: element_id Returns: bool @@ -554,21 +558,23 @@ def set_use_material_texture(element_id_list: List[int], value: bool) -> None: None """ -def display_bitmaps_as_texture_representation_in_shaded1(a0: bool) -> None: + +def display_bitmaps_as_texture_representation_in_shaded1(flag: bool) -> None: """display bitmaps as texture representation in shaded1 Parameters: - a0: a0 + flag: flag Returns: None """ -def display_bitmaps_as_texture_representation_in_shaded2(a0: bool) -> None: + +def display_bitmaps_as_texture_representation_in_shaded2(flag: bool) -> None: """display bitmaps as texture representation in shaded2 Parameters: - a0: a0 + flag: flag Returns: None From 136e03888588f0f6a8775d29250055e5e8e8b4e8 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Mon, 19 May 2025 15:15:19 +0200 Subject: [PATCH 11/52] Add rgb_color class and update type hints in various functions Signed-off-by: Michael Brunner --- pyproject.toml | 2 +- src/cadwork/__init__.pyi | 2 + src/cadwork/facet_list.pyi | 2 +- src/cadwork/point_3d.pyi | 96 +++++++++++++++++++++++ src/cadwork/rgb_color.py | 5 ++ src/utility_controller/__init__.pyi | 3 +- src/visualization_controller/__init__.pyi | 2 +- 7 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 src/cadwork/rgb_color.py diff --git a/pyproject.toml b/pyproject.toml index abe22df..fb832c6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.246.0" +version = "32.261.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' diff --git a/src/cadwork/__init__.pyi b/src/cadwork/__init__.pyi index 1aa50c0..42ae349 100644 --- a/src/cadwork/__init__.pyi +++ b/src/cadwork/__init__.pyi @@ -1,3 +1,4 @@ +from cadwork.rgb_color import rgb_color from .attribute_display_settings import attribute_display_settings from .bim_team_upload_result import bim_team_upload_result from .bim_team_upload_result_code import bim_team_upload_result_code @@ -112,6 +113,7 @@ hit_result = hit_result dimension_base_format = dimension_base_format dxf_layer_format_type = dxf_layer_format_type dxf_export_version = dxf_export_version +rgb_color = rgb_color def get_auto_attribute_elements() -> List[int]: diff --git a/src/cadwork/facet_list.pyi b/src/cadwork/facet_list.pyi index 7868591..6b580ee 100644 --- a/src/cadwork/facet_list.pyi +++ b/src/cadwork/facet_list.pyi @@ -11,7 +11,7 @@ class facet_list: int """ - def at(self, index: int) -> point_3d: + def at(self, index: int) -> vertex_list: """at Parameters: diff --git a/src/cadwork/point_3d.pyi b/src/cadwork/point_3d.pyi index 45c5cf9..457ef98 100644 --- a/src/cadwork/point_3d.pyi +++ b/src/cadwork/point_3d.pyi @@ -63,3 +63,99 @@ class point_3d: 'point_3d' """ + def __sub__(self, other: 'point_3d') -> 'point_3d': + """sub + + Parameters: + other: other + + Returns: + 'point_3d' + """ + + def __truediv__(self, other: float) -> 'point_3d': + """truediv + + Parameters: + other: other + + Returns: + 'point_3d' + """ + + def __iadd__(self, other: 'point_3d') -> 'point_3d': + """iadd + + Parameters: + other: other + + Returns: + 'point_3d' + """ + + def __isub__(self, other: 'point_3d') -> 'point_3d': + """isub + + Parameters: + other: other + + Returns: + 'point_3d' + """ + + def __imul__(self, other: float) -> 'point_3d': + """imul + + Parameters: + other: other + + Returns: + 'point_3d' + """ + + def __itruediv__(self, other: float) -> 'point_3d': + """itruediv + + Parameters: + other: other + + Returns: + 'point_3d' + """ + + def __neg__(self) -> 'point_3d': + """neg + + Returns: + 'point_3d' + """ + + def __eq__(self, other: object) -> bool: + """eq + + Parameters: + other: other + + Returns: + bool + """ + + def __ne__(self, other: object) -> bool: + """neg + + Parameters: + other: other + + Returns: + bool + """ + + def __add__(self, other: 'point_3d') -> 'point_3d': + """add + + Parameters: + other: other + + Returns: + 'point_3d' + """ diff --git a/src/cadwork/rgb_color.py b/src/cadwork/rgb_color.py new file mode 100644 index 0000000..ad1fcb6 --- /dev/null +++ b/src/cadwork/rgb_color.py @@ -0,0 +1,5 @@ +class rgb_color: + def __init__(self, r, g, b): + self.r = r + self.g = g + self.b = b diff --git a/src/utility_controller/__init__.pyi b/src/utility_controller/__init__.pyi index a5c7058..9e5784a 100644 --- a/src/utility_controller/__init__.pyi +++ b/src/utility_controller/__init__.pyi @@ -72,11 +72,12 @@ def get_language() -> str: """ -def print_message(message: str, column: int) -> None: +def print_message(message: str, row: int, column: int) -> None: """Prints a message Parameters: message: message + row: row column: column Returns: diff --git a/src/visualization_controller/__init__.pyi b/src/visualization_controller/__init__.pyi index f0d653b..8dc457c 100644 --- a/src/visualization_controller/__init__.pyi +++ b/src/visualization_controller/__init__.pyi @@ -453,7 +453,7 @@ def get_material(element_id: int) -> int: """ -def get_rgb_from_cadwork_color_id(color_id: None) -> 'rgb_color': +def get_rgb_from_cadwork_color_id(color_id: int) -> 'rgb_color': """get rgb from cadwork color id Parameters: From 7c296c55204619d457050a16834f872ed531d512 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Mon, 26 May 2025 17:24:49 +0200 Subject: [PATCH 12/52] Refactor type hints and improve documentation in machine controller Signed-off-by: Michael Brunner --- src/bim_controller/__init__.pyi | 4 +- src/cadwork/point_3d.pyi | 139 ++++++++++++++++++++++------ src/element_controller/__init__.pyi | 6 +- src/machine_controller/__init__.pyi | 120 ++++++++++++++++++++++-- 4 files changed, 230 insertions(+), 39 deletions(-) diff --git a/src/bim_controller/__init__.pyi b/src/bim_controller/__init__.pyi index bf8b46b..14666d0 100644 --- a/src/bim_controller/__init__.pyi +++ b/src/bim_controller/__init__.pyi @@ -42,12 +42,12 @@ def get_ifc2x3_element_type(element_id: int) -> ifc_2x3_element_type: """ -def set_ifc2x3_element_type(element_i_ds: List[int], element_type: element_type) -> None: +def set_ifc2x3_element_type(element_i_ds: List[int], ifc_type: ifc_2x3_element_type) -> None: """set ifc2x3 element type Parameters: element_i_ds: element_i_ds - element_type: element_type + ifc_type: element_type Returns: None diff --git a/src/cadwork/point_3d.pyi b/src/cadwork/point_3d.pyi index 457ef98..fb96ebd 100644 --- a/src/cadwork/point_3d.pyi +++ b/src/cadwork/point_3d.pyi @@ -8,61 +8,146 @@ class point_3d: y (float): The y-coordinate of the point. z (float): The z-coordinate of the point. """ - self.x = x - self.y = y - self.z = z - def dot(self, p: 'point_3d') -> float: - """dot + def __add__(self, other: 'point_3d') -> 'point_3d': + """ + Add two points component-wise. - Parameters: - p: p + Returns: + point_3d: The sum of two points. + """ + + def __sub__(self, other: 'point_3d') -> 'point_3d': + """ + Subtract two points component-wise. Returns: - float + point_3d: The difference of two points. """ - def cross(self, p: 'point_3d') -> 'point_3d': - """cross + def __mul__(self, other: float) -> 'point_3d': + """ + Multiply point by a scalar. - Parameters: - p: p + Returns: + point_3d: The scaled point. + """ + + def __rmul__(self, other: float) -> 'point_3d': + """ + Multiply point by a scalar (right-hand side). Returns: - 'point_3d' + point_3d: The scaled point. """ - def magnitude(self) -> float: - """magnitude + def __truediv__(self, other: float) -> 'point_3d': + """ + Divide point by a scalar. Returns: - float + point_3d: The scaled point. """ - def normalized(self) -> 'point_3d': - """normalized + def __iadd__(self, other: 'point_3d') -> 'point_3d': + """ + In-place addition of another point. Returns: - 'point_3d' + point_3d: The updated point. """ - def distance(self, p: 'point_3d') -> float: - """distance + def __isub__(self, other: 'point_3d') -> 'point_3d': + """ + In-place subtraction of another point. - Parameters: - p: p + Returns: + point_3d: The updated point. + """ + + def __imul__(self, other: float) -> 'point_3d': + """ + In-place multiplication by a scalar. Returns: - float + point_3d: The updated point. """ - def invert(self) -> 'point_3d': - """invert + def __itruediv__(self, other: float) -> 'point_3d': + """ + In-place division by a scalar. Returns: - 'point_3d' + point_3d: The updated point. + """ + + def __neg__(self) -> 'point_3d': """ + Negate the point (component-wise). + Returns: + point_3d: The negated point. + """ + + def __eq__(self, other: object) -> bool: + """ + Check if two points are equal. + + Returns: + bool: True if equal, False otherwise. + """ + + def __ne__(self, other: object) -> bool: + """ + Check if two points are not equal. + + Returns: + bool: True if not equal, False otherwise. + """ + + def __getitem__(self, index: int) -> float: + """ + Get coordinate by index (0: x, 1: y, 2: z). + + Returns: + float: The coordinate value. + Raises: + IndexError: If index is out of range. + """ + + def __setitem__(self, index: int, value: float) -> None: + """ + Set coordinate by index (0: x, 1: y, 2: z). + + Raises: + IndexError: If index is out of range. + """ + + def __repr__(self) -> str: + """ + Return the string representation of the point. + + Returns: + str: The string representation. + """ + + def dot(self, p: 'point_3d') -> float: + """Dot product with another point.""" + + def cross(self, p: 'point_3d') -> 'point_3d': + """Cross product with another point.""" + + def magnitude(self) -> float: + """Return the magnitude of the point vector.""" + + def normalized(self) -> 'point_3d': + """Return the normalized (unit) vector.""" + + def distance(self, p: 'point_3d') -> float: + """Euclidean distance to another point.""" + + def invert(self) -> 'point_3d': + """Return the inverted point (negated coordinates).""" def __sub__(self, other: 'point_3d') -> 'point_3d': """sub diff --git a/src/element_controller/__init__.pyi b/src/element_controller/__init__.pyi index 354ba8a..1d9f206 100644 --- a/src/element_controller/__init__.pyi +++ b/src/element_controller/__init__.pyi @@ -2131,7 +2131,7 @@ def map_elements(elements: List[int], map_query: element_map_query) -> Dict[str, elements: elements map_query: map_query - Example: + Examples: >>> import cadwork >>> import element_controller as ec >>> your_map_query = cadwork.element_map_query() @@ -2153,9 +2153,9 @@ def cast_ray_and_get_element_intersections(elements: List[int], ray_start_positi ray_end_position: ray_end_position radius: radius - Example: - >>> from cadwork import point_3d + Examples: >>> import element_controller as ec + >>> from cadwork import point_3d >>> ray_start = point_3d(0, 0, 0) >>> ray_end = point_3d(1000, 0, 0) >>> hit_result = ec.cast_ray_and_get_element_intersections(ec.get_active_identifiable_element_ids(), ray_start, ray_end, 40.0) diff --git a/src/machine_controller/__init__.pyi b/src/machine_controller/__init__.pyi index 745ac2f..58130de 100644 --- a/src/machine_controller/__init__.pyi +++ b/src/machine_controller/__init__.pyi @@ -1,4 +1,6 @@ from typing import List +from cadwork import vertex_list + def get_last_error(error_code: int) -> str: """Gets the last error @@ -41,13 +43,6 @@ def export_hundegger(hundeggertype: int) -> None: None """ -def clear_errors() -> None: - """clear errors - - Returns: - None - """ - def export_hundegger_with_file_path(hundeggertype: int, file_path: str) -> None: """Exports a Hundegger file @@ -139,3 +134,114 @@ def export_hundegger_with_file_path_and_presetting_silent(hundeggertype: int, fi None """ + +def get_element_hundegger_processings(element_id: int, hundeggertype: int) -> List[int]: + """Get Hundegger processing IDs for an element. + + Parameters: + element_id: The element ID. + hundeggertype: The Hundegger type. + + Returns: + List of processing IDs. + """ + + +def get_element_btl_processings(element_id: int, btl_version: int) -> List[int]: + """Get BTL processing IDs for an element. + + Parameters: + element_id: The element ID. + btl_version: The BTL version. + + Returns: + List of processing IDs. + """ + + +def get_processing_name(reference_element_id: int, processing_id: int) -> str: + """Get the name of a processing. + + Parameters: + reference_element_id: The reference element ID. + processing_id: The processing ID. + + Examples: + >>> import cadwork + >>> import element_controller as ec + >>> import machine_controller as mc + + >>> element: int = 123456789 + >>> processings = mc.get_element_btl_processings(element, cadwork.btl_version.btlx_2_1.value) + >>> for processing in processings: + >>> name = mc.get_processing_name(element, processing) + + Returns: + The processing name. + """ + + +def get_processing_code(reference_element_id: int, processing_id: int) -> str: + """Get the code of a processing. + + Parameters: + reference_element_id: The reference element ID. + processing_id: The processing ID. + + Examples: + >>> import cadwork + >>> import element_controller as ec + >>> import machine_controller as mc + + >>> element: int = 123456789 + >>> processings = mc.get_element_btl_processings(element, cadwork.btl_version.btlx_2_1.value) + >>> for processing in processings: + >>> code = mc.get_processing_code(element, processing) + + Returns: + The processing code. + """ + + +def get_processing_points(reference_element_id: int, processing_id: int) -> vertex_list: + """Get the points of a processing. + + Parameters: + reference_element_id: The reference element ID. + processing_id: The processing ID. + + Examples: + >>> import cadwork + >>> import element_controller as ec + >>> import machine_controller as mc + + >>> element: int = 123456789 + >>> processings = mc.get_element_btl_processings(element, cadwork.btl_version.btlx_2_1.value) + >>> for processing in processings: + >>> points = mc.get_processing_points(element, processing) + + Returns: + A vertex_list of points. + """ + + +def get_processing_btl_parameter_set(reference_element_id: int, processing_id: int) -> List[str]: + """Get the BTL parameter set for a processing. + + Parameters: + reference_element_id: The reference element ID. + processing_id: The processing ID. + + Examples: + >>> import cadwork + >>> import element_controller as ec + >>> import machine_controller as mc + + >>> element: int = 123456789 + >>> processings = mc.get_element_btl_processings(element, cadwork.btl_version.btlx_2_1.value) + >>> for processing in processings: + >>> parameters = mc.get_processing_btl_parameter_set(element, processing) + + Returns: + List of BTL parameter strings. + """ From 875bb61316046471e348d6e0c35cbe69ce20f25d Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Thu, 5 Jun 2025 11:26:18 +0200 Subject: [PATCH 13/52] Update type hints and improve documentation for IFC element types Signed-off-by: Michael Brunner --- src/bim_controller/__init__.pyi | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/bim_controller/__init__.pyi b/src/bim_controller/__init__.pyi index 14666d0..85e490b 100644 --- a/src/bim_controller/__init__.pyi +++ b/src/bim_controller/__init__.pyi @@ -2,7 +2,7 @@ from typing import List from cadwork.ifc_2x3_element_type import ifc_2x3_element_type from cadwork.ifc_options import ifc_options from cadwork.ifc_predefined_type import ifc_predefined_type -from cadwork.element_type import element_type + def get_last_error(a0: int) -> str: """get last error @@ -49,6 +49,11 @@ def set_ifc2x3_element_type(element_i_ds: List[int], ifc_type: ifc_2x3_element_t element_i_ds: element_i_ds ifc_type: element_type + Examples: + >>> ifc_entity_type = cadwork.ifc_2x3_element_type() + >>> ifc_entity_type.set_ifc_member() + >>> bimc.set_ifc2x3_element_type([element], ifc_entity_type) + Returns: None """ @@ -243,22 +248,22 @@ def get_storey_height(building: str, storey: str) -> float: """ -def get_ifc2x3_element_type_string(element_type: element_type) -> str: +def get_ifc2x3_element_type_string(entity_type: ifc_2x3_element_type) -> str: """get ifc2x3 element type string Parameters: - element_type: element_type + entity_type: entity_type Returns: str """ -def get_ifc2x3_element_type_display_string(element_type: element_type) -> str: +def get_ifc2x3_element_type_display_string(entity_type: ifc_2x3_element_type) -> str: """get ifc2x3 element type display string Parameters: - element_type: element_type + entity_type: entity_type Returns: str @@ -312,7 +317,8 @@ def get_ifc_predefined_type(element_id: int) -> 'ifc_predefined_type': IfcPredefinedType Wrapper """ -def set_ifc_predefined_type(element_i_ds: List[int], predefined_type: None) -> None: + +def set_ifc_predefined_type(element_i_ds: List[int], predefined_type: ifc_predefined_type) -> None: """Set a predefined type to elements. Attention, if you change the PredefinedType of the elements, you are responsible for ensuring that valid types are set Parameters: From 19caa2be8b72719d8a161af837109d6d26e1b032 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Thu, 5 Jun 2025 11:26:57 +0200 Subject: [PATCH 14/52] Update type hints and add examples for multi layer set functions Signed-off-by: Michael Brunner --- src/multi_layer_cover_controller/__init__.pyi | 209 ++++++++++++++++-- 1 file changed, 185 insertions(+), 24 deletions(-) diff --git a/src/multi_layer_cover_controller/__init__.pyi b/src/multi_layer_cover_controller/__init__.pyi index a1ad114..4d8a358 100644 --- a/src/multi_layer_cover_controller/__init__.pyi +++ b/src/multi_layer_cover_controller/__init__.pyi @@ -1,55 +1,82 @@ from typing import List -def set_element_multi_layer_set(element_id: int, set_id: None) -> None: + +def set_element_multi_layer_set(element_id: int, set_id: int) -> None: """Sets the multi layer set id of a cover Parameters: element_id: element_id set_id: set_id + + Examples: + >>> cover_id = element.create_cover(points, normal_vector) + >>> multi_layer_set_id = mlc.create_multi_layer_wall("Wall Type A") + >>> mlc.set_element_multi_layer_set(cover_id, multi_layer_set_id) Returns: None """ -def set_multi_layer_set_name(set_id: None, set_name: str) -> None: + +def set_multi_layer_set_name(set_id: int, set_name: str) -> None: """Sets the name for a multi layer set Parameters: set_id: set_id set_name: set_name + + Examples: + >>> multi_layer_set_id = mlc.create_multi_layer_wall("Default Wall") + >>> mlc.set_multi_layer_set_name(multi_layer_set_id, "Exterior Wall Type B") Returns: None """ -def set_cover_name(set_id: None, cover_name: str) -> None: + +def set_cover_name(set_id: int, cover_name: str) -> None: """Sets the cover name of the multi layer set Parameters: set_id: set_id cover_name: cover_name + + Examples: + >>> multi_layer_set_id = mlc.create_multi_layer_wall("Default Wall") + >>> mlc.set_cover_name(multi_layer_set_id, "Exterior Facade") Returns: None """ -def set_cover_material(set_id: None, cover_material: int) -> None: + +def set_cover_material(set_id: int, cover_material: int) -> None: """Sets the cover material of the multi layer set Parameters: set_id: set_id cover_material: cover_material + + Examples: + >>> multi_layer_set_id = mlc.create_multi_layer_wall("Default Wall") + >>> material_id = mc.get_material_id("Cement Board") + >>> mlc.set_cover_material(multi_layer_set_id, material_id) Returns: None """ -def set_cover_thickness(set_id: None, cover_thickness: float) -> None: + +def set_cover_thickness(set_id: int, cover_thickness: float) -> None: """Sets the cover thickness of the multi layer set. Only allowed for simple walls (cover without layer) Parameters: set_id: set_id cover_thickness: cover_thickness + + Examples: + >>> multi_layer_set_id = mlc.create_multi_layer_wall("Simple Wall") + >>> mlc.set_cover_thickness(multi_layer_set_id, 150.0) Returns: None @@ -60,79 +87,124 @@ def create_multi_layer_wall(set_name: str) -> int: Parameters: set_name: set_name + + Examples: + >>> wall_set_id = mlc.create_multi_layer_wall("Exterior Insulated Wall") + >>> print(f"Created new multi-layer wall with ID: {wall_set_id}") Returns: multiLayerSetID """ -def add_layer(set_id: None, element_grouping_type: None, name: str, material_id: int, thickness: float) -> None: + +def add_layer(set_id: int, layer_type: int, name: str, material_id: int, thickness: float) -> None: """Adds a new layer to the multi layer set Parameters: set_id: set_id - element_grouping_type: element_grouping_type + layer_type: layer_type name: name material_id: material_id thickness: thickness + Examples: + >>> material_id_1 = mc.get_material_id("material_1") + >>> material_id_2 = mc.get_material_id("material_2") + >>> multi_layer_set_id = mlc.create_multi_layer_wall("MultiLayerWall") + >>> layer1_thickness = 200 + >>> layer2_thickness = 15 + >>> mlc.add_layer(multi_layer_set_id, cadwork.multi_layer_type.structure.value,"Layer1", material_id_1, layer1_thickness) + >>> mlc.add_layer(multi_layer_set_id, cadwork.multi_layer_type.panel.value,"Layer2", material_id_2, layer2_thickness) + Returns: None """ -def set_layer_name(set_id: None, layer_index: int, name: str) -> None: + +def set_layer_name(set_id: int, layer_index: int, name: str) -> None: """Sets the name of a layer of the multi layer set Parameters: set_id: set_id layer_index: layer_index name: name + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> mlc.set_layer_name(multi_layer_set_id, 0, "Exterior Cladding") + >>> mlc.set_layer_name(multi_layer_set_id, 1, "Insulation Layer") Returns: None """ -def set_layer_material(set_id: None, layer_index: int, material_id: int) -> None: + +def set_layer_material(set_id: int, layer_index: int, material_id: int) -> None: """Sets the material of a layer of the multi layer set Parameters: set_id: set_id layer_index: layer_index material_id: material_id + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> insulation_material_id = mc.get_material_id("Mineral Wool") + >>> mlc.set_layer_material(multi_layer_set_id, 1, insulation_material_id) Returns: None """ -def set_layer_thickness(set_id: None, layer_index: int, thickness: float) -> None: + +def set_layer_thickness(set_id: int, layer_index: int, thickness: float) -> None: """Sets the thickness of a layer of the multi layer set Parameters: set_id: set_id layer_index: layer_index thickness: thickness + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> mlc.set_layer_thickness(multi_layer_set_id, 0, 25.0) # Set first layer to 25mm + >>> mlc.set_layer_thickness(multi_layer_set_id, 1, 120.0) # Set second layer to 120mm Returns: None """ -def set_layer_type(set_id: None, layer_index: int, element_grouping_type: None) -> None: + +def set_layer_type(set_id: int, layer_index: int, layer_type: int) -> None: """Sets the type of a layer of the multi layer set Parameters: set_id: set_id layer_index: layer_index - element_grouping_type: element_grouping_type + layer_type: layer_type + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> layer_count = mlc.get_layer_count(multi_layer_set_id) + >>> layer_mid_point_idx = layer_count // 2 + >>> mlc.set_layer_type(multi_layer_set_id, layer_mid_point_idx, cadwork.multi_layer_type.structure.value) Returns: None """ -def set_cover_color(set_id: None, cover_color: None) -> None: + +def set_cover_color(set_id: int, cover_color: int) -> None: """Sets the cover color of the multi layer set Parameters: set_id: set_id cover_color: cover_color + + Examples: + >>> multi_layer_set_id = mlc.create_multi_layer_wall("Default Wall") + >>> blue_color_id = vc.get_color_id("blue") + >>> mlc.set_cover_color(multi_layer_set_id, blue_color_id) Returns: None @@ -141,15 +213,28 @@ def set_cover_color(set_id: None, cover_color: None) -> None: def get_multi_layer_walls() -> List[int]: """Gets all multi layer wall ids + Examples: + >>> wall_ids = mlc.get_multi_layer_walls() + >>> print(f"Found {len(wall_ids)} multi-layer wall definitions") + >>> for wall_id in wall_ids: + ... name = mlc.get_multi_layer_set_name(wall_id) + ... print(f"Wall ID: {wall_id}, Name: {name}") + Returns: List[int] """ -def get_multi_layer_set_name(set_id: None) -> str: + +def get_multi_layer_set_name(set_id: int) -> str: """Gets the name for a multi layer set Parameters: set_id: set_id + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> set_name = mlc.get_multi_layer_set_name(multi_layer_set_id) + >>> print(f"Element uses multi-layer definition: {set_name}") Returns: string @@ -160,102 +245,178 @@ def get_element_multi_layer_set(element_id: int) -> int: Parameters: element_id: element_id + + Examples: + >>> cover_ids = element.get_covers() + >>> for cover_id in cover_ids: + ... multi_layer_set_id = mlc.get_element_multi_layer_set(cover_id) + ... set_name = mlc.get_multi_layer_set_name(multi_layer_set_id) + ... print(f"Cover {cover_id} uses wall type: {set_name}") Returns: multiLayerSetID """ -def get_cover_name(set_id: None) -> str: + +def get_cover_name(set_id: int) -> str: """Gets the cover name defined in the multi layer set Parameters: set_id: set_id + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> cover_name = mlc.get_cover_name(multi_layer_set_id) + >>> print(f"Cover name: {cover_name}") Returns: string """ -def get_cover_material(set_id: None) -> int: + +def get_cover_material(set_id: int) -> int: """Gets the cover material defined in the multi layer set Parameters: set_id: set_id + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> material_id = mlc.get_cover_material(multi_layer_set_id) + >>> material_name = mc.get_material_name(material_id) + >>> print(f"Cover uses material: {material_name}") Returns: materialID """ -def get_cover_thickness(set_id: None) -> float: + +def get_cover_thickness(set_id: int) -> float: """Gets the cover thickness of the multi layer set Parameters: set_id: set_id + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> thickness = mlc.get_cover_thickness(multi_layer_set_id) + >>> print(f"Cover thickness: {thickness}mm") Returns: double """ -def get_layer_count(set_id: None) -> int: + +def get_layer_count(set_id: int) -> int: """Gets the Number of Layers of the multi layer set Parameters: set_id: set_id + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> count = mlc.get_layer_count(multi_layer_set_id) + >>> print(f"Wall has {count} layers") Returns: uint64_t """ -def get_layer_name(set_id: None, layer_index: int) -> str: + +def get_layer_name(set_id: int, layer_index: int) -> str: """Gets the name of a layer of the multi layer set Parameters: set_id: set_id layer_index: layer_index + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> layer_count = mlc.get_layer_count(multi_layer_set_id) + >>> for i in range(layer_count): + ... layer_name = mlc.get_layer_name(multi_layer_set_id, i) + ... print(f"Layer {i}: {layer_name}") Returns: string """ -def get_layer_thickness(set_id: None, layer_index: int) -> float: + +def get_layer_thickness(set_id: int, layer_index: int) -> float: """Gets the thickness of a layer of the multi layer set Parameters: set_id: set_id layer_index: layer_index + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> layer_count = mlc.get_layer_count(multi_layer_set_id) + >>> total_thickness = 0 + >>> for i in range(layer_count): + ... thickness = mlc.get_layer_thickness(multi_layer_set_id, i) + ... total_thickness += thickness + ... print(f"Layer {i} thickness: {thickness}mm") + >>> print(f"Total wall thickness: {total_thickness}mm") Returns: double """ -def get_layer_material(set_id: None, layer_index: int) -> int: + +def get_layer_material(set_id: int, layer_index: int) -> int: """Gets the material of a layer of the multi layer set Parameters: set_id: set_id layer_index: layer_index + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> layer_count = mlc.get_layer_count(multi_layer_set_id) + >>> for i in range(layer_count): + ... material_id = mlc.get_layer_material(multi_layer_set_id, i) + ... material_name = mc.get_material_name(material_id) + ... print(f"Layer {i} material: {material_name}") Returns: string """ -def get_layer_type(set_id: None, layer_index: int) -> int: + +def get_layer_type(set_id: int, layer_index: int) -> int: """Gets the type of a layer of the multi layer set Parameters: set_id: set_id layer_index: layer_index + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> layer_count = mlc.get_layer_count(multi_layer_set_id) + >>> for i in range(1, layer_count + 1): + ... layer_type = mlc.get_layer_type(multi_layer_set_id, i) + ... layer_name = mlc.get_layer_name(multi_layer_set_id, i) + ... type_str = "Structure" if layer_type == cadwork.multi_layer_type.structure.value else "your logic..." + ... print(f"Layer {i} ({layer_name}): Type = {type_str}") Returns: multiLayerType """ -def get_cover_color(set_id: None) -> int: + +def get_cover_color(set_id: int) -> int: """Gets the cover color defined in the multi layer set Parameters: set_id: set_id + + Examples: + >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) + >>> color_id = mlc.get_cover_color(multi_layer_set_id) + >>> color_name = vc.get_color_name(color_id) + >>> print(f"Cover uses color: {color_name}") Returns: colorID """ - From 0503b8c7ae0c871f0224e1be76c363ab974223e9 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Thu, 5 Jun 2025 11:27:37 +0200 Subject: [PATCH 15/52] Add examples and update type hints for various functions in machine controller Signed-off-by: Michael Brunner --- src/element_controller/__init__.pyi | 380 ++++++++++++++++++++++++++-- 1 file changed, 361 insertions(+), 19 deletions(-) diff --git a/src/element_controller/__init__.pyi b/src/element_controller/__init__.pyi index 1d9f206..ebe9c3a 100644 --- a/src/element_controller/__init__.pyi +++ b/src/element_controller/__init__.pyi @@ -8,6 +8,11 @@ from cadwork.coordinate_system_data import coordinate_system_data from cadwork.element_map_query import element_map_query from cadwork.element_filter import element_filter from cadwork.hit_result import hit_result +from cadwork.vertex_list import vertex_list +from cadwork.shoulder_options import shoulder_options +from cadwork.heel_shoulder_options import heel_shoulder_options +from cadwork.double_shoulder_options import double_shoulder_options + def delete_elements(element_id_list: List[int]) -> None: """delete elements @@ -49,6 +54,17 @@ def create_rectangular_beam_points(width: float, height: float, p1: point_3d, p2 p2: p2 p3: p3 + Examples: + >>> beam_width = 200. + >>> beam_height = 400. + >>> beam_axis_start_pt = cadwork.point_3d(300., 0., 0.) + >>> beam_axis_end_pt = cadwork.point_3d(300., 0., 4000.) + >>> length_vector = (beam_axis_end_pt - beam_axis_start_pt).normalized() + >>> beam_axis_y = cadwork.point_3d(1., 0., 0.) + >>> beam_axis_z = length_vector.cross(beam_axis_y).normalized() + >>> beam_height_axis_pt = beam_axis_start_pt + beam_axis_z + >>> beam_id = ec.create_rectangular_beam_points(beam_width, beam_height, beam_axis_start_pt, beam_axis_end_pt, beam_height_axis_pt ) + Returns: int """ @@ -62,6 +78,16 @@ def create_circular_beam_points(diameter: float, p1: point_3d, p2: point_3d, p3: p2: p2 p3: p3 + Examples: + >>> beam_diameter = 120. + >>> beam_axis_start_pt = cadwork.point_3d(0., 0., 0.) + >>> beam_axis_end_pt = cadwork.point_3d(0., 0., 3000.) + >>> length_vector = (beam_axis_end_pt - beam_axis_start_pt).normalized() + >>> beam_axis_y = cadwork.point_3d(1., 0., 0.) + >>> beam_axis_z = length_vector.cross(beam_axis_y).normalized() + >>> beam_orientation_pt = beam_axis_start_pt + beam_axis_z + >>> beam_id = ec.create_circular_beam_points(beam_diameter, beam_axis_start_pt, beam_axis_end_pt, beam_orientation_pt) + Returns: int """ @@ -75,6 +101,16 @@ def create_square_beam_points(width: float, p1: point_3d, p2: point_3d, p3: poin p2: p2 p3: p3 + Examples: + >>> beam_width = 100. + >>> beam_axis_start_pt = cadwork.point_3d(500., 500., 0.) + >>> beam_axis_end_pt = cadwork.point_3d(500., 500., 2500.) + >>> length_vector = (beam_axis_end_pt - beam_axis_start_pt).normalized() + >>> reference_vector = cadwork.point_3d(0., 1., 0.) + >>> beam_axis_z = length_vector.cross(reference_vector).normalized() + >>> orientation_pt = beam_axis_start_pt + beam_axis_z + >>> beam_id = ec.create_square_beam_points(beam_width, beam_axis_start_pt, beam_axis_end_pt, orientation_pt) + Returns: int """ @@ -90,6 +126,15 @@ def create_rectangular_beam_vectors(width: float, height: float, length: float, xl: xl zl: zl + Examples: + >>> beam_width = 150. + >>> beam_height = 300. + >>> beam_length = 4000. + >>> origin_point = cadwork.point_3d(0., 0., 0.) + >>> x_direction = cadwork.point_3d(1., 0., 0.) # Direction along length + >>> z_direction = cadwork.point_3d(0., 0., 1.) # Direction along height + >>> beam_id = ec.create_rectangular_beam_vectors(beam_width, beam_height, beam_length, origin_point, x_direction, z_direction) + Returns: int """ @@ -104,6 +149,14 @@ def create_circular_beam_vectors(diameter: float, length: float, p1: point_3d, x xl: xl zl: zl + Examples: + >>> beam_diameter = 100. + >>> beam_length = 3500. + >>> origin_point = cadwork.point_3d(200., 200., 200.) + >>> x_direction = cadwork.point_3d(0., 1., 0.) # Beam aligned with Y axis + >>> z_direction = cadwork.point_3d(0., 0., 1.) # Z orientation (arbitrary for circular beam) + >>> beam_id = ec.create_circular_beam_vectors(beam_diameter, beam_length, origin_point, x_direction, z_direction) + Returns: int """ @@ -118,6 +171,14 @@ def create_square_beam_vectors(width: float, length: float, p1: point_3d, xl: po xl: xl zl: zl + Examples: + >>> beam_width = 120. + >>> beam_length = 2800. + >>> origin_point = cadwork.point_3d(0., 0., 500.) + >>> x_direction = cadwork.point_3d(1., 0., 0.) # Direction along length + >>> z_direction = cadwork.point_3d(0., 0., 1.) # Direction for orientation + >>> beam_id = ec.create_square_beam_vectors(beam_width, beam_length, origin_point, x_direction, z_direction) + Returns: int """ @@ -132,6 +193,16 @@ def create_rectangular_panel_points(width: float, thickness: float, p1: point_3d p2: p2 p3: p3 + Examples: + >>> panel_width = 1200. + >>> panel_thickness = 27. + >>> panel_corner_pt = cadwork.point_3d(0., 0., 0.) + >>> panel_length_pt = cadwork.point_3d(0., 2400., 0.) + >>> # Calculate a point to define panel orientation + >>> normal_vector = cadwork.point_3d(0., 0., 1.) # Panel normal in Z direction + >>> orientation_pt = panel_corner_pt + normal_vector + >>> panel_id = ec.create_rectangular_panel_points(panel_width, panel_thickness, panel_corner_pt, panel_length_pt, orientation_pt) + Returns: int """ @@ -147,6 +218,15 @@ def create_rectangular_panel_vectors(width: float, thickness: float, length: flo xl: xl zl: zl + Examples: + >>> panel_width = 1000. + >>> panel_thickness = 20. + >>> panel_length = 2000. + >>> origin_point = cadwork.point_3d(0., 0., 100.) + >>> x_direction = cadwork.point_3d(1., 0., 0.) # Direction along length + >>> z_direction = cadwork.point_3d(0., 0., 1.) # Panel normal direction + >>> panel_id = ec.create_rectangular_panel_vectors(panel_width, panel_thickness, panel_length, origin_point, x_direction, z_direction) + Returns: int """ @@ -159,6 +239,12 @@ def create_drilling_points(diameter: float, p1: point_3d, p2: point_3d) -> int: p1: p1 p2: p2 + Examples: + >>> drill_diameter = 30. + >>> drill_start_pt = cadwork.point_3d(100., 100., 0.) + >>> drill_end_pt = cadwork.point_3d(100., 100., 200.) + >>> drilling_id = ec.create_drilling_points(drill_diameter, drill_start_pt, drill_end_pt) + Returns: int """ @@ -172,6 +258,13 @@ def create_drilling_vectors(diameter: float, length: float, p1: point_3d, xl: po p1: p1 xl: xl + Examples: + >>> drill_diameter = 12. + >>> drill_length = 180. + >>> drill_start_pt = cadwork.point_3d(200., 200., 50.) + >>> drill_direction = cadwork.point_3d(0., 0., 1.) # Drilling in Z direction + >>> drilling_id = ec.create_drilling_vectors(drill_diameter, drill_length, drill_start_pt, drill_direction) + Returns: int """ @@ -183,6 +276,11 @@ def create_line_points(p1: point_3d, p2: point_3d) -> int: p1: p1 p2: p2 + Examples: + >>> line_start_pt = cadwork.point_3d(0., 0., 0.) + >>> line_end_pt = cadwork.point_3d(500., 500., 0.) + >>> line_id = ec.create_line_points(line_start_pt, line_end_pt) + Returns: int """ @@ -195,6 +293,12 @@ def create_line_vectors(length: float, p1: point_3d, xl: point_3d) -> int: p1: p1 xl: xl + Examples: + >>> line_length = 1000. + >>> line_start_pt = cadwork.point_3d(200., 0., 200.) + >>> line_direction = cadwork.point_3d(1., 1., 0.).normalized() # 45 degree line in XY plane + >>> line_id = ec.create_line_vectors(line_length, line_start_pt, line_direction) + Returns: int """ @@ -205,6 +309,10 @@ def create_node(p1: point_3d) -> int: Parameters: p1: p1 + Examples: + >>> node_position = cadwork.point_3d(250., 250., 100.) + >>> node_id = ec.create_node(node_position) + Returns: int """ @@ -270,7 +378,8 @@ def move_element(element_id_list: List[int], vector: point_3d) -> None: None """ -def create_polygon_beam(polygon_vertices: List[point_3d], thickness: float, xl: point_3d, zl: point_3d) -> int: + +def create_polygon_beam(polygon_vertices: vertex_list, thickness: float, xl: point_3d, zl: point_3d) -> int: """create polygon beam Parameters: @@ -279,6 +388,17 @@ def create_polygon_beam(polygon_vertices: List[point_3d], thickness: float, xl: xl: xl zl: zl + Examples: + >>> # Create a triangular beam + >>> vertices = cadwork.vertex_list() + >>> vertices.append(cadwork.point_3d(0., 0., 0.)) + >>> vertices.append(cadwork.point_3d(200., 0., 0.)) + >>> vertices.append(cadwork.point_3d(100., 173.2, 0.)) # Equilateral triangle + >>> beam_thickness = 1000. # Length of the beam + >>> extrusion_vector = cadwork.point_3d(0., 0., 1.) # Direction of extrusion + >>> z_vector = cadwork.point_3d(1., 0., 0.) # Orientation vector + >>> polygon_beam_id = ec.create_polygon_beam(vertices, beam_thickness, extrusion_vector, z_vector) + Returns: int """ @@ -293,6 +413,14 @@ def create_text_object(text: str, position: point_3d, xl: point_3d, zl: point_3d zl: zl size: size + Examples: + >>> text_content = "Cadwork API" + >>> text_position = cadwork.point_3d(0., 0., 0.) + >>> x_direction = cadwork.point_3d(1., 0., 0.) # Text direction + >>> z_direction = cadwork.point_3d(0., 0., 1.) # Text orientation + >>> text_height = 200. + >>> text_id = ec.create_text_object(text_content, text_position, x_direction, z_direction, text_height) + Returns: int """ @@ -461,6 +589,15 @@ def create_text_object_with_font(text: str, position: point_3d, xl: point_3d, zl size: size font_name: font_name + Examples: + >>> text_content = "Custom Text" + >>> text_position = cadwork.point_3d(0., 0., 0.) + >>> x_direction = cadwork.point_3d(1., 0., 0.) # Text direction + >>> z_direction = cadwork.point_3d(0., 0., 1.) # Text orientation + >>> text_height = 150. + >>> font = "Arial" + >>> text_id = ec.create_text_object_with_font(text_content, text_position, x_direction, z_direction, text_height, font) + Returns: int """ @@ -585,6 +722,23 @@ def cut_element_with_plane(element_id: int, cut_plane_normal_vector: point_3d, d cut_plane_normal_vector: cut_plane_normal_vector distance_from_global_origin: distance_from_global_origin + Examples: + >>> import math + >>> beam_height = 240. + >>> beam_id = ec.create_rectangular_beam_vectors(120., beam_height, 3000., cadwork.point_3d(0., 0., 0.), + ... cadwork.point_3d(0., 0., 1.), cadwork.point_3d(0., 1., 0.)) + >>> # Define plane normal vector (30° from vertical in Y-Z plane) + >>> angle_rad = math.radians(30) + >>> plane_normal = cadwork.point_3d(0., -math.sin(angle_rad), math.cos(angle_rad)).normalized() + >>> # Calculate distance from origin to plane + >>> plane_point = cadwork.point_3d(0., beam_height * .5, 1500.) # Point for the cut plane + >>> distance = plane_point.dot(plane_normal) # Distance from origin to plane + >>> # To measure (check result) the distance correctly in cadwork, create a parallel plane to the cut plane + >>> # with the result of distance as the offset. This plane should hit through the origin (0, 0, 0). + >>> print(f"Plane normal: {plane_normal}, Distance: {distance}") + >>> result = ec.cut_element_with_plane(beam_id, plane_normal, distance) + >>> print(f"Cut operation successful: {result}") + Returns: bool """ @@ -620,6 +774,31 @@ def slice_element_with_plane(element_id: int, cut_plane_normal_vector: point_3d, cut_plane_normal_vector: cut_plane_normal_vector distance_from_global_origin: distance_from_global_origin + Examples: + >>> import math + >>> # Create a panel to slice + >>> panel_width = 1200. + >>> panel_thickness = 20. + >>> panel_length = 2400. + >>> panel_id = ec.create_rectangular_panel_vectors(panel_width, panel_thickness, panel_length, + ... cadwork.point_3d(0., 0., 0.), + ... cadwork.point_3d(1., 0., 0.), + ... cadwork.point_3d(0., 0., 1.)) + >>> # Define plane normal vector (45° in XY plane) + >>> angle_rad = math.radians(45) + >>> plane_normal = cadwork.point_3d(math.cos(angle_rad), math.sin(angle_rad), 0.).normalized() + >>> # Calculate distance from origin to plane - slice through center of panel + >>> panel_center = cadwork.point_3d(panel_length/2., panel_width/2., 0.) + >>> ec.create_node(panel_center) # Create a node at the center of the panel + >>> distance = panel_center.dot(plane_normal) # Distance from origin to plane + >>> # Verify plane equation: dot(point_on_plane, normal) = distance + >>> # Any point on the plane should satisfy this equation + >>> print(f"Plane normal: {plane_normal}, Distance: {distance}") + >>> # Slice the panel + >>> result = ec.slice_element_with_plane(panel_id, plane_normal, distance) + >>> print(f"Slice operation successful: {result}") + >>> # Note: slice_element_with_plane keeps both parts as a joined element + Returns: bool """ @@ -662,12 +841,22 @@ def create_auto_container_from_standard_with_reference(elements: List[int], outp int """ -def create_surface(surface_vertices: List[point_3d]) -> int: + +def create_surface(surface_vertices: vertex_list) -> int: """create surface Parameters: surface_vertices: surface_vertices + Examples: + >>> # Create a rectangular surface + >>> vertices = cadwork.vertex_list() + >>> vertices.append(cadwork.point_3d(0., 0., 0.)) + >>> vertices.append(cadwork.point_3d(1000., 0., 0.)) + >>> vertices.append(cadwork.point_3d(1000., 800., 0.)) + >>> vertices.append(cadwork.point_3d(0., 800., 0.)) + >>> surface_id = ec.create_surface(vertices) + Returns: int """ @@ -770,6 +959,17 @@ def create_standard_beam_points(standard_element_name: str, p1: point_3d, p2: po p2: p2 p3: p3 + Examples: + >>> std_beam_name = "Standard-Timber-120x240" # Name as found in standard elements library + >>> beam_start_pt = cadwork.point_3d(0., 0., 0.) + >>> beam_end_pt = cadwork.point_3d(0., 0., 3000.) + >>> # Calculate orientation point + >>> length_vector = (beam_end_pt - beam_start_pt).normalized() + >>> ref_vector = cadwork.point_3d(1., 0., 0.) + >>> orientation_vector = length_vector.cross(ref_vector).normalized() + >>> orientation_pt = beam_start_pt + orientation_vector + >>> std_beam_id = ec.create_standard_beam_points(std_beam_name, beam_start_pt, beam_end_pt, orientation_pt) + Returns: int """ @@ -784,6 +984,14 @@ def create_standard_beam_vectors(standard_element_name: str, length: float, p1: xl: xl zl: zl + Examples: + >>> std_beam_name = "Standard-Timber-100x100" # Name as found in standard elements library + >>> beam_length = 2500. + >>> origin_point = cadwork.point_3d(100., 100., 100.) + >>> x_direction = cadwork.point_3d(1., 0., 0.) # Direction along length + >>> z_direction = cadwork.point_3d(0., 0., 1.) # Orientation vector + >>> std_beam_id = ec.create_standard_beam_vectors(std_beam_name, beam_length, origin_point, x_direction, z_direction) + Returns: int """ @@ -797,6 +1005,15 @@ def create_standard_panel_points(standard_element_name: str, p1: point_3d, p2: p p2: p2 p3: p3 + Examples: + >>> std_panel_name = "Standard-Panel-27mm" # Name as found in standard elements library + >>> panel_corner_pt = cadwork.point_3d(0., 0., 0.) + >>> panel_width_pt = cadwork.point_3d(1200., 0., 0.) + >>> # Calculate normal point for panel orientation (assuming Z is up) + >>> panel_normal = cadwork.point_3d(0., 0., 1.) + >>> orientation_pt = panel_corner_pt + panel_normal + >>> std_panel_id = ec.create_standard_panel_points(std_panel_name, panel_corner_pt, panel_width_pt, orientation_pt) + Returns: int """ @@ -811,6 +1028,14 @@ def create_standard_panel_vectors(standard_element_name: str, length: float, p1: xl: xl zl: zl + Examples: + >>> std_panel_name = "Standard-Panel-20mm" # Name as found in standard elements library + >>> panel_length = 2400. + >>> origin_point = cadwork.point_3d(0., 0., 0.) + >>> x_direction = cadwork.point_3d(1., 0., 0.) # Direction along length + >>> z_direction = cadwork.point_3d(0., 0., 1.) # Panel normal direction + >>> std_panel_id = ec.create_standard_panel_vectors(std_panel_name, panel_length, origin_point, x_direction, z_direction) + Returns: int """ @@ -824,6 +1049,17 @@ def create_standard_steel_points(standard_element_name: str, p1: point_3d, p2: p p2: p2 p3: p3 + Examples: + >>> std_steel_name = "IPE 200" # Name of standard steel profile from library + >>> steel_start_pt = cadwork.point_3d(0., 0., 500.) + >>> steel_end_pt = cadwork.point_3d(3000., 0., 500.) + >>> # Calculate orientation point + >>> length_vector = (steel_end_pt - steel_start_pt).normalized() + >>> up_vector = cadwork.point_3d(0., 0., 1.) + >>> side_vector = length_vector.cross(up_vector).normalized() + >>> orientation_pt = steel_start_pt + up_vector + >>> steel_id = ec.create_standard_steel_points(std_steel_name, steel_start_pt, steel_end_pt, orientation_pt) + Returns: int """ @@ -838,6 +1074,14 @@ def create_standard_steel_vectors(standard_element_name: str, length: float, p1: xl: xl zl: zl + Examples: + >>> std_steel_name = "HEA 220" # Name of standard steel profile from library + >>> steel_length = 4500. + >>> origin_point = cadwork.point_3d(200., 0., 200.) + >>> x_direction = cadwork.point_3d(0., 1., 0.) # Direction along Y axis + >>> z_direction = cadwork.point_3d(0., 0., 1.) # Up direction + >>> steel_id = ec.create_standard_steel_vectors(std_steel_name, steel_length, origin_point, x_direction, z_direction) + Returns: int """ @@ -860,6 +1104,11 @@ def create_normal_axis_points(p1: point_3d, p2: point_3d) -> int: p1: p1 p2: p2 + Examples: + >>> axis_start_pt = cadwork.point_3d(0., 0., 0.) + >>> axis_end_pt = cadwork.point_3d(0., 0., 2000.) + >>> axis_id = ec.create_normal_axis_points(axis_start_pt, axis_end_pt) + Returns: int """ @@ -872,6 +1121,12 @@ def create_normal_axis_vectors(length: float, p1: point_3d, xl: point_3d) -> int p1: p1 xl: xl + Examples: + >>> axis_length = 1500. + >>> axis_start_pt = cadwork.point_3d(200., 200., 0.) + >>> axis_direction = cadwork.point_3d(1., 0., 0.) # Direction along X axis + >>> axis_id = ec.create_normal_axis_vectors(axis_length, axis_start_pt, axis_direction) + Returns: int """ @@ -1130,6 +1385,12 @@ def create_circular_axis_points(diameter: float, p1: point_3d, p2: point_3d) -> p1: p1 p2: p2 + Examples: + >>> axis_diameter = 50. + >>> axis_start_pt = cadwork.point_3d(100., 100., 0.) + >>> axis_end_pt = cadwork.point_3d(100., 100., 300.) + >>> circular_axis_id = ec.create_circular_axis_points(axis_diameter, axis_start_pt, axis_end_pt) + Returns: int """ @@ -1143,11 +1404,19 @@ def create_circular_axis_vector(diameter: float, length: float, p1: point_3d, xl p1: p1 xl: xl + Examples: + >>> axis_diameter = 60. + >>> axis_length = 400. + >>> axis_start_pt = cadwork.point_3d(200., 200., 200.) + >>> axis_direction = cadwork.point_3d(0., 1., 0.) # Direction along Y axis + >>> circular_axis_id = ec.create_circular_axis_vector(axis_diameter, axis_length, axis_start_pt, axis_direction) + Returns: int """ -def create_polygon_panel(polygon_vertices: List[point_3d], thickness: float, xl: point_3d, zl: point_3d) -> int: + +def create_polygon_panel(polygon_vertices: vertex_list, thickness: float, xl: point_3d, zl: point_3d) -> int: """create polygon panel Parameters: @@ -1156,6 +1425,21 @@ def create_polygon_panel(polygon_vertices: List[point_3d], thickness: float, xl: xl: xl zl: zl + Examples: + >>> # Create a hexagonal panel + >>> vertices = cadwork.vertex_list() + >>> import math + >>> radius = 500. + >>> sides = 6 + >>> for i in range(sides): + ... angle = 2 * math.pi * i / sides + ... vertices.append(cadwork.point_3d(radius * math.cos(angle), radius * math.sin(angle), 0.)) + >>> vertices.append(vertices[0]) # Close the polygon + >>> panel_thickness = 20. + >>> extrusion_vector = cadwork.point_3d(0., 0., 1.) # Normal direction + >>> z_vector = cadwork.point_3d(1., 0., 0.) # Orientation vector + >>> polygon_panel_id = ec.create_polygon_panel(vertices, panel_thickness, extrusion_vector, z_vector) + Returns: int """ @@ -1744,6 +2028,17 @@ def create_text_object_with_options(position: point_3d, xl: point_3d, zl: point_ zl: zl text_options: text_options + Examples: + >>> text_position = cadwork.point_3d(0., 0., 0.) + >>> x_direction = cadwork.point_3d(1., 0., 0.) # Text direction + >>> z_direction = cadwork.point_3d(0., 0., 1.) # Text orientation + >>> options = cadwork.text_object_options() + >>> options.set_text("Advanced Text") + >>> options.set_height(200.) + >>> options.set_font_name("Verdana") + >>> options.set_bold(True) + >>> text_id = ec.create_text_object_with_options(text_position, x_direction, z_direction, options) + Returns: int """ @@ -1905,6 +2200,18 @@ def create_truncated_cone_beam_points(start_diameter: float, end_diameter: float p2: p2 p3: p3 + Examples: + >>> start_dia = 200. + >>> end_dia = 150. + >>> cone_start_pt = cadwork.point_3d(0., 0., 0.) + >>> cone_end_pt = cadwork.point_3d(0., 0., 3000.) + >>> # Calculate orientation point + >>> length_vector = (cone_end_pt - cone_start_pt).normalized() + >>> ref_vector = cadwork.point_3d(1., 0., 0.) + >>> orientation_vector = length_vector.cross(ref_vector).normalized() + >>> orientation_pt = cone_start_pt + orientation_vector + >>> cone_id = ec.create_truncated_cone_beam_points(start_dia, end_dia, cone_start_pt, cone_end_pt, orientation_pt) + Returns: int """ @@ -1920,16 +2227,35 @@ def create_truncated_cone_beam_vectors(start_diameter: float, end_diameter: floa xl: xl zl: zl + Examples: + >>> start_dia = 120. + >>> end_dia = 80. + >>> cone_length = 2500. + >>> origin_point = cadwork.point_3d(0., 0., 0.) + >>> x_direction = cadwork.point_3d(0., 0., 1.) # Direction along Z axis + >>> z_direction = cadwork.point_3d(1., 0., 0.) # Orientation vector + >>> cone_id = ec.create_truncated_cone_beam_vectors(start_dia, end_dia, cone_length, origin_point, x_direction, z_direction) + Returns: int """ -def create_spline_line(spline_points: None) -> int: + +def create_spline_line(spline_points: vertex_list) -> int: """create spline line Parameters: spline_points: spline_points + Examples: + >>> # Create a spline through multiple points + >>> points = cadwork.vertex_list() + >>> points.append(cadwork.point_3d(0., 0., 0.)) + >>> points.append(cadwork.point_3d(500., 200., 0.)) + >>> points.append(cadwork.point_3d(1000., 0., 200.)) + >>> points.append(cadwork.point_3d(1500., -100., 100.)) + >>> spline_id = ec.create_spline_line(points) + Returns: int """ @@ -2020,24 +2346,38 @@ def get_is_element_group_single_select_mode() ->bool: def get_is_element_group_multi_select_mode() ->bool: """get is element group multi select mode - Returns: - bool - """ - -def apply_image_to_surface(element: int, image_file_path: str, p1: point_3d, p2: point_3d) ->bool: - """apply image to surface - - Parameters: - element: element - image_file_path: image_file_path - p1: p1 - p2: p2 + Examples: + >>> import math + >>> # Create a beam to slice + >>> beam_width = 150. + >>> beam_height = 300. + >>> beam_length = 4000. + >>> beam_id = ec.create_rectangular_beam_vectors(beam_width, beam_height, beam_length, + ... cadwork.point_3d(0., 0., 0.), + ... cadwork.point_3d(1., 0., 0.), + ... cadwork.point_3d(0., 0., 1.)) + >>> # Define a vertical cutting plane through the middle of the beam + >>> plane_normal = cadwork.point_3d(1., 0., 0.) # Normal vector points along X-axis + >>> # A point on the plane (midpoint of the beam) + >>> plane_point = cadwork.point_3d(beam_length/2., 0., 0.) + >>> distance = plane_point.dot(plane_normal) # Distance from origin to plane + >>> # Verify with additional points on the plane + >>> test_point = cadwork.point_3d(beam_length/2., 100., 200.) + >>> on_plane = abs(test_point.dot(plane_normal) - distance) < 0.001 + >>> print(f"Test point is on plane: {on_plane}") + >>> # Slice the beam at the midpoint and get the resulting pieces + >>> new_element_ids = ec.slice_elements_with_plane_and_get_new_elements(beam_id, plane_normal, distance) + >>> print(f"Created {len(new_element_ids)} new elements: {new_element_ids}") + >>> # Visualization: different pen colors for the new elements + >>> for i, new_id in enumerate(new_element_ids): + ... vc.set_color([new_id], i+5) Returns: bool """ -def set_shoulder_options(options: None) ->None: + +def set_shoulder_options(options: shoulder_options) -> None: """set shoulder options Parameters: @@ -2047,7 +2387,8 @@ def set_shoulder_options(options: None) ->None: None """ -def set_heel_shoulder_options(options: None) ->None: + +def set_heel_shoulder_options(options: heel_shoulder_options) -> None: """set heel shoulder options Parameters: @@ -2057,7 +2398,8 @@ def set_heel_shoulder_options(options: None) ->None: None """ -def set_double_shoulder_options(options: None) ->None: + +def set_double_shoulder_options(options: double_shoulder_options) -> None: """set double shoulder options Parameters: From 6c96f31a22de3307839f88442655db039aac31e5 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Thu, 5 Jun 2025 13:30:20 +0200 Subject: [PATCH 16/52] Update version to 32.274.0 Signed-off-by: Michael Brunner --- docs/release_notes.md | 508 ++++++------------------------------------ pyproject.toml | 2 +- 2 files changed, 72 insertions(+), 438 deletions(-) diff --git a/docs/release_notes.md b/docs/release_notes.md index 2f918e5..aedb304 100644 --- a/docs/release_notes.md +++ b/docs/release_notes.md @@ -1,503 +1,137 @@ # Newly added functions, classes, and enums in cadwork 3D API 2025.0.245 -### Functions dimension_controller +* Added examples to the docstrings for better understanding. +* Corrected several argument types in function signatures. -#### get_dimension_base_format +### Functions machine_controller + +#### get_element_hundegger_processings ```python -def get_dimension_base_format(element: int) -> dimension_base_format: - """get dimension base format +def get_element_hundegger_processings(element_id: int, hundeggertype: int) -> List[int]: + """Get Hundegger processing IDs for an element. Parameters: - element: element + element_id: The element ID. + hundeggertype: The Hundegger type. Returns: - dimension_base_format + List of processing IDs. """ - ``` - -### Functions element_controller - -#### filter_elements +#### get_element_btl_processings ```python -def filter_elements(elements: List[int], element_filter: element_filter - ) -> List[int]: - """filter elements +def get_element_btl_processings(element_id: int, btl_version: int) -> List[int]: + """Get BTL processing IDs for an element. Parameters: - elements: elements - element_filter: name_filter - - Example: - >>> import cadwork - >>> import element_controller as ec - >>> your_element_filter = cadwork.element_filter() - >>> your_element_filter.set_name("beam") - >>> filtered_elements = ec.filter_elements(ec.get_active_identifiable_element_ids(), your_element_filter) - >>> print(filtered_elements) + element_id: The element ID. + btl_version: The BTL version. Returns: - List[int] + List of processing IDs. """ - ``` -#### map_elements +#### get_processing_name ```python -def map_elements(elements: List[int], map_query: element_map_query) -> Dict[ - str, List[int]]: - """map elements +def get_processing_name(reference_element_id: int, processing_id: int) -> str: + """Get the name of a processing. Parameters: - elements: elements - map_query: map_query + reference_element_id: The reference element ID. + processing_id: The processing ID. - Example: + Examples: >>> import cadwork >>> import element_controller as ec - >>> your_map_query = cadwork.element_map_query() - >>> your_map_query.set_by_subgroup() - >>> mapped_items = ec.map_elements(ec.get_active_identifiable_element_ids(), your_map_query) - >>> print(mapped_items) + >>> import machine_controller as mc + + >>> element: int = 123456789 + >>> processings = mc.get_element_btl_processings(element, cadwork.btl_version.btlx_2_1.value) + >>> for processing in processings: + >>> name = mc.get_processing_name(element, processing) Returns: - Dict[str, List[int]] + The processing name. """ - ``` -#### cast_ray_and_get_element_intersections +#### get_processing_code ```python -def cast_ray_and_get_element_intersections(elements: List[int], - ray_start_position: point_3d, ray_end_position: point_3d, radius: float - ) -> hit_result: - """cast ray and get element intersections +def get_processing_code(reference_element_id: int, processing_id: int) -> str: + """Get the code of a processing. + Parameters: - elements: elements - ray_start_position: ray_start_position - ray_end_position: ray_end_position - radius: radius + reference_element_id: The reference element ID. + processing_id: The processing ID. - Example: + Examples: >>> import cadwork >>> import element_controller as ec - >>> ray_start = cadwork.point_3d(0, 0, 0) - >>> ray_end = cadwork.point_3d(1000, 0, 0) - >>> hit_result = ec.cast_ray_and_get_element_intersections(ec.get_active_identifiable_element_ids(), ray_start, ray_end, 40.0) - >>> print(hits.get_hit_element_ids()) - >>> for element in hits.get_hit_element_ids(): - >>> print(f"ElementID {element}: {hits.get_hit_vertices_by_element(element)}") - >>> for pos in hits.get_hit_vertices_by_element(element): - >>> ec.create_node(pos) - - Returns: - hit_result - """ - -``` - - -### Functions file_controller + >>> import machine_controller as mc -#### export_dxf_file - -```python -def export_dxf_file(file_path: str, dxf_layer_format_type: -dxf_layer_format_type, dxf_export_version: dxf_export_version) -> bool: - """export dxf file - - Parameters: - file_path: file_path - dxf_layer_format_type: dxf_layer_format_type - dxf_export_version: dxf_export_version + >>> element: int = 123456789 + >>> processings = mc.get_element_btl_processings(element, cadwork.btl_version.btlx_2_1.value) + >>> for processing in processings: + >>> code = mc.get_processing_code(element, processing) Returns: - bool + The processing code. """ - ``` -#### export_dstv_file +#### get_processing_points ```python -def export_dstv_file(file_path: str) -> bool: - """export dstv file +def get_processing_points(reference_element_id: int, processing_id: int) -> vertex_list: + """Get the points of a processing. Parameters: - file_path: file_path - - Returns: - bool - """ - -``` - -### Functions utility_controller - -#### get_3d_version_name - -```python -def get_3d_version_name() -> str: - """get 3d version name - - Returns: - str - """ - -``` + reference_element_id: The reference element ID. + processing_id: The processing ID. -#### redirect_python_output_to_logger + Examples: + >>> import cadwork + >>> import element_controller as ec + >>> import machine_controller as mc -```python -def redirect_python_output_to_logger() -> None: - """redirect python output to logger. - This function is used to redirect the output of the Python interpreter to the logger. - This is useful for debugging and logging purposes. + >>> element: int = 123456789 + >>> processings = mc.get_element_btl_processings(element, cadwork.btl_version.btlx_2_1.value) + >>> for processing in processings: + >>> points = mc.get_processing_points(element, processing) Returns: - None - """ - -``` - -### Classes cadwork - -#### bim_team_upload_result - -```python -class bim_team_upload_result: - """bim team upload result + A vertex_list of points. """ - - def __init__(self): - """ - Instance of the bim_team_upload_result class. - - Attributes: - upload_result_code (bim_team_upload_result_code): The result code of the upload. - share_link (str): The share link for the uploaded BIM team result. - """ - self.upload_result_code = bim_team_upload_result_code.ok - self.share_link = '' - ``` -### Classes cadwork - -#### bim_team_upload_result_code +#### get_processing_btl_parameter_set ```python -@unique -class bim_team_upload_result_code(IntEnum): - """bim team upload result code - - Examples: - >>> cadwork.bim_team_upload_result_code.ok - ok - """ - ok = 0 - """""" - error_general_error = 1 - """""" - error_too_many_models = 2 - """""" - error_insufficient_storage = 3 - """""" - error_invalid_project_id = 4 - """""" - error_authentication_failed = 5 - """""" - - def __int__(self) -> int: - return self.value - -``` +def get_processing_btl_parameter_set(reference_element_id: int, processing_id: int) -> List[str]: + """Get the BTL parameter set for a processing. -### Classes cadwork - -#### dimension_base_format - -```python -@unique -class dimension_base_format(IntEnum): - """ Enumeration for dimension base format. - - Examples: - >>> cadwork.dimension_base_format.sum_only - - """ - none = 0 - """""" - distance_only = 1 - """""" - sum_only = 2 - """""" - distance_and_sum = 3 - """""" - sum_moved = 4 - """""" - - def __int__(self) -> int: - return self.value - -``` - -### Classes cadwork - -#### dxf_export_version - -```python -@unique -class dxf_export_version(IntEnum): - """ Enumeration for DXF export version. + Parameters: + reference_element_id: The reference element ID. + processing_id: The processing ID. Examples: - >>> cadwork.dxf_export_version.auto_cad_r27 - - """ - auto_cad_r10 = 0 - """""" - auto_cad_r27 = 1 - """""" - - def __int__(self) -> int: - return self.value - -``` - -### Classes cadwork - -#### dxf_layer_format_type - -```python -@unique -class dxf_layer_format_type(IntEnum): - """ Enumeration for DXF layer format type. + >>> import cadwork + >>> import element_controller as ec + >>> import machine_controller as mc - Examples: - >>> cadwork.dxf_layer_format_type.color + >>> element: int = 123456789 + >>> processings = mc.get_element_btl_processings(element, cadwork.btl_version.btlx_2_1.value) + >>> for processing in processings: + >>> parameters = mc.get_processing_btl_parameter_set(element, processing) + Returns: + List of BTL parameter strings. """ - all_in_no_1 = 0 - """""" - color = 1 - """""" - material = 2 - """""" - name = 3 - """""" - group = 4 - """""" - subgroup = 5 - """""" - - def __int__(self) -> int: - return self.value - -``` - - -### Classes cadwork - -#### element_filter - -```python -class element_filter: - - def set_name(self, name: str) -> None: - """set name - - Parameters: - name: name - - Returns: - None - """ - - def set_group(self, group: str) -> None: - """set group - - Parameters: - group: group - - Returns: - None - """ - - def set_subgroup(self, subgroup: str) -> None: - """set subgroup - - Parameters: - subgroup: subgroup - - Returns: - None - """ - - def set_comment(self, comment: str) -> None: - """set comment - - Parameters: - comment: comment - - Returns: - None - """ - - def set_user_attribute(self, number: int, user_attribute: str) -> None: - """set user attribute - - Parameters: - number: number - user_attribute: user_attribute - - Returns: - None - """ - - def set_sku(self, sku: str) -> None: - """set sku - - Parameters: - sku: sku - - Returns: - None - """ - - def set_production_number(self, production_number: int) -> None: - """set production number - - Parameters: - production_number: production_number - - Returns: - None - """ - - def set_part_number(self, part_number: int) -> None: - """set part number - - Parameters: - part_number: part_number - - Returns: - None - """ - ``` - -### Classes cadwork - -#### element_map_query - -```python -class element_map_query: - - def set_by_name(self) -> None: - """set by name - - Returns: - None - """ - - def set_by_group(self) -> None: - """set by group - - Returns: - None - """ - - def set_by_subgroup(self) -> None: - """set by subgroup - - Returns: - None - """ - - def set_by_comment(self) -> None: - """set by comment - - Returns: - None - """ - - def set_by_user_attribute(self, number: int) -> None: - """set by user attribute - - Parameters: - number: number - - Returns: - None - """ - - def set_by_sku(self) -> None: - """set by sku - - Returns: - None - """ - - def set_by_production_number(self) -> None: - """set by production number - - Returns: - None - """ - - def set_by_part_number(self) -> None: - """set by part number - - Returns: - None - """ - - def set_by_building(self) -> None: - """set by building - - Returns: - None - """ - - def set_by_storey(self) -> None: - """set by storey - - Returns: - None - """ - -``` - - -### Classes cadwork - -#### hit_result - -```python -class hit_result: - - def get_hit_element_ids(self) -> List[int]: - """get hit element ids - - Returns: - List[int] - """ - - def get_hit_vertices_by_element(self, element_id: int) -> List[point_3d]: - """get hit vertices by element - - Parameters: - element_id: element_id - - Returns: - List[point_3d] - """ - -``` \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index fb832c6..18b7a41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.261.0" +version = "32.274.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' From 3570a6e92b989b93a1208641999f993e5e19a174 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Fri, 6 Jun 2025 12:46:13 +0200 Subject: [PATCH 17/52] Update release notes for cadwork 3D Signed-off-by: Michael Brunner --- docs/release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release_notes.md b/docs/release_notes.md index aedb304..47b60b9 100644 --- a/docs/release_notes.md +++ b/docs/release_notes.md @@ -1,4 +1,4 @@ -# Newly added functions, classes, and enums in cadwork 3D API 2025.0.245 +# Newly added functions in cadwork 3D API Build >= 2025.0.274 * Added examples to the docstrings for better understanding. * Corrected several argument types in function signatures. From dad2f40b589bed6bd8c2914e6202159c64030c73 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Tue, 8 Jul 2025 11:03:36 +0200 Subject: [PATCH 18/52] Add examples to function docstrings in various modules Signed-off-by: Michael Brunner --- src/cadwork/point_3d.pyi | 99 +------------------ src/file_controller/__init__.pyi | 148 ++++++++++++++++++++++++++++ src/machine_controller/__init__.pyi | 102 +++++++++++++++++++ 3 files changed, 253 insertions(+), 96 deletions(-) diff --git a/src/cadwork/point_3d.pyi b/src/cadwork/point_3d.pyi index fb96ebd..4e73bfa 100644 --- a/src/cadwork/point_3d.pyi +++ b/src/cadwork/point_3d.pyi @@ -8,6 +8,9 @@ class point_3d: y (float): The y-coordinate of the point. z (float): The z-coordinate of the point. """ + self.x = x + self.y = y + self.z = z def __add__(self, other: 'point_3d') -> 'point_3d': """ @@ -148,99 +151,3 @@ class point_3d: def invert(self) -> 'point_3d': """Return the inverted point (negated coordinates).""" - def __sub__(self, other: 'point_3d') -> 'point_3d': - """sub - - Parameters: - other: other - - Returns: - 'point_3d' - """ - - def __truediv__(self, other: float) -> 'point_3d': - """truediv - - Parameters: - other: other - - Returns: - 'point_3d' - """ - - def __iadd__(self, other: 'point_3d') -> 'point_3d': - """iadd - - Parameters: - other: other - - Returns: - 'point_3d' - """ - - def __isub__(self, other: 'point_3d') -> 'point_3d': - """isub - - Parameters: - other: other - - Returns: - 'point_3d' - """ - - def __imul__(self, other: float) -> 'point_3d': - """imul - - Parameters: - other: other - - Returns: - 'point_3d' - """ - - def __itruediv__(self, other: float) -> 'point_3d': - """itruediv - - Parameters: - other: other - - Returns: - 'point_3d' - """ - - def __neg__(self) -> 'point_3d': - """neg - - Returns: - 'point_3d' - """ - - def __eq__(self, other: object) -> bool: - """eq - - Parameters: - other: other - - Returns: - bool - """ - - def __ne__(self, other: object) -> bool: - """neg - - Parameters: - other: other - - Returns: - bool - """ - - def __add__(self, other: 'point_3d') -> 'point_3d': - """add - - Parameters: - other: other - - Returns: - 'point_3d' - """ diff --git a/src/file_controller/__init__.pyi b/src/file_controller/__init__.pyi index 410fc01..63ce1a2 100644 --- a/src/file_controller/__init__.pyi +++ b/src/file_controller/__init__.pyi @@ -23,6 +23,14 @@ def export_stl_file(element_id_list: List[int], file_path: str) -> None: element_id_list: element_id_list file_path: file_path + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model.stl" + >>> fc.export_stl_file(selected_elements, output_path) + Returns: None """ @@ -60,6 +68,16 @@ def export_webgl(element_id_list: List[int], file_path: str) -> bool: element_id_list: element_id_list file_path: file_path + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model.html" + >>> success = fc.export_webgl(selected_elements, output_path) + >>> if success: + >>> print("WebGL export completed successfully") + Returns: did operation succeed """ @@ -72,6 +90,16 @@ def export_3d_file(element_id_list: List[int], file_path: str) -> bool: element_id_list: element_id_list file_path: file_path + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model.3d" + >>> success = fc.export_3d_file(selected_elements, output_path) + >>> if success: + >>> print("3D file export completed successfully") + Returns: did operation succeed """ @@ -124,6 +152,17 @@ def export_step_file(element_list: List[int], file_path: str, scale_factor: floa version: version text_mode: text_mode + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model.stp" + >>> scale_factor = 1_000.0 + >>> version = 214 # STEP version + >>> text_mode = False + >>> fc.export_step_file(selected_elements, output_path, scale_factor, version, text_mode) + Returns: None """ @@ -147,6 +186,14 @@ def export_obj_file(elements: List[int], file_path: str) -> None: elements: elements file_path: file_path + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model.obj" + >>> fc.export_obj_file(selected_elements, output_path) + Returns: None """ @@ -172,6 +219,27 @@ def export_fbx_file(elements: List[int], file_path: str, fbx_format: int) -> Non elements: elements file_path: file_path fbx_format: fbx_format + Available formats: + - 0 or default: FBX binary(*.fbx) + - 1: FBX binary(*.fbx) + - 2: FBX ascii(*.fbx) + - 3: FBX encrypted(*.fbx) + - 4: FBX 6.0 binary(*.fbx) + - 5: FBX 6.0 ascii(*.fbx) + - 6: FBX 6.0 encrypted(*.fbx) + + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model.fbx" + >>> fbx_format = 1 # FBX binary format + >>> fc.export_fbx_file(selected_elements, output_path, fbx_format) + + >>> # Export as ASCII format + >>> fbx_format = 2 # FBX ascii format + >>> fc.export_fbx_file(selected_elements, output_path, fbx_format) Returns: None @@ -215,6 +283,14 @@ def export_3dc_file(element_id_list: List[int], file_path: str) -> None: element_id_list: element_id_list file_path: file_path + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model.3dc" + >>> fc.export_3dc_file(selected_elements, output_path) + Returns: None """ @@ -237,6 +313,12 @@ def export_btl_file_for_nesting(file_path: str) -> None: Parameters: file_path: file_path + Examples: + >>> import file_controller as fc + + >>> output_path = r"C:/exports/nesting_project.btl" + >>> fc.export_btl_file_for_nesting(output_path) + Returns: None """ @@ -253,6 +335,17 @@ def export_rhino_file(element_id_list: List[int], file_path: str, version: int, use_default_assignment: use_default_assignment write_standard_attributes: write_standard_attributes + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model.3dm" + >>> version = 8 # Rhino version + >>> use_default_assignment = True + >>> write_standard_attributes = False + >>> fc.export_rhino_file(selected_elements, output_path, version, use_default_assignment, write_standard_attributes) + Returns: None """ @@ -299,6 +392,17 @@ def export_sat_file(elements: List[int], file_path: str, scale_factor: float, bi binary: binary version: version + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model.sat" + >>> scale_factor = 1.0 + >>> binary_format = True + >>> version = 25000 # SAT version + >>> fc.export_sat_file(selected_elements, output_path, scale_factor, binary_format, version) + Returns: None """ @@ -311,6 +415,14 @@ def export_glb_file(elements: List[int], file_path: str) -> None: elements: elements file_path: file_path + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model.glb" + >>> fc.export_glb_file(selected_elements, output_path) + Returns: None """ @@ -353,6 +465,18 @@ def export_rhino_file_with_options(element_id_list: List[int], file_path: str, v write_standard_attributes: write_standard_attributes rhino_options: rhino_options + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model.3dm" + >>> version = 8 # Rhino version + >>> use_default_assignment = True + >>> write_standard_attributes = False + >>> rhino_options = None # Use default options + >>> fc.export_rhino_file_with_options(selected_elements, output_path, version, use_default_assignment, write_standard_attributes, rhino_options) + Returns: None """ @@ -401,6 +525,18 @@ def export_step_file_extrude_drillings(elements: List[int], file_path: str, scal text_mode: text_mode imperial_units: imperial_units + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model_with_drillings.step" + >>> scale_factor = 1.0 + >>> version = 214 # STEP version + >>> text_mode = False + >>> imperial_units = False + >>> fc.export_step_file_extrude_drillings(selected_elements, output_path, scale_factor, version, text_mode, imperial_units) + Returns: None """ @@ -418,6 +554,18 @@ def export_step_file_cut_drillings(elements: List[int], file_path: str, scale_fa text_mode: text_mode imperial_units: imperial_units + Examples: + >>> import element_controller as ec + >>> import file_controller as fc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> output_path = r"C:/exports/model_cut_drillings.step" + >>> scale_factor = 1.0 + >>> version = 214 # STEP version + >>> text_mode = False + >>> imperial_units = False + >>> fc.export_step_file_cut_drillings(selected_elements, output_path, scale_factor, version, text_mode, imperial_units) + Returns: None """ diff --git a/src/machine_controller/__init__.pyi b/src/machine_controller/__init__.pyi index 58130de..ce864ef 100644 --- a/src/machine_controller/__init__.pyi +++ b/src/machine_controller/__init__.pyi @@ -19,6 +19,14 @@ def export_btl(btl_version: int, file_path: str) -> None: btl_version: btl_version file_path: file_path + Examples: + >>> import cadwork + >>> import machine_controller as mc + + >>> btl_version = cadwork.btl_version.btlx_2_1.value + >>> output_path = "C:/exports/timber_project.btlx" + >>> mc.export_btl(btl_version, output_path) + Returns: None """ @@ -29,6 +37,12 @@ def export_weinmann_mfb(mfb_version: int) -> None: Parameters: mfb_version: mfb_version + Examples: + >>> import machine_controller as mc + + >>> mfb_version = cadwork.weinmann_mfb_version.wup_3_4.value + >>> mc.export_weinmann_mfb(mfb_version) + Returns: None """ @@ -39,6 +53,13 @@ def export_hundegger(hundeggertype: int) -> None: Parameters: hundeggertype: hundeggertype + Examples: + >>> import cadwork + >>> import machine_controller as mc + + >>> hundegger_type = cadwork.hundegger_machine_type.k2.value + >>> mc.export_hundegger(hundegger_type) + Returns: None """ @@ -50,6 +71,14 @@ def export_hundegger_with_file_path(hundeggertype: int, file_path: str) -> None: hundeggertype: hundeggertype file_path: file_path + Examples: + >>> import cadwork + >>> import machine_controller as mc + + >>> hundegger_type = cadwork.hundegger_machine_type.k2.value + >>> output_path = "C:/exports/hundegger_project.k2" + >>> mc.export_hundegger_with_file_path(hundegger_type, output_path) + Returns: None """ @@ -62,6 +91,15 @@ def export_hundegger_with_file_path_and_presetting(hundeggertype: int, file_path file_path: file_path presetting: presetting + Examples: + >>> import cadwork + >>> import machine_controller as mc + + >>> hundegger_type = cadwork.hundegger_machine_type.k2.value + >>> output_path = r"C:/exports/hundegger_project.k2" + >>> presetting_file = r"...3d/Machine/Hundegger/K2/hundegger_settings.xml" + >>> mc.export_hundegger_with_file_path_and_presetting(hundegger_type, output_path, presetting_file) + Returns: None """ @@ -74,6 +112,15 @@ def export_btl_with_presetting(btl_version: int, file_path: str, presetting: str file_path: file_path presetting: presetting + Examples: + >>> import cadwork + >>> import machine_controller as mc + + >>> btl_version = cadwork.btl_version.btlx_2_1.value + >>> output_path = r"C:/exports/timber_project.btlx" + >>> presetting_file = r"...3d/Machine/BTL/btl_settings.xml" + >>> mc.export_btl_with_presetting(btl_version, output_path, presetting_file) + Returns: None """ @@ -85,6 +132,15 @@ def calculate_btl_machine_data(elements: List[int], btl_version: int) -> None: elements: elements btl_version: btl_version + Examples: + >>> import cadwork + >>> import element_controller as ec + >>> import machine_controller as mc + + >>> beam_elements = ec.get_all_identifiable_element_ids() + >>> btl_version = cadwork.btl_version.btlx_2_1.value + >>> mc.calculate_btl_machine_data(beam_elements, btl_version) + Returns: None """ @@ -96,6 +152,15 @@ def calculate_hundegger_machine_data(elements: List[int], hunderggertype: int) - elements: elements hunderggertype: hunderggertype + Examples: + >>> import cadwork + >>> import element_controller as ec + >>> import machine_controller as mc + + >>> beam_elements = ec.get_all_identifiable_element_ids() + >>> hundegger_type = cadwork.hundegger_machine_type.k2.value + >>> mc.calculate_hundegger_machine_data(beam_elements, hundegger_type) + Returns: None """ @@ -118,6 +183,14 @@ def export_hundegger_with_file_path_silent(hundeggertype: int, file_path: str) - hundeggertype: hundeggertype file_path: file_path + Examples: + >>> import cadwork + >>> import machine_controller as mc + + >>> hundegger_type = cadwork.hundegger_machine_type.k2.value + >>> output_path = r"C:/exports/hundegger_project.k2" + >>> mc.export_hundegger_with_file_path_silent(hundegger_type, output_path) + Returns: None """ @@ -130,6 +203,15 @@ def export_hundegger_with_file_path_and_presetting_silent(hundeggertype: int, fi file_path: file_path presetting: presetting + Examples: + >>> import cadwork + >>> import machine_controller as mc + + >>> hundegger_type = cadwork.hundegger_machine_type.k2.value + >>> output_path = r"C:/exports/hundegger_project.k2" + >>> presetting_file = r"...3d/Machine/Hundegger/K2/hundegger_settings.xml" + >>> mc.export_hundegger_with_file_path_and_presetting_silent(hundegger_type, output_path, presetting_file) + Returns: None """ @@ -142,6 +224,16 @@ def get_element_hundegger_processings(element_id: int, hundeggertype: int) -> Li element_id: The element ID. hundeggertype: The Hundegger type. + Examples: + >>> import cadwork + >>> import element_controller as ec + >>> import machine_controller as mc + + >>> element: int = 123456789 + >>> hundegger_type = cadwork.hundegger_machine_type.k2.value + >>> processings = mc.get_element_hundegger_processings(element, hundegger_type) + >>> print(f"Found {len(processings)} Hundegger processings") + Returns: List of processing IDs. """ @@ -154,6 +246,16 @@ def get_element_btl_processings(element_id: int, btl_version: int) -> List[int]: element_id: The element ID. btl_version: The BTL version. + Examples: + >>> import cadwork + >>> import element_controller as ec + >>> import machine_controller as mc + + >>> element: int = 123456789 + >>> btl_version = cadwork.btl_version.btlx_2_1.value + >>> processings = mc.get_element_btl_processings(element, btl_version) + >>> print(f"Found {len(processings)} BTL processings") + Returns: List of processing IDs. """ From ccbb9fd32935381f9a725e1b53be45839d0a0fac Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Tue, 8 Jul 2025 13:00:19 +0200 Subject: [PATCH 19/52] Add examples to function docstrings Signed-off-by: Michael Brunner --- src/bim_controller/__init__.pyi | 92 +++++++++++++++++++++-- src/visualization_controller/__init__.pyi | 3 +- 2 files changed, 86 insertions(+), 9 deletions(-) diff --git a/src/bim_controller/__init__.pyi b/src/bim_controller/__init__.pyi index 85e490b..62cdd70 100644 --- a/src/bim_controller/__init__.pyi +++ b/src/bim_controller/__init__.pyi @@ -20,15 +20,17 @@ def get_ifc_guid(element_id: int) -> str: Parameters: element_id: element_id - Returns: - str - """ + Examples: + >>> import element_controller as ec + >>> import bim_controller as bc -def clear_errors() -> None: - """clear errors + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> ifc_guid = bc.get_ifc_guid(element) + >>> print(f"IFC GUID: {ifc_guid}") Returns: - None + str """ def get_ifc2x3_element_type(element_id: int) -> ifc_2x3_element_type: @@ -37,6 +39,15 @@ def get_ifc2x3_element_type(element_id: int) -> ifc_2x3_element_type: Parameters: element_id: element_id + Examples: + >>> import element_controller as ec + >>> import bim_controller as bc + >>> import cadwork # needed for ifc_2x3_element_type + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> ifc_type = bc.get_ifc2x3_element_type(element) + Returns: ifc_2x3_element_type """ @@ -50,9 +61,14 @@ def set_ifc2x3_element_type(element_i_ds: List[int], ifc_type: ifc_2x3_element_t ifc_type: element_type Examples: + >>> import element_controller as ec + >>> import bim_controller as bc + >>> import cadwork + + >>> selected_elements = ec.get_all_identifiable_element_ids() >>> ifc_entity_type = cadwork.ifc_2x3_element_type() >>> ifc_entity_type.set_ifc_member() - >>> bimc.set_ifc2x3_element_type([element], ifc_entity_type) + >>> bc.set_ifc2x3_element_type(selected_elements, ifc_entity_type) Returns: None @@ -64,6 +80,14 @@ def import_ifc_as_graphical_object(file_path: str) -> bool: Parameters: file_path: file_path + Examples: + >>> import bim_controller as bc + + >>> ifc_file_path = r"C:/imports/building_model.ifc" + >>> success = bc.import_ifc_as_graphical_object(ifc_file_path) + >>> if success: + >>> print("IFC imported as graphical object successfully") + Returns: bool """ @@ -74,6 +98,14 @@ def import_bcf(file_path: str) -> bool: Parameters: file_path: file_path + Examples: + >>> import bim_controller as bc + + >>> bcf_file_path = r"C:/imports/issues.bcf" + >>> success = bc.import_bcf(bcf_file_path) + >>> if success: + >>> print("BCF file imported successfully") + Returns: bool """ @@ -84,6 +116,14 @@ def export_bcf(file_path: str) -> bool: Parameters: file_path: file_path + Examples: + >>> import bim_controller as bc + + >>> bcf_output_path = r"C:/exports/project_issues.bcf" + >>> success = bc.export_bcf(bcf_output_path) + >>> if success: + >>> print("BCF file exported successfully") + Returns: bool """ @@ -95,6 +135,16 @@ def export_ifc(element_i_ds: List[int], file_path: str) -> bool: element_i_ds: element_i_ds file_path: file_path + Examples: + >>> import element_controller as ec + >>> import bim_controller as bc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> ifc_output_path = r"C:/exports/building_model.ifc" + >>> success = bc.export_ifc(selected_elements, ifc_output_path) + >>> if success: + >>> print("IFC file exported successfully") + Returns: bool """ @@ -117,6 +167,14 @@ def set_storey_height(building: str, storey: str, height: float) -> None: storey: storey height: height + Examples: + >>> import bim_controller as bc + + >>> building_name = "Building A" + >>> storey_name = "Ground Floor" + >>> height_millimeters = 3_500 + >>> bc.set_storey_height(building_name, storey_name, height_millimeters) + Returns: None """ @@ -212,6 +270,15 @@ def set_building_and_storey(element_id_list: List[int], building: str, storey: s building: building storey: storey + Examples: + >>> import element_controller as ec + >>> import bim_controller as bc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> building_name = "Building A" + >>> storey_name = "Ground Floor" + >>> bc.set_building_and_storey(selected_elements, building_name, storey_name) + Returns: None """ @@ -325,7 +392,16 @@ def set_ifc_predefined_type(element_i_ds: List[int], predefined_type: ifc_predef element_i_ds: element_i_ds predefined_type: predefined_type + Examples: + >>> import element_controller as ec + >>> import bim_controller as bc + >>> import cadwork + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> predefined_type = cadwork.ifc_predefined_type() + >>> predefined_type.set_member() + >>> bc.set_ifc_predefined_type(selected_elements, predefined_type) + Returns: None """ - diff --git a/src/visualization_controller/__init__.pyi b/src/visualization_controller/__init__.pyi index 8dc457c..1fc703c 100644 --- a/src/visualization_controller/__init__.pyi +++ b/src/visualization_controller/__init__.pyi @@ -481,7 +481,8 @@ def get_camera_data() -> camera_data: camera data """ -def set_camera_data(camera_data: None) -> None: + +def set_camera_data(camera_data: camera_data) -> None: """Set the camera data - this will override the current camera data Parameters: From 1963592a75fdd3757a732c7beb95e584dc2ecc7f Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Tue, 8 Jul 2025 16:40:06 +0200 Subject: [PATCH 20/52] Add examples to function docstrings in endtype and element controllers Signed-off-by: Michael Brunner --- src/endtype_controller/__init__.pyi | 192 +++++++++++++++++++++++++++- 1 file changed, 185 insertions(+), 7 deletions(-) diff --git a/src/endtype_controller/__init__.pyi b/src/endtype_controller/__init__.pyi index 109e05a..4729b48 100644 --- a/src/endtype_controller/__init__.pyi +++ b/src/endtype_controller/__init__.pyi @@ -16,6 +16,13 @@ def get_endtype_id(name: str) -> int: Parameters: name: name + Examples: + >>> import endtype_controller as etc + + >>> endtype_name = "Tenon_100x50" + >>> endtype_id = etc.get_endtype_id(endtype_name) + >>> print(f"Endtype ID: {endtype_id}") + Returns: int """ @@ -26,6 +33,15 @@ def get_endtype_id_start(element_id: int) -> int: Parameters: element_id: element_id + Examples: + >>> import element_controller as ec + >>> import endtype_controller as etc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> start_endtype_id = etc.get_endtype_id_start(element) + >>> print(f"Start endtype ID: {start_endtype_id}") + Returns: int """ @@ -36,6 +52,15 @@ def get_endtype_id_end(element_id: int) -> int: Parameters: element_id: element_id + Examples: + >>> import element_controller as ec + >>> import endtype_controller as etc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> end_endtype_id = etc.get_endtype_id_end(element) + >>> print(f"End endtype ID: {end_endtype_id}") + Returns: int """ @@ -48,6 +73,20 @@ def get_endtype_id_facet(element_id: int, face_number: int) -> int: element_id: element_id face_number: face_number + Note: + Endtypes can only be set on faces that are placed at start or end points. + Endtypes cannot be placed on arbitrary faces. + + Examples: + >>> import element_controller as ec + >>> import endtype_controller as etc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> face_number = 1 + >>> facet_endtype_id = etc.get_endtype_id_facet(element, face_number) + >>> print(f"Facet endtype ID: {facet_endtype_id}") + Returns: int """ @@ -59,6 +98,15 @@ def set_endtype_name_start(element_id: int, name: str) -> None: element_id: element_id name: name + Examples: + >>> import element_controller as ec + >>> import endtype_controller as etc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> endtype_name = "Tenon_100x50" + >>> etc.set_endtype_name_start(element, endtype_name) + Returns: None """ @@ -70,6 +118,15 @@ def set_endtype_name_end(element_id: int, name: str) -> None: element_id: element_id name: name + Examples: + >>> import element_controller as ec + >>> import endtype_controller as etc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> endtype_name = "Mortise_100x50" + >>> etc.set_endtype_name_end(element, endtype_name) + Returns: None """ @@ -83,6 +140,20 @@ def set_endtype_name_facet(element_id: int, name: str, face_number: int) -> None name: name face_number: face_number + Note: + Endtypes can only be set on faces that are placed at start or end points. + Endtypes cannot be placed on arbitrary faces. + + Examples: + >>> import element_controller as ec + >>> import endtype_controller as etc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> endtype_name = "Dovetail_60x30" + >>> face_number = 2 + >>> etc.set_endtype_name_facet(element, endtype_name, face_number) + Returns: None """ @@ -94,6 +165,15 @@ def set_endtype_id_start(element_id: int, endtype_id: int) -> None: element_id: element_id endtype_id: endtype_id + Examples: + >>> import element_controller as ec + >>> import endtype_controller as etc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> endtype_id = 12345 + >>> etc.set_endtype_id_start(element, endtype_id) + Returns: None """ @@ -105,6 +185,15 @@ def set_endtype_id_end(element_id: int, endtype_id: int) -> None: element_id: element_id endtype_id: endtype_id + Examples: + >>> import element_controller as ec + >>> import endtype_controller as etc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> endtype_id = 54321 + >>> etc.set_endtype_id_end(element, endtype_id) + Returns: None """ @@ -118,12 +207,19 @@ def set_endtype_id_facet(element_id: int, endtype_id: int, face_number: int) -> endtype_id: endtype_id face_number: face_number - Returns: - None - """ + Note: + Endtypes can only be set on faces that are placed at start or end points. + Endtypes cannot be placed on arbitrary faces. + + Examples: + >>> import element_controller as ec + >>> import endtype_controller as etc -def clear_errors() -> None: - """clear errors + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> endtype_id = 67890 + >>> face_number = 3 + >>> etc.set_endtype_id_facet(element, endtype_id, face_number) Returns: None @@ -137,6 +233,15 @@ def create_new_endtype(endtype_name: str, endtype_id: int, folder_name: str) -> endtype_id: endtype_id folder_name: folder_name + Examples: + >>> import endtype_controller as etc + + >>> endtype_name = "Custom_Joint_80x40" + >>> endtype_id = 99999 + >>> folder_name = "Custom_Joints" + >>> new_id = etc.create_new_endtype(endtype_name, endtype_id, folder_name) + >>> print(f"Created endtype with ID: {new_id}") + Returns: int """ @@ -147,6 +252,13 @@ def get_endtype_name(element_id: int) -> str: Parameters: element_id: element_id + Examples: + >>> import endtype_controller as etc + + >>> endtype_id = 12345 + >>> endtype_name = etc.get_endtype_name(endtype_id) + >>> print(f"Endtype name: {endtype_name}") + Returns: str """ @@ -157,6 +269,15 @@ def get_endtype_name_start(element_id: int) -> str: Parameters: element_id: element_id + Examples: + >>> import element_controller as ec + >>> import endtype_controller as etc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> start_name = etc.get_endtype_name_start(element) + >>> print(f"Start endtype name: {start_name}") + Returns: str """ @@ -167,11 +288,19 @@ def get_endtype_name_end(element_id: int) -> str: Parameters: element_id: element_id + Examples: + >>> import element_controller as ec + >>> import endtype_controller as etc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> end_name = etc.get_endtype_name_end(element) + >>> print(f"End endtype name: {end_name}") + Returns: str """ - def get_endtype_name_facet(element_id: int, face_number: int) -> str: """get endtype name facet @@ -179,6 +308,20 @@ def get_endtype_name_facet(element_id: int, face_number: int) -> str: element_id: element_id face_number: face_number + Note: + Endtypes can only be set on faces that are placed at start or end points. + Endtypes cannot be placed on arbitrary faces. + + Examples: + >>> import element_controller as ec + >>> import endtype_controller as etc + + >>> selected_elements = ec.get_all_identifiable_element_ids() + >>> element = selected_elements[0] + >>> face_number = 2 + >>> facet_name = etc.get_endtype_name_facet(element, face_number) + >>> print(f"Facet endtype name: {facet_name}") + Returns: str """ @@ -186,6 +329,12 @@ def get_endtype_name_facet(element_id: int, face_number: int) -> str: def get_existing_tenon_ids() -> List[int]: """Get the existing tenon endtypeIDs + Examples: + >>> import endtype_controller as etc + + >>> tenon_ids = etc.get_existing_tenon_ids() + >>> print(f"Available tenon endtype IDs: {tenon_ids}") + Returns: list of existing tenon endtypeIDs """ @@ -193,6 +342,12 @@ def get_existing_tenon_ids() -> List[int]: def get_existing_lengthening_ids() -> List[int]: """Get the existing lengthening endtypeIDs + Examples: + >>> import endtype_controller as etc + + >>> lengthening_ids = etc.get_existing_lengthening_ids() + >>> print(f"Available lengthening endtype IDs: {lengthening_ids}") + Returns: list of existing lengthening endtypeIDs """ @@ -200,6 +355,12 @@ def get_existing_lengthening_ids() -> List[int]: def get_existing_dovetail_ids() -> List[int]: """Get the existing dovetail endtypeIDs + Examples: + >>> import endtype_controller as etc + + >>> dovetail_ids = etc.get_existing_dovetail_ids() + >>> print(f"Available dovetail endtype IDs: {dovetail_ids}") + Returns: list of existing dovetail endtypeIDs """ @@ -207,6 +368,12 @@ def get_existing_dovetail_ids() -> List[int]: def get_existing_dovetail_dado_ids() -> List[int]: """Get the existing dado endtypeIDs + Examples: + >>> import endtype_controller as etc + + >>> dado_ids = etc.get_existing_dovetail_dado_ids() + >>> print(f"Available dado endtype IDs: {dado_ids}") + Returns: list of existing dado endtypeIDs """ @@ -214,6 +381,12 @@ def get_existing_dovetail_dado_ids() -> List[int]: def get_existing_japanese_tenon_ids() -> List[int]: """Get the existing japanese-tenon endtypeIDs + Examples: + >>> import endtype_controller as etc + + >>> japanese_tenon_ids = etc.get_existing_japanese_tenon_ids() + >>> print(f"Available japanese-tenon endtype IDs: {japanese_tenon_ids}") + Returns: list of existing japanese-tenon endtypeIDs """ @@ -221,7 +394,12 @@ def get_existing_japanese_tenon_ids() -> List[int]: def start_endtype_dialog() -> int: """Start endtype dialog + Examples: + >>> import endtype_controller as etc + + >>> selected_endtype_id = etc.start_endtype_dialog() + >>> print(f"User selected endtype ID: {selected_endtype_id}") + Returns: Selected endtypeID """ - From 66b39c68356891e59c9e7812f994200a7d1ad4d4 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Tue, 8 Jul 2025 16:40:39 +0200 Subject: [PATCH 21/52] Update version to 32.296.0 Signed-off-by: Michael Brunner --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 18b7a41..044efd5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.274.0" +version = "32.296.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' From f084b39dc8b3df357d1a883242610b0aa7d9df90 Mon Sep 17 00:00:00 2001 From: BobillierCaddev Date: Wed, 3 Sep 2025 15:45:20 +0200 Subject: [PATCH 22/52] Feature/[API-519] harmonized python stubs with c interfaces (#272) * [API-519] Updated documentation version * [API-519] Updated python version in conf files * [API-519] Updated mkdocs.yml to add some sections, change doc style and automatically create hyperlink for known types * [API-519] Updated custom js script to delete the last column in the automatically generated doc tab * [API-519] Removed the "src." in the module path in the doc section config to fix the cross module links * [API-519] Added a section about custom types * [API-519] Added a missing class in the doc (attribute_display_settings) * [API-519] Improved the attribute controller documentation * [API-519] Added ifc_predefined_type class in the doc * [API-519] Improved the bim controller documentation * [API-519] Added vba_catalog_item_type class in the doc * [API-519] Improved the connector axis controller documentation * [API-519] Improved the dimension controller documentation * [API-519] Improved the element controller documentation * [API-519] Improved the endtype controller documentation * [API-519] Improved the file controller documentation * [API-519] Improved the utility controller documentation * [API-519] Removed get_last_error method * [API-519] Improved the geometry controller documentation * [API-519] Improved the list controller documentation * [API-519] Improved the machine controller documentation * [API-519] Improved the material controller documentation * [API-519] Improved the menu controller documentation * [API-519] Improved the layer cover controller documentation * [API-519] Improved the roof controller documentation * [API-519] Improved the scene controller documentation * [API-519] Improved the shop drawing controller documentation * [API-519] Improved the visualization controller documentation * [API-519] Corrected some method signature to match the C++ ones * Corrected python version to 3.12 --- .github/workflows/publish.yml | 2 +- .github/workflows/test_publish.yml | 4 +- Dockerfile | 2 +- docs/documentation/api_types.md | 6 + docs/documentation/attribute_controller.md | 2 +- .../attribute_display_settings.md | 6 + docs/documentation/bim_controller.md | 2 +- docs/documentation/bim_team_upload_result.md | 8 +- docs/documentation/brep_data.md | 8 +- docs/documentation/camera_data.md | 4 +- .../connector_axis_controller.md | 2 +- docs/documentation/coordinate_system_data.md | 6 + docs/documentation/dimension_controller.md | 2 +- docs/documentation/element_controller.md | 2 +- docs/documentation/element_filter.md | 2 +- docs/documentation/element_map_query.md | 2 +- .../element_module_properties.md | 2 +- docs/documentation/element_type.md | 2 +- docs/documentation/endtype_controller.md | 2 +- docs/documentation/enums.md | 55 +- docs/documentation/extended_settings.md | 2 +- docs/documentation/file_controller.md | 2 +- docs/documentation/geometry_controller.md | 2 +- docs/documentation/hit_result.md | 8 +- docs/documentation/ifc_2x3_element_type.md | 2 +- docs/documentation/ifc_options.md | 10 +- docs/documentation/ifc_predefined_type.md | 6 + docs/documentation/import_3dc_options.md | 6 + docs/documentation/layer_settings.md | 2 +- docs/documentation/list_controller.md | 2 +- docs/documentation/machine_controller.md | 2 +- docs/documentation/material_controller.md | 2 +- docs/documentation/menu_controller.md | 2 +- .../multi_layer_cover_controller.md | 2 +- docs/documentation/point_3d.md | 2 +- docs/documentation/process_type.md | 2 +- docs/documentation/rhino_export_options.md | 2 +- docs/documentation/roof_controller.md | 2 +- docs/documentation/scene_controller.md | 2 +- docs/documentation/shop_drawing_controller.md | 2 +- docs/documentation/shoulder_options.md | 11 +- docs/documentation/standard_element_type.md | 6 + docs/documentation/text_object_options.md | 4 +- docs/documentation/utility_controller.md | 2 +- .../documentation/visualization_controller.md | 2 +- docs/documentation/window_geometry.md | 2 +- docs/js/tablesort.js | 9 +- mkdocs.yml | 18 +- pyproject.toml | 2 +- src/attribute_controller/__init__.pyi | 1451 +++++------ src/bim_controller/__init__.pyi | 248 +- src/cadwork/api_types.pyi | 22 + src/cadwork/attribute_display_settings.pyi | 1 + src/cadwork/vba_catalog_item_type.pyi | 50 + src/connector_axis_controller/__init__.pyi | 468 ++-- src/dimension_controller/__init__.pyi | 224 +- src/element_controller/__init__.pyi | 2112 ++++++++--------- src/endtype_controller/__init__.pyi | 195 +- src/file_controller/__init__.pyi | 454 ++-- src/geometry_controller/__init__.pyi | 968 +++----- src/list_controller/__init__.pyi | 177 +- src/machine_controller/__init__.pyi | 197 +- src/material_controller/__init__.pyi | 763 +++--- src/menu_controller/__init__.pyi | 6 +- src/multi_layer_cover_controller/__init__.pyi | 314 +-- src/roof_controller/__init__.pyi | 72 +- src/scene_controller/__init__.pyi | 153 +- src/shop_drawing_controller/__init__.pyi | 183 +- src/utility_controller/__init__.pyi | 763 +++--- src/visualization_controller/__init__.pyi | 454 ++-- 70 files changed, 4077 insertions(+), 5437 deletions(-) create mode 100644 docs/documentation/api_types.md create mode 100644 docs/documentation/attribute_display_settings.md create mode 100644 docs/documentation/coordinate_system_data.md create mode 100644 docs/documentation/ifc_predefined_type.md create mode 100644 docs/documentation/import_3dc_options.md create mode 100644 docs/documentation/standard_element_type.md create mode 100644 src/cadwork/api_types.pyi create mode 100644 src/cadwork/vba_catalog_item_type.pyi diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8906cb8..61d26e9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.12' - run: pip install build - run: python -m build - uses: pypa/gh-action-pypi-publish@release/v1 \ No newline at end of file diff --git a/.github/workflows/test_publish.yml b/.github/workflows/test_publish.yml index e92c40f..fb83b2d 100644 --- a/.github/workflows/test_publish.yml +++ b/.github/workflows/test_publish.yml @@ -18,10 +18,10 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.12' - run: pip install build - run: python -m build - uses: pypa/gh-action-pypi-publish@release/v1 with: repository-url: https://test.pypi.org/legacy/ - skip-existing: true \ No newline at end of file + skip-existing: true diff --git a/Dockerfile b/Dockerfile index fd991d7..8c973a7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.10 +FROM python:3.12 WORKDIR /app diff --git a/docs/documentation/api_types.md b/docs/documentation/api_types.md new file mode 100644 index 0000000..081a321 --- /dev/null +++ b/docs/documentation/api_types.md @@ -0,0 +1,6 @@ +# Api Types + +::: cadwork.api_types + rendering: + show_root_heading: false + show_source: true diff --git a/docs/documentation/attribute_controller.md b/docs/documentation/attribute_controller.md index 850334b..7d372e0 100644 --- a/docs/documentation/attribute_controller.md +++ b/docs/documentation/attribute_controller.md @@ -1,6 +1,6 @@ # Attribute Controller -::: src.attribute_controller +::: attribute_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/attribute_display_settings.md b/docs/documentation/attribute_display_settings.md new file mode 100644 index 0000000..55188ce --- /dev/null +++ b/docs/documentation/attribute_display_settings.md @@ -0,0 +1,6 @@ +# attribute_display_settings + +::: cadwork.attribute_display_settings + rendering: + show_root_heading: false + show_source: true diff --git a/docs/documentation/bim_controller.md b/docs/documentation/bim_controller.md index 5fb70c9..2ba4033 100644 --- a/docs/documentation/bim_controller.md +++ b/docs/documentation/bim_controller.md @@ -1,6 +1,6 @@ # BIM Controller -::: src.bim_controller +::: bim_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/bim_team_upload_result.md b/docs/documentation/bim_team_upload_result.md index 9480cff..dec1542 100644 --- a/docs/documentation/bim_team_upload_result.md +++ b/docs/documentation/bim_team_upload_result.md @@ -1,6 +1,12 @@ # BIMteam upload -::: src.cadwork.bim_team_upload_result +::: cadwork.bim_team_upload_result + rendering: + show_root_heading: false + show_source: true + + +::: cadwork.bim_team_upload_result_code rendering: show_root_heading: false show_source: true \ No newline at end of file diff --git a/docs/documentation/brep_data.md b/docs/documentation/brep_data.md index 56f91a2..6d27061 100644 --- a/docs/documentation/brep_data.md +++ b/docs/documentation/brep_data.md @@ -1,21 +1,21 @@ # BREP -::: src.cadwork.facet_list +::: cadwork.facet_list rendering: show_root_heading: false show_source: true -::: src.cadwork.edge_list +::: cadwork.edge_list rendering: show_root_heading: false show_source: true -::: src.cadwork.polygon_list +::: cadwork.polygon_list rendering: show_root_heading: false show_source: true -::: src.cadwork.vertex_list +::: cadwork.vertex_list rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/camera_data.md b/docs/documentation/camera_data.md index 48c5643..08e7de2 100644 --- a/docs/documentation/camera_data.md +++ b/docs/documentation/camera_data.md @@ -1,11 +1,11 @@ # Camera Data -::: src.cadwork.camera_data +::: cadwork.camera_data rendering: show_root_heading: false show_source: true -::: src.cadwork.projection_type +::: cadwork.projection_type rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/connector_axis_controller.md b/docs/documentation/connector_axis_controller.md index 46c236a..139d862 100644 --- a/docs/documentation/connector_axis_controller.md +++ b/docs/documentation/connector_axis_controller.md @@ -1,6 +1,6 @@ # Connector Axis Controller -::: src.connector_axis_controller +::: connector_axis_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/coordinate_system_data.md b/docs/documentation/coordinate_system_data.md new file mode 100644 index 0000000..f499bb6 --- /dev/null +++ b/docs/documentation/coordinate_system_data.md @@ -0,0 +1,6 @@ +# coordinate_system_data + +::: cadwork.coordinate_system_data + rendering: + show_root_heading: false + show_source: true diff --git a/docs/documentation/dimension_controller.md b/docs/documentation/dimension_controller.md index a1a2d23..906f076 100644 --- a/docs/documentation/dimension_controller.md +++ b/docs/documentation/dimension_controller.md @@ -1,6 +1,6 @@ # Dimension Controller -::: src.dimension_controller +::: dimension_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/element_controller.md b/docs/documentation/element_controller.md index 7abf8a3..12a4049 100644 --- a/docs/documentation/element_controller.md +++ b/docs/documentation/element_controller.md @@ -1,6 +1,6 @@ # Element Controller -::: src.element_controller +::: element_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/element_filter.md b/docs/documentation/element_filter.md index 6560517..b6b54ae 100644 --- a/docs/documentation/element_filter.md +++ b/docs/documentation/element_filter.md @@ -1,6 +1,6 @@ # element_filter -::: src.cadwork.element_filter +::: cadwork.element_filter rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/element_map_query.md b/docs/documentation/element_map_query.md index 48e1c63..c378158 100644 --- a/docs/documentation/element_map_query.md +++ b/docs/documentation/element_map_query.md @@ -1,6 +1,6 @@ # element_map_query -::: src.cadwork.element_map_query +::: cadwork.element_map_query rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/element_module_properties.md b/docs/documentation/element_module_properties.md index d5f6ef4..0d98804 100644 --- a/docs/documentation/element_module_properties.md +++ b/docs/documentation/element_module_properties.md @@ -1,6 +1,6 @@ # element_module_properties -::: src.cadwork.element_module_properties +::: cadwork.element_module_properties rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/element_type.md b/docs/documentation/element_type.md index c6a897c..86c07b2 100644 --- a/docs/documentation/element_type.md +++ b/docs/documentation/element_type.md @@ -1,6 +1,6 @@ # element_type -::: src.cadwork.element_type +::: cadwork.element_type rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/endtype_controller.md b/docs/documentation/endtype_controller.md index 6552168..efc2c01 100644 --- a/docs/documentation/endtype_controller.md +++ b/docs/documentation/endtype_controller.md @@ -1,6 +1,6 @@ # End-Type Controller -::: src.endtype_controller +::: endtype_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/enums.md b/docs/documentation/enums.md index 6c3f0e3..614bb71 100644 --- a/docs/documentation/enums.md +++ b/docs/documentation/enums.md @@ -2,95 +2,102 @@ ## Node symbols -::: src.cadwork.node_symbol +::: cadwork.node_symbol rendering: show_root_heading: false show_source: true ## Element module -::: src.cadwork.element_module_detail +::: cadwork.element_module_detail rendering: show_root_heading: false show_source: true -::: src.cadwork.division_zone_direction +::: cadwork.division_zone_direction rendering: show_root_heading: false show_source: true -::: src.cadwork.element_grouping_type +::: cadwork.element_grouping_type rendering: show_root_heading: false show_source: true ## F-Keys -::: src.cadwork.shortcut_key +::: cadwork.shortcut_key rendering: show_root_heading: false show_source: true -::: src.cadwork.shortcut_key_modifier +::: cadwork.shortcut_key_modifier rendering: show_root_heading: false show_source: true ## Machines -::: src.cadwork.btl_version +::: cadwork.btl_version rendering: show_root_heading: false show_source: true -::: src.cadwork.hundegger_machine_type +::: cadwork.hundegger_machine_type rendering: show_root_heading: false show_source: true -::: src.cadwork.weinmann_mfb_version +::: cadwork.weinmann_mfb_version rendering: show_root_heading: false show_source: true ## IFC Aggregation Behaviour -::: src.cadwork.ifc_element_combine_behaviour +::: cadwork.ifc_element_combine_behaviour rendering: show_root_heading: false show_source: true ## Multi Layer Cover Type -::: src.cadwork.multi_layer_type +::: cadwork.multi_layer_type rendering: show_root_heading: false show_source: true ## BIMteam upload -::: src.cadwork.bim_team_upload_result_code +::: cadwork.bim_team_upload_result_code rendering: show_root_heading: false show_source: true ### Dimenson base format -::: src.cadwork.dimension_base_format -rendering: -show_root_heading: false -show_source: true +::: cadwork.dimension_base_format + rendering: + show_root_heading: false + show_source: true ### DXF export version -::: src.cadwork.dxf_export_version -rendering: -show_root_heading: false -show_source: true +::: cadwork.dxf_export_version + rendering: + show_root_heading: false + show_source: true ### DXF layer format type -::: src.cadwork.dxf_layer_format_type -rendering: -show_root_heading: false -show_source: true +::: cadwork.dxf_layer_format_type + rendering: + show_root_heading: false + show_source: true + +## Vba catalog + +::: cadwork.vba_catalog_item_type + rendering: + show_root_heading: false + show_source: true diff --git a/docs/documentation/extended_settings.md b/docs/documentation/extended_settings.md index aac68de..ee3acda 100644 --- a/docs/documentation/extended_settings.md +++ b/docs/documentation/extended_settings.md @@ -1,6 +1,6 @@ # extended_settings -::: src.cadwork.extended_settings +::: cadwork.extended_settings rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/file_controller.md b/docs/documentation/file_controller.md index 2e77d4c..148a6da 100644 --- a/docs/documentation/file_controller.md +++ b/docs/documentation/file_controller.md @@ -1,6 +1,6 @@ # File Controller -::: src.file_controller +::: file_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/geometry_controller.md b/docs/documentation/geometry_controller.md index 1572b8e..5ead026 100644 --- a/docs/documentation/geometry_controller.md +++ b/docs/documentation/geometry_controller.md @@ -1,6 +1,6 @@ # Geometry Controller -::: src.geometry_controller +::: geometry_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/hit_result.md b/docs/documentation/hit_result.md index 6fae9fb..18e66b2 100644 --- a/docs/documentation/hit_result.md +++ b/docs/documentation/hit_result.md @@ -1,6 +1,6 @@ # hit_result -::: src.cadwork.hit_result -rendering: -show_root_heading: false -show_source: true +::: cadwork.hit_result + rendering: + show_root_heading: false + show_source: true diff --git a/docs/documentation/ifc_2x3_element_type.md b/docs/documentation/ifc_2x3_element_type.md index 52c866d..05191f6 100644 --- a/docs/documentation/ifc_2x3_element_type.md +++ b/docs/documentation/ifc_2x3_element_type.md @@ -1,6 +1,6 @@ # ifc_2x3_element_type -::: src.cadwork.ifc_2x3_element_type +::: cadwork.ifc_2x3_element_type rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/ifc_options.md b/docs/documentation/ifc_options.md index 4bb3a3d..49fb18d 100644 --- a/docs/documentation/ifc_options.md +++ b/docs/documentation/ifc_options.md @@ -1,26 +1,26 @@ # IFC Options -::: src.cadwork.ifc_options +::: cadwork.ifc_options rendering: show_root_heading: false show_source: true -::: src.cadwork.ifc_options_aggregation +::: cadwork.ifc_options_aggregation rendering: show_root_heading: false show_source: true -::: src.cadwork.ifc_options_level_of_detail +::: cadwork.ifc_options_level_of_detail rendering: show_root_heading: false show_source: true -::: src.cadwork.ifc_options_project_data +::: cadwork.ifc_options_project_data rendering: show_root_heading: false show_source: true -::: src.cadwork.ifc_options_properties +::: cadwork.ifc_options_properties rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/ifc_predefined_type.md b/docs/documentation/ifc_predefined_type.md new file mode 100644 index 0000000..e0c0775 --- /dev/null +++ b/docs/documentation/ifc_predefined_type.md @@ -0,0 +1,6 @@ +# ifc_predefined_type + +::: cadwork.ifc_predefined_type + rendering: + show_root_heading: false + show_source: true diff --git a/docs/documentation/import_3dc_options.md b/docs/documentation/import_3dc_options.md new file mode 100644 index 0000000..9fa2731 --- /dev/null +++ b/docs/documentation/import_3dc_options.md @@ -0,0 +1,6 @@ +# import_3dc_options + +::: cadwork.import_3dc_options + rendering: + show_root_heading: false + show_source: true \ No newline at end of file diff --git a/docs/documentation/layer_settings.md b/docs/documentation/layer_settings.md index d56c0e7..06b8d59 100644 --- a/docs/documentation/layer_settings.md +++ b/docs/documentation/layer_settings.md @@ -1,6 +1,6 @@ # Layer Settings -::: src.cadwork.layer_settings +::: cadwork.layer_settings rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/list_controller.md b/docs/documentation/list_controller.md index 1d8fa3e..7564e75 100644 --- a/docs/documentation/list_controller.md +++ b/docs/documentation/list_controller.md @@ -1,6 +1,6 @@ # List Controller -::: src.list_controller +::: list_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/machine_controller.md b/docs/documentation/machine_controller.md index f5b5415..9a40c80 100644 --- a/docs/documentation/machine_controller.md +++ b/docs/documentation/machine_controller.md @@ -1,6 +1,6 @@ # Machine Controller -::: src.machine_controller +::: machine_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/material_controller.md b/docs/documentation/material_controller.md index f76ecde..218d0b4 100644 --- a/docs/documentation/material_controller.md +++ b/docs/documentation/material_controller.md @@ -1,6 +1,6 @@ # Material Controller -::: src.material_controller +::: material_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/menu_controller.md b/docs/documentation/menu_controller.md index 8d5e890..38b129e 100644 --- a/docs/documentation/menu_controller.md +++ b/docs/documentation/menu_controller.md @@ -1,6 +1,6 @@ # Menu Controller -::: src.menu_controller +::: menu_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/multi_layer_cover_controller.md b/docs/documentation/multi_layer_cover_controller.md index dc78ddf..6f73ee9 100644 --- a/docs/documentation/multi_layer_cover_controller.md +++ b/docs/documentation/multi_layer_cover_controller.md @@ -1,6 +1,6 @@ # Multi Layer Cover Controller -::: src.multi_layer_cover_controller +::: multi_layer_cover_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/point_3d.md b/docs/documentation/point_3d.md index 0e7dd15..95af39f 100644 --- a/docs/documentation/point_3d.md +++ b/docs/documentation/point_3d.md @@ -1,6 +1,6 @@ # point_3d -::: src.cadwork.point_3d +::: cadwork.point_3d rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/process_type.md b/docs/documentation/process_type.md index ea04168..095a950 100644 --- a/docs/documentation/process_type.md +++ b/docs/documentation/process_type.md @@ -1,6 +1,6 @@ # process_type -::: src.cadwork.process_type +::: cadwork.process_type rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/rhino_export_options.md b/docs/documentation/rhino_export_options.md index a68a8e9..62d4b81 100644 --- a/docs/documentation/rhino_export_options.md +++ b/docs/documentation/rhino_export_options.md @@ -1,6 +1,6 @@ # rhino_options -::: src.cadwork.rhino_options +::: cadwork.rhino_options rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/roof_controller.md b/docs/documentation/roof_controller.md index 094f6cf..66efda1 100644 --- a/docs/documentation/roof_controller.md +++ b/docs/documentation/roof_controller.md @@ -1,6 +1,6 @@ # Roof Controller -::: src.roof_controller +::: roof_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/scene_controller.md b/docs/documentation/scene_controller.md index 60fb920..1719974 100644 --- a/docs/documentation/scene_controller.md +++ b/docs/documentation/scene_controller.md @@ -1,6 +1,6 @@ # Scene Controller -::: src.scene_controller +::: scene_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/shop_drawing_controller.md b/docs/documentation/shop_drawing_controller.md index 6eaddc8..45be541 100644 --- a/docs/documentation/shop_drawing_controller.md +++ b/docs/documentation/shop_drawing_controller.md @@ -1,6 +1,6 @@ # Shop Drawing Controller -::: src.shop_drawing_controller +::: shop_drawing_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/shoulder_options.md b/docs/documentation/shoulder_options.md index b0ca2c8..fe04389 100644 --- a/docs/documentation/shoulder_options.md +++ b/docs/documentation/shoulder_options.md @@ -1,16 +1,21 @@ # Shoulder options -::: src.cadwork.double_shoulder_options +::: cadwork.double_shoulder_options + rendering: + show_root_heading: false + show_source: true + +::: cadwork.shoulder_options rendering: show_root_heading: false show_source: true -::: src.cadwork.heel_shoulder_beam_geometry +::: cadwork.heel_shoulder_beam_geometry rendering: show_root_heading: false show_source: true -::: src.cadwork.heel_shoulder_options +::: cadwork.heel_shoulder_options rendering: show_root_heading: false show_source: true \ No newline at end of file diff --git a/docs/documentation/standard_element_type.md b/docs/documentation/standard_element_type.md new file mode 100644 index 0000000..fe6efdc --- /dev/null +++ b/docs/documentation/standard_element_type.md @@ -0,0 +1,6 @@ +# standard_element_type + +::: cadwork.standard_element_type + rendering: + show_root_heading: false + show_source: true diff --git a/docs/documentation/text_object_options.md b/docs/documentation/text_object_options.md index 196567f..5e77c6b 100644 --- a/docs/documentation/text_object_options.md +++ b/docs/documentation/text_object_options.md @@ -1,11 +1,11 @@ # Text Object Options -::: src.cadwork.text_object_options +::: cadwork.text_object_options rendering: show_root_heading: false show_source: true -::: src.cadwork.text_element_type +::: cadwork.text_element_type rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/utility_controller.md b/docs/documentation/utility_controller.md index c3f8c00..6c712a0 100644 --- a/docs/documentation/utility_controller.md +++ b/docs/documentation/utility_controller.md @@ -1,6 +1,6 @@ # Utility Controller -::: src.utility_controller +::: utility_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/visualization_controller.md b/docs/documentation/visualization_controller.md index 29d8c5e..77690ce 100644 --- a/docs/documentation/visualization_controller.md +++ b/docs/documentation/visualization_controller.md @@ -1,6 +1,6 @@ # Visualization Controller -::: src.visualization_controller +::: visualization_controller rendering: show_root_heading: false show_source: true diff --git a/docs/documentation/window_geometry.md b/docs/documentation/window_geometry.md index 659170d..567ba69 100644 --- a/docs/documentation/window_geometry.md +++ b/docs/documentation/window_geometry.md @@ -1,6 +1,6 @@ # window_geometry -::: src.cadwork.window_geometry +::: cadwork.window_geometry rendering: show_root_heading: true show_source: true \ No newline at end of file diff --git a/docs/js/tablesort.js b/docs/js/tablesort.js index 98717ae..4d659ea 100644 --- a/docs/js/tablesort.js +++ b/docs/js/tablesort.js @@ -1,6 +1,11 @@ document$.subscribe(function () { var tables = document.querySelectorAll("article table:not([class])") + + tables.forEach(function (table) { - new Tablesort(table) + table.querySelectorAll('tr').forEach(row => { + if(row.children[3]) row.children[3].style.display = 'none'; // Hide the 4th column + }) + new Tablesort(table) // Initialize Tablesort on the table }) -}) +}) \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 53111d9..db73c89 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -38,8 +38,11 @@ nav: - Attribute Controller: documentation/attribute_controller.md - BIM Controller: documentation/bim_controller.md - Cadwork: + - Api Types: documentation/api_types.md + - Attribute Display Settings: documentation/attribute_display_settings.md - Element Module Properties: documentation/element_module_properties.md - Element Type: documentation/element_type.md + - Standard Element Type: documentation/standard_element_type.md - Process Type: documentation/process_type.md - Point 3D: documentation/point_3d.md - Enumerations: documentation/enums.md @@ -48,16 +51,19 @@ nav: - BREP data: documentation/brep_data.md - IFC: - IFC2x3 Element Type: documentation/ifc_2x3_element_type.md + - IFC Predefined Type: documentation/ifc_predefined_type.md - IFC Options: documentation/ifc_options.md - Camera: documentation/camera_data.md - Layer Settings: documentation/layer_settings.md - Text Object Options: documentation/text_object_options.md + - Import 3DC Options: documentation/import_3dc_options.md - Window Geometry: documentation/window_geometry.md - BIMteam Upload Result: documentation/bim_team_upload_result.md - Shoulder cut options: documentation/shoulder_options.md - Element Filter: documentation/element_filter.md - Element Map Query: documentation/element_map_query.md - Hit Result: documentation/hit_result.md + - Coordinate System Data: documentation/coordinate_system_data.md - Connector Axis Controller: documentation/connector_axis_controller.md - Dimension Controller: documentation/dimension_controller.md - Element Controller: documentation/element_controller.md @@ -133,8 +139,18 @@ extra_css: - https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.7/katex.min.css plugins: - - mkdocstrings - search + - autorefs # Automatically generate references for known types and functions + - mkdocstrings: + handlers: + python: + paths: [src] # Directory containing Python modules + options: + show_signature_annotations: true + show_type_annotations: true + docstring_style: google # Set the docstring style + cross_reference: true # Enable cross-referencing to make links to classes, methods, and functions + show_source: false # Disable source code display extra: social: diff --git a/pyproject.toml b/pyproject.toml index 044efd5..3801c22 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.296.0" +version = "32.297.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' diff --git a/src/attribute_controller/__init__.pyi b/src/attribute_controller/__init__.pyi index 0bdfaf4..5b947a4 100644 --- a/src/attribute_controller/__init__.pyi +++ b/src/attribute_controller/__init__.pyi @@ -3,1844 +3,1641 @@ from cadwork.attribute_display_settings import attribute_display_settings from cadwork.element_grouping_type import element_grouping_type from cadwork.element_type import element_type from cadwork.extended_settings import extended_settings +from cadwork.layer_settings import layer_settings +from cadwork.node_symbol import node_symbol from cadwork.process_type import process_type +from cadwork.api_types import * -def get_last_error(error_code: int) -> str: - """Gets the last error +def set_name(element_id_list: List[ElementId], name: str) -> None: + """Sets the element name. Parameters: - error_code: error_code - - Returns: - error string + element_id_list: The element id list. + name: The element name. """ -def set_name(element_id_list: List[int], name: str) -> None: - """Sets the element name +def set_group(element_id_list: List[ElementId], group: str) -> None: + """Sets the element group. Parameters: - element_id_list: element_id_list - name: name - - Returns: - None + element_id_list: The element id list. + group: The element group. """ -def set_group(element_id_list: List[int], group: str) -> None: - """Sets the element group +def set_subgroup(element_id_list: List[ElementId], subgroup: str) -> None: + """Sets the element subgroup. Parameters: - element_id_list: element_id_list - group: group - - Returns: - None + element_id_list: The element id list. + subgroup: The element subgroup. """ -def set_subgroup(element_id_list: List[int], subgroup: str) -> None: - """Sets the element subgroup +def set_comment(element_id_list: List[ElementId], comment: str) -> None: + """Sets the element comment. Parameters: - element_id_list: element_id_list - subgroup: subgroup - - Returns: - None + element_id_list: The element id list. + comment: The element comment. """ -def set_comment(element_id_list: List[int], comment: str) -> None: - """Sets the element comment +def set_user_attribute(element_id_list: List[ElementId], number: UserAttributeId, user_attribute: str) -> None: + """Sets the element user attribute. Parameters: - element_id_list: element_id_list - comment: comment - - Returns: - None + element_id_list: The element id list. + number: The user attribute id. + user_attribute: The user attribute. """ -def set_user_attribute(element_id_list: List[int], number: int, user_attribute: str) -> None: - """Sets the element user attribute +def set_sku(element_id_list: List[ElementId], sku: str) -> None: + """Sets the element SKU. Parameters: - element_id_list: element_id_list - number: number - user_attribute: user_attribute - - Returns: - None - """ - -def set_sku(element_id_list: List[int], sku: str) -> None: - """Sets the element SKU - - Parameters: - element_id_list: element_id_list - sku: sku - - Returns: - None + element_id_list: The element id list. + sku: The element SKU. """ -def set_production_number(element_id_list: List[int], production_number: int) -> None: - """Sets the element production number +def set_production_number(element_id_list: List[ElementId], production_number: UnsignedInt) -> None: + """Sets the element production number. Parameters: - element_id_list: element_id_list - production_number: production_number - - Returns: - None + element_id_list: The element id list. + production_number: The element production number. """ -def set_part_number(element_id_list: List[int], part_number: int) -> None: - """Sets the element part number +def set_part_number(element_id_list: List[ElementId], part_number: UnsignedInt) -> None: + """Sets the element part number. Parameters: - element_id_list: element_id_list - part_number: part_number - - Returns: - None + element_id_list: The element id list. + part_number: The element part number. """ -def set_additional_data(element_id_list: List[int], data_id: str, data_text: str) -> None: - """Sets the element additional data +def set_additional_data(element_id_list: List[ElementId], data_id: str, data_text: str) -> None: + """Sets the element additional data. Parameters: - element_id_list: element_id_list - data_id: data_id - data_text: data_text - - Returns: - None + element_id_list: The element id list. + data_id: The data id. + data_text: The element additional data. """ -def delete_additional_data(element_id_list: List[int], data_id: str) -> None: - """Deletes the element additional data +def delete_additional_data(element_id_list: List[ElementId], data_id: str) -> None: + """Deletes the element additional data. Parameters: - element_id_list: element_id_list - data_id: data_id - - Returns: - None + element_id_list: The element id list. + data_id: The data id. """ -def set_user_attribute_name(number: int, user_attribute_name: str) -> None: - """Sets the user attribute name +def set_user_attribute_name(number: UserAttributeId, user_attribute_name: str) -> None: + """Sets the user attribute name. Parameters: - number: number - user_attribute_name: user_attribute_name - - Returns: - None + number: The user attribute id. + user_attribute_name: The user attribute name. """ -def set_process_type_and_extended_settings_from_name(element_id_list: List[int]) -> None: - """Sets the element process type and extended settings from the element name +def set_process_type_and_extended_settings_from_name(element_id_list: List[ElementId]) -> None: + """Sets the element process type and extended settings from the element name. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ -def set_name_process_type(name: str, process_type: None) -> None: - """Sets the process type for an element name +def set_name_process_type(name: str, process_type: process_type) -> None: + """Sets the process type for an element name. Parameters: - name: name - process_type: process_type - - Returns: - None + name: The element name. + process_type: The process type. """ -def set_name_extended_settings(name: str, extended_settings: None) -> None: - """Sets the extended settings for an element name +def set_name_extended_settings(name: str, extended_settings: extended_settings) -> None: + """Sets the extended settings for an element name. Parameters: - name: name - extended_settings: extended_settings - - Returns: - None + name: The element name. + extended_settings: The extended settings. """ -def set_output_type(element_id_list: List[int], process_type: None) -> None: - """Sets the element output type +def set_output_type(element_id_list: List[ElementId], process_type: process_type) -> None: + """Sets the element output type. Parameters: - element_id_list: element_id_list - process_type: process_type - - Returns: - None + element_id_list: The element id list. + process_type: The process type. """ -def set_extended_settings(element_id_list: List[int], extended_settings: None) -> None: - """Sets the element extended settings +def set_extended_settings(element_id_list: List[ElementId], extended_settings: extended_settings) -> None: + """Sets the element extended settings. Parameters: - element_id_list: element_id_list - extended_settings: extended_settings - - Returns: - None + element_id_list: The element id list. + extended_settings: The extended settings. """ +def set_wall(element_id_list: List[ElementId]) -> None: + """Sets the element to wall. -def set_wall(element_ids: List[int]) -> None: - """set wall + Deprecated : + Use [set_framed_wall][attribute_controller.set_framed_wall] instead. Parameters: - element_ids: element_ids - - Returns: - None + element_id_list: The element id list. """ -def set_floor(element_ids: List[int]) -> None: - """set floor +def set_floor(element_id_list: List[ElementId]) -> None: + """Set floor. + Deprecated : + Use [set_framed_floor][attribute_controller.set_framed_floor] instead. + Parameters: - element_ids: element_ids - - Returns: - None + element_id_list: The element id list. """ -def set_opening(element_id_list: List[int]) -> None: - """Sets the element to opening +def set_opening(element_id_list: List[ElementId]) -> None: + """Sets the element to opening. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ -def set_fastening_attribute(element_id_list: List[int], value: str) -> None: - """Sets the element fastening attribute +def set_fastening_attribute(element_id_list: List[ElementId], value: str) -> None: + """Sets the element fastening attribute. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The fastening attribute value. """ -def set_element_material(element_id_list: List[int], material: int) -> None: - """Sets the element material +def set_element_material(element_id_list: List[ElementId], material: MaterialId) -> None: + """Sets the element material. Parameters: - element_id_list: element_id_list - material: material - - Returns: - None + element_id_list: The element id list. + material: The element material id. """ -def set_assembly_number(element_id_list: List[int], assembly_number: str) -> None: - """set assembly number +def set_assembly_number(element_id_list: List[ElementId], assembly_number: str) -> None: + """set assembly number. Parameters: - element_id_list: element_id_list - assembly_number: assembly_number - - Returns: - None + element_id_list: The element id list. + assembly_number: The assembly number. """ -def set_list_quantity(element_id_list: List[int], list_quantity: int) -> None: - """set list quantity +def set_list_quantity(element_id_list: List[ElementId], list_quantity: UnsignedInt) -> None: + """Set list quantity. Parameters: - element_id_list: element_id_list - list_quantity: list_quantity - - Returns: - None + element_id_list: The element id list. + list_quantity: The list quantity. """ -def set_layer_settings(element_id_list: List[int], layer_settings: None) -> None: - """set layer settings +def set_layer_settings(element_id_list: List[ElementId], layer_settings: layer_settings) -> None: + """Set layer settings. Parameters: - element_id_list: element_id_list - layer_settings: layer_settings - - Returns: - None + element_id_list: The element id list. + layer_settings: The layer settings. """ -def set_ignore_in_vba_calculation(elements: List[int], ignore: bool) -> None: - """Sets if the element should be ignored in VBA Calculation +def set_ignore_in_vba_calculation(element_id_list: List[ElementId], ignore: bool) -> None: + """Sets if the element should be ignored in VBA Calculation. Parameters: - elements: elements - ignore: ignore - - Returns: - None + element_id_list: The element id list. + ignore: True if the element should be ignored in VBA calculation, false otherwise. """ def clear_errors() -> None: - """clear errors - - Returns: - None + """clear all errors. """ -def set_reference_wall_2dc(elements: List[int], _2dc_file_path: str) -> None: - """Applies a new 2dc reference wall to an element +def set_reference_wall_2dc(element_id_list: List[ElementId], _2dc_file_path: str) -> None: + """Applies a new 2dc reference wall to an element. Parameters: - elements: elements - _2dc_file_path: _2dc_file_path - - Returns: - None + element_id_list: The element id list. + _2dc_file_path: The 2dc file path. """ -def get_user_attribute_count() -> int: - """get user attribute count - +def get_user_attribute_count() -> UnsignedInt: + """Get user attribute count. + Returns: - int + The count of user attributes. """ -def set_standard_part(elements: List[int]) -> None: +def set_standard_part(element_id_list: List[ElementId]) -> None: """Sets covers (wall,opening or floor) to standard part. Parameters: - elements: elements - - Returns: - None + element_id_list: The element id list. """ -def set_solid_wall(elements: List[int]) -> None: +def set_solid_wall(element_id_list: List[ElementId]) -> None: """Sets elements to solid wall. Parameters: - elements: elements - - Returns: - None + element_id_list: The element id list. """ -def set_log_wall(elements: List[int]) -> None: +def set_log_wall(element_id_list: List[ElementId]) -> None: """Sets elements to log wall. Parameters: - elements: elements - - Returns: - None + element_id_list: The element id list. """ -def set_solid_floor(elements: List[int]) -> None: +def set_solid_floor(element_id_list: List[ElementId]) -> None: """Sets elements to solid floor. Parameters: - elements: elements - - Returns: - None + element_id_list: The element id list. """ -def set_roof(elements: List[int]) -> None: - """set roof +def set_roof(element_id_list: List[ElementId]) -> None: + """Set roof. - Parameters: - elements: elements + Deprecated : + Use [set_framed_roof][attribute_controller.set_framed_roof] instead. - Returns: - None + Parameters: + element_id_list: The element id list. """ -def set_solid_roof(elements: List[int]) -> None: +def set_solid_roof(element_id_list: List[ElementId]) -> None: """Sets elements to solid roof cover. Parameters: - elements: elements - - Returns: - None + element_id_list: The element id list. """ -def get_node_symbol(element: int) -> int: - """get node symbol +def get_node_symbol(element_id: ElementId) -> node_symbol: + """Get node symbol. Parameters: - element: element + element_id: The element id. Returns: - int + The node symbol of the element. """ -def set_node_symbol(elements: List[int], symbol: int) -> None: - """set node symbol +def set_node_symbol(element_id_list: List[ElementId], symbol: node_symbol) -> None: + """Set node symbol. Parameters: - elements: elements - symbol: symbol - - Returns: - None + element_id_list: The element id list. + symbol: The node symbol. """ def enable_attribute_display() -> None: - """enable attribute display - - Returns: - None + """Enable attribute display. """ def disable_attribute_display() -> None: - """disable attribute display - - Returns: - None + """Disable attribute display. """ def is_attribute_display_enabled() -> bool: - """is attribute display enabled + """Is attribute display enabled. Returns: - bool + True if attribute display is enabled, false otherwise. """ def update_auto_attribute() -> None: - """update auto attribute - - Returns: - None + """Update the auto attribute. """ -def set_additional_guid(elements: List[int], data_id: str, guid: str) -> None: - """set additional guid +def set_additional_guid(element_id_list: List[ElementId], data_id: str, guid: str) -> None: + """Set additional guid. Parameters: - elements: elements - data_id: data_id - guid: guid - - Returns: - None + element_id_list: The element id list. + data_id: The data id. + guid: The guid to set. """ - def add_item_to_group_list(item: str) -> None: - """add item to group list + """Add item to group list. Parameters: - item: item - - Returns: - None + item: The item to add in the group list. """ def add_item_to_subgroup_list(item: str) -> None: - """add item to subgroup list + """Add item to subgroup list. Parameters: - item: item - - Returns: - None + item: The item to add in the subgroup list. """ - def add_item_to_comment_list(item: str) -> None: - """add item to comment list - - Parameters: - item: item + """Add item to comment list. - Returns: - None + Args: + item: The item to add in the comment list. """ def add_item_to_sku_list(item: str) -> None: - """add item to sku list + """Add item to sku list. Parameters: - item: item - - Returns: - None + item: The item to add in the sku list. """ -def add_item_to_user_attribute_list(attribute_number: int, item: str) -> None: - """add item to user attribute list +def add_item_to_user_attribute_list(attribute_number: UserAttributeId, item: str) -> None: + """Add item to user attribute list. Parameters: - attribute_number: attribute_number - item: item - - Returns: - None + attribute_number: The attribute number. + item: The item to add in the user attribute list. """ -def set_container_number(elements: List[int], number: int) -> None: - """set container number +def set_container_number(element_id_list: List[ElementId], number: UnsignedInt) -> None: + """Set container number. Parameters: - elements: elements - number: number - - Returns: - None + element_id_list: The element id list. + number: The container number. """ def get_name_list_items() -> List[str]: - """get name list items + """Retrieve a list of name for all items Returns: - List[str] + A list of names for all items. """ def add_item_to_name_list(item: str) -> None: - """add item to name list + """Add item to name list. Parameters: - item: item - - Returns: - None + item: The item to add in the name list. """ def delete_item_from_comment_list(item: str) -> bool: - """delete item from comment list + """Delete item from comment list. Parameters: - item: item + item: The item to delete from the comment list. Returns: - bool + True if the item was successfully deleted, false otherwise. """ def delete_item_from_group_list(item: str) -> bool: - """delete item from group list + """Delete item from group list. Parameters: - item: item + item: The item to delete from the group list. Returns: - bool + True if the item was successfully deleted, false otherwise. """ def delete_item_from_sku_list(item: str) -> bool: - """delete item from sku list + """Delete item from sku list. Parameters: - item: item + item: The item to delete from the sku list. Returns: - bool + True if the item was successfully deleted, false otherwise. """ def delete_item_from_subgroup_list(item: str) -> bool: - """delete item from subgroup list + """Delete item from subgroup list. Parameters: - item: item + item: The item to delete from the subgroup list. Returns: - bool + True if the item was successfully deleted, false otherwise. """ -def delete_item_from_user_attribute_list(attribute_number: int, item: str) -> bool: - """delete item from user attribute list +def delete_item_from_user_attribute_list(attribute_number: UserAttributeId, item: str) -> bool: + """Delete item from user attribute list. Parameters: - attribute_number: attribute_number - item: item + attribute_number: The attribute number. + item: The item to delete from the user attribute list. Returns: - bool + True if the item was successfully deleted, false otherwise. """ def set_attribute_display_settings_for_2d(settings: attribute_display_settings) -> None: - """set attribute display settings for 2d + """Set attribute display settings for 2d. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_2d_with_layout(settings: attribute_display_settings) -> None: - """set attribute display settings for 2d with layout + """Set attribute display settings for 2d with layout. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_2d_without_layout(settings: attribute_display_settings) -> None: - """set attribute display settings for 2d without layout + """Set attribute display settings for 2d without layout. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_3d(settings: attribute_display_settings) -> None: - """set attribute display settings for 3d + """Set attribute display settings for 3d. Parameters: - settings: settings + settings: The display settings to apply. + """ - Returns: - None + +def set_attribute_display_settings_for_3d(settings: attribute_display_settings) -> None: + """Set attribute display settings for 3d. + + Parameters: + settings: The display settings to apply. """ def set_attribute_display_settings_for_container(settings: attribute_display_settings) -> None: - """set attribute display settings for container + """Set attribute display settings for container. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ - def set_attribute_display_settings_for_export_solid(settings: attribute_display_settings) -> None: - """set attribute display settings for export solid + """Set attribute display settings for export solid. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_framed_wall_axis(settings: attribute_display_settings) -> None: - """set attribute display settings for framed wall axis + """Set attribute display settings for framed wall axis. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_framed_wall_beam(settings: attribute_display_settings) -> None: - """set attribute display settings for framed wall beam + """Set attribute display settings for framed wall beam. Parameters: - settings: settings + settings: The display settings to apply. + """ - Returns: - None + +def set_attribute_display_settings_for_framed_wall_beam(settings: attribute_display_settings) -> None: + """Set attribute display settings for framed wall beam. + + Parameters: + settings: The display settings to apply. """ def set_attribute_display_settings_for_framed_wall_opening(settings: attribute_display_settings) -> None: - """set attribute display settings for framed wall opening + """Set attribute display settings for framed wall opening. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_framed_wall_panel(settings: attribute_display_settings) -> None: - """set attribute display settings for framed wall panel + """Set attribute display settings for framed wall panel. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_log_wall_axis(settings: attribute_display_settings) -> None: - """set attribute display settings for log wall axis + """Set attribute display settings for log wall axis. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_log_wall_beam(settings: attribute_display_settings) -> None: - """set attribute display settings for log wall beam + """Set attribute display settings for log wall beam. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_log_wall_opening(settings: attribute_display_settings) -> None: - """set attribute display settings for log wall opening + """Set attribute display settings for log wall opening. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_log_wall_panel(settings: attribute_display_settings) -> None: - """set attribute display settings for log wall panel + """Set attribute display settings for log wall panel. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ - def set_attribute_display_settings_for_machine(settings: attribute_display_settings) -> None: - """set attribute display settings for machine + """Set attribute display settings for machine. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_nesting_element(settings: attribute_display_settings) -> None: - """set attribute display settings for nesting element + """Set attribute display settings for nesting element. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_nesting_volume(settings: attribute_display_settings) -> None: - """set attribute display settings for nesting volume + """Set attribute display settings for nesting volume. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_solid_wall_axis(settings: attribute_display_settings) -> None: - """set attribute display settings for solid wall axis + """Set attribute display settings for solid wall axis. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_solid_wall_beam(settings: attribute_display_settings) -> None: - """set attribute display settings for solid wall beam + """Set attribute display settings for solid wall beam. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_solid_wall_opening(settings: attribute_display_settings) -> None: - """set attribute display settings for solid wall opening + """Set attribute display settings for solid wall opening. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ def set_attribute_display_settings_for_solid_wall_panel(settings: attribute_display_settings) -> None: - """set attribute display settings for solid wall panel + """Set attribute display settings for solid wall panel. Parameters: - settings: settings - - Returns: - None + settings: The display settings to apply. """ -def set_framed_floor(element_id_list: List[int]) -> None: - """Sets the elements to framed floor +def set_framed_floor(element_id_list: List[ElementId]) -> None: + """Sets the elements to framed floor. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ -def set_framed_roof(element_id_list: List[int]) -> None: - """Sets the elements to framed roof +def set_framed_roof(element_id_list: List[ElementId]) -> None: + """Sets the elements to framed roof. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ -def set_framed_wall(element_id_list: List[int]) -> None: - """Sets the element to framed wall +def set_framed_wall(element_id_list: List[ElementId]) -> None: + """Sets the element to framed wall. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ -def get_name_list_items_by_element_type(element_tpye: element_type) -> List[str]: - """get name list items by element type +def get_name_list_items_by_element_type(element_type: element_type) -> List[str]: + """Get name list items by element type. Parameters: - element_tpye: element_tpye + element_type: The element type to filter by. Returns: - List[str] + The list of names for the specified element type. """ -def get_name(element_id: int) -> str: - """Gets the element name +def get_name(element_id: ElementId) -> str: + """Gets the element name. Parameters: - element_id: element_id + element_id: The element id. Returns: - element name + The element name. """ -def get_group(element_id: int) -> str: - """Gets the element group +def get_group(element_id: ElementId) -> str: + """Gets the element group. Parameters: - element_id: element_id + element_id: The element id. Returns: - element group + The element group. """ -def get_subgroup(element_id: int) -> str: - """Gets the element subgroup +def get_subgroup(element_id: ElementId) -> str: + """Gets the element subgroup. Parameters: - element_id: element_id + element_id: The element id. Returns: - element subgroup + The element subgroup. """ -def get_comment(element_id: int) -> str: - """Gets the element comment +def get_comment(element_id: ElementId) -> str: + """Gets the element comment. Parameters: - element_id: element_id + element_id: The element id. Returns: - element comment + The element comment. """ -def get_user_attribute(element_id: int, number: int) -> str: - """Gets the element user attribute +def get_user_attribute(element_id: ElementId, number: UserAttributeId) -> str: + """Gets the element user attribute. Parameters: - element_id: element_id - number: number + element_id: The element id. + number: The user attribute number. Returns: - element user attribute + The element user attribute. """ -def get_sku(element_id: int) -> str: - """Gets the element SKU +def get_sku(element_id: ElementId) -> str: + """Gets the element SKU. Parameters: - element_id: element_id + element_id: The element id. Returns: - element SKU + The element SKU. """ -def get_production_number(element_id: int) -> int: - """Gets the element production number +def get_production_number(element_id: ElementId) -> UnsignedInt: + """Gets the element production number. Parameters: - element_id: element_id + element_id: The element id. Returns: - element production number + The element production number. """ -def get_part_number(element_id: int) -> int: - """Gets the element part number +def get_part_number(element_id: ElementId) -> UnsignedInt: + """Gets the element part number. Parameters: - element_id: element_id + element_id: The element id. Returns: - element part number + The element part number. """ -def get_additional_data(element_id: int, data_id: str) -> str: - """Gets the element additional data +def get_additional_data(element_id: ElementId, data_id: str) -> str: + """Gets the element additional data. Parameters: - element_id: element_id - data_id: data_id + element_id: The element id. + data_id: The data id. Returns: - element additional data + The element additional data. """ -def get_user_attribute_name(number: int) -> str: - """Gets the user attribute name +def get_user_attribute_name(number: UserAttributeId) -> str: + """Gets the user attribute name. Parameters: - number: number + number: The user attribute number. Returns: - user attribute name + The user attribute name. """ -def get_wall_situation(element_id: int) -> str: - """Gets the element wall situation +def get_wall_situation(element_id: ElementId) -> str: + """Gets the element wall situation. Parameters: - element_id: element_id + element_id: The element id. Returns: - element wall situation + The element wall situation. """ -def get_element_material_name(element_id: int) -> str: - """Gets the element material name +def get_element_material_name(element_id: ElementId) -> str: + """Gets the element material name. Parameters: - element_id: element_id + element_id: The element id. Returns: - element material name + The element material name. """ -def get_prefab_layer(element_id: int) -> str: - """Gets the element prefab layer +def get_prefab_layer(element_id: ElementId) -> str: + """Gets the element prefab layer. Parameters: - element_id: element_id + element_id: The element id. Returns: - element prefab layer + The element prefab layer. """ -def get_machine_calculation_set(element_id: int) -> str: - """Gets the element machine calculation set +def get_machine_calculation_set(element_id: ElementId) -> str: + """Gets the element machine calculation set. Parameters: - element_id: element_id + element_id: The element id. Returns: - element machine calculation set + The element machine calculation set. """ -def get_cutting_set(element_id: int) -> str: - """Gets the element cutting set +def get_cutting_set(element_id: ElementId) -> str: + """Gets the element cutting set. Parameters: - element_id: element_id + element_id: The element id. Returns: - element cutting set + The element cutting set. """ def get_name_process_type(name: str) -> process_type: - """Gets the process type for an element name + """Gets the process type for an element name. Parameters: - name: name + name: The element name. Returns: - process type + The process type. """ def get_name_extended_settings(name: str) -> extended_settings: - """Gets the extended settings for an element name + """Gets the extended settings for an element name. Parameters: - name: name + name: The element name. Returns: - extended settings + The extended settings. """ -def get_output_type(element_id: int) -> process_type: - """Gets the element output type +def get_output_type(element_id: ElementId) -> process_type: + """Gets the element output type. Parameters: - element_id: element_id + element_id: The element id. Returns: - element output type + The element output type. """ -def get_extended_settings(element_id: int) -> extended_settings: - """Gets the element extended settings +def get_extended_settings(element_id: ElementId) -> extended_settings: + """Gets the element extended settings. Parameters: - element_id: element_id + element_id: The element id. Returns: - element extended settings + The element extended settings. """ -def get_element_type(element_id: int) -> element_type: - """Gets the element type +def get_element_type(element_id: ElementId) -> element_type: + """Gets the element type. Parameters: - element_id: element_id + element_id: The element id. Returns: - element type + The element type. """ -def get_fastening_attribute(element_id: int) -> str: - """Get the element fastening attribute +def get_fastening_attribute(element_id: ElementId) -> str: + """Get the element fastening attribute. Parameters: - element_id: element_id + element_id: The element id. Returns: - element fastening attribute + The element fastening attribute. """ -def get_assembly_number(element_id: int) -> str: - """get assembly number +def get_assembly_number(element_id: ElementId) -> str: + """Get assembly number. Parameters: - element_id: element_id + element_id: The element id. Returns: - str + The assembly number. """ -def get_list_quantity(element_id: int) -> int: - """get list quantity +def get_list_quantity(element_id: ElementId) -> UnsignedInt: + """Get list quantity. Parameters: - element_id: element_id + element_id: The element id. Returns: - int + The list quantity. """ -def get_ignore_in_vba_calculation(element: int) -> bool: - """get ignore in vba calculation +def get_ignore_in_vba_calculation(element_id: ElementId) -> bool: + """Get ignore in vba calculation. Parameters: - element: element + element_id: The element id. Returns: - bool + True if the element is ignored in VBA calculation, false otherwise. """ -def get_standard_element_name(element_id: int) -> str: - """get standard element name +def get_standard_element_name(element_id: ElementId) -> str: + """Get standard element name. Parameters: - element_id: element_id + element_id: The element id. Returns: - str + The standard element name. """ -def get_steel_shape_name(element_id: int) -> str: - """get steel shape name +def get_steel_shape_name(element_id: ElementId) -> str: + """Get steel shape name. Parameters: - element_id: element_id + element_id: The element id. Returns: - str + The steel shape name. """ -def is_beam(element_id: int) -> bool: - """Tests if element is beam +def is_beam(element_id: ElementId) -> bool: + """Tests if element is beam. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element beam + True if the element is a beam, false otherwise. """ -def is_panel(element_id: int) -> bool: - """Tests if element is panel +def is_panel(element_id: ElementId) -> bool: + """Tests if element is panel. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element panel + True if the element is a panel, false otherwise. """ -def is_opening(element_id: int) -> bool: - """Tests if element is opening +def is_opening(element_id: ElementId) -> bool: + """Tests if element is opening. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element opening + True if the element is an opening, false otherwise. """ -def is_wall(element_id: int) -> bool: - """Tests if element is wall +def is_wall(element_id: ElementId) -> bool: + """Tests if element is wall. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element wall + True if the element is a wall, false otherwise. """ -def is_floor(element_id: int) -> bool: - """Tests if element is floor +def is_floor(element_id: ElementId) -> bool: + """Tests if element is floor. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element floor + True if the element is a floor, false otherwise. """ -def is_roof(element_id: int) -> bool: - """Tests if element is roof +def is_roof(element_id: ElementId) -> bool: + """Tests if element is roof. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element roof + True if the element is a roof, false otherwise. """ -def is_metal(element_id: int) -> bool: - """Tests if element is metal +def is_metal(element_id: ElementId) -> bool: + """Tests if element is metal. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element metal + True if the element is metal, false otherwise. """ -def is_export_solid(element_id: int) -> bool: - """Tests if element is export solid +def is_export_solid(element_id: ElementId) -> bool: + """Tests if element is export solid. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element export solid + True if the element is an export solid, false otherwise. """ -def is_container(element_id: int) -> bool: - """Tests if element is container +def is_container(element_id: ElementId) -> bool: + """Tests if element is container. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element container + True if the element is a container, false otherwise. """ -def is_connector_axis(element_id: int) -> bool: - """Tests if element is connector axis +def is_connector_axis(element_id: ElementId) -> bool: + """Tests if element is connector axis. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element connector axis + True if the element is a connector axis, false otherwise. """ -def is_drilling(element_id: int) -> bool: - """Tests if element is drilling +def is_drilling(element_id: ElementId) -> bool: + """Tests if element is drilling. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element drilling + True if the element is drilling, false otherwise. """ -def is_node(element_id: int) -> bool: - """Tests if element is node +def is_node(element_id: ElementId) -> bool: + """Tests if element is node. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element node + True if the element is a node, false otherwise. """ -def is_auxiliary(element_id: int) -> bool: - """Tests if element is auxiliary +def is_auxiliary(element_id: ElementId) -> bool: + """Tests if element is auxiliary. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element auxiliary + True if the element is auxiliary, false otherwise. """ -def is_roof_surface(element_id: int) -> bool: - """Tests if the element is roof surface +def is_roof_surface(element_id: ElementId) -> bool: + """Tests if the element is roof surface. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element roof surface + True if the element is a roof surface, false otherwise. """ -def is_caddy_object(element_id: int) -> bool: - """Tests if the element is caddy object +def is_caddy_object(element_id: ElementId) -> bool: + """Tests if the element is caddy object. Parameters: - element_id: element_id + element_id: The element id. Returns: - is element caddy object + True if the element is a caddy object, false otherwise. """ -def is_envelope(element_id: int) -> bool: - """is envelope +def is_envelope(element_id: ElementId) -> bool: + """Tests if the element is an envelope. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is an envelope, false otherwise. """ -def is_architecture_wall_2dc(element: int) -> bool: - """Tests if the element has a 2dc reference wall +def is_architecture_wall_2dc(element_id: ElementId) -> bool: + """Tests if the element is a 2dc reference wall. Parameters: - element: element + element_id: The element id. Returns: - is architecturewall 2dc + True if the element is a 2dc reference wall, false otherwise. """ -def is_architecture_wall_xml(element: int) -> bool: - """Tests if the element has a xml reference wall +def is_architecture_wall_xml(element_id: ElementId) -> bool: + """Tests if the element is a xml reference wall. Parameters: - element: element + element_id: The element id. Returns: - is architecturewall xml + True if the element is a xml reference wall, false otherwise. """ -def is_surface(element_id: int) -> bool: - """Tests if the element is a Surface +def is_surface(element_id: ElementId) -> bool: + """Tests if the element is a Surface. Parameters: - element_id: element_id + element_id: The element id. Returns: - is Surface + True if the element is a Surface, false otherwise. """ -def is_line(element_id: int) -> bool: - """Tests if the element is a Line +def is_line(element_id: ElementId) -> bool: + """Tests if the element is a Line. Parameters: - element_id: element_id + element_id: The element id. Returns: - is Line + True if the element is a Line, false otherwise. """ -def get_auto_attribute(element_id: int, number: int) -> str: - """get auto attribute +def get_auto_attribute(element_id: ElementId, number: UnsignedInt) -> str: + """Get auto attribute. Parameters: - element_id: element_id - number: number + element_id: The element id. + number: The auto attribute number. Returns: - str + The auto attribute value. """ -def get_auto_attribute_name(number: int) -> str: - """get auto attribute name +def get_auto_attribute_name(number: UnsignedInt) -> str: + """Get auto attribute name. Parameters: - number: number + number: The auto attribute number. Returns: - str + The auto attribute name. """ -def is_framed_wall(element_id: int) -> bool: - """is framed wall +def is_framed_wall(element_id: ElementId) -> bool: + """Tests if the element is a framed wall. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a framed wall, false otherwise. """ -def is_solid_wall(element_id: int) -> bool: - """is solid wall +def is_solid_wall(element_id: ElementId) -> bool: + """Tests if the element is a solid wall. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a solid wall, false otherwise. """ -def is_log_wall(element_id: int) -> bool: - """is log wall +def is_log_wall(element_id: ElementId) -> bool: + """Tests if the element is a log wall. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a log wall, false otherwise. """ -def is_framed_floor(element_id: int) -> bool: - """is framed floor +def is_framed_floor(element_id: ElementId) -> bool: + """Tests if the element is a framed floor. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a framed floor, false otherwise. """ -def is_solid_floor(element_id: int) -> bool: - """is solid floor +def is_solid_floor(element_id: ElementId) -> bool: + """Tests if the element is a solid floor. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a solid floor, false otherwise. """ -def is_framed_roof(element_id: int) -> bool: - """is framed roof +def is_framed_roof(element_id: ElementId) -> bool: + """Tests if the element is a framed roof. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a framed roof, false otherwise. """ -def is_solid_roof(element_id: int) -> bool: - """is solid roof +def is_solid_roof(element_id: ElementId) -> bool: + """Tests if the element is a solid roof. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a solid roof, false otherwise. """ -def get_additional_guid(element_id: int, data_id: str) -> str: - """get additional guid +def get_additional_guid(element_id: ElementId, data_id: str) -> str: + """Get additional guid. Parameters: - element_id: element_id - data_id: data_id + element_id: The element id. + data_id: The data id. Returns: - str + The additional guid associated with the element and data id. """ -def get_prefab_layer_all_assigned(element_id: int) -> List[int]: - """get prefab layer all assigned +def get_prefab_layer_all_assigned(element_id: ElementId) -> List[int]: + """Get all assigned prefab layers. Parameters: - element_id: element_id + element_id: The element id. Returns: - List[int] + The list of all assigned prefab layers for the element. """ -def get_prefab_layer_with_dimensions(element_id: int) -> List[int]: - """get prefab layer with dimensions +def get_prefab_layer_with_dimensions(element_id: ElementId) -> List[int]: + """Get prefab layer with dimensions. Parameters: - element_id: element_id + element_id: The element id. Returns: - List[int] + The list of prefab layers with dimensions for the element. """ -def get_prefab_layer_without_dimensions(element_id: int) -> List[int]: - """get prefab layer without dimensions +def get_prefab_layer_without_dimensions(element_id: ElementId) -> List[int]: + """Get prefab layer without dimensions. Parameters: - element_id: element_id + element_id: The element id. Returns: - List[int] + The list of prefab layers without dimensions for the element. """ -def is_nesting_parent(element_id: int) -> bool: - """is nesting parent +def is_nesting_parent(element_id: ElementId) -> bool: + """Tests if the element is a nesting parent. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a nesting parent, false otherwise. """ -def is_nesting_raw_part(element_id: int) -> bool: - """is nesting raw part +def is_nesting_raw_part(element_id: ElementId) -> bool: + """Tests if the element is a nesting raw part. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a nesting raw part, false otherwise. """ -def get_container_number(element_id: int) -> int: - """get container number +def get_container_number(element_id: ElementId) -> UnsignedInt: + """Get container number. Parameters: - element_id: element_id + element_id: The element id. Returns: - int + The container number associated with the element. """ -def get_container_number_with_prefix(element_id: int) -> str: - """get container number with prefix +def get_container_number_with_prefix(element_id: ElementId) -> str: + """Get container number with prefix. Parameters: - element_id: element_id + element_id: The element id. Returns: - str + The container number with prefix associated with the element. """ def get_group_list_items() -> List[str]: - """get group list items + """Get group list items. Returns: - List[str] + The list of group list items. """ def get_subgroup_list_items() -> List[str]: - """get subgroup list items + """Get subgroup list items. Returns: - List[str] + The list of subgroup list items. """ def get_comment_list_items() -> List[str]: - """get comment list items + """Get comment list items. Returns: - List[str] + The list of comment list items. """ def get_sku_list_items() -> List[str]: - """get sku list items + """Get sku list items. Returns: - List[str] + The list of sku list items. """ -def get_user_attribute_list_items(element_id: int) -> List[str]: - """get user attribute list items +def get_user_attribute_list_items(element_id: ElementId) -> List[str]: + """Get user attribute list items. Parameters: - element_id: element_id + element_id: The element id. Returns: - List[str] + The list of user attribute list items. """ -def is_circular_mep(element_id: int) -> bool: - """is circular mep +def is_circular_mep(element_id: ElementId) -> bool: + """Test if element is circular mep. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a circular mep, false otherwise. """ -def is_rectangular_mep(element_id: int) -> bool: - """is rectangular mep +def is_rectangular_mep(element_id: ElementId) -> bool: + """Test if element is rectangular mep. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a rectangular mep, false otherwise. """ - -def get_machine_calculation_state(element_id: int) -> str: - """get machine calculation state +def get_machine_calculation_state(element_id: ElementId) -> str: + """Get machine calculation state. Parameters: - element_id: element_id + element_id: The element id. Returns: - str + The machine calculation state of the element. """ -def get_machine_calculation_set_machine_type(element_id: int) -> str: - """get machine calculation set machine type +def get_machine_calculation_set_machine_type(element_id: ElementId) -> str: + """Get machine calculation set machine type. Parameters: - element_id: element_id + element_id: The element id. Returns: - str + The machine calculation set machine type of the element. """ - -def is_btl_processing_group(element_id: int) -> bool: - """is btl processing group +def is_btl_processing_group(element_id: ElementId) -> bool: + """Test if element is btl processing group. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a btl processing group, false otherwise. """ - -def is_hundegger_processing_group(element_id: int) -> bool: - """is hundegger processing group +def is_hundegger_processing_group(element_id: ElementId) -> bool: + """Test if element is hundegger processing group. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is a hundegger processing group, false otherwise. """ def get_element_grouping_type() -> element_grouping_type: - """Get the element grouping type (group, subgroup) + """Get the element grouping type (group, subgroup). Returns: - element grouping type + The element grouping type. """ def set_element_grouping_type(element_grouping_type: element_grouping_type) -> None: - """Set the element grouping type (group, subgroup) + """Set the element grouping type (group, subgroup). Parameters: - element_grouping_type: element_grouping_type - - Returns: - None + element_grouping_type: The element grouping type to set. """ -def get_associated_nesting_name(element_id: int) -> str: - """get associated nesting name +def get_associated_nesting_name(element_id: ElementId) -> str: + """Get associated nesting name Parameters: - element_id: element_id + element_id: The element id. Returns: - str + The associated nesting name. """ -def get_associated_nesting_number(element_id: int) -> str: - """get associated nesting number +def get_associated_nesting_number(element_id: ElementId) -> str: + """Get associated nesting number. Parameters: - element_id: element_id + element_id: The element id. Returns: - str + The associated nesting number. """ def get_attribute_display_settings_for_2d() -> attribute_display_settings: - """get attribute display settings for 2d + """Get attribute display settings for 2d. Returns: - attribute_display_settings + The attribute display settings for 2d. """ def get_attribute_display_settings_for_2d_with_layout() -> attribute_display_settings: - """get attribute display settings for 2d with layout + """Get attribute display settings for 2d with layout. Returns: - attribute_display_settings + The attribute display settings for 2d with layout. """ def get_attribute_display_settings_for_2d_without_layout() -> attribute_display_settings: - """get attribute display settings for 2d without layout + """Get attribute display settings for 2d without layout. Returns: - attribute_display_settings + The attribute display settings for 2d without layout. """ def get_attribute_display_settings_for_3d() -> attribute_display_settings: - """get attribute display settings for 3d + """Get attribute display settings for 3d. Returns: - attribute_display_settings + The attribute display settings for 3d. """ def get_attribute_display_settings_for_container() -> attribute_display_settings: - """get attribute display settings for container + """Get attribute display settings for container. Returns: - attribute_display_settings + The attribute display settings for container. """ def get_attribute_display_settings_for_export_solid() -> attribute_display_settings: - """get attribute display settings for export solid + """Get attribute display settings for export solid. Returns: - attribute_display_settings + The attribute display settings for export solid. """ def get_attribute_display_settings_for_framed_wall_axis() -> attribute_display_settings: - """get attribute display settings for framed wall axis + """Get attribute display settings for framed wall axis. Returns: - attribute_display_settings + The attribute display settings for framed wall axis. """ def get_attribute_display_settings_for_framed_wall_beam() -> attribute_display_settings: - """get attribute display settings for framed wall beam + """Get attribute display settings for framed wall beam. Returns: - attribute_display_settings + The attribute display settings for framed wall beam. """ def get_attribute_display_settings_for_framed_wall_opening() -> attribute_display_settings: - """get attribute display settings for framed wall opening + """Get attribute display settings for framed wall opening. Returns: - attribute_display_settings + The attribute display settings for framed wall opening. """ def get_attribute_display_settings_for_framed_wall_panel() -> attribute_display_settings: - """get attribute display settings for framed wall panel + """Get attribute display settings for framed wall panel. Returns: - attribute_display_settings + The attribute display settings for framed wall panel. """ def get_attribute_display_settings_for_log_wall_axis() -> attribute_display_settings: - """get attribute display settings for log wall axis + """Get attribute display settings for log wall axis. Returns: - attribute_display_settings + The attribute display settings for log wall axis. """ def get_attribute_display_settings_for_log_wall_beam() -> attribute_display_settings: - """get attribute display settings for log wall beam + """Get attribute display settings for log wall beam. Returns: - attribute_display_settings + The attribute display settings for log wall beam. """ def get_attribute_display_settings_for_log_wall_opening() -> attribute_display_settings: - """get attribute display settings for log wall opening + """Get attribute display settings for log wall opening. Returns: - attribute_display_settings + The attribute display settings for log wall opening. """ def get_attribute_display_settings_for_log_wall_panel() -> attribute_display_settings: - """get attribute display settings for log wall panel + """Get attribute display settings for log wall panel. Returns: - attribute_display_settings + The attribute display settings for log wall panel. """ def get_attribute_display_settings_for_machine() -> attribute_display_settings: - """get attribute display settings for machine + """Get attribute display settings for machine. Returns: - attribute_display_settings + The attribute display settings for machine. """ def get_attribute_display_settings_for_nesting_element() -> attribute_display_settings: - """get attribute display settings for nesting element + """Get attribute display settings for nesting element. Returns: - attribute_display_settings + The attribute display settings for nesting element. """ def get_attribute_display_settings_for_nesting_volume() -> attribute_display_settings: - """get attribute display settings for nesting volume + """Get attribute display settings for nesting volume. Returns: - attribute_display_settings + The attribute display settings for nesting volume. """ def get_attribute_display_settings_for_solid_wall_axis() -> attribute_display_settings: - """get attribute display settings for solid wall axis + """Get attribute display settings for solid wall axis. Returns: - attribute_display_settings + The attribute display settings for solid wall axis. """ def get_attribute_display_settings_for_solid_wall_beam() -> attribute_display_settings: - """get attribute display settings for solid wall beam + """Get attribute display settings for solid wall beam. Returns: - attribute_display_settings + The attribute display settings for solid wall beam. """ def get_attribute_display_settings_for_solid_wall_opening() -> attribute_display_settings: - """get attribute display settings for solid wall opening + """Get attribute display settings for solid wall opening. Returns: - attribute_display_settings + The attribute display settings for solid wall opening. """ def get_attribute_display_settings_for_solid_wall_panel() -> attribute_display_settings: - """get attribute display settings for solid wall panel + """Get attribute display settings for solid wall panel. Returns: - attribute_display_settings + The attribute display settings for solid wall panel. """ -def is_processing(element_id: int) -> bool: - """is processing +def is_processing(element_id: ElementId) -> bool: + """Tests if element is processing. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is processing, false otherwise. """ -def delete_user_attribute(number: int) -> bool: +def delete_user_attribute(number: UserAttributeId) -> bool: """Delete user attribute from attribute list. The attribute is only deleted when the attribute is not used. Parameters: - number: number + number: The attribute number. Returns: - bool deletion successfully + True if the attribute was successfully deleted, false otherwise. """ -def is_attribute_visible_in_modify_window(number: int) -> bool: - """is attribute visible in modify window +def is_attribute_visible_in_modify_window(number: UnsignedInt) -> bool: + """Test if attribute is visible in modify window. Parameters: - number: number + number: The attribute number. Returns: - bool + True if the attribute is visible in the modify window, false otherwise. """ -def set_attribute_visibility_in_modify_window(number: int, visibility: bool) -> None: - """set attribute visibility in modify window +def set_attribute_visibility_in_modify_window(number: UnsignedInt, visibility: bool) -> None: + """Set attribute visibility in modify window. Parameters: - number: number - visibility: visibility - - Returns: - None + number: The attribute number. + visibility: The visibility state. """ -def set_cutting_set(element_id_list: List[int], cutting_set_name: str) -> bool: - """set cutting set +def set_cutting_set(element_id_list: List[ElementId], cutting_set_name: str) -> bool: + """Set cutting set. Parameters: - element_id_list: element_id_list - cutting_set_name: cutting_set_name + element_id_list: The list of element ids. + cutting_set_name: The name of the cutting set. Returns: - bool + True if the cutting set was successfully set, false otherwise. """ -def get_standard_element_material_id(element_id: int) ->int: - """get standard element material id +def get_standard_element_material_id(element_id: ElementId) -> int: + """Get standard element material id. Parameters: - element_id: element_id + element_id: The element id. Returns: - int + The standard element material id. """ \ No newline at end of file diff --git a/src/bim_controller/__init__.pyi b/src/bim_controller/__init__.pyi index 62cdd70..3a2f864 100644 --- a/src/bim_controller/__init__.pyi +++ b/src/bim_controller/__init__.pyi @@ -2,23 +2,13 @@ from typing import List from cadwork.ifc_2x3_element_type import ifc_2x3_element_type from cadwork.ifc_options import ifc_options from cadwork.ifc_predefined_type import ifc_predefined_type +from cadwork.api_types import * - -def get_last_error(a0: int) -> str: - """get last error - - Parameters: - a0: a0 - - Returns: - str - """ - -def get_ifc_guid(element_id: int) -> str: - """get ifc guid +def get_ifc_guid(element_id: ElementId) -> str: + """Get the IFC GUID of an element. Parameters: - element_id: element_id + element_id: The element id. Examples: >>> import element_controller as ec @@ -30,14 +20,14 @@ def get_ifc_guid(element_id: int) -> str: >>> print(f"IFC GUID: {ifc_guid}") Returns: - str + A string representing the IFC GUID. """ -def get_ifc2x3_element_type(element_id: int) -> ifc_2x3_element_type: - """get ifc2x3 element type +def get_ifc2x3_element_type(element_id: ElementId) -> ifc_2x3_element_type: + """Get ifc2x3 element type. Parameters: - element_id: element_id + element_id: The element id. Examples: >>> import element_controller as ec @@ -49,17 +39,17 @@ def get_ifc2x3_element_type(element_id: int) -> ifc_2x3_element_type: >>> ifc_type = bc.get_ifc2x3_element_type(element) Returns: - ifc_2x3_element_type + The ifc_2x3_element_type of the element. """ -def set_ifc2x3_element_type(element_i_ds: List[int], ifc_type: ifc_2x3_element_type) -> None: - """set ifc2x3 element type +def set_ifc2x3_element_type(element_id_list: List[ElementId], ifc_type: ifc_2x3_element_type) -> None: + """Set ifc2x3 element type. Parameters: - element_i_ds: element_i_ds - ifc_type: element_type - + element_id_list: The list of element ids. + ifc_type: The ifc_2x3_element_type to set. + Examples: >>> import element_controller as ec >>> import bim_controller as bc @@ -69,16 +59,13 @@ def set_ifc2x3_element_type(element_i_ds: List[int], ifc_type: ifc_2x3_element_t >>> ifc_entity_type = cadwork.ifc_2x3_element_type() >>> ifc_entity_type.set_ifc_member() >>> bc.set_ifc2x3_element_type(selected_elements, ifc_entity_type) - - Returns: - None """ def import_ifc_as_graphical_object(file_path: str) -> bool: - """import ifc as graphical object + """Imports ifc as graphical object. Parameters: - file_path: file_path + file_path: The path to the IFC file. Examples: >>> import bim_controller as bc @@ -89,14 +76,14 @@ def import_ifc_as_graphical_object(file_path: str) -> bool: >>> print("IFC imported as graphical object successfully") Returns: - bool + True if the import was successful, false otherwise. """ def import_bcf(file_path: str) -> bool: - """import bcf + """Imports a BCF file. Parameters: - file_path: file_path + file_path: The path to the BCF file. Examples: >>> import bim_controller as bc @@ -107,14 +94,14 @@ def import_bcf(file_path: str) -> bool: >>> print("BCF file imported successfully") Returns: - bool + True if the import was successful, false otherwise. """ def export_bcf(file_path: str) -> bool: - """export bcf + """Exports a BCF file. Parameters: - file_path: file_path + file_path: The path where the BCF file will be exported. Examples: >>> import bim_controller as bc @@ -125,15 +112,15 @@ def export_bcf(file_path: str) -> bool: >>> print("BCF file exported successfully") Returns: - bool + True if the export was successful, false otherwise. """ -def export_ifc(element_i_ds: List[int], file_path: str) -> bool: - """export ifc +def export_ifc(element_id_list: List[ElementId], file_path: str) -> bool: + """Export IFC file. Parameters: - element_i_ds: element_i_ds - file_path: file_path + element_id_list: The list of element ids. + file_path: The path where the IFC file will be exported. Examples: >>> import element_controller as ec @@ -146,26 +133,26 @@ def export_ifc(element_i_ds: List[int], file_path: str) -> bool: >>> print("IFC file exported successfully") Returns: - bool + True if the export was successful, false otherwise. """ -def import_ifc_return_exchange_objects(file_path: str) -> List[int]: - """imports an IFC File and returns the ids of the Exchange Objects +def import_ifc_return_exchange_objects(file_path: str) -> List[ElementId]: + """Imports an IFC File and returns the ids of the Exchange Objects. Parameters: - file_path: file_path + file_path: The path to the IFC file. Returns: - List[int] + The ids of the exchange objects. """ def set_storey_height(building: str, storey: str, height: float) -> None: - """set storey height + """Set storey height. Parameters: - building: building - storey: storey - height: height + building: The name of the building. + storey: The name of the storey. + height: The height of the storey. Examples: >>> import bim_controller as bc @@ -174,101 +161,92 @@ def set_storey_height(building: str, storey: str, height: float) -> None: >>> storey_name = "Ground Floor" >>> height_millimeters = 3_500 >>> bc.set_storey_height(building_name, storey_name, height_millimeters) - - Returns: - None """ -def convert_exchange_objects(exchange_objects: List[int]) -> List[int]: - """converts a list of Exchange Objects to Cadwork Elements +def convert_exchange_objects(exchange_objects: List[ElementId]) -> List[ElementId]: + """Converts a list of Exchange Objects to Cadwork Elements. Parameters: - exchange_objects: exchange_objects + exchange_objects: A list of Exchange Object id to convert. Returns: - List[int] + The list of Cadwork Element ids. """ -def export_ifc2x3_silently(element_i_ds: List[int], file_path: str) -> bool: - """export ifc2x3 silently +def export_ifc2x3_silently(element_id_list: List[ElementId], file_path: str) -> bool: + """Export IFC2x3 silently. Parameters: - element_i_ds: element_i_ds - file_path: file_path + element_id_list: The list of element ids. + file_path: The path where the IFC file will be exported. Returns: - bool + True if the export was successful, false otherwise. """ -def export_ifc4_silently(element_i_ds: List[int], file_path: str) -> bool: - """export ifc4 silently +def export_ifc4_silently(element_id_list: List[ElementId], file_path: str) -> bool: + """Exports IFC4 silently. Parameters: - element_i_ds: element_i_ds - file_path: file_path + element_id_list: The list of element ids. + file_path: The path where the IFC file will be exported. Returns: - bool + True if the export was successful, false otherwise. """ -def export_ifc2x3_silently_with_options(element_i_ds: List[int], file_path: str, options: ifc_options) -> bool: - """export ifc2x3 silently with options +def export_ifc2x3_silently_with_options(element_id_list: List[ElementId], file_path: str, options: ifc_options) -> bool: + """Exports IFC2x3 silently with options. Parameters: - element_i_ds: element_i_ds - file_path: file_path - options: options + element_id_list: The list of element ids. + file_path: The path where the IFC file will be exported. + options: The export options. Returns: - bool + True if the export was successful, false otherwise. """ -def export_ifc4_silently_with_options(element_i_ds: List[int], file_path: str, options: ifc_options) -> bool: - """export ifc4 silently with options +def export_ifc4_silently_with_options(element_id_list: List[ElementId], file_path: str, options: ifc_options) -> bool: + """Exports IFC4 silently with options. Parameters: - element_i_ds: element_i_ds - file_path: file_path - options: options + element_id_list: The list of element ids. + file_path: The path where the IFC file will be exported. + options: The export options. Returns: - bool + True if the export was successful, false otherwise. """ -def update_bmt_structure_created_elements(element_i_ds: List[int]) -> None: +def update_bmt_structure_created_elements(element_id_list: List[ElementId]) -> None: """This function takes the specified elements and inserts them into the BMT structure and adds them to the active building and storey. Parameters: - element_i_ds: element_i_ds - - Returns: - None + element_id_list: The list of element ids to be updated in the BMT structure. """ -def update_bmt_structure_building_storey(element_i_ds: List[int]) -> None: +def update_bmt_structure_building_storey(element_id_list: List[ElementId]) -> None: """This function takes the specified elements and inserts them into the BMT structure and adds them to the assigned Building and Storey. Parameters: - element_i_ds: element_i_ds - - Returns: - None + element_id_list: The list of element ids to be updated in the BMT structure. """ def get_ifc_options() -> ifc_options: - """Get the IfcOptions with the settings used in the document + """Get the IfcOptions with the settings used in the document. Returns: - ifc_options + The IfcOptions object containing the current settings. """ -def set_building_and_storey(element_id_list: List[int], building: str, storey: str) -> None: - """set building and storey +def set_building_and_storey(element_id_list: List[ElementId], building: str, storey: str) -> None: + """Set building and storey. Parameters: - element_id_list: element_id_list - building: building - storey: storey + element_id_list: The list of element ids. + building: The building name. + storey: The storey name. Examples: >>> import element_controller as ec @@ -278,119 +256,116 @@ def set_building_and_storey(element_id_list: List[int], building: str, storey: s >>> building_name = "Building A" >>> storey_name = "Ground Floor" >>> bc.set_building_and_storey(selected_elements, building_name, storey_name) - - Returns: - None """ -def get_building(element: int) -> str: - """get building +def get_building(element_id: ElementId) -> str: + """Get building name for a given element. Parameters: - element: element + element_id: The element id. Returns: - str + The name of the building. """ -def get_storey(element: int) -> str: - """get storey +def get_storey(element_id: ElementId) -> str: + """Get storey name for a given element. Parameters: - element: element + element_id: The element id. Returns: - str + The name of the storey. """ def get_storey_height(building: str, storey: str) -> float: - """get storey height + """Get storey height for a given building and storey. Parameters: - building: building - storey: storey + building: The building name. + storey: The storey name. Returns: - float + The height of the storey. """ def get_ifc2x3_element_type_string(entity_type: ifc_2x3_element_type) -> str: - """get ifc2x3 element type string + """Get IFC2x3 element type string. Parameters: - entity_type: entity_type + entity_type: The entity type. Returns: - str + The string representation of the IFC2x3 element type. """ def get_ifc2x3_element_type_display_string(entity_type: ifc_2x3_element_type) -> str: - """get ifc2x3 element type display string + """Get IFC2x3 element type display string. Parameters: - entity_type: entity_type + entity_type: The entity type. Returns: - str + The display string representation of the IFC2x3 element type. """ def get_all_buildings() -> List[str]: - """get all buildings + """Get all buildings. Returns: - List[str] + A list of all building. """ def get_all_storeys(building: str) -> List[str]: - """get all storeys + """Get all storeys. Parameters: - building: building + building: The building name. Returns: - List[str] + A list of all storeys in the building. """ -def get_element_id_from_base64_ifc_guid(base_64_ifc_guid: str) -> int: - """get element id from base64 ifc guid +def get_element_id_from_base64_ifc_guid(base_64_ifc_guid: str) -> ElementId: + """Get element id from base64 ifc guid. Parameters: - base_64_ifc_guid: base_64_ifc_guid + base_64_ifc_guid: The base64 IFC GUID. Returns: - int + The element id corresponding to the base64 IFC GUID. """ -def get_ifc_base64_guid(element_id: int) -> str: - """Get IFC base64 Guid from element ID +def get_ifc_base64_guid(element_id: ElementId) -> str: + """Get IFC base64 Guid from element id. Parameters: - element_id: element_id + element_id: The element id. Returns: The IFC GUID in base64 string format ("28kif20KPEuBjk2m1N3ep$"). """ -def get_ifc_predefined_type(element_id: int) -> 'ifc_predefined_type': +def get_ifc_predefined_type(element_id: ElementId) -> 'ifc_predefined_type': """Get the IfcPredefinedType of an element. Parameters: - element_id: element_id + element_id: The element id. Returns: - IfcPredefinedType Wrapper + The IfcPredefinedType of the element. """ -def set_ifc_predefined_type(element_i_ds: List[int], predefined_type: ifc_predefined_type) -> None: - """Set a predefined type to elements. Attention, if you change the PredefinedType of the elements, you are responsible for ensuring that valid types are set +def set_ifc_predefined_type(element_id_list: List[ElementId], predefined_type: ifc_predefined_type) -> None: + """Set a predefined type to elements. Attention, if you change the PredefinedType of the elements, you are responsible for ensuring that valid types are set. Parameters: - element_i_ds: element_i_ds - predefined_type: predefined_type + element_id_list: The list of element ids. + predefined_type: The predefined type to set. Examples: >>> import element_controller as ec @@ -401,7 +376,4 @@ def set_ifc_predefined_type(element_i_ds: List[int], predefined_type: ifc_predef >>> predefined_type = cadwork.ifc_predefined_type() >>> predefined_type.set_member() >>> bc.set_ifc_predefined_type(selected_elements, predefined_type) - - Returns: - None """ diff --git a/src/cadwork/api_types.pyi b/src/cadwork/api_types.pyi new file mode 100644 index 0000000..7e1d19d --- /dev/null +++ b/src/cadwork/api_types.pyi @@ -0,0 +1,22 @@ +from typing import Annotated + +UnsignedInt = Annotated[int, "Must be >= 0"] +"""""" +MaterialId = Annotated[int, "Must be >= 0"] +"""""" +ColorId = Annotated[int, "Must be >= 0"] +"""""" +EndtypeId = Annotated[int, "Must be >= 0"] +"""""" +AxisId = Annotated[int, "Must be >= 0"] +"""""" +MenuIndex = Annotated[int, "Normal int"] +"""""" +ReferenceSide = Annotated[int, "Must be >= 0"] +"""""" +MultiLayerSetId = Annotated[int, "Must be >= 0"] +"""""" +UserAttributeId = Annotated[int, "Must be >= 0"] +"""""" +ElementId = Annotated[int, "Must be >= 0"] +"""""" \ No newline at end of file diff --git a/src/cadwork/attribute_display_settings.pyi b/src/cadwork/attribute_display_settings.pyi index 86a2fc7..0491826 100644 --- a/src/cadwork/attribute_display_settings.pyi +++ b/src/cadwork/attribute_display_settings.pyi @@ -1,4 +1,5 @@ class attribute_display_settings: + """attribute display settings""" def get_text_position_percentage(self) -> int: """get text position percentage diff --git a/src/cadwork/vba_catalog_item_type.pyi b/src/cadwork/vba_catalog_item_type.pyi new file mode 100644 index 0000000..7728235 --- /dev/null +++ b/src/cadwork/vba_catalog_item_type.pyi @@ -0,0 +1,50 @@ +from enum import IntEnum, unique + + +@unique +class vba_catalog_item_type(IntEnum): + """ Enumeration for vba item types. + + Examples: + >>> cadwork.vba_catalog_item_type.nut + nut + """ + null = 0 + """""" + nut = 1 + """""" + washer = 2 + """""" + wpecial_ring = 3 + """""" + square_washer = 4 + """""" + wooden_plug = 5 + """""" + bolt_with_head = 10001 + """""" + bolt_without_head = 10002 + """""" + lag_bolt = 10003 + """""" + bolt_peg = 10004 + """""" + normal_screw = 10005 + """""" + wooden_dowl = 10006 + """""" + bolt_anchor = 10007 + """""" + bolt_with_mushroom_head = 10008 + """""" + bolt_with_conical_head = 10009 + """""" + bolt_with_head_and_washer = 10010 + """""" + hanger_bolt = 10011 + """""" + connection_screw = 10012 + """""" + + def __int__(self) -> int: + return self.value diff --git a/src/connector_axis_controller/__init__.pyi b/src/connector_axis_controller/__init__.pyi index 0695469..9208955 100644 --- a/src/connector_axis_controller/__init__.pyi +++ b/src/connector_axis_controller/__init__.pyi @@ -1,242 +1,202 @@ from typing import List from cadwork.point_3d import point_3d +from cadwork.api_types import * +from cadwork.vba_catalog_item_type import vba_catalog_item_type - -def get_last_error(error_code: int) -> str: - """get last error - - Parameters: - error_code: error_code - - Returns: - str - """ - - -def create_standard_connector(axis_name: str, point1: point_3d, point2: point_3d) -> int: +def create_standard_connector(axis_name: str, point1: point_3d, point2: point_3d) -> ElementId: """Creates a standard connector axis between two points. Parameters: - axis_name: axis_name - point1: point1 - point2: point2 + axis_name: Name of the standard connector axis. + point1: The first point defining the connector axis. + point2: The second point defining the connector axis. Returns: - int + The element id of the created standard connector axis. """ -def set_bolt_length(axis_id: int, length: float) -> None: - """Sets the Bolt Length +def set_bolt_length(axis_id: ElementId, length: float) -> None: + """Sets the Bolt Length. Parameters: - axis_id: axis_id - length: length - - Returns: - None + axis_id: The id of the axis. + length: The bolt length. """ -def set_bolt_length_automatic(axis_id: int, length_automatic: bool) -> None: - """Sets the Bolt Length Automatic +def set_bolt_length_automatic(axis_id: ElementId, length_automatic: bool) -> None: + """Sets the Bolt Length Automatic. Parameters: - axis_id: axis_id - length_automatic: length_automatic - - Returns: - None + axis_id: The id of the axis. + length_automatic: True if the bolt length should be automatic, false otherwise. """ -def set_diameter(axis_id: int, diameter: float) -> None: - """Sets the Drilling Diameter for all Sections +def set_diameter(axis_id: ElementId, diameter: float) -> None: + """Sets the Drilling Diameter for all Sections. Parameters: - axis_id: axis_id - diameter: diameter - - Returns: - None + axis_id: The id of the axis. + diameter: The drilling diameter to set for all sections. """ -def set_section_diameter(axis_id: int, section_nr: int, diameter: float) -> None: - """Sets the Drilling Diameter for a specific Sections +def set_section_diameter(axis_id: ElementId, section_index: UnsignedInt, diameter: float) -> None: + """Sets the Drilling Diameter for a specific Sections. Parameters: - axis_id: axis_id - section_nr: section_nr - diameter: diameter - - Returns: - None + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) + diameter: The drilling diameter to set for the specific section. """ -def check_axis(axis_id: int) -> bool: +def check_axis(axis_id: ElementId) -> bool: """Returns if the axis is valid. Parameters: - axis_id: axis_id + axis_id: The id of the axis. Returns: - bool + True if the axis is valid, false otherwise. """ def clear_errors() -> None: - """clear errors - - Returns: - None + """Clear all errors. """ -def update_axis_cutting_ability(axis_i_ds: List[int]) -> None: - """updates the Connection Config (CuttingAbility) of Axis/VBAs +def update_axis_cutting_ability(axis_id_list: List[ElementId]) -> None: + """Updates the Connection Config (CuttingAbility) of Axis/VBAs. Parameters: - axis_i_ds: axis_i_ds - - Returns: - None + axis_id_list: The axis id list. """ -def set_bolt_item(axis_id: int, item_guid: str) -> None: - """Sets the Bolt Item +def set_bolt_item(axis_id: ElementId, item_guid: str) -> None: + """Sets the Bolt Item. Parameters: - axis_id: axis_id - item_guid: item_guid - - Returns: - None + axis_id: The id of the axis. + item_guid: The bolt item guid to set. """ -def create_blank_connector(diameter: float, start_point: point_3d, end_point: point_3d) -> int: - """create blank connector +def create_blank_connector(diameter: float, start_point: point_3d, end_point: point_3d) -> ElementId: + """Creates a blank connector between two points. Parameters: - diameter: diameter - start_point: start_point - end_point: end_point + diameter: The diameter of the connector. + start_point: The start point of the connector. + end_point: The end point of the connector. Returns: - int + The element id of the created blank connector. """ def import_from_file(file_path: str) -> None: - """import from file + """Import from file. Parameters: - file_path: file_path - - Returns: - None + file_path: The path to the file to import. """ def start_configuration_dialog() -> None: """Starts the ConnectorAxis configuration dialog. - - Returns: - None """ -def get_item_guid_by_name(name: str, item_type: int) -> str: - """get item guid by name +def get_item_guid_by_name(name: str, item_type: vba_catalog_item_type) -> str: + """Get item guid by name. Parameters: - name: name - item_type: item_type + name: The name of the item. + item_type: The type of the item. Returns: - str + The guid of the item. """ -def get_bolt_length(axis_id: int) -> float: - """Gets the Bolt Length +def get_bolt_length(axis_id: ElementId) -> float: + """Gets the Bolt Length. Parameters: - axis_id: axis_id + axis_id: The id of the axis. Returns: - float + The bolt length. """ -def get_bolt_over_length(axis_id: int) -> float: - """Gets the Bolt OverLength +def get_bolt_over_length(axis_id: ElementId) -> float: + """Gets the Bolt OverLength. Parameters: - axis_id: axis_id + axis_id: The id of the axis. Returns: - float + The bolt over length. """ -def set_bolt_over_length(axis_id: int, over_length: float) -> None: - """Sets the Bolt OverLength +def set_bolt_over_length(axis_id: ElementId, over_length: float) -> None: + """Sets the Bolt OverLength. Parameters: - axis_id: axis_id - over_length: over_length - - Returns: - None + axis_id: The id of the axis. + over_length: The bolt over length. """ -def get_bolt_length_automatic(axis_id: int) -> bool: - """Returns if Bolt Length Automatic is set +def get_bolt_length_automatic(axis_id: ElementId) -> bool: + """Returns if Bolt Length Automatic is set. Parameters: - axis_id: axis_id + axis_id: The id of the axis. Returns: - bool + True if the bolt length is automatic, false otherwise. """ -def get_bolt_item_guid(axis_id: int) -> str: - """Gets the Guid of the Bolt Item +def get_bolt_item_guid(axis_id: ElementId) -> str: + """Gets the Guid of the Bolt Item. Parameters: - axis_id: axis_id + axis_id: The id of the axis. Returns: - str + The guid of the bolt item. """ -def get_section_diameter(axis_id: int, section_nr: int) -> float: - """Gets the Drilling Diameter of a specific Sections +def get_section_diameter(axis_id: ElementId, section_index: UnsignedInt) -> float: + """Gets the Drilling Diameter of a specific Sections. Parameters: - axis_id: axis_id - section_nr: section_nr + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) Returns: - float + The drilling diameter of the specified section. """ -def get_axis_items_guids(axis_id: int) -> List[str]: +def get_axis_items_guids(axis_id: ElementId) -> List[str]: """Returns a list of GUIDs of all axis items. Parameters: - axis_id: axis_id + axis_id: The id of the axis. Returns: - List[str] + The list of GUIDs of all axis items. """ @@ -244,10 +204,10 @@ def get_axis_item_name(guid: str) -> str: """Returns the name of an axis item. Parameters: - guid: guid + guid: The guid of the axis item. Returns: - str + The name of the axis item. """ @@ -255,10 +215,10 @@ def get_axis_item_material(guid: str) -> str: """Returns the material of an axis item. Parameters: - guid: guid + guid: The guid of the axis item. Returns: - str + The material of the axis item. """ @@ -266,10 +226,10 @@ def get_axis_item_norm(guid: str) -> str: """Returns the norm of an axis item. Parameters: - guid: guid + guid: The guid of the axis item. Returns: - str + The norm of the axis item. """ @@ -277,22 +237,22 @@ def get_axis_item_strength_category(guid: str) -> str: """Returns the strength category of an axis item. Parameters: - guid: guid + guid: The guid of the axis item. Returns: - str + The strength category of the axis item. """ -def get_axis_item_user_field(guid: str, user_item_nr: int) -> str: +def get_axis_item_user_field(guid: str, user_item_number: int) -> str: """Returns an userfield value of an axis item. Parameters: - guid: guid - user_item_nr: user_item_nr + guid: The guid of the axis item. + user_item_number: The user item number. Returns: - str + The user field value. """ @@ -300,305 +260,285 @@ def get_axis_item_order_number(guid: str) -> str: """Returns the strength category of an axis item. Parameters: - guid: guid + guid: The guid of the axis item. Returns: - str + The strength category of the axis item. """ -def get_bolt_order_number(axis_id: int) -> str: +def get_bolt_order_number(axis_id: ElementId) -> str: """Returns the ordernumber of a bolt item. Parameters: - axis_id: axis_id + axis_id: The id of the axis. Returns: - str + The order number of the bolt item. """ -def get_section_count(axis_id: int) -> int: +def get_section_count(axis_id: ElementId) -> int: """Returns the number of sections. Parameters: - axis_id: axis_id + axis_id: The id of the axis. Returns: - int + The number of sections of the axis. """ -def get_section_material_name(axis_id: int, section_nr: int) -> str: +def get_section_material_name(axis_id: ElementId, section_index: UnsignedInt) -> str: """Returns material of a section contact element. Parameters: - axis_id: axis_id - section_nr: section_nr + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) Returns: - str + The material of the section contact element. """ -def get_section_contact_element(axis_id: float, section_nr: int) -> int: - """get section contact element +def get_section_contact_element(axis_id: float, section_index: UnsignedInt) -> ElementId: + """Gets the section contact element. Parameters: - axis_id: axis_id - section_nr: section_nr + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) Returns: - int + The element id of the section contact element. """ -def get_bolt_diameter(axis_id: int) -> float: - """get bolt diameter +def get_bolt_diameter(axis_id: ElementId) -> float: + """Gets the bolt diameter. Parameters: - axis_id: axis_id + axis_id: The id of the axis. Returns: - float + The bolt diameter. """ - def get_standard_connector_list() -> List[str]: """Returns a list of all standard connectors. Returns: - List[str] + The list of standard connector names. """ -def get_counterbore_diameter_for_start_side(axis_id: int, section_index: int, diameter: float, depth: float, - is_conical: bool) -> float: - """get counterbore diameter for start side +def get_counterbore_diameter_for_start_side(axis_id: ElementId, section_index: UnsignedInt) -> float: + """Gets the counterbore diameter for the start side. Parameters: - axis_id: axis_id - section_index: section_index - diameter: diameter - depth: depth - is_conical: is_conical + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) + diameter: [UNUSED PARAMETER] + depth: [UNUSED PARAMETER] + is_conical: [UNUSED PARAMETER] Returns: - float + The counterbore diameter for the start side. """ -def get_counterbore_diameter_for_end_side(axis_id: int, section_index: int) -> float: +def get_counterbore_diameter_for_end_side(axis_id: ElementId, section_index: UnsignedInt) -> float: """Gets the counterbore diameter for the end side of a section. Parameters: - axis_id: The ID of the axis. + axis_id: The id of the axis. section_index: The index of the section. Returns: - float: The counterbore diameter for the end side. + The counterbore diameter for the end side. """ -def get_counterbore_depth_for_start_side(axis_id: int, section_index: int) -> float: - """get counterbore depth for start side +def get_counterbore_depth_for_start_side(axis_id: ElementId, section_index: UnsignedInt) -> float: + """Gets the counterbore depth for the start side. Parameters: - axis_id: The ID of the axis. + axis_id: The id of the axis. section_index: The index of the section. Returns: - float + The counterbore depth for the start side. """ -def get_counterbore_depth_for_end_side(axis_id: int, section_index: int) -> float: - """get counterbore depth for end side +def get_counterbore_depth_for_end_side(axis_id: ElementId, section_index: UnsignedInt) -> float: + """Gets the counterbore depth for the end side. Parameters: - axis_id: The ID of the axis. - section_index: The index of the section + axis_id: The id of the axis. + section_index: The index of the section. Returns: - float + The counterbore depth for the end side. """ - -def get_counterbore_is_conical_for_start_side(axis_id: int, section_index: int) -> bool: - """get counterbore is conical for start side +def get_counterbore_is_conical_for_start_side(axis_id: ElementId, section_index: UnsignedInt) -> bool: + """Get if counterbore is conical for start side. Parameters: - axis_id: The ID of the axis. + axis_id: The id of the axis. section_index: The index of the section Returns: - bool + True if the counterbore is conical for the start side, false otherwise. """ -def get_counterbore_is_conical_for_end_side(axis_id: int, section_index: int) -> bool: - """get counterbore is conical for end side +def get_counterbore_is_conical_for_end_side(axis_id: ElementId, section_index: UnsignedInt) -> bool: + """Get if counterbore is conical for end side. Parameters: - axis_id: The ID of the axis. - section_index: The index of the section + axis_id: The id of the axis. + section_index: The index of the section. Returns: - bool - """ + True if the counterbore is conical for the end side, false otherwise. + """ -def set_counterbore_for_start_side(axis_id: int, section_index: int, diameter: float, depth: float, +def set_counterbore_for_start_side(axis_id: ElementId, section_index: UnsignedInt, diameter: float, depth: float, is_conical: bool) -> None: - """set counterbore for start side + """Sets the counterbore for the start side. Parameters: - axis_id: axis_id - section_index: section_index - diameter: diameter - depth: depth - is_conical: is_conical - - Returns: - None + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) + diameter: The diameter of the counterbore. + depth: The depth of the counterbore. + is_conical: True if the counterbore is conical, false otherwise. """ -def set_counterbore_for_end_side(axis_id: int, section_index: int, diameter: float, depth: float, +def set_counterbore_for_end_side(axis_id: ElementId, section_index: UnsignedInt, diameter: float, depth: float, is_conical: bool) -> None: - """set counterbore for end side + """Sets the counterbore for the end side. Parameters: - axis_id: axis_id - section_index: section_index - diameter: diameter - depth: depth - is_conical: is_conical - - Returns: - None + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) + diameter: The diameter of the counterbore. + depth: The depth of the counterbore. + is_conical: True if the counterbore is conical, false otherwise. """ -def get_intersection_count(intersection_index: int) -> int: - """get intersection count +def get_intersection_count(intersection_index: UnsignedInt) -> int: + """Get the intersection count. Parameters: - intersection_index: intersection_index + intersection_index: The index of the intersection. (0-based index) Returns: - int + The intersection count. """ - -def get_item_guids_at_intersection(axis_id: int, intersection_index: int) -> List[str]: - """get item guids at intersection +def get_item_guids_at_intersection(axis_id: ElementId, intersection_index: UnsignedInt) -> List[str]: + """Get item GUIDs at intersection. Parameters: - axis_id: axis_id - intersection_index: intersection_index + axis_id: The id of the axis. + intersection_index: The index of the intersection. (0-based index) Returns: - List[str] + The list of item GUIDs at the intersection. """ -def set_item_guids_at_intersection(axis_id: int, intersection_index: int, item_guids: List[str]) -> None: - """set item guids at intersection +def set_item_guids_at_intersection(axis_id: ElementId, intersection_index: UnsignedInt, item_guids: List[str]) -> None: + """Sets item GUIDs at intersection. Parameters: - axis_id: axis_id - intersection_index: intersection_index - item_guids: item_guids - - Returns: - None + axis_id: The id of the axis. + intersection_index: The index of the intersection. (0-based index) + item_guids: The item GUIDs to set. """ - -def get_section_length(axis_id: int, section_index: int) -> float: - """get section length +def get_section_length(axis_id: ElementId, section_index: UnsignedInt) -> float: + """Get section length. Parameters: - axis_id: axis_id - section_index: section_index + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) Returns: - float + The length of the section. """ -def get_section_oblong_drilling_is_enabled(axis_id: int, section_index: int) -> bool: - """get section oblong drilling is enabled +def get_section_oblong_drilling_is_enabled(axis_id: ElementId, section_index: UnsignedInt) -> bool: + """Get if the section oblong drilling is enabled. Parameters: - axis_id: axis_id - section_index: section_index + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) Returns: - bool + True if the section oblong drilling is enabled, false otherwise. """ -def get_section_oblong_drilling_positive_value(axis_id: int, section_index: int) -> float: - """get section oblong drilling positive value +def get_section_oblong_drilling_positive_value(axis_id: ElementId, section_index: UnsignedInt) -> float: + """Get section oblong drilling positive value. Parameters: - axis_id: axis_id - section_index: section_index + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) Returns: - float + The positive value of the section oblong drilling. """ -def get_section_oblong_drilling_negative_value(axis_id: int, section_index: int) -> float: - """get section oblong drilling negative value +def get_section_oblong_drilling_negative_value(axis_id: ElementId, section_index: UnsignedInt) -> float: + """Get the section oblong drilling negative value Parameters: - axis_id: axis_id - section_index: section_index + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) Returns: - float + The negative value of the section oblong drilling. """ -def get_section_oblong_drilling_angle(axis_id: int, section_index: int) -> float: - """get section oblong drilling angle +def get_section_oblong_drilling_angle(axis_id: ElementId, section_index: UnsignedInt) -> float: + """Get section oblong drilling angle. Parameters: - axis_id: axis_id - section_index: section_index + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) Returns: - float + The angle of the section oblong drilling. """ -def set_section_oblong_drilling_is_disabled(axis_id: int, section_index: int) -> None: - """set section oblong drilling is disabled +def set_section_oblong_drilling_is_disabled(axis_id: ElementId, section_index: UnsignedInt) -> None: + """Disable the section oblong drilling. Parameters: - axis_id: axis_id - section_index: section_index - - Returns: - None + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) """ -def set_section_oblong_drilling_is_enabled(axis_id: int, section_index: int, positive_value: float, +def set_section_oblong_drilling_is_enabled(axis_id: ElementId, section_index: UnsignedInt, positive_value: float, negative_value: float, angle: float) -> None: - """set section oblong drilling is enabled + """Enable the section oblong drilling with parameters. Parameters: - axis_id: axis_id - section_index: section_index - positive_value: positive_value - negative_value: negative_value - angle: angle - - Returns: - None + axis_id: The id of the axis. + section_index: The index of the section. (0-based index) + positive_value: The positive value of the section oblong drilling. + negative_value: The negative value of the section oblong drilling. + angle: The angle of the section oblong drilling. """ diff --git a/src/dimension_controller/__init__.pyi b/src/dimension_controller/__init__.pyi index cfe689d..03e7bf1 100644 --- a/src/dimension_controller/__init__.pyi +++ b/src/dimension_controller/__init__.pyi @@ -1,241 +1,209 @@ from typing import List -from cadwork import point_3d +from cadwork.point_3d import point_3d from cadwork.dimension_base_format import dimension_base_format +from cadwork.api_types import * -def create_dimension(xl: point_3d, plane_normal: point_3d, distance: point_3d, dimension_points: List[point_3d]) -> int: - """creates a dimension element +def create_dimension(xl: point_3d, plane_normal: point_3d, distance: point_3d, dimension_points: List[point_3d]) -> ElementId: + """Creates a dimension element. Parameters: - xl: xl - plane_normal: plane_normal - distance: distance - dimension_points: dimension_points + xl: The x direction of the dimension. + plane_normal: The normal vector of the dimension plane. + distance: The distance vector from the anchor point to the dimension reference point. + dimension_points: A list of dimension points. Returns: - elementID of created dimension element + The element id of the created dimension element. """ -def set_orientation(elements: List[int], view_dir: point_3d, view_dir_up: point_3d) -> None: - """sets the orientation of a dimension element +def set_orientation(element_id_list: List[ElementId], view_dir: point_3d, view_dir_up: point_3d) -> None: + """Sets the orientation of dimension elements. Parameters: - elements: elements - view_dir: view_dir - view_dir_up: view_dir_up - - Returns: - None + element_id_list: The element id list. + view_dir: The view direction vector. + view_dir_up: The view direction up vector. """ -def add_segment(element: int, segment: point_3d) -> None: - """adds a segment to a dimension element +def add_segment(element_id: ElementId, segment: point_3d) -> None: + """Adds a segment to a dimension element. Parameters: - element: element - segment: segment - - Returns: - None + element_id: The element id. + segment: The segment to add. """ -def set_precision(elements: List[int], precision: int) -> None: - """sets the precision/decimal places of a dimension element +def set_precision(element_id_list: List[ElementId], precision: UnsignedInt) -> None: + """Sets the precision/decimal places of a dimension element. Parameters: - elements: elements - precision: precision - - Returns: - None + element_id_list: The element id list. + precision: The precision/decimal places to set. """ -def set_text_size(elements: List[int], text_size: float) -> None: - """sets the text size a dimension element +def set_text_size(element_id_list: List[ElementId], text_size: float) -> None: + """Sets the text size of a dimension element. Parameters: - elements: elements - text_size: text_size - - Returns: - None + element_id_list: The element id list. + text_size: The text size to set. """ -def set_line_thickness(elements: List[int], thickness: float) -> None: - """sets the line thickness a dimension element +def set_line_thickness(element_id_list: List[ElementId], thickness: float) -> None: + """Sets the line thickness of a dimension element. Parameters: - elements: elements - thickness: thickness - - Returns: - None + element_id_list: The element id list. + thickness: The line thickness to set. """ -def set_total_dimension(elements: List[int], total: bool) -> None: - """sets if the total dimension is shown in a dimension element +def set_total_dimension(element_id_list: List[ElementId], total: bool) -> None: + """Set whether the visualisation of the overall dimension is set for a dimension element. Parameters: - elements: elements - total: total - - Returns: - None + element_id_list: The element id list. + total: True if the visualisation is set, false otherwise. """ -def set_text_color(elements: List[int], color_id: int) -> None: - """sets the text color a dimension element +def set_text_color(element_id_list: List[ElementId], color_id: ColorId) -> None: + """Sets the text color of a dimension element. Parameters: - elements: elements - color_id: color_id - - Returns: - None + element_id_list: The element id list. + color_id: The color id to set. """ -def set_line_color(elements: List[int], color_id: int) -> None: - """sets the line color a dimension element +def set_line_color(element_id_list: List[ElementId], color_id: ColorId) -> None: + """Sets the line color of a dimension element. Parameters: - elements: elements - color_id: color_id - - Returns: - None - """ + element_id_list: The element id list. + color_id: The color id to set. + """ -def set_default_anchor_length(elements: List[int], length: float) -> None: - """sets the default anchor length a dimension element +def set_default_anchor_length(element_id_list: List[ElementId], length: float) -> None: + """Sets the default anchor length of a dimension element. Parameters: - elements: elements - length: length - - Returns: - None + element_id_list: The element id list. + length: The default anchor length to set. """ -def set_distance(elements: List[int], distance: point_3d) -> None: - """sets the distance vector between the points and the line +def set_distance(element_id_list: List[ElementId], distance: point_3d) -> None: + """Sets the distance vector between the points and the line. Parameters: - elements: elements - distance: distance - - Returns: - None + element_id_list: The element id list. + distance: The distance vector to set. """ -def shift_distance_and_texts(elements: List[int], shifted: bool) -> None: - """sets if distance and texts are shifted +def shift_distance_and_texts(element_id_list: List[ElementId], shifted: bool) -> None: + """Sets if distance and texts are shifted. Parameters: - elements: elements - shifted: shifted - - Returns: - None + element_id_list: The element id list. + shifted: True if distance and texts are shifted, false otherwise. """ -def get_dimension_points(element: int) -> List[point_3d]: - """gets all dimension points ordered by dimension direction +def get_dimension_points(element_id: ElementId) -> List[point_3d]: + """Gets all dimension points ordered by dimension direction. Parameters: - element: element + element_id: The element id. Returns: - ICwAPI3DVertexList + A list of dimension points. """ -def get_default_anchor_length(element: int) -> float: - """gets the default anchor length +def get_default_anchor_length(element_id: ElementId) -> float: + """Gets the default anchor length. Parameters: - element: element + element_id: The element id. Returns: - double + The default anchor length. """ -def get_distance(element: int) -> point_3d: +def get_distance(element_id: ElementId) -> point_3d: """Get the distance to the dimension reference point. The point is in the plane of the dimensioning. Parameters: - element: element + element_id: The element id. Returns: - point_3d + The distance vector. """ -def get_plane_normal(element: int) -> point_3d: - """Get the plane normal +def get_plane_normal(element_id: ElementId) -> point_3d: + """Get the plane normal. Parameters: - element: element + element_id: The element id. Returns: - normal + The plane normal vector. """ -def get_plane_xl(element: int) -> point_3d: - """Get the plane x direction +def get_plane_xl(element_id: ElementId) -> point_3d: + """Get the plane x direction. Parameters: - element: element + element_id: The element id. Returns: - x direction + The plane x direction vector. """ -def get_segment_count(element: int) -> int: - """Get count of segments +def get_segment_count(element_id: ElementId) -> int: + """Get count of segments. Parameters: - element: element + element_id: The element id. Returns: - segment count + The number of segments. """ -def get_segment_distance(element: int, segment_index: int) -> float: - """Get the distance from the anchor point to the dimension segment +def get_segment_distance(element_id: ElementId, segment_index: int) -> float: + """Get the distance from the anchor point to the dimension segment. Parameters: - element: element - segment_index: segment_index + element_id: The element id. + segment_index: The segment index. Returns: - distance + The distance from the anchor point to the dimension segment. """ -def get_segment_direction(element: int, segment_index: int) -> point_3d: - """get segment direction +def get_segment_direction(element_id: ElementId, segment_index: int) -> point_3d: + """Get the normalized direction from the anchor point to the point on the dimension. Parameters: - element: element - segment_index: segment_index + element_id: The element id. + segment_index: The segment index. Returns: - point_3d + The segment direction vector. """ -def get_total_dimension(element: int) ->bool: - """get total dimension +def get_total_dimension(element_id: ElementId) -> bool: + """Query whether the visualisation of the overall dimension is set for a dimension element. Parameters: - element: element + element_id: The element id. Returns: - bool + True if the visualisation is set, false otherwise. For elements that are not of type dimension, the return value is per default false. """ -def get_dimension_base_format(element: int) -> dimension_base_format: - """get dimension base format +def get_dimension_base_format(element_id: ElementId) -> dimension_base_format: + """Get the dimension base format. Parameters: - element: element + element_id: The element id. Returns: - dimension_base_format + The format used for the dimension. Enum value `None` may indicate that something went wrong while retrieving the value due to e.g. the element not being a valid dimension. """ diff --git a/src/element_controller/__init__.pyi b/src/element_controller/__init__.pyi index ebe9c3a..f0f59bc 100644 --- a/src/element_controller/__init__.pyi +++ b/src/element_controller/__init__.pyi @@ -3,6 +3,7 @@ from cadwork.edge_list import edge_list from cadwork.element_module_properties import element_module_properties from cadwork.facet_list import facet_list from cadwork.point_3d import point_3d +from cadwork.standard_element_type import standard_element_type from cadwork.text_object_options import text_object_options from cadwork.coordinate_system_data import coordinate_system_data from cadwork.element_map_query import element_map_query @@ -12,53 +13,44 @@ from cadwork.vertex_list import vertex_list from cadwork.shoulder_options import shoulder_options from cadwork.heel_shoulder_options import heel_shoulder_options from cadwork.double_shoulder_options import double_shoulder_options +from cadwork.api_types import * - -def delete_elements(element_id_list: List[int]) -> None: - """delete elements +def delete_elements(element_id_list: List[ElementId]) -> None: + """Deletes the specified elements. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ -def join_elements(element_id_list: List[int]) -> None: - """join elements - +def join_elements(element_id_list: List[ElementId]) -> None: + """Joins the specified elements together. + Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ -def join_top_level_elements(element_id_list: List[int]) -> None: - """join top level elements +def join_top_level_elements(element_id_list: List[ElementId]) -> None: + """Joins the specified top-level elements together. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ -def create_rectangular_beam_points(width: float, height: float, p1: point_3d, p2: point_3d, p3: point_3d) -> int: - """create rectangular beam points +def create_rectangular_beam_points(width: float, height: float, first_point: point_3d, second_point: point_3d, third_point: point_3d) -> ElementId: + """Creates a rectangular beam using points. Parameters: - width: width - height: height - p1: p1 - p2: p2 - p3: p3 + width: The width of the beam. + height: The height of the beam. + first_point: The first point. + second_point: The second point. + third_point: The third point. Examples: >>> beam_width = 200. >>> beam_height = 400. >>> beam_axis_start_pt = cadwork.point_3d(300., 0., 0.) - >>> beam_axis_end_pt = cadwork.point_3d(300., 0., 4000.) + >>> beam_axis_end_pt = cadwork.point_3d(300., 0., 4000.) >>> length_vector = (beam_axis_end_pt - beam_axis_start_pt).normalized() >>> beam_axis_y = cadwork.point_3d(1., 0., 0.) >>> beam_axis_z = length_vector.cross(beam_axis_y).normalized() @@ -66,17 +58,17 @@ def create_rectangular_beam_points(width: float, height: float, p1: point_3d, p2 >>> beam_id = ec.create_rectangular_beam_points(beam_width, beam_height, beam_axis_start_pt, beam_axis_end_pt, beam_height_axis_pt ) Returns: - int + The ID of the created rectangular beam. """ -def create_circular_beam_points(diameter: float, p1: point_3d, p2: point_3d, p3: point_3d) -> int: - """create circular beam points +def create_circular_beam_points(diameter: float, first_point: point_3d, second_point: point_3d, third_point: point_3d) -> ElementId: + """Creates a circular beam using points. Parameters: - diameter: diameter - p1: p1 - p2: p2 - p3: p3 + diameter: The diameter of the beam. + first_point: The first point. + second_point: The second point. + third_point: The third point. Examples: >>> beam_diameter = 120. @@ -89,17 +81,17 @@ def create_circular_beam_points(diameter: float, p1: point_3d, p2: point_3d, p3: >>> beam_id = ec.create_circular_beam_points(beam_diameter, beam_axis_start_pt, beam_axis_end_pt, beam_orientation_pt) Returns: - int + The ID of the created circular beam. """ -def create_square_beam_points(width: float, p1: point_3d, p2: point_3d, p3: point_3d) -> int: - """create square beam points +def create_square_beam_points(width: float, first_point: point_3d, second_point: point_3d, third_point: point_3d) -> ElementId: + """Creates a square beam using points. Parameters: - width: width - p1: p1 - p2: p2 - p3: p3 + width: The width of the beam. + first_point: The first point. + second_point: The second point. + third_point: The third point. Examples: >>> beam_width = 100. @@ -112,19 +104,19 @@ def create_square_beam_points(width: float, p1: point_3d, p2: point_3d, p3: poin >>> beam_id = ec.create_square_beam_points(beam_width, beam_axis_start_pt, beam_axis_end_pt, orientation_pt) Returns: - int + The ID of the created square beam. """ -def create_rectangular_beam_vectors(width: float, height: float, length: float, p1: point_3d, xl: point_3d, zl: point_3d) -> int: - """create rectangular beam vectors +def create_rectangular_beam_vectors(width: float, height: float, length: float, starting_point: point_3d, x_local_direction: point_3d, z_local_direction: point_3d) -> ElementId: + """Creates a rectangular beam using vectors. Parameters: - width: width - height: height - length: length - p1: p1 - xl: xl - zl: zl + width: The width of the beam. + height: The height of the beam. + length: The length of the beam. + starting_point: The starting point. + x_local_direction: The direction of the X-axis. + z_local_direction: The direction of the Z-axis. Examples: >>> beam_width = 150. @@ -136,18 +128,18 @@ def create_rectangular_beam_vectors(width: float, height: float, length: float, >>> beam_id = ec.create_rectangular_beam_vectors(beam_width, beam_height, beam_length, origin_point, x_direction, z_direction) Returns: - int + The ID of the created rectangular beam. """ -def create_circular_beam_vectors(diameter: float, length: float, p1: point_3d, xl: point_3d, zl: point_3d) -> int: - """create circular beam vectors +def create_circular_beam_vectors(diameter: float, length: float, starting_point: point_3d, x_local_direction: point_3d, z_local_direction: point_3d) -> ElementId: + """Creates a circular beam using vectors. Parameters: - diameter: diameter - length: length - p1: p1 - xl: xl - zl: zl + diameter: The diameter of the beam. + length: The length of the beam. + starting_point: The starting point of the beam. + x_local_direction: The local X direction vector. + z_local_direction: The local Z direction vector. Examples: >>> beam_diameter = 100. @@ -158,18 +150,18 @@ def create_circular_beam_vectors(diameter: float, length: float, p1: point_3d, x >>> beam_id = ec.create_circular_beam_vectors(beam_diameter, beam_length, origin_point, x_direction, z_direction) Returns: - int + The ID of the created circular beam. """ -def create_square_beam_vectors(width: float, length: float, p1: point_3d, xl: point_3d, zl: point_3d) -> int: - """create square beam vectors +def create_square_beam_vectors(width: float, length: float, starting_point: point_3d, x_local_direction: point_3d, z_local_direction: point_3d) -> ElementId: + """Creates a square beam using vectors. Parameters: - width: width - length: length - p1: p1 - xl: xl - zl: zl + width: The width of the beam. + length: The length of the beam. + starting_point: The starting point of the beam. + x_local_direction: The local X direction vector. + z_local_direction: The local Z direction vector. Examples: >>> beam_width = 120. @@ -180,18 +172,18 @@ def create_square_beam_vectors(width: float, length: float, p1: point_3d, xl: po >>> beam_id = ec.create_square_beam_vectors(beam_width, beam_length, origin_point, x_direction, z_direction) Returns: - int + The ID of the created square beam. """ -def create_rectangular_panel_points(width: float, thickness: float, p1: point_3d, p2: point_3d, p3: point_3d) -> int: - """create rectangular panel points +def create_rectangular_panel_points(width: float, thickness: float, first_point: point_3d, second_point: point_3d, third_point: point_3d) -> ElementId: + """Create a rectangular panel using points. Parameters: - width: width - thickness: thickness - p1: p1 - p2: p2 - p3: p3 + width: The width of the panel. + thickness: The thickness of the panel. + first_point: The first corner point of the panel. + second_point: The second corner point of the panel. + third_point: The third corner point of the panel. Examples: >>> panel_width = 1200. @@ -204,19 +196,19 @@ def create_rectangular_panel_points(width: float, thickness: float, p1: point_3d >>> panel_id = ec.create_rectangular_panel_points(panel_width, panel_thickness, panel_corner_pt, panel_length_pt, orientation_pt) Returns: - int + The ID of the created rectangular panel. """ -def create_rectangular_panel_vectors(width: float, thickness: float, length: float, p1: point_3d, xl: point_3d, zl: point_3d) -> int: - """create rectangular panel vectors +def create_rectangular_panel_vectors(width: float, thickness: float, length: float, starting_point: point_3d, x_local_direction: point_3d, z_local_direction: point_3d) -> ElementId: + """Create a rectangular panel using vectors. Parameters: - width: width - thickness: thickness - length: length - p1: p1 - xl: xl - zl: zl + width: The width of the panel. + thickness: The thickness of the panel. + length: The length of the panel. + starting_point: The starting point of the panel. + x_local_direction: The local X direction vector. + z_local_direction: The local Z direction vector. Examples: >>> panel_width = 1000. @@ -228,16 +220,16 @@ def create_rectangular_panel_vectors(width: float, thickness: float, length: flo >>> panel_id = ec.create_rectangular_panel_vectors(panel_width, panel_thickness, panel_length, origin_point, x_direction, z_direction) Returns: - int + The ID of the created rectangular panel. """ -def create_drilling_points(diameter: float, p1: point_3d, p2: point_3d) -> int: - """create drilling points +def create_drilling_points(diameter: float, first_point: point_3d, second_point: point_3d) -> ElementId: + """Creates drilling using points. Parameters: - diameter: diameter - p1: p1 - p2: p2 + diameter: The diameter of the drilling. + first_point: The starting point of the drilling. + second_point: The ending point of the drilling. Examples: >>> drill_diameter = 30. @@ -246,17 +238,17 @@ def create_drilling_points(diameter: float, p1: point_3d, p2: point_3d) -> int: >>> drilling_id = ec.create_drilling_points(drill_diameter, drill_start_pt, drill_end_pt) Returns: - int + The ID of the created drilling. """ -def create_drilling_vectors(diameter: float, length: float, p1: point_3d, xl: point_3d) -> int: - """create drilling vectors +def create_drilling_vectors(diameter: float, length: float, starting_point: point_3d, drilling_direction: point_3d) -> ElementId: + """Creates drilling using vectors. Parameters: - diameter: diameter - length: length - p1: p1 - xl: xl + diameter: The diameter of the drilling. + length: The length of the drilling. + starting_point: The starting point of the drilling. + drilling_direction: The direction of the drilling. Examples: >>> drill_diameter = 12. @@ -266,15 +258,15 @@ def create_drilling_vectors(diameter: float, length: float, p1: point_3d, xl: po >>> drilling_id = ec.create_drilling_vectors(drill_diameter, drill_length, drill_start_pt, drill_direction) Returns: - int + The ID of the created drilling. """ -def create_line_points(p1: point_3d, p2: point_3d) -> int: - """create line points +def create_line_points(first_point: point_3d, second_point: point_3d) -> ElementId: + """Creates a line using points. Parameters: - p1: p1 - p2: p2 + first_point: The first point of the line. + second_point: The second point of the line. Examples: >>> line_start_pt = cadwork.point_3d(0., 0., 0.) @@ -282,16 +274,16 @@ def create_line_points(p1: point_3d, p2: point_3d) -> int: >>> line_id = ec.create_line_points(line_start_pt, line_end_pt) Returns: - int + The ID of the created line. """ -def create_line_vectors(length: float, p1: point_3d, xl: point_3d) -> int: - """create line vectors +def create_line_vectors(length: float, starting_point: point_3d, line_direction: point_3d) -> ElementId: + """Creates a line using vectors. Parameters: - length: length - p1: p1 - xl: xl + length: The length of the line. + starting_point: The starting point of the line. + line_direction: The direction of the line. Examples: >>> line_length = 1000. @@ -300,93 +292,78 @@ def create_line_vectors(length: float, p1: point_3d, xl: point_3d) -> int: >>> line_id = ec.create_line_vectors(line_length, line_start_pt, line_direction) Returns: - int + The ID of the created line. """ -def create_node(p1: point_3d) -> int: - """create node +def create_node(node_position: point_3d) -> ElementId: + """Creates a node. Parameters: - p1: p1 + node_position: The position of the node. Examples: >>> node_position = cadwork.point_3d(250., 250., 100.) >>> node_id = ec.create_node(node_position) Returns: - int + The ID of the created node. """ -def solder_elements(element_id_list: List[int]) -> List[int]: - """solder elements +def solder_elements(element_id_list: List[ElementId]) -> List[ElementId]: + """Solders elements together. Parameters: - element_id_list: element_id_list + element_id_list: The element id list. Returns: - List[int] + The list of soldered element IDs. """ -def convert_beam_to_panel(element_id_list: List[int]) -> None: - """convert beam to panel +def convert_beam_to_panel(element_id_list: List[ElementId]) -> None: + """Converts beams to panels. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ -def convert_panel_to_beam(element_id_list: List[int]) -> None: - """convert panel to beam +def convert_panel_to_beam(element_id_list: List[ElementId]) -> None: + """Converts panels to beams. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ -def delete_all_element_end_types(element_id_list: List[int]) -> None: - """delete all element end types +def delete_all_element_end_types(element_id_list: List[ElementId]) -> None: + """Deletes all end types of the elements. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ -def delete_all_element_processes(element_id_list: List[int]) -> None: - """delete all element processes +def delete_all_element_processes(element_id_list: List[ElementId]) -> None: + """Deletes all processes of the elements. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ -def move_element(element_id_list: List[int], vector: point_3d) -> None: - """move element +def move_element(element_id_list: List[ElementId], move_vector: point_3d) -> None: + """Moves the provided element by a specified vector. Parameters: - element_id_list: element_id_list - vector: vector - - Returns: - None + element_id_list: The element id list. + move_vector: The vector by which to move the elements. """ -def create_polygon_beam(polygon_vertices: vertex_list, thickness: float, xl: point_3d, zl: point_3d) -> int: - """create polygon beam +def create_polygon_beam(polygon_vertices: vertex_list, thickness: float, x_local_direction: point_3d, z_local_direction: point_3d) -> ElementId: + """Creates a polygon beam. Parameters: - polygon_vertices: polygon_vertices - thickness: thickness - xl: xl - zl: zl + polygon_vertices: The vertices of the polygon. + thickness: The thickness of the beam. + x_local_direction: The x local direction of the beam. + z_local_direction: The z local direction of the beam. Examples: >>> # Create a triangular beam @@ -400,18 +377,18 @@ def create_polygon_beam(polygon_vertices: vertex_list, thickness: float, xl: poi >>> polygon_beam_id = ec.create_polygon_beam(vertices, beam_thickness, extrusion_vector, z_vector) Returns: - int + The ID of the created polygon beam. """ -def create_text_object(text: str, position: point_3d, xl: point_3d, zl: point_3d, size: float) -> int: - """create text object +def create_text_object(text: str, position: point_3d, x_local_direction: point_3d, z_local_direction: point_3d, size: float) -> ElementId: + """Creates a text object. Parameters: - text: text - position: position - xl: xl - zl: zl - size: size + text: The text content. + position: The position of the text. + x_local_direction: The x local direction of the text. + z_local_direction: The z local direction of the text. + size: The size of the text. Examples: >>> text_content = "Cadwork API" @@ -422,172 +399,142 @@ def create_text_object(text: str, position: point_3d, xl: point_3d, zl: point_3d >>> text_id = ec.create_text_object(text_content, text_position, x_direction, z_direction, text_height) Returns: - int + The ID of the created text object. """ -def copy_elements(element_id_list: List[int], copy_vector: point_3d) -> List[int]: - """copy elements +def copy_elements(element_id_list: List[ElementId], copy_vector: point_3d) -> List[int]: + """Copy a list of elements. Parameters: - element_id_list: element_id_list - copy_vector: copy_vector + element_id_list: The element id list. + copy_vector: The vector by which to copy the elements. Returns: - List[int] + The IDs of the copied elements. """ -def rotate_elements(element_id_list: List[int], origin: point_3d, rotation_axis: point_3d, rotation_angle: float) -> None: - """rotate elements +def rotate_elements(element_id_list: List[ElementId], origin: point_3d, rotation_axis: point_3d, rotation_angle: float) -> None: + """Rotate the provided elements around a specified axis. Parameters: - element_id_list: element_id_list - origin: origin - rotation_axis: rotation_axis - rotation_angle: rotation_angle - - Returns: - None + element_id_list: The element id list. + origin: The origin point of the rotation. + rotation_axis: The axis around which to rotate the elements. + rotation_angle: The angle by which to rotate the elements un degree. """ -def subtract_elements(hard_elements: List[int], soft_elements: List[int]) -> List[int]: - """subtract elements +def subtract_elements(hard_elements: List[ElementId], soft_elements: List[ElementId]) -> List[ElementId]: + """Subtracts a list of "soft" elements from a list of "hard" elements. Parameters: - hard_elements: hard_elements - soft_elements: soft_elements + hard_elements: The list of "hard" elements. + soft_elements: The list of "soft" elements. Returns: - List[int] + The list of resulting elements. """ -def check_element_id(element_id: int) -> bool: - """check element id +def check_element_id(element_id: ElementId) -> bool: + """Check if the provided element ID exists. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element ID exists, false otherwise. """ -def start_element_module_calculation(covers: List[int]) -> None: - """start element module calculation +def start_element_module_calculation(covers: List[ElementId]) -> None: + """Starts the calculation of the element module for a list of covers. Parameters: - covers: covers - - Returns: - None + covers: The list of cover element IDs. """ def set_element_detail_path(path: str) -> None: - """set element detail path + """Sets the detail path for the element. Parameters: - path: path - - Returns: - None + path: The detail path. """ -def get_element_from_cadwork_guid(cadwork_guid: str) -> int: - """get element from cadwork guid +def get_element_from_cadwork_guid(cadwork_guid: str) -> ElementId: + """Gets element from cadwork guid. Parameters: - cadwork_guid: cadwork_guid + cadwork_guid: The cadwork guid. Returns: - int + The element ID. """ -def add_elements_to_undo(elements: List[int], cmd: int) -> None: - """add elements to undo +def add_elements_to_undo(element_id_list: List[ElementId], cmd: int) -> None: + """Add elements to the undo stack. Parameters: - elements: elements - cmd: cmd - - Returns: - None + element_id_list: The elements to add. + cmd: The command associated with the undo. """ def make_undo() -> None: - """make undo - - Returns: - None + """Performs an undo operation, reverting the last change made. """ def make_redo() -> None: - """make redo - - Returns: - None + """Performs a redo operation, reapplying the last undone change. """ -def split_elements(elements: List[int]) -> None: - """split elements +def split_elements(element_id_list: List[ElementId]) -> None: + """Splits elements. Parameters: - elements: elements - - Returns: - None + element_id_list: The elements to split. """ -def set_line_to_marking_line(elements: List[int]) -> None: - """set line to marking line +def set_line_to_marking_line(element_id_list: List[ElementId]) -> None: + """Sets the line to the marking line. Parameters: - elements: elements - - Returns: - None + element_id_list: The elements to modify. """ -def set_line_to_normal_line(elements: List[int]) -> None: - """set line to normal line +def set_line_to_normal_line(element_id_list: List[ElementId]) -> None: + """Sets the line to the normal line. Parameters: - elements: elements - - Returns: - None + element_id_list: The elements to modify. """ -def create_auto_export_solid_from_standard(elements: List[int], output_name: str, standard_element_name: str) -> int: - """create auto export solid from standard +def create_auto_export_solid_from_standard(element_id_list: List[ElementId], output_name: str, standard_element_name: str) -> ElementId: + """Creates an auto export solid from a standard element. Parameters: - elements: elements - output_name: output_name - standard_element_name: standard_element_name + element_id_list: The elements to use. + output_name: The output name. + standard_element_name: The standard element name. Returns: - int + The element ID of the created solid. """ -def set_element_module_properties_for_elements(elements: List[int], properties: None) -> None: - """set element module properties for elements +def set_element_module_properties_for_elements(element_id_list: List[ElementId], properties: element_module_properties) -> None: + """Sets the element module properties for elements. Parameters: - elements: elements - properties: properties - - Returns: - None + element_id_list: The elements to modify. + properties: The properties to set. """ -def create_text_object_with_font(text: str, position: point_3d, xl: point_3d, zl: point_3d, size: float, font_name: str) -> int: - """create text object with font +def create_text_object_with_font(text: str, position: point_3d, x_local_direction: point_3d, z_local_direction: point_3d, size: float, font_name: str) -> ElementId: + """Creates a text object with a specific font. Parameters: - text: text - position: position - xl: xl - zl: zl - size: size - font_name: font_name + text: The text to be displayed in the text object. + position: The position of the text object. + x_local_direction: The X-axis direction of the text object. + z_local_direction: The Z-axis direction of the text object. + size: The size of the text object. + font_name: The font name. Examples: >>> text_content = "Custom Text" @@ -599,128 +546,104 @@ def create_text_object_with_font(text: str, position: point_3d, xl: point_3d, zl >>> text_id = ec.create_text_object_with_font(text_content, text_position, x_direction, z_direction, text_height, font) Returns: - int + The element ID of the created text object. """ -def apply_transformation_coordinate(elements: List[int], old_point: point_3d, old_xl: point_3d, old_yl: point_3d, new_point: point_3d, new_xl: point_3d, new_yl: point_3d) -> None: - """apply transformation coordinate +def apply_transformation_coordinate(element_id_list: List[ElementId], old_point: point_3d, old_x_local_direction: point_3d, old_y_local_direction: point_3d, new_point: point_3d, new_x_local_direction: point_3d, new_y_local_direction: point_3d) -> None: + """Apply transformation coordinate to elements. Parameters: - elements: elements - old_point: old_point - old_xl: old_xl - old_yl: old_yl - new_point: new_point - new_xl: new_xl - new_yl: new_yl - - Returns: - None + element_id_list: The elements to modify. + old_point: The old point. + old_x_local_direction: The old X local direction. + old_y_local_direction: The old Y local direction. + new_point: The new point. + new_x_local_direction: The new X local direction. + new_y_local_direction: The new Y local direction. """ -def delete_elements_with_undo(elements: List[int]) -> None: - """delete elements with undo +def delete_elements_with_undo(element_id_list: List[ElementId]) -> None: + """Deletes the provided elements with undo functionality. Parameters: - elements: elements - - Returns: - None + element_id_list: The elements to delete. """ -def add_created_elements_to_undo(elements: List[int]) -> None: - """add created elements to undo +def add_created_elements_to_undo(element_id_list: List[ElementId]) -> None: + """Adds created elements to the undo stack. Parameters: - elements: elements - - Returns: - None + element_id_list: The elements to add. """ -def add_modified_elements_to_undo(elements: List[int]) -> None: - """add modified elements to undo +def add_modified_elements_to_undo(element_id_list: List[ElementId]) -> None: + """Adds modified elements to the undo stack. Parameters: - elements: elements - - Returns: - None + element_id_list: The elements to add. """ -def recreate_elements(elements: List[int]) -> None: - """recreate elements +def recreate_elements(element_id_list: List[ElementId]) -> None: + """Recreate elements based on the provided list. Parameters: - elements: elements - - Returns: - None + element_id_list: The elements to recreate. """ -def create_multi_wall(elements: List[int]) -> None: - """create multi wall +def create_multi_wall(element_id_list: List[ElementId]) -> None: + """Creates a multi-wall structure. Parameters: - elements: elements - - Returns: - None + element_id_list: The elements to use in the multi-wall structure. """ -def get_user_element_ids() -> List[int]: - """get user element ids +def get_user_element_ids() -> List[ElementId]: + """Gets a list of user element IDs. Returns: - List[int] + The user element IDs. """ -def get_user_element_ids_with_existing(elements: List[int]) -> List[int]: - """get user element ids with existing +def get_user_element_ids_with_existing(element_id_list: List[ElementId]) -> List[ElementId]: + """Retrieve a list of user element IDs that exist in the provided list. Parameters: - elements: elements + element_id_list: The elements to check for existence. Returns: - List[int] + The list of existing user element IDs. """ def clear_errors() -> None: - """clear errors - - Returns: - None + """Clears all errors. """ -def glide_elements(element_i_ds: List[int], glide_point: point_3d) -> None: - """glide elements +def glide_elements(element_id_list: List[ElementId], glide_point: point_3d) -> None: + """Glides elements to a specified point. Parameters: - element_i_ds: element_i_ds - glide_point: glide_point - - Returns: - None + element_id_list: The elements to glide. + glide_point: The glide destination point. """ -def cut_elements_with_miter(first_id: int, second_id: int) -> bool: - """cut elements with miter +def cut_elements_with_miter(first_id: ElementId, second_id: ElementId) -> bool: + """Cut two elements with a miter joint. Parameters: - first_id: first_id - second_id: second_id + first_id: The ID of the first element. + second_id: The ID of the second element. Returns: - bool + True if the cut operation was successful, false otherwise. """ -def cut_element_with_plane(element_id: int, cut_plane_normal_vector: point_3d, distance_from_global_origin: float) -> bool: - """cut element with plane +def cut_element_with_plane(element_id: ElementId, cut_plane_normal_vector: point_3d, distance_from_global_origin: float) -> bool: + """Cut an element with a plane. Parameters: - element_id: element_id - cut_plane_normal_vector: cut_plane_normal_vector - distance_from_global_origin: distance_from_global_origin + element_id: The element id. + cut_plane_normal_vector: The normal vector of the cut plane. + distance_from_global_origin: The distance from the global origin to the cut plane. Examples: >>> import math @@ -740,39 +663,39 @@ def cut_element_with_plane(element_id: int, cut_plane_normal_vector: point_3d, d >>> print(f"Cut operation successful: {result}") Returns: - bool + True if the cut operation was successful, false otherwise. """ -def create_circular_mep(diameter: float, points: List[point_3d]) -> int: - """create circular mep +def create_circular_mep(diameter: float, points: List[point_3d]) -> ElementId: + """Create a circular MEP (Mechanical, Electrical, and Plumbing) element. Parameters: - diameter: diameter - points: points + diameter: The diameter of the circular MEP. + points: The points defining the circular MEP. Returns: - int + The ID of the created circular MEP element. """ -def create_rectangular_mep(width: float, depth: float, points: List[point_3d]) -> int: - """create rectangular mep +def create_rectangular_mep(width: float, depth: float, points: List[point_3d]) -> ElementId: + """Create a rectangular MEP (Mechanical, Electrical, and Plumbing) element. Parameters: - width: width - depth: depth - points: points + width: The width of the rectangular MEP. + depth: The depth of the rectangular MEP. + points: The points defining the rectangular MEP. Returns: - int + The ID of the created rectangular MEP element. """ -def slice_element_with_plane(element_id: int, cut_plane_normal_vector: point_3d, distance_from_global_origin: float) -> bool: - """slice element with plane +def slice_element_with_plane(element_id: ElementId, cut_plane_normal_vector: point_3d, distance_from_global_origin: float) -> bool: + """Slice an element with a plane. Parameters: - element_id: element_id - cut_plane_normal_vector: cut_plane_normal_vector - distance_from_global_origin: distance_from_global_origin + element_id: The element id. + cut_plane_normal_vector: The normal vector of the cut plane. + distance_from_global_origin: The distance from the global origin to the slicing plane. Examples: >>> import math @@ -800,53 +723,53 @@ def slice_element_with_plane(element_id: int, cut_plane_normal_vector: point_3d, >>> # Note: slice_element_with_plane keeps both parts as a joined element Returns: - bool + True if the slicing operation was successful, false otherwise. """ -def create_auto_container_from_standard(elements: List[int], output_name: str, standard_element_name: str) -> int: - """create auto container from standard +def create_auto_container_from_standard(element_id_list: List[ElementId], output_name: str, standard_element_name: str) -> ElementId: + """Create an auto container from a standard element. Parameters: - elements: elements - output_name: output_name - standard_element_name: standard_element_name + element_id_list: The list of elements to be used in the auto container. + output_name: The name of the output. + standard_element_name: The name of the standard element. Returns: - int + The id of the created auto container element. """ -def create_auto_export_solid_from_standard_with_reference(elements: List[int], output_name: str, standard_element_name: str, reference_id: int) -> int: - """create auto export solid from standard with reference +def create_auto_export_solid_from_standard_with_reference(element_id_list: List[ElementId], output_name: str, standard_element_name: str, reference_id: ElementId) -> ElementId: + """Creates an auto export solid from a standard element with a reference. Parameters: - elements: elements - output_name: output_name - standard_element_name: standard_element_name - reference_id: reference_id + element_id_list: The list of elements to be used in the export solid. + output_name: The name of the output. + standard_element_name: The name of the standard element. + reference_id: The ID of the reference element. Returns: - int + The id of the created auto export solid element. """ -def create_auto_container_from_standard_with_reference(elements: List[int], output_name: str, standard_element_name: str, reference_id: int) -> int: - """create auto container from standard with reference +def create_auto_container_from_standard_with_reference(element_id_list: List[ElementId], output_name: str, standard_element_name: str, reference_id: ElementId) -> ElementId: + """Creates an auto container from a standard element with a reference. Parameters: - elements: elements - output_name: output_name - standard_element_name: standard_element_name - reference_id: reference_id + element_id_list: The list of elements to be used in the auto container. + output_name: The name of the output. + standard_element_name: The name of the standard element. + reference_id: The ID of the reference element. Returns: - int + The ID of the created auto container element. """ -def create_surface(surface_vertices: vertex_list) -> int: - """create surface +def create_surface(surface_vertices: vertex_list) -> ElementId: + """Creates a surface from a list of vertices. Parameters: - surface_vertices: surface_vertices + surface_vertices: The list of vertices defining the surface. Examples: >>> # Create a rectangular surface @@ -858,106 +781,85 @@ def create_surface(surface_vertices: vertex_list) -> int: >>> surface_id = ec.create_surface(vertices) Returns: - int + The ID of the created surface element. """ -def stretch_start_facet(elements: List[int], stretch_vector: point_3d) -> None: - """stretch start facet +def stretch_start_facet(element_id_list: List[ElementId], stretch_vector: point_3d) -> None: + """Stretch the start facet of the given elements. Parameters: - elements: elements - stretch_vector: a vector that defines the stretch direction and distance - - Returns: - None + element_id_list: The list of elements to be stretched. + stretch_vector: A vector that defines the stretch direction and distance. """ -def stretch_end_facet(elements: List[int], stretch_vector: point_3d) -> None: - """stretch end facet +def stretch_end_facet(element_id_list: List[ElementId], stretch_vector: point_3d) -> None: + """Stretch the end facet of the given elements. Parameters: - elements: elements - stretch_vector: a vector that defines the stretch direction and distance - - Returns: - None + element_id_list: The list of elements to be stretched. + stretch_vector: A vector that defines the stretch direction and distance. """ -def set_export_solid_contents(export_solid_id: int, element_i_ds: List[int]) -> None: - """set export solid contents +def set_export_solid_contents(export_solid_id: ElementId, element_id_list: List[ElementId]) -> None: + """Sets the contents of an export solid. Parameters: - export_solid_id: export_solid_id - element_i_ds: element_i_ds - - Returns: - None + export_solid_id: The ID of the export solid to set the contents for. + element_id_list: The list of element IDs to set as the contents of the export solid. """ -def set_container_contents(container_id: int, element_i_ds: List[int]) -> None: - """set container contents +def set_container_contents(container_id: ElementId, element_id_list: List[ElementId]) -> None: + """Sets the contents of a container. Parameters: - container_id: container_id - element_i_ds: element_i_ds - - Returns: - None + container_id: The ID of the container to set the contents for. + element_id_list: The list of element IDs to set as the contents of the container. """ -def set_parent_opening_variants_opening_angle(element_i_ds: List[int], angle: float) -> None: - """set parent opening variants opening angle +def set_parent_opening_variants_opening_angle(element_id_list: List[ElementId], angle: float) -> None: + """Sets the opening angle of the parent opening variants. Parameters: - element_i_ds: element_i_ds - angle: angle - - Returns: - None + element_id_list: The list of element IDs to set the opening angle for. + angle: The opening angle to set. """ -def mirror_move_elements(elements: List[int], plane: point_3d, plane_distance: float) -> None: - """mirror move elements +def mirror_move_elements(element_id_list: List[ElementId], plane: point_3d, plane_distance: float) -> None: + """Mirrors and moves elements across a plane. Parameters: - elements: elements - plane: plane - plane_distance: plane_distance - - Returns: - None + element_id_list: The list of element IDs to mirror and move. + plane: The plane to mirror across. + plane_distance: The distance from the plane. """ -def mirror_copy_elements(elements: List[int], plane: point_3d, plane_distance: float) -> List[int]: - """mirror copy elements +def mirror_copy_elements(element_id_list: List[ElementId], plane: point_3d, plane_distance: float) -> List[ElementId]: + """Copies elements by mirroring them across a plane. Parameters: - elements: elements - plane: plane - plane_distance: plane_distance + element_id_list: The ID of the element to copy. + plane: The plane to mirror across. + plane_distance: The distance from the plane. Returns: - List[int] + The list of IDs of the copied elements. """ -def reset_element_cadwork_guid(element_id: int) -> None: - """reset element cadwork guid +def reset_element_cadwork_guid(element_id: ElementId) -> None: + """Sets the Cadwork Guid of an element to NULL. Parameters: - element_id: element_id - - Returns: - None + element_id: The element id. """ -def create_standard_beam_points(standard_element_name: str, p1: point_3d, p2: point_3d, p3: point_3d) -> int: - """create standard beam points +def create_standard_beam_points(standard_element_name: str, first_point: point_3d, second_point: point_3d, third_point: point_3d) -> ElementId: + """Creates a standard beam using points. Parameters: - standard_element_name: standard_element_name - p1: p1 - p2: p2 - p3: p3 + standard_element_name: The name of the standard element. + first_point: The first point. + second_point: The second point. + third_point: The third point. Examples: >>> std_beam_name = "Standard-Timber-120x240" # Name as found in standard elements library @@ -971,18 +873,18 @@ def create_standard_beam_points(standard_element_name: str, p1: point_3d, p2: po >>> std_beam_id = ec.create_standard_beam_points(std_beam_name, beam_start_pt, beam_end_pt, orientation_pt) Returns: - int + The ID of the created standard beam. """ -def create_standard_beam_vectors(standard_element_name: str, length: float, p1: point_3d, xl: point_3d, zl: point_3d) -> int: - """create standard beam vectors +def create_standard_beam_vectors(standard_element_name: str, length: float, starting_point: point_3d, x_local_direction: point_3d, z_local_direction: point_3d) -> ElementId: + """Creates a standard beam using vectors. Parameters: - standard_element_name: standard_element_name - length: length - p1: p1 - xl: xl - zl: zl + standard_element_name: The name of the standard element. + length: The length of the beam. + starting_point: The starting point of the beam. + x_local_direction: The local X direction vector. + z_local_direction: The local Z direction vector. Examples: >>> std_beam_name = "Standard-Timber-100x100" # Name as found in standard elements library @@ -993,17 +895,17 @@ def create_standard_beam_vectors(standard_element_name: str, length: float, p1: >>> std_beam_id = ec.create_standard_beam_vectors(std_beam_name, beam_length, origin_point, x_direction, z_direction) Returns: - int + The ID of the created standard beam. """ -def create_standard_panel_points(standard_element_name: str, p1: point_3d, p2: point_3d, p3: point_3d) -> int: - """create standard panel points +def create_standard_panel_points(standard_element_name: str, first_point: point_3d, second_point: point_3d, third_point: point_3d) -> ElementId: + """Creates a standard panel using points. Parameters: - standard_element_name: standard_element_name - p1: p1 - p2: p2 - p3: p3 + standard_element_name: The name of the standard element. + first_point: The first point. + second_point: The second point. + third_point: The third point. Examples: >>> std_panel_name = "Standard-Panel-27mm" # Name as found in standard elements library @@ -1015,18 +917,18 @@ def create_standard_panel_points(standard_element_name: str, p1: point_3d, p2: p >>> std_panel_id = ec.create_standard_panel_points(std_panel_name, panel_corner_pt, panel_width_pt, orientation_pt) Returns: - int + The id of the created standard panel. """ -def create_standard_panel_vectors(standard_element_name: str, length: float, p1: point_3d, xl: point_3d, zl: point_3d) -> int: - """create standard panel vectors +def create_standard_panel_vectors(standard_element_name: str, length: float, starting_point: point_3d, x_local_direction: point_3d, z_local_direction: point_3d) -> ElementId: + """Creates a standard panel using vectors. Parameters: - standard_element_name: standard_element_name - length: length - p1: p1 - xl: xl - zl: zl + standard_element_name: The name of the standard element. + length: The length of the panel. + starting_point: The starting point of the panel. + x_local_direction: The local X direction vector. + z_local_direction: The local Z direction vector. Examples: >>> std_panel_name = "Standard-Panel-20mm" # Name as found in standard elements library @@ -1037,17 +939,17 @@ def create_standard_panel_vectors(standard_element_name: str, length: float, p1: >>> std_panel_id = ec.create_standard_panel_vectors(std_panel_name, panel_length, origin_point, x_direction, z_direction) Returns: - int + The id of the created standard panel. """ -def create_standard_steel_points(standard_element_name: str, p1: point_3d, p2: point_3d, p3: point_3d) -> int: - """create standard steel points +def create_standard_steel_points(standard_element_name: str, first_point: point_3d, second_point: point_3d, third_point: point_3d) -> ElementId: + """Creates a standard steel element using points. Parameters: - standard_element_name: standard_element_name - p1: p1 - p2: p2 - p3: p3 + standard_element_name: The name of the standard element. + first_point: The first point. + second_point: The second point. + third_point: The third point. Examples: >>> std_steel_name = "IPE 200" # Name of standard steel profile from library @@ -1061,18 +963,18 @@ def create_standard_steel_points(standard_element_name: str, p1: point_3d, p2: p >>> steel_id = ec.create_standard_steel_points(std_steel_name, steel_start_pt, steel_end_pt, orientation_pt) Returns: - int + The id of the created standard steel element. """ -def create_standard_steel_vectors(standard_element_name: str, length: float, p1: point_3d, xl: point_3d, zl: point_3d) -> int: - """create standard steel vectors +def create_standard_steel_vectors(standard_element_name: str, length: float, starting_point: point_3d, x_local_direction: point_3d, z_local_direction: point_3d) -> ElementId: + """Creates a standard steel element using vectors. Parameters: - standard_element_name: standard_element_name - length: length - p1: p1 - xl: xl - zl: zl + standard_element_name: The name of the standard element. + length: The length of the element. + starting_point: The starting point of the element. + x_local_direction: The local X direction vector. + z_local_direction: The local Z direction vector. Examples: >>> std_steel_name = "HEA 220" # Name of standard steel profile from library @@ -1083,26 +985,23 @@ def create_standard_steel_vectors(standard_element_name: str, length: float, p1: >>> steel_id = ec.create_standard_steel_vectors(std_steel_name, steel_length, origin_point, x_direction, z_direction) Returns: - int + The id of the created standard steel element. """ -def move_element_with_undo(element_id_list: List[int], vector: point_3d) -> None: - """move element with undo +def move_element_with_undo(element_id_list: List[ElementId], vector: point_3d) -> None: + """Moves an element with undo functionality. Parameters: - element_id_list: element_id_list - vector: vector - - Returns: - None + element_id_list: The element id list. + vector: The vector to move the element. """ -def create_normal_axis_points(p1: point_3d, p2: point_3d) -> int: - """create normal axis points +def create_normal_axis_points(first_point: point_3d, second_point: point_3d) -> ElementId: + """Creates a normal axis using points. Parameters: - p1: p1 - p2: p2 + first_point: The first point of the axis. + second_point: The second point of the axis. Examples: >>> axis_start_pt = cadwork.point_3d(0., 0., 0.) @@ -1110,16 +1009,16 @@ def create_normal_axis_points(p1: point_3d, p2: point_3d) -> int: >>> axis_id = ec.create_normal_axis_points(axis_start_pt, axis_end_pt) Returns: - int + The id of the created normal axis. """ -def create_normal_axis_vectors(length: float, p1: point_3d, xl: point_3d) -> int: - """create normal axis vectors +def create_normal_axis_vectors(length: float, starting_point: point_3d, axis_direction: point_3d) -> ElementId: + """Creates a normal axis using vectors. Parameters: - length: length - p1: p1 - xl: xl + length: The length of the axis. + starting_point: The starting point of the axis. + axis_direction: The direction vector of the axis. Examples: >>> axis_length = 1500. @@ -1128,262 +1027,223 @@ def create_normal_axis_vectors(length: float, p1: point_3d, xl: point_3d) -> int >>> axis_id = ec.create_normal_axis_vectors(axis_length, axis_start_pt, axis_direction) Returns: - int + The id of the created normal axis. """ -def convert_bolt_to_standardconnector(elements: List[int], standard_element_name: str) -> None: - """convert bolt to standardconnector +def convert_bolt_to_standardconnector(element_id_list: List[ElementId], standard_element_name: str) -> None: + """Converts bolts to standard connectors. Parameters: - elements: elements - standard_element_name: standard_element_name - - Returns: - None + element_id_list: The list of bolts to convert. + standard_element_name: The name of the standard element. """ -def extrude_surface_to_auxiliary_vector(surface: int, vector: point_3d) -> int: - """extrude surface to auxiliary vector +def extrude_surface_to_auxiliary_vector(surface: ElementId, vector: point_3d) -> ElementId: + """Extrudes a surface to create an auxiliary element. Parameters: - surface: surface - vector: vector + surface: The surface to extrude. + vector: The vector to extrude along. Returns: - int + The id of the created auxiliary element. """ -def extrude_surface_to_panel_vector(surface: int, vector: point_3d) -> int: - """extrude surface to panel vector +def extrude_surface_to_panel_vector(surface: ElementId, vector: point_3d) -> ElementId: + """Extrudes a surface to create a panel element. Parameters: - surface: surface - vector: vector + surface: The surface to extrude. + vector: The vector to extrude along. Returns: - int + The id of the created panel element. """ -def extrude_surface_to_beam_vector(surface: int, vector: point_3d) -> int: - """extrude surface to beam vector +def extrude_surface_to_beam_vector(surface: ElementId, vector: point_3d) -> ElementId: + """Extrudes a surface to create a beam element. Parameters: - surface: surface - vector: vector + surface: The surface to extrude. + vector: The vector to extrude along. Returns: - int + The id of the created beam element. """ -def convert_container_to_container_block(elements: List[int]) -> None: - """convert container to container block +def convert_container_to_container_block(element_id_list: List[ElementId]) -> None: + """Converts a container to a container block. Parameters: - elements: elements - - Returns: - None + element_id_list: The list of elements to convert. """ -def create_bounding_box_local(reference_element: int, elements: List[int]) -> int: - """create bounding box local +def create_bounding_box_local(reference_element: ElementId, element_id_list: List[ElementId]) -> ElementId: + """Creates a local bounding box for a list of elements relative to a reference element. Parameters: - reference_element: reference_element - elements: elements + reference_element: The ID of the reference element. + element_id_list: The list of elements for which to create the bounding box. Returns: - int + The ID of the created bounding box element. """ -def create_bounding_box_global(elements: List[int]) -> int: - """create bounding box global +def create_bounding_box_global(element_id_list: List[ElementId]) -> ElementId: + """Creates a global bounding box for a list of elements. Parameters: - elements: elements + element_id_list: The list of elements for which to create the bounding box. Returns: - int + The ID of the created bounding box element. """ -def convert_auxiliary_to_panel(elements: List[int]) -> None: - """convert auxiliary to panel +def convert_auxiliary_to_panel(element_id_list: List[ElementId]) -> None: + """Converts auxiliary elements to panel. Parameters: - elements: elements - - Returns: - None + element_id_list: The list of elements to convert. """ -def convert_auxiliary_to_beam(elements: List[int]) -> None: - """convert auxiliary to beam +def convert_auxiliary_to_beam(element_id_list: List[ElementId]) -> None: + """Converts auxiliary elements to beams. Parameters: - elements: elements - - Returns: - None + element_id_list: The list of elements to convert. """ -def auto_set_rough_volume_situation(elements: List[int]) -> None: - """auto set rough volume situation +def auto_set_rough_volume_situation(element_id_list: List[ElementId]) -> None: + """Automatically sets the rough volume situation for a list of elements. Parameters: - elements: elements - - Returns: - None + element_id_list: The list of elements to process. """ -def rough_volume_situation_manual(cover: int, add_partner: List[int], remove_partner: List[int]) -> None: - """rough volume situation manual +def rough_volume_situation_manual(cover: ElementId, add_partner: List[ElementId], remove_partner: List[ElementId]) -> None: + """Manually sets the rough volume situation for a cover element. Parameters: - cover: cover - add_partner: add_partner - remove_partner: remove_partner - - Returns: - None + cover: The cover element ID. + add_partner: The list of partner element IDs to add. + remove_partner: The list of partner element IDs to remove. """ -def auto_set_parts_situation(elements: List[int]) -> None: - """auto set parts situation +def auto_set_parts_situation(element_id_list: List[ElementId]) -> None: + """Automatically sets the parts situation for a list of elements. Parameters: - elements: elements - - Returns: - None + element_id_list: The list of elements to process. """ -def parts_situation_manual(cover: int, add_childs: List[int], remove_childs: List[int]) -> None: - """parts situation manual +def parts_situation_manual(cover: ElementId, add_childs: List[ElementId], remove_childs: List[ElementId]) -> None: + """Manually sets the parts situation for a cover element. Parameters: - cover: cover - add_childs: add_childs - remove_childs: remove_childs - - Returns: - None + cover: The cover element ID. + add_childs: The list of child element IDs to add. + remove_childs: The list of child element IDs to remove. """ -def activate_rv_without_situation() -> List[int]: - """activate rv without situation +def activate_rv_without_situation() -> List[ElementId]: + """Activates the rough volume situation for elements without a situation. Returns: - List[int] + The list of IDs of the elements for which the rough volume situation was activated. """ -def activate_parts_without_situation() -> List[int]: - """activate parts without situation +def activate_parts_without_situation() -> List[ElementId]: + """Activates the parts situation for elements without a situation. Returns: - List[int] + The list of IDs of the elements for which the parts situation was activated. """ -def add_elements_to_detail(elements: List[int], detail: int) -> None: - """add elements to detail +def add_elements_to_detail(element_id_list: List[ElementId], detail: int) -> None: + """Adds elements to a detail. Parameters: - elements: The list of elements to be added to the detail - detail: The ID of the detail - - Returns: - None + element_id_list: The list of elements to be added to the detail. + detail: The ID of the detail. """ -def subtract_elements_with_undo(hard_elements: List[int], soft_elements: List[int], with_undo: bool) -> List[int]: - """subtract elements with undo +def subtract_elements_with_undo(hard_element_id_list: List[ElementId], soft_element_id_list: List[ElementId], with_undo: bool) -> List[ElementId]: + """Subtracts a list of "soft" elements from a list of "hard" elements with undo functionality. Parameters: - hard_elements: hard_elements - soft_elements: soft_elements - with_undo: with_undo + hard_element_id_list: The list of "hard" elements. + soft_element_id_list: The list of "soft" elements. + with_undo: Indicate whether the operation should be added to the undo stack. Returns: - List[int] + The list of elements resulting from the subtraction. """ -def create_linear_optimization(elements: List[int], optimization_number: int, total_length: float, start_cut: float, end_cut: float, saw_kerf: float, is_production_list: bool) -> int: +def create_linear_optimization(element_id_list: List[ElementId], optimization_number: int, total_length: float, start_cut: float, end_cut: float, saw_kerf: float, is_production_list: bool) -> ElementId: """create linear optimization Parameters: - elements: elements - optimization_number: optimization_number - total_length: total_length - start_cut: start_cut - end_cut: end_cut - saw_kerf: saw_kerf - is_production_list: is_production_list + element_id_list: The list of elements to be optimized. + optimization_number: The optimization number, nested parent element id. + total_length: The total length for the optimization. + start_cut: The start cut for the optimization. + end_cut: The end cut for the optimization. + saw_kerf: The saw kerf for the optimization. + is_production_list: A flag indicating if this is a production list. Returns: - int + The ID of the created linear optimization element. """ -def start_element_module_calculation_silently(covers: List[int]) -> None: - """start element module calculation silently +def start_element_module_calculation_silently(covers: List[ElementId]) -> None: + """Starts the calculation of the element module for a list of covers silently (without user interaction). Parameters: - covers: covers - - Returns: - None + covers: The list of covers for which to start the element module calculation. """ -def replace_physical_drillings_with_drilling_axes(elements: List[int], mininum_diameter: float, maximum_diameter: float) -> List[int]: - """replace physical drillings with drilling axes +def replace_physical_drillings_with_drilling_axes(element_id_list: List[ElementId], mininum_diameter: float, maximum_diameter: float) -> List[ElementId]: + """Replaces physical drillings with drilling axes based on diameter range. Parameters: - elements: elements - mininum_diameter: mininum_diameter - maximum_diameter: maximum_diameter + element_id_list: The list of elements to process. + mininum_diameter: The minimum diameter of the drilling. + maximum_diameter: The maximum diameter of the drilling. Returns: - List[int] + The list of IDs of the elements where the replacement was successful. """ -def cut_element_with_processing_group(soft_element: int, processing: int) -> None: - """cut element with processing group +def cut_element_with_processing_group(soft_element: ElementId, processing: ElementId) -> None: + """Cuts an element with a processing group. Parameters: - soft_element: soft_element - processing: processing - - Returns: - None + soft_element: The ID of the element to be cut. + processing: The ID of the processing group. """ -def add_element_to_detail(elements: List[int], detail: int) -> None: - """add element to detail +def add_element_to_detail(element_id_list: List[ElementId], detail: int) -> None: + """Adds elements to a detail. Parameters: - elements: elements - detail: detail - - Returns: - None + element_id_list: The list of elements to be added to the detail. + detail: The ID of the detail. """ -def convert_elements_to_auxiliary_elements(elements: List[int]) -> None: - """convert elements to auxiliary elements +def convert_elements_to_auxiliary_elements(element_id_list: List[ElementId]) -> None: + """Converts elements to auxiliary elements. Parameters: - elements: elements - - Returns: - None + element_id_list: The list of elements to be converted. """ -def create_circular_axis_points(diameter: float, p1: point_3d, p2: point_3d) -> int: - """create circular axis points +def create_circular_axis_points(diameter: float, first_point: point_3d, second_point: point_3d) -> ElementId: + """Creates a circular axis using points. Parameters: - diameter: diameter - p1: p1 - p2: p2 + diameter: The diameter of the circular axis. + first_point: The first point defining the axis. + second_point: The second point defining the axis. Examples: >>> axis_diameter = 50. @@ -1392,17 +1252,17 @@ def create_circular_axis_points(diameter: float, p1: point_3d, p2: point_3d) -> >>> circular_axis_id = ec.create_circular_axis_points(axis_diameter, axis_start_pt, axis_end_pt) Returns: - int + The ID of the created circular axis element. """ -def create_circular_axis_vector(diameter: float, length: float, p1: point_3d, xl: point_3d) -> int: - """create circular axis vector +def create_circular_axis_vector(diameter: float, length: float, starting_point: point_3d, axis_direction: point_3d) -> ElementId: + """Creates a circular axis using a vector. Parameters: - diameter: diameter - length: length - p1: p1 - xl: xl + diameter: The diameter of the circular axis. + length: The length of the circular axis. + starting_point: The starting point. + axis_direction: The direction of the X-axis. Examples: >>> axis_diameter = 60. @@ -1412,18 +1272,18 @@ def create_circular_axis_vector(diameter: float, length: float, p1: point_3d, xl >>> circular_axis_id = ec.create_circular_axis_vector(axis_diameter, axis_length, axis_start_pt, axis_direction) Returns: - int + The ID of the created circular axis element. """ -def create_polygon_panel(polygon_vertices: vertex_list, thickness: float, xl: point_3d, zl: point_3d) -> int: - """create polygon panel +def create_polygon_panel(polygon_vertices: vertex_list, thickness: float, x_local_direction: point_3d, z_local_direction: point_3d) -> ElementId: + """Creates a polygon panel. Parameters: - polygon_vertices: polygon_vertices - thickness: thickness - xl: xl - zl: zl + polygon_vertices: The vertices of the polygon. + thickness: The thickness of the panel. + x_local_direction: The X-axis direction of the panel. + z_local_direction: The Z-axis direction of the panel. Examples: >>> # Create a hexagonal panel @@ -1441,592 +1301,556 @@ def create_polygon_panel(polygon_vertices: vertex_list, thickness: float, xl: po >>> polygon_panel_id = ec.create_polygon_panel(vertices, panel_thickness, extrusion_vector, z_vector) Returns: - int + The ID of the created polygon panel element. """ -def cut_elements_with_overmeasure(hard_elements: List[int], soft_elements: List[int]) -> None: - """cut elements with overmeasure +def cut_elements_with_overmeasure(hard_element_id_list: List[ElementId], soft_element_id_list: List[ElementId]) -> None: + """Cuts elements with overmeasure. Parameters: - hard_elements: hard_elements - soft_elements: soft_elements - - Returns: - None + hard_element_id_list: The list of hard elements. + soft_element_id_list: The list of soft elements. """ -def cut_log_corner_joint(settings_name: str, elements: List[int]) -> None: - """cut log corner joint +def cut_log_corner_joint(settings_name: str, element_id_list: List[ElementId]) -> None: + """Cuts log corner joint. Parameters: - settings_name: settings_name - elements: elements - - Returns: - None + settings_name: The name of the settings to be used for the cut. + element_id_list: The list of elements to be cut. """ -def get_edge_selection(elements: List[int]) -> edge_list: - """get edge selection +def get_edge_selection(element_id_list: List[ElementId]) -> edge_list: + """Retrieves the edge selection of the provided elements. Parameters: - elements: elements + element_id_list: The list of element IDs. Returns: - edge_list + The list of edges selected. """ -def get_facets_with_lasso(elements: List[int]) -> facet_list: - """get facets with lasso +def get_facets_with_lasso(element_id_list: List[ElementId]) -> facet_list: + """Retrieves the facets of elements within a lasso selection. Parameters: - elements: elements + element_id_list: The list of elements to check for facets within the lasso selection. Returns: - facet_list + The list of facets selected. """ -def create_standard_element_from_guid_points(guid: str, p1: point_3d, p2: point_3d, p3: point_3d) -> int: - """create standard element from guid points +def create_standard_element_from_guid_points(guid: str, first_point: point_3d, second_point: point_3d, third_point: point_3d) -> ElementId: + """Creates a standard element from GUID points. Parameters: - guid: guid - p1: p1 - p2: p2 - p3: p3 + guid: The GUID of the standard element. + first_point: The first point. + second_point: The second point. + third_point: The third point. Returns: - int + The id of the created standard element. """ -def create_standard_element_from_guid_vectors(guid: str, length: float, p1: point_3d, xl: point_3d, zl: point_3d) -> int: - """create standard element from guid vectors +def create_standard_element_from_guid_vectors(guid: str, length: float, starting_point: point_3d, x_local_direction: point_3d, z_local_direction: point_3d) -> ElementId: + """Creates a standard element from GUID vectors. Parameters: - guid: guid - length: length - p1: p1 - xl: xl - zl: zl + guid: The GUID of the standard element. + length: The length of the element. + starting_point: The starting point of the element. + x_local_direction: The X-axis direction vector. + z_local_direction: The Z-axis direction vector. Returns: - int + The ID of the created standard element. """ -def fillet_edge(element_id: int, edge_start: point_3d, edge_end: point_3d, radius: float) -> None: - """fillet edge +def fillet_edge(element_id: ElementId, edge_start: point_3d, edge_end: point_3d, radius: float) -> None: + """Fillet an edge of an element. Parameters: - element_id: element_id - edge_start: edge_start - edge_end: edge_end - radius: radius - - Returns: - None + element_id: The element id. + edge_start: The start point of the edge. + edge_end: The end point of the edge. + radius: The radius of the fillet. """ -def chamfer_edge(element_id: int, edge_start: point_3d, edge_end: point_3d, length: float) -> None: - """chamfer edge +def chamfer_edge(element_id: ElementId, edge_start: point_3d, edge_end: point_3d, length: float) -> None: + """Chamfers an edge of an element. Parameters: - element_id: element_id - edge_start: edge_start - edge_end: edge_end - length: length - - Returns: - None + element_id: The element id. + edge_start: The start point of the edge. + edge_end: The end point of the edge. + length: The length of the chamfer. """ -def convert_drilling_to_circular_beam(elements: List[int]) -> None: - """convert drilling to circular beam +def convert_drilling_to_circular_beam(element_id_list: List[ElementId]) -> None: + """Converts drilling to circular beam. Parameters: - elements: elements - - Returns: - None + element_id_list: The list of element IDs to convert. """ -def convert_lines_to_surfaces(elements: List[int]) -> List[int]: - """convert lines to surfaces +def convert_lines_to_surfaces(element_id_list: List[ElementId]) -> List[ElementId]: + """Converts lines to surfaces. Parameters: - elements: elements + element_id_list: The list of element IDs to convert. Returns: - List[int] + The list of element IDs that were converted. """ -def convert_surfaces_to_volume(elements: List[int]) -> int: - """convert surfaces to volume +def convert_surfaces_to_volume(element_id_list: List[ElementId]) -> ElementId: + """Converts surfaces to volume. Parameters: - elements: elements + element_id_list: The list of element IDs to convert. Returns: - int + The ID of the created volume element. """ -def cut_corner_lap(elements: List[int], depth: float, clearance_base: float, clearance_side: float, backcut: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cut corner lap +def cut_corner_lap(element_id_list: List[ElementId], depth: float, clearance_base: float, clearance_side: float, backcut: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: + """Cuts a corner-lap joint with specific parameters. Parameters: - elements: elements - depth: depth - clearance_base: clearance_base - clearance_side: clearance_side - backcut: backcut - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance - - Returns: - None + element_id_list: The list of elements to be cut. + depth: The vertical depth of the lap cut applied to each element. + clearance_base: Additional clearance applied at the bottom (base) of the lap cut for fitting tolerance. + clearance_side: Additional clearance on the side faces of the cut to prevent tight joints or interference. + backcut: A small offset or undercut applied to the outer face of the cut to improve fit or reduce friction. + drilling_count: The number of drill holes to create for fasteners (e.g., bolts or dowels). + drilling_diameter: The diameter of each drill hole. + drilling_tolerance: The tolerance applied to the hole size for bolt head clearance or easier insertion. """ -def cut_t_lap(elements: List[int], depth: float, clearance_base: float, clearance_side: float, backcut: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cut t lap +def cut_t_lap(element_id_list: List[ElementId], depth: float, clearance_base: float, clearance_side: float, backcut: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: + """Cuts a T-lap joint with specific parameters. Parameters: - elements: elements - depth: depth - clearance_base: clearance_base - clearance_side: clearance_side - backcut: backcut - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance - - Returns: - None + element_id_list: The list of elements to be cut. + depth: The vertical depth of the cut where the intersecting element will be placed. + clearance_base: Additional clearance at the base (bottom) of the cut to ensure a proper fit. + clearance_side: Additional clearance on the side faces of the cut to avoid tight fitting. + backcut: A small offset or undercut applied inward to improve fitting during assembly. + drilling_count: The number of drill holes to create for fasteners (e.g., bolts or dowels). + drilling_diameter: The diameter of each drill hole. + drilling_tolerance: The tolerance applied to the hole size for bolt head clearance or easier insertion. """ -def cut_cross_lap(elements: List[int], depth: float, clearance_base: float, clearance_side: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cut cross lap +def cut_cross_lap(element_id_list: List[ElementId], depth: float, clearance_base: float, clearance_side: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: + """Cuts a cross-lap joint with specific parameters. Parameters: - elements: elements - depth: depth - clearance_base: clearance_base - clearance_side: clearance_side - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance - - Returns: - None + element_id_list: The list of elements to be cut. + depth: The vertical depth of the cross-lap cut, typically half the thickness of the material. + clearance_base: Additional clearance at the bottom of the cut to ensure a proper fit between intersecting elements. + clearance_side: Additional clearance on the side walls of the cut to prevent tight fits or friction. + drilling_count: The number of drill holes to create for fasteners (e.g., bolts or dowels). + drilling_diameter: The diameter of each drill hole. + drilling_tolerance: The tolerance applied to the hole size for bolt head clearance or easier insertion. """ -def delete_processes_keep_cutting_bodies(elements: List[int], keep_cutting_elements_only: bool) -> List[int]: - """delete processes keep cutting bodies +def delete_processes_keep_cutting_bodies(element_id_list: List[ElementId], keep_cutting_elements_only: bool) -> List[ElementId]: + """Gets the cutting bodies of all processes (and deletes processes), like Ctrl+D Action Parameters: - elements: elements - keep_cutting_elements_only: keep_cutting_elements_only + element_id_list: The list of elements to be processed. + keep_cutting_elements_only: True if the return element id contains only cutting elements, false otherwise. Returns: - List[int] + The id list of all removed geometry, cuttings bodies. """ -def cut_double_tenon(elements: List[int], depth1: float, depth2: float, clearance: float, backcut: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cut double tenon +def cut_double_tenon(element_id_list: List[ElementId], depth1: float, depth2: float, clearance: float, backcut: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: + """Cut a double tenon joint with specific parameters. Parameters: - elements: elements - depth1: depth1 - depth2: depth2 - clearance: clearance - backcut: backcut - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance - - Returns: - None + element_id_list: The list of elements to be cut. + depth1: The depth of the first tenon shoulder. + depth2: The depth of the second tenon shoulder. + clearance: Additional clearance applied around the tenons for fitting tolerance during assembly. + backcut: A small undercut or inward offset to ensure the tenons fit without surface interference. + drilling_count: The number of drill holes to create for fasteners (e.g., bolts or dowels). + drilling_diameter: The diameter of each drill hole. + drilling_tolerance: The tolerance applied to the hole size for bolt head clearance or easier insertion. """ -def get_coordinate_system_data_nesting_child(nesting_parent_id: int, nesting_child_id: int) -> 'coordinate_system_data': - """get coordinate system data nesting child +def get_coordinate_system_data_nesting_child(nesting_parent_id: ElementId, nesting_child_id: ElementId) -> coordinate_system_data: + """Get the coordinate system of nesting child Parameters: - nesting_parent_id: nesting_parent_id - nesting_child_id: nesting_child_id + nesting_parent_id: The nesting parent id. + nesting_child_id: The nesting child id. Returns: - coordinate_system_data + A global element coordinate-system of the nested child element consisting of a Point1, a Point2 and a Point3. You can get the local placement by subtracting the parent coordinate - system with child coordinate - system. """ -def cut_half_lap(elements: List[int], length: float, clearance_length: float, clearance_depth: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cut half lap +def cut_half_lap(element_id_list: List[ElementId], length: float, clearance_length: float, clearance_depth: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: + """Cut a half-lap joint with specific parameters. Parameters: - elements: elements - length: length - clearance_length: clearance_length - clearance_depth: clearance_depth - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance - - Returns: - None + element_id_list: The list of elements to be cut. + length: The length of the half-lap joint along the main axis of the elements. + clearance_length: Additional clearance along the length of the cut to ensure proper fitting. + clearance_depth: Additional clearance in the depth direction to avoid tight joints or surface interference. + drilling_count: The number of drill holes to create for fasteners (e.g., bolts or dowels). + drilling_diameter: The diameter of each drill hole. + drilling_tolerance: The tolerance applied to the hole size for bolt head clearance or easier insertion. """ -def cut_simple_scarf(elements: List[int], length: float, depth: float, clearance_length: float, clearance_depth: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cut simple scarf +def cut_simple_scarf(element_id_list: List[ElementId], length: float, depth: float, clearance_length: float, clearance_depth: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: + """Cut a simple scarf joint with specific parameters. Parameters: - elements: elements - length: length - depth: depth - clearance_length: clearance_length - clearance_depth: clearance_depth - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance - - Returns: - None + element_id_list: The list of elements to be cut. + length: The distance between the two starting points of the cut. + depth: The vertical depth of the initial straight cut before the diagonal cut begins. + clearance_length: The additional length clearance applied along the initial (depth) cut. + clearance_depth: The additional depth clearance applied along the diagonal cut. + drilling_count: The number of drill holes to be created for fasteners (e.g., bolts or dowels). + drilling_diameter: The diameter of each drill hole. + drilling_tolerance: The tolerance applied to the hole size, typically for fitting the bolt head or allowing easier assembly. """ -def cut_diagonal_cut(elements: List[int], length: float, clearance_length: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cut diagonal cut +def cut_diagonal_cut(element_id_list: List[ElementId], length: float, clearance_length: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: + """Cut a diagonal cut joint with specific parameters. Parameters: - elements: elements - length: length - clearance_length: clearance_length - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance - - Returns: - None + element_id_list: The list of elements to be cut. + length: The total length of the diagonal cut applied along the element. + clearance_length: Additional clearance along the cut length to ensure proper fitting between elements. + drilling_count: The number of drill holes to create for fasteners (e.g., bolts or dowels). + drilling_diameter: The diameter of each drill hole. + drilling_tolerance: The tolerance applied to the hole size for bolt head clearance or easier insertion. """ -def get_all_identifiable_element_ids() -> List[int]: - """get all identifiable element ids +def get_all_identifiable_element_ids() -> List[ElementId]: + """Retrieves a list of all identifiable elements. Returns: - List[int] + A list of all identifiable element IDs. """ -def get_visible_identifiable_element_ids() -> List[int]: - """get visible identifiable element ids +def get_visible_identifiable_element_ids() -> List[ElementId]: + """Get a list of all visible identifiable elements. Returns: - List[int] + A list of IDs of all visible identifiable elements. """ -def get_invisible_identifiable_element_ids() -> List[int]: - """get invisible identifiable element ids +def get_invisible_identifiable_element_ids() -> List[ElementId]: + """Get a list of all invisible identifiable elements. Returns: - List[int] + A list of IDs of all invisible identifiable elements. """ -def get_active_identifiable_element_ids() -> List[int]: - """get active identifiable element ids +def get_active_identifiable_element_ids() -> List[ElementId]: + """Get a list of all active identifiable elements. Returns: - List[int] + A list of IDs of all active identifiable elements. """ -def get_inactive_all_identifiable_element_ids() -> List[int]: - """get inactive all identifiable element ids +def get_inactive_all_identifiable_element_ids() -> List[ElementId]: + """Get a list of all inactive identifiable elements. Returns: - List[int] + A list of IDs of all inactive identifiable elements. """ -def get_inactive_visible_identifiable_element_ids() -> List[int]: - """get inactive visible identifiable element ids +def get_inactive_visible_identifiable_element_ids() -> List[ElementId]: + """Get a list of all inactive visible identifiable elements. Returns: - List[int] + A list of IDs of all inactive visible identifiable elements. """ -def check_if_point_is_in_element(point: point_3d, element_id: int) -> bool: - """check if point is in element +def check_if_point_is_in_element(point: point_3d, element_id: ElementId) -> bool: + """Check if a point is inside an element. Parameters: - point: point - element_id: element_id + point: The point to check. + element_id: The ID of the element to check against. Returns: - bool + True if the point is inside the element, false otherwise. """ -def check_if_point_is_on_element(point: point_3d, element_id: int) -> bool: - """check if point is on element +def check_if_point_is_on_element(point: point_3d, element_id: ElementId) -> bool: + """Check if a point is on the surface of an element. Parameters: - point: point - element_id: element_id + point: The point to check. + element_id: The ID of the element to check against. Returns: - bool + True if the point is on the surface of the element, false otherwise. """ -def get_element_contact_facets(first_id: int, second_id: int) -> facet_list: - """get element contact facets +def get_element_contact_facets(first_id: ElementId, second_id: ElementId) -> facet_list: + """Retrieves the contact facets between two elements. Parameters: - first_id: first_id - second_id: second_id + first_id: The ID of the first element. + second_id: The ID of the second element. Returns: - facet_list + The list of contact facets between the two elements. """ -def get_element_raw_interface_vertices(first_id: int, second_id: int) -> List[point_3d]: - """get element raw interface vertices +def get_element_raw_interface_vertices(first_id: ElementId, second_id: ElementId) -> List[point_3d]: + """Get the raw interface vertices between two elements. Parameters: - first_id: first_id - second_id: second_id + first_id: The ID of the first element. + second_id: The ID of the second element. Returns: - List[point_3d] + The list of raw interface vertices between the two elements. """ def get_standard_export_solid_list() -> List[str]: - """get standard export solid list + """Retrieves a list of standard export solid names. Returns: - List[str] + The list of standard export solid names. """ def get_standard_container_list() -> List[str]: - """get standard container list + """Retrieves a list of standard container names. Returns: - List[str] + The list of standard container names. """ def get_standard_beam_list() -> List[str]: - """get standard beam list + """Retrieves a list of standard beam names. Returns: - List[str] + The list of standard beam names. """ def get_standard_panel_list() -> List[str]: - """get standard panel list + """Retrieves a list of standard panel names. Returns: - List[str] + The list of standard panel names. """ -def get_variant_sibling_element_ids(element_id: int) -> List[int]: - """get variant sibling element ids +def get_variant_sibling_element_ids(element_id: ElementId) -> List[ElementId]: + """Retrieves a list of variant sibling element IDs. Parameters: - element_id: element_id + element_id: The element id. Returns: - List[int] + The list of variant sibling element IDs. """ -def get_reference_element(element: int) -> int: - """get reference element +def get_reference_element(element_id: ElementId) -> ElementId: + """Get the reference element for a given element. Parameters: - element: element + element_id: The element id. Returns: - int + The reference element ID. """ -def get_element_contact_vertices(first_id: int, second_id: int) -> List[point_3d]: - """get element contact vertices +def get_element_contact_vertices(first_id: ElementId, second_id: ElementId) -> List[point_3d]: + """Get the contact vertices between two elements. Parameters: - first_id: first_id - second_id: second_id + first_id: The ID of the first element. + second_id: The ID of the second element. Returns: - List[point_3d] + The list of contact vertices between the two elements. """ -def get_nesting_parent_id(element_id: int) -> int: - """get nesting parent id +def get_nesting_parent_id(element_id: ElementId) -> ElementId: + """Get the parent ID of a nested element. Parameters: - element_id: element_id + element_id: The element id. Returns: - int + The ID of the parent element. """ -def check_if_elements_are_in_collision(first_element_id: int, second_element_id: int) -> bool: - """check if elements are in collision +def check_if_elements_are_in_collision(first_element_id: ElementId, second_element_id: ElementId) -> bool: + """Check if two elements are in collision. Parameters: - first_element_id: first_element_id - second_element_id: second_element_id + first_element_id: The ID of the first element. + second_element_id: The ID of the second element. Returns: - bool + True if the elements are in collision, false otherwise. """ -def check_if_elements_are_in_contact(first_element_id: int, second_element_id: int) -> bool: - """check if elements are in contact +def check_if_elements_are_in_contact(first_element_id: ElementId, second_element_id: ElementId) -> bool: + """Check if two elements are in contact. Parameters: - first_element_id: first_element_id - second_element_id: second_element_id + first_element_id: The ID of the first element. + second_element_id: The ID of the second element. Returns: - bool + True if the elements are in contact, false otherwise. """ -def get_element_module_properties_for_element(element_id: int) -> element_module_properties: - """get element module properties for element +def get_element_module_properties_for_element(element_id: ElementId) -> element_module_properties: + """Retrieves the module properties for a specific element. Parameters: - element_id: element_id + element_id: The element id. Returns: - element_module_properties + The module properties of the element. """ -def get_element_type_description(element_id: int) -> str: - """get element type description +def get_element_type_description(element_id: ElementId) -> str: + """Retrieves the type description of a specific element. Parameters: - element_id: element_id + element_id: The element id. Returns: - str + The type description of the element. """ -def get_opening_variant_ids(elements: List[int], opening_type: int) -> List[int]: - """get opening variant ids +def get_opening_variant_ids(element_id_list: List[ElementId], opening_type: int) -> List[int]: + """Get the opening variant IDs for a list of elements. Parameters: - elements: elements - opening_type: opening_type + element_id_list: The list of element IDs. + opening_type: The type of opening to check for. Unknown = 0, Window = 1, Door = 2. Returns: - List[int] + The list of opening variant IDs. """ -def get_parent_container_id(element_id: int) -> int: - """get parent container id +def get_parent_container_id(element_id: ElementId) -> ElementId: + """Get the parent container ID of a nested element. Parameters: - element_id: element_id + element_id: The element id. Returns: - int + The ID of the parent element. """ -def get_export_solid_content_elements(element_id: int) -> List[int]: - """get export solid content elements +def get_export_solid_content_elements(element_id: ElementId) -> List[ElementId]: + """Get the content elements of an export solid. Parameters: - element_id: element_id + element_id: The element id. Returns: - List[int] + The list of content elements. """ -def get_container_content_elements(element_id: int) -> List[int]: - """get container content elements +def get_container_content_elements(element_id: ElementId) -> List[ElementId]: + """Get the content elements of a container. Parameters: - element_id: element_id + element_id: The element id. Returns: - List[int] + The list of content elements. """ def get_element_detail_path() -> str: - """get element detail path + """Get the detail path of the element module. Returns: - str + The detail path of the element module. """ -def get_element_cadwork_guid(element_id: int) -> str: - """get element cadwork guid +def get_element_cadwork_guid(element_id: ElementId) -> str: + """Get the Cadwork GUID of a specific element. Parameters: - element_id: element_id + element_id: The element id. Returns: - str + The Cadwork GUID of the element. """ -def get_bounding_box_vertices_local(reference_element: int, elements: List[int]) -> List[point_3d]: - """get bounding box vertices local +def get_bounding_box_vertices_local(reference_element: ElementId, element_id_list: List[ElementId]) -> List[point_3d]: + """Retrieves the local bounding box vertices for a list of elements relative to a reference element. Parameters: - reference_element: reference_element - elements: elements + reference_element: The ID of the reference element. + element_id_list: The list of elements for which to retrieve the bounding box vertices. Returns: - List[point_3d] + The list of vertices representing the local bounding box of the elements. """ -def get_bounding_box_vertices_global(elements: List[int]) -> List[point_3d]: - """get bounding box vertices global +def get_bounding_box_vertices_global(element_id_list: List[ElementId]) -> List[point_3d]: + """Get the global bounding box vertices for a list of elements. Parameters: - elements: elements + element_id_list: The list of elements for which to retrieve the bounding box vertices. Returns: - List[point_3d] + The list of vertices representing the global bounding box of the elements. """ -def get_all_nesting_raw_parts() -> List[int]: - """get all nesting raw parts +def get_all_nesting_raw_parts() -> List[ElementId]: + """Get a list of all raw parts in a nesting operation. Returns: - List[int] + The list of IDs of all raw parts in a nesting operation. """ -def get_joined_elements(element_id: int) -> List[int]: - """get joined elements +def get_joined_elements(element_id: ElementId) -> List[ElementId]: + """Retrieves the IDs of elements that have been joined with the specified element. Parameters: - element_id: element_id + element_id: The element id. Returns: - List[int] + The list of IDs of the joined elements. """ -def check_element_duplicates(elements: List[int]) -> List[int]: - """check element duplicates +def check_element_duplicates(element_id_list: List[ElementId]) -> List[ElementId]: + """Checks for duplicate elements in the provided list. Parameters: - elements: elements + element_id_list: The list of element IDs to check for duplicates. Returns: - List[int] + The list of duplicate elements. """ -def get_elements_in_contact(element: int) -> List[int]: - """get elements in contact +def get_elements_in_contact(element_id: ElementId) -> List[ElementId]: + """Retrieves a list of elements in contact with a specific element. Parameters: - element: element + element_id: The ID of the element to check for contact. Returns: - List[int] + The list of IDs of the elements in contact with the specified element. """ -def create_text_object_with_options(position: point_3d, xl: point_3d, zl: point_3d, text_options: text_object_options) -> int: - """create text object with options +def create_text_object_with_options(position: point_3d, x_local_direction: point_3d, z_local_direction: point_3d, text_options: text_object_options) -> ElementId: + """Creates a text object with the specified options. Parameters: - position: position - xl: xl - zl: zl - text_options: text_options + position: The position of the text object. + x_local_direction: The X-axis direction of the text object. + z_local_direction: The Z-axis direction of the text object. + text_options: The options for the text object. Examples: >>> text_position = cadwork.point_3d(0., 0., 0.) @@ -2040,165 +1864,135 @@ def create_text_object_with_options(position: point_3d, xl: point_3d, zl: point_ >>> text_id = ec.create_text_object_with_options(text_position, x_direction, z_direction, options) Returns: - int + The ID of the created text object. """ -def convert_surfaces_to_roof_surfaces(elements: List[int], roof_name: str) -> None: - """convert surfaces to roof surfaces +def convert_surfaces_to_roof_surfaces(element_id_list: List[ElementId], roof_name: str) -> None: + """Converts surfaces to roof surfaces. Parameters: - elements: elements - roof_name: roof_name - - Returns: - None + element_id_list: The list of elements to convert. + roof_name: The name of the roof surface. """ -def start_standard_element_dialog(standard_element_type: None) -> str: - """start standard element dialog +def start_standard_element_dialog(standard_element_type: standard_element_type) -> str: + """Starts the standard element dialogue based on the chosen element type. Parameters: - standard_element_type: standard_element_type + standard_element_type: The type of the standard element to create. Returns: - str + The GUID of the selected standard element if the item is valid, else null. """ def remove_standard_connector_axis(guid: str) -> None: - """remove standard connector axis + """Removes a standard connector axis. Parameters: - guid: guid - - Returns: - None + guid: The unique identifier of the standard connector axis to be removed. """ def remove_standard_beam(guid: str) -> None: - """remove standard beam + """Removes a standard beam. Parameters: - guid: guid - - Returns: - None + guid: The unique identifier of the standard connector axis to be removed. """ def remove_standard_panel(guid: str) -> None: - """remove standard panel + """Removes a standard panel. Parameters: - guid: guid - - Returns: - None + guid: The unique identifier of the standard panel to be removed. """ def remove_standard_container(guid: str) -> None: - """remove standard container + """Removes a standard container. Parameters: - guid: guid - - Returns: - None + guid: The unique identifier of the standard container to be removed. """ def remove_standard_export_solid(guid: str) -> None: - """remove standard export solid + """Removes a standard export solid. Parameters: - guid: guid - - Returns: - None + guid: The unique identifier of the standard export solid to be removed. """ -def get_user_element_ids_with_count(count: int) -> List[int]: - """get user element ids with count +def get_user_element_ids_with_count(count: int) -> List[ElementId]: + """Retrieves a list of user element IDs. Parameters: - count: count + count: The maximal number of elements to select. Returns: - List[int] + The list of user element IDs. """ -def cut_scarf_straight(elements: List[int], length: float, depth: float, clearance_length: float, clearance_depth: float, clearance_hook: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cut scarf straight +def cut_scarf_straight(element_id_list: List[ElementId], length: float, depth: float, clearance_length: float, clearance_depth: float, clearance_hook: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: + """Cuts a straight scarf joint (lengthwise) with specific parameters. Parameters: - elements: elements - length: length - depth: depth - clearance_length: clearance_length - clearance_depth: clearance_depth - clearance_hook: clearance_hook - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance - - Returns: - None + element_id_list: The list of elements to apply the scarf cut to. + length: The total length of the scarf joint cut, measured along the element’s longitudinal axis. + depth: The depth of the vertical cut where both side join. + clearance_length: Additional clearance along the length direction to ensure proper fitting of the joint. + clearance_depth: Additional clearance in the depth direction to avoid tight fits or interference. + clearance_hook: Clearance added specifically at the hook or notch feature of the joint, if any. + drilling_count: The number of holes to be drilled, typically for bolts, pegs, or dowels to reinforce the joint. + drilling_diameter: The diameter of each drilled hole. + drilling_tolerance: The tolerance added to the hole size for easier assembly or bolt head fitting. """ -def cut_scarf_diagonal(elements: List[int], length: float, depth: float, clearance_length: float, clearance_depth: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cut scarf diagonal +def cut_scarf_diagonal(element_id_list: List[ElementId], length: float, depth: float, clearance_length: float, clearance_depth: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: + """Cuts a diagonal scarf joint (lengthwise) with specific parameters. Parameters: - elements: elements - length: length - depth: depth - clearance_length: clearance_length - clearance_depth: clearance_depth - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance - - Returns: - None + element_id_list: The list of elements on which the diagonal scarf cut will be applied. + length: The total length of the scarf joint measured along the element’s axis. + depth: The vertical depth of the initial straight section before the diagonal cut begins. + clearance_length: Additional clearance along the length direction to facilitate proper fitting of the joint. + clearance_depth: Additional clearance along the depth direction to avoid tight joints or misalignment. + drilling_count: The number of drill holes for mechanical fasteners (e.g., bolts or dowels). + drilling_diameter: The diameter of each drill hole. + drilling_tolerance: Tolerance added to the hole diameter for ease of insertion or head fit. """ -def cut_scarf_with_wedge(elements: List[int], length: float, depth: float, clearance_length: float, clearance_depth: float, wedge_width: float, drilling_count: int, drilling_diameter: float, drilling_tolerance: float) -> None: - """cut scarf with wedge +def cut_scarf_with_wedge(element_id_list: List[ElementId], length: float, depth: float, clearance_length: float, clearance_depth: float, wedge_width: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: + """Cuts a diagonal scarf joint with an added wedge, using specific parameters. Parameters: - elements: elements - length: length - depth: depth - clearance_length: clearance_length - clearance_depth: clearance_depth - wedge_width: wedge_width - drilling_count: drilling_count - drilling_diameter: drilling_diameter - drilling_tolerance: drilling_tolerance - - Returns: - None + element_id_list: The list of elements on which to apply the scarf-with-wedge cut. + length: The total length of the scarf joint, measured along the main axis of the element. + depth: The vertical depth of the straight portion of the cut before the diagonal section. + clearance_length: Additional clearance along the length direction for proper fit of the joint. + clearance_depth: Additional clearance in the depth direction to avoid interference. + wedge_width: The width of the wedge feature inserted or carved as part of the joint geometry. + drilling_count: The number of drill holes used to secure the joint (e.g., for bolts, pegs, or dowels). + drilling_diameter: The diameter of the drilled holes. + drilling_tolerance: Tolerance applied to the hole size, often used for easier bolt fitting or head clearance. """ -def cut_beam_end_profile(elements: List[int], profile_name: str, on_start_face: bool, on_end_face: bool) -> None: - """cut beam end profile +def cut_beam_end_profile(element_id_list: List[ElementId], profile_name: str, on_start_face: bool, on_end_face: bool) -> None: + """Add end profile to beam elements. Parameters: - elements: elements - profile_name: profile_name - on_start_face: on_start_face - on_end_face: on_end_face - - Returns: - None + element_id_list: The list of elements to modify. + profile_name: The name of the profile to add. + on_start_face: Cut on the start face? + on_end_face: Cut on the end face? """ -def create_truncated_cone_beam_points(start_diameter: float, end_diameter: float, p1: point_3d, p2: point_3d, p3: point_3d) -> int: - """create truncated cone beam points +def create_truncated_cone_beam_points(start_diameter: float, end_diameter: float, first_point: point_3d, second_point: point_3d, third_point: point_3d) -> ElementId: + """Creates a truncated cone beam using points. Parameters: - start_diameter: start_diameter - end_diameter: end_diameter - p1: p1 - p2: p2 - p3: p3 + start_diameter: The starting diameter of the beam. + end_diameter: The ending diameter of the beam. + first_point: The first point. + second_point: The second point. + third_point: The third point. Examples: >>> start_dia = 200. @@ -2213,19 +2007,19 @@ def create_truncated_cone_beam_points(start_diameter: float, end_diameter: float >>> cone_id = ec.create_truncated_cone_beam_points(start_dia, end_dia, cone_start_pt, cone_end_pt, orientation_pt) Returns: - int + The ID of the created beam. """ -def create_truncated_cone_beam_vectors(start_diameter: float, end_diameter: float, length: float, p1: point_3d, xl: point_3d, zl: point_3d) -> int: - """create truncated cone beam vectors +def create_truncated_cone_beam_vectors(start_diameter: float, end_diameter: float, length: float, starting_point: point_3d, x_local_direction: point_3d, z_local_direction: point_3d) -> ElementId: + """Creates a truncated cone beam using vectors. Parameters: - start_diameter: start_diameter - end_diameter: end_diameter - length: length - p1: p1 - xl: xl - zl: zl + start_diameter: The starting diameter of the beam. + end_diameter: The ending diameter of the beam. + length: The length of the beam. + starting_point: The starting point. + x_local_direction: The direction of the X-axis. + z_local_direction: The direction of the Z-axis. Examples: >>> start_dia = 120. @@ -2237,15 +2031,15 @@ def create_truncated_cone_beam_vectors(start_diameter: float, end_diameter: floa >>> cone_id = ec.create_truncated_cone_beam_vectors(start_dia, end_dia, cone_length, origin_point, x_direction, z_direction) Returns: - int + The ID of the created beam. """ -def create_spline_line(spline_points: vertex_list) -> int: - """create spline line +def create_spline_line(spline_points: vertex_list) -> ElementId: + """Creates a spline line. Parameters: - spline_points: spline_points + spline_points: The points defining the spline. Examples: >>> # Create a spline through multiple points @@ -2257,94 +2051,51 @@ def create_spline_line(spline_points: vertex_list) -> int: >>> spline_id = ec.create_spline_line(points) Returns: - int + The ID of the created spline. """ -def unjoin_elements(element_id_list: List[int]) -> bool: - """unjoin elements +def unjoin_elements(element_id_list: List[ElementId]) -> bool: + """Unjoins the specified elements. Parameters: - element_id_list: element_id_list + element_id_list: The element id list. Returns: - bool + True if the operation was successful, false if an error occured. """ -def unjoin_top_level_elements(element_id_list: List[int]) -> bool: - """unjoin top level elements +def unjoin_top_level_elements(element_id_list: List[ElementId]) -> bool: + """Unjoins the specified top-level elements. Parameters: - element_id_list: element_id_list + element_id_list: The element id list. Returns: - bool + True if the operation was successful, false if an error occured. """ def set_element_group_single_select_mode() -> None: - """set element group single select mode - - Returns: - None + """ Switches the current element group selection mode so that single elements of a group are selectable. """ def set_element_group_multi_select_mode() -> None: - """set element group multi select mode - - Returns: - None + """Switches the current element group selection mode so that all elements of a group are selected when selecting one of it. """ -def convert_circular_beam_to_drilling(elements: List[int]) -> None: - """convert circular beam to drilling +def convert_circular_beam_to_drilling(element_id_list: List[ElementId]) -> None: + """Converts circular beams to drillings. Parameters: - elements: elements - - Returns: - None + element_id_list: The list of element IDs to convert. """ -def slice_elements_with_plane_and_get_new_elements(element: int, cut_plane_normal_vector: point_3d, distance_from_global_origin: float) -> List[int]: - """slice elements with plane and get new elements +def slice_elements_with_plane_and_get_new_elements(element_id: ElementId, cut_plane_normal_vector: point_3d, distance_from_global_origin: float) -> List[ElementId]: + """Slices an element with a plane and returns the new elements. Parameters: - element: The ID of the element to be sliced - cut_plane_normal_vector: The normal vector of the cutting plane - distance_from_global_origin: list of IDs of the new elements created by the slicing operation - - Returns: - List[int] - """ - -def get_elements_in_collision(element: int) ->List[int]: - """get elements in collision - - Parameters: - element: element - - Returns: - List[int] - """ - -def get_text_object_options(element: int) ->'text_object_options': - """get text object options - - Parameters: - element: element - - Returns: - text_object_options - """ - -def get_is_element_group_single_select_mode() ->bool: - """get is element group single select mode - - Returns: - bool - """ - -def get_is_element_group_multi_select_mode() ->bool: - """get is element group multi select mode + element_id: The ID of the element to be sliced. + cut_plane_normal_vector: The normal vector of the cutting plane. + distance_from_global_origin: The distance from the global origin to the cutting plane. Examples: >>> import math @@ -2367,93 +2118,109 @@ def get_is_element_group_multi_select_mode() ->bool: >>> print(f"Test point is on plane: {on_plane}") >>> # Slice the beam at the midpoint and get the resulting pieces >>> new_element_ids = ec.slice_elements_with_plane_and_get_new_elements(beam_id, plane_normal, distance) - >>> print(f"Created {len(new_element_ids)} new elements: {new_element_ids}") + >>> print(f"Created {len(new_element_ids)} new element_id_list: {new_element_ids}") >>> # Visualization: different pen colors for the new elements >>> for i, new_id in enumerate(new_element_ids): ... vc.set_color([new_id], i+5) Returns: - bool + The list of IDs of the new elements created by the slicing operation. """ - -def set_shoulder_options(options: shoulder_options) -> None: - """set shoulder options +def get_elements_in_collision(element_id: ElementId) -> List[ElementId]: + """Retrieves a list of elements in collision with a specific element. Parameters: - options: options + element_id: The ID of the element to check for collision. Returns: - None + A list of IDs of the elements in collision with the specified element. """ - -def set_heel_shoulder_options(options: heel_shoulder_options) -> None: - """set heel shoulder options +def get_text_object_options(element_id: ElementId) ->'text_object_options': + """Retrieves the text object options for a specific element e.g. font, text content, etc. Parameters: - options: options + element_id: The ID of the element to retrieve options for. Returns: - None + The text object options for the specified element. """ +def get_is_element_group_single_select_mode() ->bool: + """Gets whether the current element group selection mode is setup to select single elements. -def set_double_shoulder_options(options: double_shoulder_options) -> None: - """set double shoulder options + Returns: + True if the current element group selection mode is set to single select, false otherwise. + """ - Parameters: - options: options +def get_is_element_group_multi_select_mode() ->bool: + """Gets whether the current element group selection mode is setup to select multiple elements. Returns: - None + True if the current element group selection mode is set to multi select, false otherwise. """ -def cut_shoulder(element_id_list: List[int], connecting_element_id_list: - List[int]) ->None: - """cut shoulder + +def set_shoulder_options(options: shoulder_options) -> None: + """Sets the shoulder cut options. Parameters: - element_id_list: element_id_list - connecting_element_id_list: connecting_element_id_list + options: The shoulder options to set. + """ - Returns: - None + +def set_heel_shoulder_options(options: heel_shoulder_options) -> None: + """Sets the heel shoulder cut options. + + Parameters: + options: The heel shoulder options to set. """ -def cut_heel_shoulder(element_id_list: List[int], - connecting_element_id_list: List[int]) ->None: - """cut heel shoulder + +def set_double_shoulder_options(options: double_shoulder_options) -> None: + """Sets the double shoulder cut options. Parameters: - element_id_list: element_id_list - connecting_element_id_list: connecting_element_id_list + options: The double shoulder options to set. + """ - Returns: - None +def cut_shoulder(element_id_list: List[ElementId], connecting_element_id_list: + List[ElementId]) ->None: + """Cuts shoulder with current 3D options. + + Parameters: + element_id_list: The element id list. + connecting_element_id_list: The list of elements that intersect or connect with the cut elements, used to determine the cutting geometry. """ -def cut_double_shoulder(element_id_list: List[int], - connecting_element_id_list: List[int]) ->None: - """cut double shoulder +def cut_heel_shoulder(element_id_list: List[ElementId], + connecting_element_id_list: List[ElementId]) ->None: + """Cuts heel with current 3D options Parameters: - element_id_list: element_id_list - connecting_element_id_list: connecting_element_id_list + element_id_list: The element id list. + connecting_element_id_list: The list of elements that intersect or connect with the cut elements, used to determine the cutting geometry. + """ - Returns: - None +def cut_double_shoulder(element_id_list: List[ElementId], + connecting_element_id_list: List[ElementId]) ->None: + """Cuts a double shoulder joint using the current 3D cutting options. + + Parameters: + element_id_list: The element id list. + connecting_element_id_list: The list of elements that intersect or connect with the cut elements, used to determine the cutting geometry. """ -def filter_elements(elements: List[int], element_filter: element_filter) -> List[int]: - """filter elements +def filter_elements(element_id_list: List[ElementId], element_filter: element_filter) -> List[ElementId]: + """Filters a list of elements based on a provided filter. Parameters: - elements: elements - element_filter: name_filter + element_id_list: The list of elements to filter. + element_filter: The filter to apply to the list of elements. - Example: + Examples: >>> import cadwork >>> import element_controller as ec >>> your_element_filter = cadwork.element_filter() @@ -2462,16 +2229,16 @@ def filter_elements(elements: List[int], element_filter: element_filter) -> List >>> print(filtered_elements) Returns: - List[int] + The filtered list of element IDs. """ -def map_elements(elements: List[int], map_query: element_map_query) -> Dict[str, List[int]]: - """map elements +def map_elements(element_id_list: List[ElementId], map_query: element_map_query) -> Dict[str, List[ElementId]]: + """Maps a list of elements based on a provided map query. Parameters: - elements: elements - map_query: map_query + element_id_list: The list of elements to map. + map_query: The map query to apply to the list of elements. Examples: >>> import cadwork @@ -2482,18 +2249,19 @@ def map_elements(elements: List[int], map_query: element_map_query) -> Dict[str, >>> print(mapped_items) Returns: - Dict[str, List[int]] + The map of elements that pass the map query. """ -def cast_ray_and_get_element_intersections(elements: List[int], ray_start_position: point_3d, +def cast_ray_and_get_element_intersections(element_id_list: List[ElementId], ray_start_position: point_3d, ray_end_position: point_3d, radius: float) -> hit_result: - """cast ray and get element intersections + """Casts a ray through the 3D model and calculates all intersection points between the ray and specified elements. This function performs ray casting against each specified element to find intersection points.For each element hit by the ray, it returns the element ID and all points where the ray intersects with that element. The ray is defined by a start point, end point, and radius. + Parameters: - elements: elements - ray_start_position: ray_start_position - ray_end_position: ray_end_position - radius: radius + element_id_list: List of element IDs to test against the ray. + ray_start_position: 3D start point of the ray. + ray_end_position: 3D end point of the ray. + radius: Radius of the ray cylinder (allows testing against a volume rather than just a line). Examples: >>> import element_controller as ec @@ -2508,5 +2276,5 @@ def cast_ray_and_get_element_intersections(elements: List[int], ray_start_positi >>> ec.create_node(pos) Returns: - hit_result + Contains list of elements that were hit by the ray and list of vertices that are queried via ElementID. """ diff --git a/src/endtype_controller/__init__.pyi b/src/endtype_controller/__init__.pyi index 4729b48..1fccb18 100644 --- a/src/endtype_controller/__init__.pyi +++ b/src/endtype_controller/__init__.pyi @@ -1,20 +1,11 @@ from typing import List +from cadwork.api_types import * -def get_last_error(error_code: int) -> str: - """get last error +def get_endtype_id(name: str) -> EndtypeId: + """Gets the endtype id by endtype name. Parameters: - error_code: error_code - - Returns: - str - """ - -def get_endtype_id(name: str) -> int: - """Gets the endtypeID by endtypename - - Parameters: - name: name + name: The endtype name. Examples: >>> import endtype_controller as etc @@ -24,14 +15,14 @@ def get_endtype_id(name: str) -> int: >>> print(f"Endtype ID: {endtype_id}") Returns: - int + The wanted endtype id. """ -def get_endtype_id_start(element_id: int) -> int: - """Gets the endtypeID of the start face +def get_endtype_id_start(element_id: ElementId) -> EndtypeId: + """Gets the endtype id of the start face. Parameters: - element_id: element_id + element_id: The element id. Examples: >>> import element_controller as ec @@ -43,14 +34,14 @@ def get_endtype_id_start(element_id: int) -> int: >>> print(f"Start endtype ID: {start_endtype_id}") Returns: - int + The wanted endtype id. """ -def get_endtype_id_end(element_id: int) -> int: - """Gets the endtypeID of the end face +def get_endtype_id_end(element_id: ElementId) -> EndtypeId: + """Gets the endtype id of the end face. Parameters: - element_id: element_id + element_id: The element id. Examples: >>> import element_controller as ec @@ -62,16 +53,16 @@ def get_endtype_id_end(element_id: int) -> int: >>> print(f"End endtype ID: {end_endtype_id}") Returns: - int + The wanted endtype id. """ -def get_endtype_id_facet(element_id: int, face_number: int) -> int: - """get endtype id facet +def get_endtype_id_facet(element_id: ElementId, face_number: int) -> EndtypeId: + """Gets the endtype id of a face with the face number. Parameters: - element_id: element_id - face_number: face_number + element_id: The element id. + face_number: The face number. 0 <= aFaceNumber < element face count. Note: Endtypes can only be set on faces that are placed at start or end points. @@ -88,15 +79,15 @@ def get_endtype_id_facet(element_id: int, face_number: int) -> int: >>> print(f"Facet endtype ID: {facet_endtype_id}") Returns: - int + The wanted endtype id. """ -def set_endtype_name_start(element_id: int, name: str) -> None: - """Sets the endtype to start face by endtypename +def set_endtype_name_start(element_id: ElementId, name: str) -> None: + """Sets the endtype to start face by endtype name. Parameters: - element_id: element_id - name: name + element_id: The element id. + name: The endtype name. Examples: >>> import element_controller as ec @@ -106,17 +97,14 @@ def set_endtype_name_start(element_id: int, name: str) -> None: >>> element = selected_elements[0] >>> endtype_name = "Tenon_100x50" >>> etc.set_endtype_name_start(element, endtype_name) - - Returns: - None """ -def set_endtype_name_end(element_id: int, name: str) -> None: - """Sets the endtype to end face by endtypename +def set_endtype_name_end(element_id: ElementId, name: str) -> None: + """Sets the endtype to end face by endtype name. Parameters: - element_id: element_id - name: name + element_id: The element id. + name: The endtype name. Examples: >>> import element_controller as ec @@ -126,19 +114,16 @@ def set_endtype_name_end(element_id: int, name: str) -> None: >>> element = selected_elements[0] >>> endtype_name = "Mortise_100x50" >>> etc.set_endtype_name_end(element, endtype_name) - - Returns: - None """ -def set_endtype_name_facet(element_id: int, name: str, face_number: int) -> None: - """set endtype name facet +def set_endtype_name_facet(element_id: ElementId, name: str, face_number: int) -> None: + """Sets the endtype to a face by endtype name. Parameters: - element_id: element_id - name: name - face_number: face_number + element_id: The element id. + name: The endtype name. + face_number: The face number. 0 <= aFaceNumber < element face count. Note: Endtypes can only be set on faces that are placed at start or end points. @@ -153,17 +138,14 @@ def set_endtype_name_facet(element_id: int, name: str, face_number: int) -> None >>> endtype_name = "Dovetail_60x30" >>> face_number = 2 >>> etc.set_endtype_name_facet(element, endtype_name, face_number) - - Returns: - None """ -def set_endtype_id_start(element_id: int, endtype_id: int) -> None: - """Sets the endtype to start face by endtypeID +def set_endtype_id_start(element_id: ElementId, endtype_id: EndtypeId) -> None: + """Sets the endtype to start face by endtype id. Parameters: - element_id: element_id - endtype_id: endtype_id + element_id: The element id. + endtype_id: The endtype id. Examples: >>> import element_controller as ec @@ -173,17 +155,14 @@ def set_endtype_id_start(element_id: int, endtype_id: int) -> None: >>> element = selected_elements[0] >>> endtype_id = 12345 >>> etc.set_endtype_id_start(element, endtype_id) - - Returns: - None """ -def set_endtype_id_end(element_id: int, endtype_id: int) -> None: - """Sets the endtype to end face by endtypeID +def set_endtype_id_end(element_id: ElementId, endtype_id: EndtypeId) -> None: + """Sets the endtype to end face by endtype id. Parameters: - element_id: element_id - endtype_id: endtype_id + element_id: The element id. + endtype_id: The endtype id. Examples: >>> import element_controller as ec @@ -193,19 +172,16 @@ def set_endtype_id_end(element_id: int, endtype_id: int) -> None: >>> element = selected_elements[0] >>> endtype_id = 54321 >>> etc.set_endtype_id_end(element, endtype_id) - - Returns: - None """ -def set_endtype_id_facet(element_id: int, endtype_id: int, face_number: int) -> None: - """set endtype id facet +def set_endtype_id_facet(element_id: ElementId, endtype_id: EndtypeId, face_number: int) -> None: + """Sets the endtype to a face by endtype id. Parameters: - element_id: element_id - endtype_id: endtype_id - face_number: face_number + element_id: The element id. + endtype_id: The endtype id. + face_number: The face number. 0 <= aFaceNumber < element face count. Note: Endtypes can only be set on faces that are placed at start or end points. @@ -220,18 +196,15 @@ def set_endtype_id_facet(element_id: int, endtype_id: int, face_number: int) -> >>> endtype_id = 67890 >>> face_number = 3 >>> etc.set_endtype_id_facet(element, endtype_id, face_number) - - Returns: - None """ -def create_new_endtype(endtype_name: str, endtype_id: int, folder_name: str) -> int: - """Creates a new Endtype +def create_new_endtype(endtype_name: str, endtype_id: EndtypeId, folder_name: str) -> EndtypeId: + """Creates a new Endtype. Parameters: - endtype_name: endtype_name - endtype_id: endtype_id - folder_name: folder_name + endtype_name: The new endtype name. + endtype_id: The new endtype id. + folder_name: The new endtype folder. Examples: >>> import endtype_controller as etc @@ -243,14 +216,14 @@ def create_new_endtype(endtype_name: str, endtype_id: int, folder_name: str) -> >>> print(f"Created endtype with ID: {new_id}") Returns: - int + The ID of the created endtype. """ -def get_endtype_name(element_id: int) -> str: - """Gets the endtypename by endtypeID +def get_endtype_name(element_id: ElementId) -> str: + """Gets the endtype name by endtype id. Parameters: - element_id: element_id + element_id: The endtype id. Examples: >>> import endtype_controller as etc @@ -260,14 +233,14 @@ def get_endtype_name(element_id: int) -> str: >>> print(f"Endtype name: {endtype_name}") Returns: - str + The endtype name. """ -def get_endtype_name_start(element_id: int) -> str: - """Gets the endtypename of the start face +def get_endtype_name_start(element_id: ElementId) -> str: + """Gets the endtype name of the start face. Parameters: - element_id: element_id + element_id: The element id. Examples: >>> import element_controller as ec @@ -279,14 +252,14 @@ def get_endtype_name_start(element_id: int) -> str: >>> print(f"Start endtype name: {start_name}") Returns: - str + The endtype name of the start face. """ -def get_endtype_name_end(element_id: int) -> str: - """Gets the endtypename of the end face +def get_endtype_name_end(element_id: ElementId) -> str: + """Gets the endtype name of the end face. Parameters: - element_id: element_id + element_id: The element id. Examples: >>> import element_controller as ec @@ -298,15 +271,15 @@ def get_endtype_name_end(element_id: int) -> str: >>> print(f"End endtype name: {end_name}") Returns: - str + The endtype name of the end face. """ -def get_endtype_name_facet(element_id: int, face_number: int) -> str: - """get endtype name facet +def get_endtype_name_facet(element_id: ElementId, face_number: int) -> str: + """Gets the endtype name of the face with a number. Parameters: - element_id: element_id - face_number: face_number + element_id: The element id. + face_number: The face number. 0 <= aFaceNumber < element face count. Note: Endtypes can only be set on faces that are placed at start or end points. @@ -323,11 +296,11 @@ def get_endtype_name_facet(element_id: int, face_number: int) -> str: >>> print(f"Facet endtype name: {facet_name}") Returns: - str + The endtype name of the face. """ -def get_existing_tenon_ids() -> List[int]: - """Get the existing tenon endtypeIDs +def get_existing_tenon_ids() -> List[EndtypeId]: + """Get the existing tenon endtype id list. Examples: >>> import endtype_controller as etc @@ -336,11 +309,11 @@ def get_existing_tenon_ids() -> List[int]: >>> print(f"Available tenon endtype IDs: {tenon_ids}") Returns: - list of existing tenon endtypeIDs + List of existing tenon endtype id. """ -def get_existing_lengthening_ids() -> List[int]: - """Get the existing lengthening endtypeIDs +def get_existing_lengthening_ids() -> List[EndtypeId]: + """Get the existing lengthening endtype id list. Examples: >>> import endtype_controller as etc @@ -349,11 +322,11 @@ def get_existing_lengthening_ids() -> List[int]: >>> print(f"Available lengthening endtype IDs: {lengthening_ids}") Returns: - list of existing lengthening endtypeIDs + List of existing lengthening endtype id. """ -def get_existing_dovetail_ids() -> List[int]: - """Get the existing dovetail endtypeIDs +def get_existing_dovetail_ids() -> List[EndtypeId]: + """Get the existing dovetail endtype id list. Examples: >>> import endtype_controller as etc @@ -362,11 +335,11 @@ def get_existing_dovetail_ids() -> List[int]: >>> print(f"Available dovetail endtype IDs: {dovetail_ids}") Returns: - list of existing dovetail endtypeIDs + List of existing dovetail endtype id. """ -def get_existing_dovetail_dado_ids() -> List[int]: - """Get the existing dado endtypeIDs +def get_existing_dovetail_dado_ids() -> List[EndtypeId]: + """Get the existing dado endtype id list. Examples: >>> import endtype_controller as etc @@ -375,11 +348,11 @@ def get_existing_dovetail_dado_ids() -> List[int]: >>> print(f"Available dado endtype IDs: {dado_ids}") Returns: - list of existing dado endtypeIDs + List of existing dado endtype id. """ -def get_existing_japanese_tenon_ids() -> List[int]: - """Get the existing japanese-tenon endtypeIDs +def get_existing_japanese_tenon_ids() -> List[EndtypeId]: + """Get the existing japanese-tenon endtype id list. Examples: >>> import endtype_controller as etc @@ -388,11 +361,11 @@ def get_existing_japanese_tenon_ids() -> List[int]: >>> print(f"Available japanese-tenon endtype IDs: {japanese_tenon_ids}") Returns: - list of existing japanese-tenon endtypeIDs + List of existing japanese-tenon endtype id. """ def start_endtype_dialog() -> int: - """Start endtype dialog + """Start endtype dialog. Examples: >>> import endtype_controller as etc @@ -401,5 +374,5 @@ def start_endtype_dialog() -> int: >>> print(f"User selected endtype ID: {selected_endtype_id}") Returns: - Selected endtypeID + Selected endtype id. """ diff --git a/src/file_controller/__init__.pyi b/src/file_controller/__init__.pyi index 63ce1a2..2cb38d0 100644 --- a/src/file_controller/__init__.pyi +++ b/src/file_controller/__init__.pyi @@ -1,27 +1,17 @@ from typing import List -from cadwork import point_3d +from cadwork.import_3dc_options import import_3dc_options +from cadwork.point_3d import point_3d from cadwork.bim_team_upload_result import bim_team_upload_result from cadwork.dxf_layer_format_type import dxf_layer_format_type from cadwork.dxf_export_version import dxf_export_version +from cadwork.api_types import * - -def get_last_error(error_code: int) -> str: - """Gets the last error +def export_stl_file(element_id_list: List[ElementId], file_path: str) -> None: + """Exports an STL file. Parameters: - error_code: error_code - - Returns: - error string - """ - - -def export_stl_file(element_id_list: List[int], file_path: str) -> None: - """Exports an STL file - - Parameters: - element_id_list: element_id_list - file_path: file_path + element_id_list: The list of element id to export. + file_path: The output file path. Examples: >>> import element_controller as ec @@ -30,43 +20,40 @@ def export_stl_file(element_id_list: List[int], file_path: str) -> None: >>> selected_elements = ec.get_all_identifiable_element_ids() >>> output_path = r"C:/exports/model.stl" >>> fc.export_stl_file(selected_elements, output_path) - - Returns: - None """ -def import_step_file(file_path: str, scale_factor: float) -> List[int]: - """Imports a STEP file +def import_step_file(file_path: str, scale_factor: float) -> List[ElementId]: + """Imports a STEP file. Parameters: - file_path: file_path - scale_factor: scale_factor + file_path: The input file path. + scale_factor: The file scale factor. Returns: - imported element ID list + The imported list of element id. """ -def import_step_file_with_message_option(file_path: str, scale_factor: float, hide_message: bool) -> List[int]: - """Imports a STEP file +def import_step_file_with_message_option(file_path: str, scale_factor: float, hide_message: bool) -> List[ElementId]: + """Imports a STEP file with message option. Parameters: - file_path: file_path - scale_factor: scale_factor - hide_message: hide_message + file_path: The input file path. + scale_factor: The file scale factor. + hide_message: Hide message. Returns: - imported element ID list + The imported list of element id. """ -def export_webgl(element_id_list: List[int], file_path: str) -> bool: - """Exports a WebGL file +def export_webgl(element_id_list: List[ElementId], file_path: str) -> bool: + """Exports a WebGL file. Parameters: - element_id_list: element_id_list - file_path: file_path + element_id_list: The list of element id to export. + file_path: The output file path. Examples: >>> import element_controller as ec @@ -79,16 +66,16 @@ def export_webgl(element_id_list: List[int], file_path: str) -> bool: >>> print("WebGL export completed successfully") Returns: - did operation succeed + True on successful export, false otherwise. """ -def export_3d_file(element_id_list: List[int], file_path: str) -> bool: - """Exports a 3D file +def export_3d_file(element_id_list: List[ElementId], file_path: str) -> bool: + """Exports a 3D file. Parameters: - element_id_list: element_id_list - file_path: file_path + element_id_list: The list of element id to export. + file_path: The output file path. Examples: >>> import element_controller as ec @@ -101,56 +88,58 @@ def export_3d_file(element_id_list: List[int], file_path: str) -> bool: >>> print("3D file export completed successfully") Returns: - did operation succeed + True on successful export, false otherwise. """ -def import_sat_file(file_path: str, scale_factor: float, binary: bool) -> List[int]: - """Imports an SAT file +def import_sat_file(file_path: str, scale_factor: float, binary: bool) -> List[ElementId]: + """Imports an SAT file. Parameters: - file_path: file_path - scale_factor: scale_factor - binary: binary + file_path: The input file path. + scale_factor: The scale factor. + binary: Is the import file binary. Returns: - imported element ID list + The imported list of element id. """ -def import_3dc_file(file_path: str) -> List[int]: - """Imports a 3DC file +def import_3dc_file(file_path: str) -> List[ElementId]: + """Imports a 3DC file. Parameters: - file_path: file_path + file_path: The input file path. Returns: - imported element ID list + The imported list of element id. """ -def import_rhino_file(file_path: str, without_dialog: bool) -> List[int]: - """Imports a Rhino file +def import_rhino_file(file_path: str, without_dialog: bool) -> List[ElementId]: + """Imports a Rhino file. Parameters: - file_path: file_path - without_dialog: without_dialog + file_path: The input file path. + without_dialog: Import without dialog? Returns: - imported element ID list + The imported list of element id. """ -def export_step_file(element_list: List[int], file_path: str, scale_factor: float, version: int, +def export_step_file(element_id_list: List[ElementId], file_path: str, scale_factor: float, version: int, text_mode: bool) -> None: - """Exports a STEP file + """Exports a STEP file. Parameters: - element_list: element_list - file_path: file_path - scale_factor: scale_factor - version: version - text_mode: text_mode + element_id_list: The list of element id to export. + file_path: The output file path. + scale_factor: The file scale factor. + version: The file export version : + - 214 = STEP AP214 + - 203 = STEP AP203 (default value) + text_mode: Use text mode. PARAMETER UNUSED Examples: >>> import element_controller as ec @@ -162,29 +151,23 @@ def export_step_file(element_list: List[int], file_path: str, scale_factor: floa >>> version = 214 # STEP version >>> text_mode = False >>> fc.export_step_file(selected_elements, output_path, scale_factor, version, text_mode) - - Returns: - None """ def import_3dz_file(file_path: str) -> None: - """Imports a 3DZ file + """Imports a 3DZ file. Parameters: - file_path: file_path - - Returns: - None + file_path: The input file path. """ -def export_obj_file(elements: List[int], file_path: str) -> None: - """Exports a OBJ file +def export_obj_file(element_id_list: List[ElementId], file_path: str) -> None: + """Exports a OBJ file. Parameters: - elements: elements - file_path: file_path + element_id_list: The list of element id to export. + file_path: The output file path. Examples: >>> import element_controller as ec @@ -193,40 +176,39 @@ def export_obj_file(elements: List[int], file_path: str) -> None: >>> selected_elements = ec.get_all_identifiable_element_ids() >>> output_path = r"C:/exports/model.obj" >>> fc.export_obj_file(selected_elements, output_path) - - Returns: - None """ -def import_sat_file_silently(file_path: str, scale_factor: float, binary: bool) -> List[int]: - """Imports a SAT File without messages +def import_sat_file_silently(file_path: str, scale_factor: float, binary: bool) -> List[ElementId]: + """Imports a SAT File without messages. Parameters: - file_path: file_path - scale_factor: scale_factor - binary: binary + file_path: The input file path. + scale_factor: The scale factor. + binary: Is the import file binary. Returns: - List[int] + The imported list of element id. """ -def export_fbx_file(elements: List[int], file_path: str, fbx_format: int) -> None: - """Exports a FBX file +def export_fbx_file(element_id_list: List[ElementId], file_path: str, fbx_format: int) -> None: + """Exports a FBX file. Parameters: - elements: elements - file_path: file_path - fbx_format: fbx_format - Available formats: - - 0 or default: FBX binary(*.fbx) - - 1: FBX binary(*.fbx) - - 2: FBX ascii(*.fbx) - - 3: FBX encrypted(*.fbx) - - 4: FBX 6.0 binary(*.fbx) - - 5: FBX 6.0 ascii(*.fbx) - - 6: FBX 6.0 encrypted(*.fbx) + element_id_list: The list of element id to export. + file_path: The output file path. + fbx_format: The FBX format. + + Available values : + + + - 1 = "FBX binary(*.fbx)"; + - 2 = "FBX ascii(*.fbx)"; + - 3 = "FBX encrypted(*.fbx)"; + - 4 = "FBX 6.0 binary(*.fbx)"; + - 5 = "FBX 6.0 ascii(*.fbx)"; + - 6 = "FBX 6.0 encrypted(*.fbx)"; Examples: >>> import element_controller as ec @@ -240,48 +222,39 @@ def export_fbx_file(elements: List[int], file_path: str, fbx_format: int) -> Non >>> # Export as ASCII format >>> fbx_format = 2 # FBX ascii format >>> fc.export_fbx_file(selected_elements, output_path, fbx_format) - - Returns: - None """ def clear_errors() -> None: - """clear errors - - Returns: - None + """Clears all errors. """ -def import_3dc_file_with_glide(file_path: str) -> List[int]: - """Imports a 3DC file with glide +def import_3dc_file_with_glide(file_path: str) -> List[ElementId]: + """Imports a 3DC file with glide. Parameters: - file_path: file_path + file_path: The input file path. Returns: - imported element ID list + The imported list of element id. """ def import_btl_file(file_path: str) -> None: - """Imports a BTL file + """Imports a BTL file. Parameters: - file_path: file_path - - Returns: - None + file_path: The input file path. """ -def export_3dc_file(element_id_list: List[int], file_path: str) -> None: - """Exports a 3D file +def export_3dc_file(element_id_list: List[ElementId], file_path: str) -> None: + """Exports a 3D file. Parameters: - element_id_list: element_id_list - file_path: file_path + element_id_list: The list of element id to export. + file_path: The output file path. Examples: >>> import element_controller as ec @@ -290,50 +263,47 @@ def export_3dc_file(element_id_list: List[int], file_path: str) -> None: >>> selected_elements = ec.get_all_identifiable_element_ids() >>> output_path = r"C:/exports/model.3dc" >>> fc.export_3dc_file(selected_elements, output_path) - - Returns: - None """ def import_btl_file_for_nesting(file_path: str) -> None: - """Imports a BTL file for nesting + """Imports a BTL file for nesting. Parameters: - file_path: file_path - - Returns: - None + file_path: The input file path. """ def export_btl_file_for_nesting(file_path: str) -> None: - """Exports a BTL file for nesting + """Exports a BTL file for nesting. Parameters: - file_path: file_path + file_path: The output file path. Examples: >>> import file_controller as fc >>> output_path = r"C:/exports/nesting_project.btl" >>> fc.export_btl_file_for_nesting(output_path) - - Returns: - None """ -def export_rhino_file(element_id_list: List[int], file_path: str, version: int, use_default_assignment: bool, +def export_rhino_file(element_id_list: List[ElementId], file_path: str, version: int, use_default_assignment: bool, write_standard_attributes: bool) -> None: - """Exports a 3dm rhino file + """Exports a 3dm rhino file. Parameters: - element_id_list: element_id_list - file_path: file_path - version: version - use_default_assignment: use_default_assignment - write_standard_attributes: write_standard_attributes + element_id_list: The list of element id to export. + file_path: The output file path. + version: The rhino version : + + + - 5 = V5.0, + - 6 = V6.0, + - 7 = V7.0, + - 8 = V8.0 + use_default_assignment: True if default assignment is used. False if no attributes are exported. + write_standard_attributes: True if exported with standard attribute, false otherwise. Examples: >>> import element_controller as ec @@ -345,52 +315,51 @@ def export_rhino_file(element_id_list: List[int], file_path: str, version: int, >>> use_default_assignment = True >>> write_standard_attributes = False >>> fc.export_rhino_file(selected_elements, output_path, version, use_default_assignment, write_standard_attributes) - - Returns: - None """ -def import_bxf_file(file_path: str, insert_position: point_3d) -> List[int]: - """import bxf file +def import_bxf_file(file_path: str, insert_position: point_3d) -> List[ElementId]: + """Imports a BXF file. Parameters: - file_path: file_path - insert_position: insert_position + file_path: The import file path. + insert_position: The position where the imported elements will be inserted. Returns: - List[int] + The list of IDs of the imported elements. """ def get_blum_export_path() -> str: - """get blum export path + """Gets the path of the Blum export. Returns: - str + The path of the Blum export. """ def set_blum_export_path(path: str) -> None: - """set blum export path + """Sets the path of the Blum export. Parameters: - path: path - - Returns: - None + path: The new path for the Blum export. """ -def export_sat_file(elements: List[int], file_path: str, scale_factor: float, binary: bool, version: int) -> None: - """exports a SAT File +def export_sat_file(element_id_list: List[ElementId], file_path: str, scale_factor: float, binary: bool, version: int) -> None: + """Exports a SAT File. Parameters: - elements: elements - file_path: file_path - scale_factor: scale_factor - binary: binary - version: version + element_id_list: The list of element id to export. + file_path: The output file path. + scale_factor: The file scale factor. + binary: Whether to write the SAT file in binary or a human readable format. + version: The ACIS version to use : + + + - 3400 = v34.0 + - 3200 = v32.0 + - 2100 = v21.0 Examples: >>> import element_controller as ec @@ -402,18 +371,15 @@ def export_sat_file(elements: List[int], file_path: str, scale_factor: float, bi >>> binary_format = True >>> version = 25000 # SAT version >>> fc.export_sat_file(selected_elements, output_path, scale_factor, binary_format, version) - - Returns: - None """ -def export_glb_file(elements: List[int], file_path: str) -> None: - """exports a GLB File +def export_glb_file(element_id_list: List[ElementId], file_path: str) -> None: + """Exports a GLB File. Parameters: - elements: elements - file_path: file_path + element_id_list: The list of element id to export. + file_path: The output file path. Examples: >>> import element_controller as ec @@ -422,48 +388,51 @@ def export_glb_file(elements: List[int], file_path: str) -> None: >>> selected_elements = ec.get_all_identifiable_element_ids() >>> output_path = r"C:/exports/model.glb" >>> fc.export_glb_file(selected_elements, output_path) - - Returns: - None """ -def import_variant_file(file_path: str, insert_position: point_3d) -> List[int]: - """imports a variant by .val-File +def import_variant_file(file_path: str, insert_position: point_3d) -> List[ElementId]: + """Imports a variant (.val-File). Parameters: - file_path: file_path - insert_position: insert_position + file_path: The import file path. + insert_position: The position where the imported variant elements will be inserted. Returns: - imported element ID list + The imported list of element id. """ def import_element_light(file_path: str, insert_position: point_3d) -> int: - """import element light + """Imports a light element from a file. Parameters: - file_path: file_path - insert_position: insert_position + file_path: The import file path. + insert_position: The position where the imported light element will be inserted. Returns: - int + The ID of the imported light element. """ -def export_rhino_file_with_options(element_id_list: List[int], file_path: str, version: int, +def export_rhino_file_with_options(element_id_list: List[ElementId], file_path: str, version: int, use_default_assignment: bool, write_standard_attributes: bool, rhino_options: None) -> None: - """exports elements to a rhino 3dm file based on the export options + """Exports elements to a rhino 3dm file based on the export options. Parameters: - element_id_list: element_id_list - file_path: file_path - version: version - use_default_assignment: use_default_assignment - write_standard_attributes: write_standard_attributes - rhino_options: rhino_options + element_id_list: The list of element id to export. + file_path: The output file path. + version: The rhino version : + + + - 5 = V5.0, + - 6 = V6.0, + - 7 = V7.0, + - 8 = V8.0 + use_default_assignment: True if default assignment is used. False if no attributes are exported. + write_standard_attributes: True if exported with standard attribute, false otherwise. + rhino_options: The Rhino export option. Examples: >>> import element_controller as ec @@ -476,54 +445,50 @@ def export_rhino_file_with_options(element_id_list: List[int], file_path: str, v >>> write_standard_attributes = False >>> rhino_options = None # Use default options >>> fc.export_rhino_file_with_options(selected_elements, output_path, version, use_default_assignment, write_standard_attributes, rhino_options) - - Returns: - None """ -def import_3dc_file_with_options(file_path: str, import3dc_options: None) -> List[int]: - """imports a 3d or a 3dc file depending on the import options +def import_3dc_file_with_options(file_path: str, import_3dc_options: import_3dc_options) -> List[ElementId]: + """Imports a 3d or a 3dc file depending on the import options. Parameters: - file_path: file_path - import3dc_options: import3dc_options + file_path: The input file path. + import_3dc_options: The 3dc import options. Returns: - imported element ID list + The imported list of element id. """ -def get_import_3dc_options() -> 'import_3dc_options': - """get import 3dc options +def get_import_3dc_options() -> import_3dc_options: + """Get the 3dc import options. Returns: - import_3dc_options + The 3dc import options. """ def load_webgl_preset_file(file_path: str) -> None: - """loads a preset file for the WebGl export + """Loads a preset file for the WebGl export. Parameters: - file_path: file_path - - Returns: - None + file_path: The preset file path. """ -def export_step_file_extrude_drillings(elements: List[int], file_path: str, scale_factor: float, version: int, +def export_step_file_extrude_drillings(element_id_list: List[ElementId], file_path: str, scale_factor: float, version: int, text_mode: bool, imperial_units: bool) -> None: - """Exports a STEP file with extruded drillings + """Exports a STEP file with extruded drillings. Parameters: - elements: elements - file_path: file_path - scale_factor: scale_factor - version: version - text_mode: text_mode - imperial_units: imperial_units + element_id_list: The list of element id to export. + file_path: The output file path. + scale_factor: The file scale factor. + version: The file export version : + - 214 = STEP AP214 + - 203 = STEP AP203 (default value) + text_mode: Use text mode. PARAMETER UNUSED + imperial_units: Use imperial units. Examples: >>> import element_controller as ec @@ -536,23 +501,22 @@ def export_step_file_extrude_drillings(elements: List[int], file_path: str, scal >>> text_mode = False >>> imperial_units = False >>> fc.export_step_file_extrude_drillings(selected_elements, output_path, scale_factor, version, text_mode, imperial_units) - - Returns: - None """ -def export_step_file_cut_drillings(elements: List[int], file_path: str, scale_factor: float, version: int, +def export_step_file_cut_drillings(element_id_list: List[ElementId], file_path: str, scale_factor: float, version: int, text_mode: bool, imperial_units: bool) -> None: - """Exports a STEP file with extruded drillings + """Exports a STEP file with extruded drillings. Parameters: - elements: elements - file_path: file_path - scale_factor: scale_factor - version: version - text_mode: text_mode - imperial_units: imperial_units + element_id_list: The list of element id to export. + file_path: The output file path. + scale_factor: The file scale factor. + version: The file export version : + - 214 = STEP AP214 + - 203 = STEP AP203 (default value) + text_mode: Use text mode. PARAMETER UNUSED + imperial_units: Use imperial units. Examples: >>> import element_controller as ec @@ -565,60 +529,58 @@ def export_step_file_cut_drillings(elements: List[int], file_path: str, scale_fa >>> text_mode = False >>> imperial_units = False >>> fc.export_step_file_cut_drillings(selected_elements, output_path, scale_factor, version, text_mode, imperial_units) - - Returns: - None """ -def export_sat_file_cut_drillings(elements: List[int], file_path: str, +def export_sat_file_cut_drillings(element_id_list: List[ElementId], file_path: str, scale_factor: float, binary: bool, version: int) -> None: - """export sat file cut drillings + """Exports a SAT File with extruded drillings (cut drilling holes into bodies). Parameters: - elements: elements - file_path: file_path - scale_factor: scale_factor - binary: binary - version: version + element_id_list: The list of element id to export. + file_path: The output file path. + scale_factor: The file scale factor. + binary: Whether to write the SAT file in binary or a human readable format. + version: The ACIS version to use : - Returns: - None + + - 3400 = v34.0 + - 3200 = v32.0 + - 2100 = v21.0 """ -def upload_to_bim_team_and_create_share_link(elements: None - ) -> bim_team_upload_result: - """upload to bim team and create share link +def upload_to_bim_team_and_create_share_link(element_id_list: List[ElementId]) -> bim_team_upload_result: + """Exports the elements to BIMteam and creates a share link. Parameters: - elements: elements + element_id_list: The list of element id to export. Returns: - bim_team_upload_result + The result object with a result code and a share link. If the code is not ok (0), the share link string is empty. """ def export_dxf_file(file_path: str, dxf_layer_format_type: dxf_layer_format_type, dxf_export_version: dxf_export_version) -> bool: - """export dxf file + """Exports visible elements in the scene to a DXF file. Parameters: - file_path: file_path - dxf_layer_format_type: dxf_layer_format_type - dxf_export_version: dxf_export_version + file_path: The output file path. + dxf_layer_format_type: The format type of how to organize layers. + dxf_export_version: The dxf version to use for the export. Returns: - bool + True on successful export, false otherwise. """ def export_dstv_file(file_path: str) -> bool: - """export dstv file + """Exports active elements in the scene to a DSTV (.stp) file. Parameters: - file_path: file_path + file_path: The output file path. Returns: - bool + True on successful export, false otherwise. """ diff --git a/src/geometry_controller/__init__.pyi b/src/geometry_controller/__init__.pyi index de9fdbb..35323b9 100644 --- a/src/geometry_controller/__init__.pyi +++ b/src/geometry_controller/__init__.pyi @@ -1,1124 +1,914 @@ from typing import List +from cadwork.api_types import ElementId, UnsignedInt from cadwork.facet_list import facet_list from cadwork.point_3d import point_3d -def rotate_height_axis_90(element_id_list: List[int]) -> None: - """rotate height axis 90 +def rotate_height_axis_90(element_id_list: List[ElementId]) -> None: + """Rotates the element height axis 90 degrees. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ - -def rotate_height_axis_180(element_id_list: List[int]) -> None: - """rotate height axis 180 +def rotate_height_axis_180(element_id_list: List[ElementId]) -> None: + """Rotates the element height axis 180 degrees. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ - -def set_over_width(element_id_list: List[int], value: float) -> None: - """set over width +def set_over_width(element_id_list: List[ElementId], value: float) -> None: + """Sets the element overwidth. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The element overwidth. """ - -def set_over_height(element_id_list: List[int], value: float) -> None: - """set over height +def set_over_height(element_id_list: List[ElementId], value: float) -> None: + """Sets the element overheight. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The element overheight. """ - -def set_over_length(element_id_list: List[int], value: float) -> None: - """set over length +def set_over_length(element_id_list: List[ElementId], value: float) -> None: + """Sets the element overlength. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The element overlength. """ - -def set_rounding_width(element_id_list: List[int], value: float) -> None: - """set rounding width +def set_rounding_width(element_id_list: List[ElementId], value: float) -> None: + """Sets the element rounding width. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The element rounding width. """ - -def set_rounding_height(element_id_list: List[int], value: float) -> None: - """set rounding height +def set_rounding_height(element_id_list: List[ElementId], value: float) -> None: + """Sets the element rounding height. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The element rounding height. """ - -def set_rounding_length(element_id_list: List[int], value: float) -> None: - """set rounding length +def set_rounding_length(element_id_list: List[ElementId], value: float) -> None: + """Sets the element rounding length. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The element rounding length. """ - -def set_cross_correction_negative_width(element_id_list: List[int], value: float) -> None: - """set cross correction negative width +def set_cross_correction_negative_width(element_id_list: List[ElementId], value: float) -> None: + """Sets the element negative width cross correction. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The element negative width cross correction. """ - -def set_cross_correction_positive_width(element_id_list: List[int], value: float) -> None: - """set cross correction positive width +def set_cross_correction_positive_width(element_id_list: List[ElementId], value: float) -> None: + """Sets the element positive width cross correction. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The element positive width cross correction. """ - -def set_cross_correction_negative_height(element_id_list: List[int], value: float) -> None: - """set cross correction negative height +def set_cross_correction_negative_height(element_id_list: List[ElementId], value: float) -> None: + """Sets the element negative height cross correction. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The element negative height cross correction. """ - -def set_cross_correction_positive_height(element_id_list: List[int], value: float) -> None: - """set cross correction positive height +def set_cross_correction_positive_height(element_id_list: List[ElementId], value: float) -> None: + """Sets the element positive height cross correction. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The element positive height cross correction. """ - -def set_cross_correction_negative_length(element_id_list: List[int], value: float) -> None: - """set cross correction negative length +def set_cross_correction_negative_length(element_id_list: List[ElementId], value: float) -> None: + """Sets the element negative length cross correction. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The element negative length cross correction. """ - -def set_cross_correction_positive_length(element_id_list: List[int], value: float) -> None: - """set cross correction positive length +def set_cross_correction_positive_length(element_id_list: List[ElementId], value: float) -> None: + """Sets the element positive length cross correction. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: The element positive length cross correction. """ - -def apply_global_scale(element_id_list: List[int], scale: float, origin: point_3d) -> None: - """apply global scale +def apply_global_scale(element_id_list: List[ElementId], scale: float, origin: point_3d) -> None: + """Applies a global scale to element. Parameters: - element_id_list: element_id_list - scale: scale - origin: origin - - Returns: - None + element_id_list: The element id list. + scale: The global scale. + origin: The scaling origin. """ - -def auto_regenerate_axes(element_id_list: List[int]) -> None: - """auto regenerate axes +def auto_regenerate_axes(element_id_list: List[ElementId]) -> None: + """Automatically regenerates axes on element. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ - -def rotate_length_axis_90(element_id_list: List[int]) -> None: - """rotate length axis 90 +def rotate_length_axis_90(element_id_list: List[ElementId]) -> None: + """Rotates element length axis 90 degrees. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ - -def rotate_length_axis_180(element_id_list: List[int]) -> None: - """rotate length axis 180 +def rotate_length_axis_180(element_id_list: List[ElementId]) -> None: + """Rotates element length axis 180 degrees. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ - -def invert_model(element_id_list: List[int]) -> None: - """invert model +def invert_model(element_id_list: List[ElementId]) -> None: + """Inverts element model. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The element id list. """ - -def set_width_real(elements: List[int], width: float) -> None: - """set width real +def set_width_real(element_id_list: List[ElementId], width: float) -> None: + """Sets the element real width. Parameters: - elements: elements - width: width - - Returns: - None + element_id_list: The element id list. + width: The element real width. """ - -def set_height_real(elements: List[int], height: float) -> None: - """set height real +def set_height_real(element_id_list: List[ElementId], height: float) -> None: + """Sets the element real height. Parameters: - elements: elements - height: height - - Returns: - None + element_id_list: The element id list. + height: The element real height. """ - -def set_length_real(elements: List[int], length: float) -> None: - """set length real +def set_length_real(element_id_list: List[ElementId], length: float) -> None: + """Sets the element real length. Parameters: - elements: elements - length: length - - Returns: - None + element_id_list: The element id list. + length: The element real length. """ - -def rotate_height_axis_2_points(elements: List[int], point1: point_3d, point2: point_3d) -> None: - """rotate height axis 2 points +def rotate_height_axis_2_points(element_id_list: List[ElementId], point1: point_3d, point2: point_3d) -> None: + """Rotates the element height axis via 2 points. Parameters: - elements: elements - point1: point1 - point2: point2 - - Returns: - None + element_id_list: The element id list. + point1: The first point. + point2: The second point. """ - def clear_errors() -> None: - """clear errors - - Returns: - None + """Clears all errors. """ - -def set_drilling_tolerance(elements: List[int], tolerance: float) -> None: - """set drilling tolerance +def set_drilling_tolerance(element_id_list: List[ElementId], tolerance: float) -> None: + """Sets the drilling tolerance of the axis. Parameters: - elements: elements - tolerance: tolerance - - Returns: - None + element_id_list: The element id list. + tolerance: The new drilling tolerance. """ - -def auto_regenerate_axes_silently(element_id_list: List[int]) -> None: - """auto regenerate axes silently +def auto_regenerate_axes_silently(element_id_list: List[ElementId]) -> None: + """Automatically regenerates axes on elements without any user interaction. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The list of element IDs for which the axes will be regenerated. """ - -def rotate_length_axis_2_points(elements: List[int], point1: point_3d, point2: point_3d) -> None: - """rotate length axis 2 points +def rotate_length_axis_2_points(element_id_list: List[ElementId], point1: point_3d, point2: point_3d) -> None: + """Rotates the element length axis via 2 points. Parameters: - elements: elements - point1: point1 - point2: point2 - - Returns: - None + element_id_list: The element id list. + point1: The first point. + point2: The second point. """ - -def get_width(element_id: int) -> float: - """get width +def get_width(element_id: ElementId) -> float: + """Gets the element width. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element width. """ - -def get_height(element_id: int) -> float: - """get height +def get_height(element_id: ElementId) -> float: + """Gets the element height. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element height. """ - -def get_length(element_id: int) -> float: - """get length +def get_length(element_id: ElementId) -> float: + """Gets the element length. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element length. """ - -def get_p1(element_id: int) -> point_3d: - """get p1 +def get_p1(element_id: ElementId) -> point_3d: + """Gets the element P1. Parameters: - element_id: element_id + element_id: The element Id. Returns: - point_3d + The element P1. """ - -def get_p2(element_id: int) -> point_3d: - """get p2 +def get_p2(element_id: ElementId) -> point_3d: + """Gets the element P2. Parameters: - element_id: element_id + element_id: The element Id. Returns: - point_3d + The element P2. """ - -def get_p3(element_id: int) -> point_3d: - """get p3 +def get_p3(element_id: ElementId) -> point_3d: + """Gets the element P3. Parameters: - element_id: element_id + element_id: The element Id. Returns: - point_3d + The element P3. """ - -def get_start_height_cut_angle(element_id: int) -> float: - """get start height cut angle +def get_start_height_cut_angle(element_id: ElementId) -> float: + """Gets the element start height cut angle. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element start height cut angle. """ - -def get_start_width_cut_angle(element_id: int) -> float: - """get start width cut angle +def get_start_width_cut_angle(element_id: ElementId) -> float: + """Gets the element start width cut angle. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element start width cut angle. """ - -def get_end_height_cut_angle(element_id: int) -> float: - """get end height cut angle +def get_end_height_cut_angle(element_id: ElementId) -> float: + """Gets the element end height cut angle. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element end height cut angle. """ - -def get_end_width_cut_angle(element_id: int) -> float: - """get end width cut angle +def get_end_width_cut_angle(element_id: ElementId) -> float: + """Gets the element end width cut angle. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element end width cut angle. """ - -def get_over_width(element_id: int) -> float: - """get over width +def get_over_width(element_id: ElementId) -> float: + """Gets the element overwidth. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element overwidth. """ - -def get_over_height(element_id: int) -> float: - """get over height +def get_over_height(element_id: ElementId) -> float: + """Gets the element overheight. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element overheight. """ - -def get_over_length(element_id: int) -> float: - """get over length +def get_over_length(element_id: ElementId) -> float: + """Gets the element overlength. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element overlength. """ - -def get_rounding_width(element_id: int) -> float: - """get rounding width +def get_rounding_width(element_id: ElementId) -> float: + """Gets the element rounding width. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element rounding width. """ - -def get_rounding_height(element_id: int) -> float: - """get rounding height +def get_rounding_height(element_id: ElementId) -> float: + """Gets the element rounding height. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element rounding height. """ - -def get_rounding_length(element_id: int) -> float: - """get rounding length +def get_rounding_length(element_id: ElementId) -> float: + """Gets the element rounding length. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element rounding length. """ - -def get_cross_correction_negative_width(element_id: int) -> float: - """get cross correction negative width +def get_cross_correction_negative_width(element_id: ElementId) -> float: + """Gets the element negative width cross correction. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element negative width cross correction. """ - -def get_cross_correction_positive_width(element_id: int) -> float: - """get cross correction positive width +def get_cross_correction_positive_width(element_id: ElementId) -> float: + """Gets the element positive width cross correction. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element positive width cross correction. """ - -def get_cross_correction_negative_height(element_id: int) -> float: - """get cross correction negative height +def get_cross_correction_negative_height(element_id: ElementId) -> float: + """Gets the element negative height cross correction. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element negative height cross correction. """ - -def get_cross_correction_positive_height(element_id: int) -> float: - """get cross correction positive height +def get_cross_correction_positive_height(element_id: ElementId) -> float: + """Gets the element positive height cross correction. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element positive height cross correction. """ - -def get_cross_correction_negative_length(element_id: int) -> float: - """get cross correction negative length +def get_cross_correction_negative_length(element_id: ElementId) -> float: + """Gets the element negative length cross correction. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element negative length cross correction. """ - -def get_cross_correction_positive_length(element_id: int) -> float: - """get cross correction positive length +def get_cross_correction_positive_length(element_id: ElementId) -> float: + """Gets the element positive length cross correction. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element positive length cross correction. """ - -def get_weight(element_id: int) -> float: - """get weight +def get_weight(element_id: ElementId) -> float: + """Gets the element real weight. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element real weight. """ - -def get_list_weight(element_id: int) -> float: - """get list weight +def get_list_weight(element_id: ElementId) -> float: + """Gets the element list weight. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element list weight. """ - -def get_volume(element_id: int) -> float: - """get volume +def get_volume(element_id: ElementId) -> float: + """Gets the element rough volume (does not include negative geometry operations, such as end-types, drillings, connectors, openings, and MEP elements). Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element rough volume. """ - -def get_list_volume(element_id: int) -> float: - """get list volume +def get_list_volume(element_id: ElementId) -> float: + """Gets the element list volume. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element list volume. """ - -def get_xl(element_id: int) -> point_3d: - """get xl +def get_xl(element_id: ElementId) -> point_3d: + """Gets the element length axis direction (direction from P1 to P2). Parameters: - element_id: element_id + element_id: The element Id. Returns: - point_3d + The element XL vector. """ - -def get_yl(element_id: int) -> point_3d: - """get yl +def get_yl(element_id: ElementId) -> point_3d: + """Gets the element width axis direction (ZL cross XL). Parameters: - element_id: element_id + element_id: The element Id. Returns: - point_3d + The element YL vector. """ - -def get_zl(element_id: int) -> point_3d: - """get zl +def get_zl(element_id: ElementId) -> point_3d: + """Gets the element height/thickness axis direction (direction from P1 to P3). Parameters: - element_id: element_id + element_id: The element Id. Returns: - point_3d + The element ZL vector. """ - -def get_center_of_gravity(element_id: int) -> point_3d: - """get center of gravity +def get_center_of_gravity(element_id: ElementId) -> point_3d: + """Gets the element center of gravity. Parameters: - element_id: element_id + element_id: The element Id. Returns: - point_3d + The element center of gravity position. """ - -def get_reference_side(element_id: int) -> int: - """get reference side +def get_reference_side(element_id: ElementId) -> int: + """Gets the element reference side. Parameters: - element_id: element_id + element_id: The element Id. Returns: - int + The element reference side. """ - -def get_element_vertices(element_id: int) -> List[point_3d]: - """get element vertices +def get_element_vertices(element_id: ElementId) -> List[point_3d]: + """Gets the element vertices. Parameters: - element_id: element_id + element_id: The element Id. Returns: - List[point_3d] + The element vertice list. """ - -def get_element_facets(element_id: int) -> facet_list: - """get element facets +def get_element_facets(element_id: ElementId) -> facet_list: + """Gets the element facet list. Parameters: - element_id: element_id + element_id: The element Id. Returns: - facet_list + The element facet list. """ - -def get_list_width(element_id: int) -> float: - """get list width +def get_list_width(element_id: ElementId) -> float: + """Gets the element list width. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element list width. """ - -def get_list_height(element_id: int) -> float: - """get list height +def get_list_height(element_id: ElementId) -> float: + """Gets the element list height. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element list height. """ - -def get_list_length(element_id: int) -> float: - """get list length +def get_list_length(element_id: ElementId) -> float: + """Gets the element list length. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The element list length. """ - -def get_minimum_distance_between_elements(first_id: int, second_id: int) -> float: - """get minimum distance between elements +def get_minimum_distance_between_elements(first_id: ElementId, second_id: ElementId) -> float: + """Gets the minimum distance between 2 elements. Parameters: - first_id: first_id - second_id: second_id + first_id: The first element id. + second_id: The second element id. Returns: - float + The minimum distance. """ - -def get_total_area_of_all_faces(element: int) -> float: - """get total area of all faces +def get_total_area_of_all_faces(element_id: ElementId) -> float: + """Gets the total area of all faces for element. Parameters: - element: element + element_id: The element Id. Returns: - float + The element total faces area. """ - -def get_area_of_front_face(element: int) -> float: - """get area of front face +def get_area_of_front_face(element_id: ElementId) -> float: + """Gets the front face area for element. Parameters: - element: element + element_id: The element Id. Returns: - float + The element front face area. """ - -def get_door_surface(elements: List[int]) -> float: - """get door surface +def get_door_surface(element_id_list: List[ElementId]) -> float: + """Gets the element door surface. Parameters: - elements: elements + element_id_list: The element id list. Returns: - float + The element door surface. """ - -def get_window_surface(elements: List[int]) -> float: - """get window surface +def get_window_surface(element_id_list: List[ElementId]) -> float: + """Gets the element window surface. Parameters: - elements: elements + element_id_list: The element id list. Returns: - float + The element window surface. """ - def get_local_x() -> point_3d: - """get local x + """Gets the rotated global coordinate direction (X'). Returns: - point_3d + The local X vector. """ - def get_local_z() -> point_3d: - """get local z + """Gets the rotated global coordinate direction (Z'). Returns: - point_3d + The local Y vector. """ - def get_local_y() -> point_3d: - """get local y + """Gets the rotated global coordinate direction (Y'). Returns: - point_3d + The local Z vector. """ - -def get_drilling_tolerance(element: int) -> float: - """get drilling tolerance +def get_drilling_tolerance(element_id: ElementId) -> float: + """Gets the drilling tolerance of an axis. Parameters: - element: element + element_id: The element Id. Returns: - float + The drilling tolerance. """ - -def get_element_reference_face_vertices(element_id: int) -> List[point_3d]: - """get element reference face vertices +def get_element_reference_face_vertices(element_id: ElementId) -> List[point_3d]: + """Gets the vertices of the reference side. Parameters: - element_id: element_id + element_id: The element Id. Returns: - List[point_3d] + The vertexlist of all points. """ - -def get_element_reference_face_area(element_id: int) -> float: - """get element reference face area +def get_element_reference_face_area(element_id: ElementId) -> float: + """Gets the area of the reference side. Parameters: - element_id: element_id + element_id: The element Id. Returns: - float + The area(size) of reference face. """ - -def get_center_of_gravity_for_list(elements: List[int]) -> point_3d: - """get center of gravity for list +def get_center_of_gravity_for_list(element_id_list: List[ElementId]) -> point_3d: + """Gets the center of gravity for a list of elements. Parameters: - elements: elements + element_id_list: The list of element IDs. Returns: - point_3d + The center of gravity as a vector3D. """ - -def get_center_of_gravity_for_list_considering_materials(elements: List[int]) -> point_3d: - """get center of gravity for list considering materials +def get_center_of_gravity_for_list_considering_materials(element_id_list: List[ElementId]) -> point_3d: + """Gets the center of gravity for a list of elements, considering their materials. Parameters: - elements: elements + element_id_list: The list of element IDs. Returns: - point_3d + The center of gravity as a vector3D. """ - -def get_element_facet_count(element_id: int) -> int: - """get element facet count +def get_element_facet_count(element_id: ElementId) -> UnsignedInt: + """Gets the count of facets for a specific element. Parameters: - element_id: element_id + element_id: The ID of the element. Returns: - int + The count of facets. """ - -def get_weight_real(element_id: int) -> float: - """get weight real +def get_weight_real(element_id: ElementId) -> float: + """Gets the real weight of the element. Parameters: - element_id: element_id + element_id: The ID of the element. Returns: - float + The real weight of the element. """ - -def get_actual_physical_weight(element: int) -> float: - """get actual physical weight +def get_actual_physical_weight(element_id: ElementId) -> float: + """Gets the actual physical weight. Parameters: - element: element + element_id: The element id. Returns: - float + The actual physical weight. """ - -def get_actual_physical_volume(element_id: int) -> float: - """Gets actual physical volume (includes negative geometry operations, such as end-types, drillings, connectors, - openings, and MEP elements) (it might also take into account different drilling - bodies and counterbores in a connector) - +def get_actual_physical_volume(element_id: ElementId) -> float: + """Gets actual physical volume (includes negative geometry operations, such as end-types, drillings, connectors, openings, and MEP elements; it might also take into account different drilling bodies and counterbores in a connector). Parameters: - element_id: element_id + element_id: The element id. Returns: - float + The actual physical volume. """ - def are_facets_coplanar(first_facet: List[point_3d], second_facet: List[point_3d]) -> bool: - """are facets coplanar + """Tests if facets are coplanar. Parameters: - first_facet: first_facet - second_facet: second_facet + first_facet: The first facet. + second_facet: The second facet. Returns: - bool + True if facets are coplanar, false otherwise. """ - -def get_round_machine_rough_part_negative_width(element_id: int) -> bool: - """get round machine rough part negative width +def get_round_machine_rough_part_negative_width(element_id: ElementId) -> bool: + """Gets the value of option RoundMachineRoughPartNegativeWidth. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + The option RoundMachineRoughPartNegativeWidth value. """ - -def set_round_machine_rough_part_negative_width(elements: List[int], value: bool) -> None: - """set round machine rough part negative width +def set_round_machine_rough_part_negative_width(element_id_list: List[ElementId], value: bool) -> None: + """Sets the value of option RoundMachineRoughPartNegativeWidth. Parameters: - elements: elements - value: value - - Returns: - None + element_id_list: The element id list. + value: The new option RoundMachineRoughPartNegativeWidth value. """ - -def get_round_machine_rough_part_positive_width(element_id: int) -> bool: - """get round machine rough part positive width +def get_round_machine_rough_part_positive_width(element_id: ElementId) -> bool: + """Gets the value of option RoundMachineRoughPartPositiveWidth. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + The option RoundMachineRoughPartPositiveWidth value. """ - -def set_round_machine_rough_part_positive_width(elements: List[int], value: bool) -> None: - """set round machine rough part positive width +def set_round_machine_rough_part_positive_width(element_id_list: List[ElementId], value: bool) -> None: + """Sets the value of option RoundMachineRoughPartPositiveWidth. Parameters: - elements: elements - value: value - - Returns: - None + element_id_list: The element id list. + value: The new option RoundMachineRoughPartPositiveWidth value. """ - -def get_round_machine_rough_part_negative_height(element_id: int) -> bool: - """get round machine rough part negative height +def get_round_machine_rough_part_negative_height(element_id: ElementId) -> bool: + """Gets the value of option RoundMachineRoughPartNegativeHeight. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + The option RoundMachineRoughPartNegativeHeight value. """ - -def set_round_machine_rough_part_negative_height(elements: List[int], value: bool) -> None: - """set round machine rough part negative height +def set_round_machine_rough_part_negative_height(element_id_list: List[ElementId], value: bool) -> None: + """Sets the value of option RoundMachineRoughPartNegativeHeight. Parameters: - elements: elements - value: value - - Returns: - None + element_id_list: The element id list. + value: The new option RoundMachineRoughPartNegativeHeight value. """ - -def get_round_machine_rough_part_positive_height(element_id: int) -> bool: - """get round machine rough part positive height +def get_round_machine_rough_part_positive_height(element_id: ElementId) -> bool: + """Gets the value of option RoundMachineRoughPartPositiveHeight. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + The option RoundMachineRoughPartPositiveHeight value. """ - -def set_round_machine_rough_part_positive_height(elements: List[int], value: bool) -> None: - """set round machine rough part positive height +def set_round_machine_rough_part_positive_height(element_id_list: List[ElementId], value: bool) -> None: + """Sets the value of option RoundMachineRoughPartPositiveHeight. Parameters: - elements: elements - value: value - - Returns: - None + element_id_list: The element id list. + value: The new option RoundMachineRoughPartPositiveHeight options. """ - -def get_round_machine_rough_part_negative_length(element_id: int) -> bool: - """get round machine rough part negative length +def get_round_machine_rough_part_negative_length(element_id: ElementId) -> bool: + """Gets the value of option RoundMachineRoughPartNegativeLength. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + The option RoundMachineRoughPartNegativeLength value. """ - -def set_round_machine_rough_part_negative_length(elements: List[int], value: bool) -> None: - """set round machine rough part negative length +def set_round_machine_rough_part_negative_length(element_id_list: List[ElementId], value: bool) -> None: + """Sets the value of option RoundMachineRoughPartNegativeLength. Parameters: - elements: elements - value: value - - Returns: - None + element_id_list: The element id list. + value: The new option RoundMachineRoughPartNegativeLength value. """ - -def get_round_machine_rough_part_positive_length(element_id: int) -> bool: - """get round machine rough part positive length +def get_round_machine_rough_part_positive_length(element_id: ElementId) -> bool: + """Gets the value of option RoundMachineRoughPartPositiveLength. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + The option RoundMachineRoughPartPositiveLength value. """ - -def set_round_machine_rough_part_positive_length(elements: List[int], value: bool) -> None: - """set round machine rough part positive length +def set_round_machine_rough_part_positive_length(element_id_list: List[ElementId], value: bool) -> None: + """Sets the value of option RoundMachineRoughPartPositiveLength. Parameters: - elements: elements - value: value - - Returns: - None + element_id_list: The element id list. + value: The new option RoundMachineRoughPartPositiveLength value. """ - def get_standard_element_width_from_guid(standard_element_guid: str) -> float: - """get standard element width from guid + """Gets the standard element width from guid. Parameters: - standard_element_guid: standard_element_guid + standard_element_guid: The standard element guid. Returns: - float + The standard element width. """ - def get_standard_element_height_from_guid(standard_element_guid: str) -> float: - """get standard element height from guid + """Gets the standard element height from guid. Parameters: - standard_element_guid: standard_element_guid + standard_element_guid: The standard element guid. Returns: - float + The standard element height. """ - def get_standard_element_length_from_guid(standard_element_guid: str) -> float: - """get standard element length from guid + """Gets the standard element length from guid. Parameters: - standard_element_guid: standard_element_guid + standard_element_guid: The standard element guid. Returns: - float + The standard element length. """ - def get_standard_element_width_from_name(standard_element_name: str) -> float: - """get standard element width from name + """Gets the standard element width from name. Parameters: - standard_element_name: standard_element_name + standard_element_name: The standard element name. Returns: - float + The standard element width. """ - def get_standard_element_height_from_name(standard_element_name: str) -> float: - """get standard element height from name + """Gets the standard element height from name. Parameters: - standard_element_name: standard_element_name + standard_element_name: The standard element name. Returns: - float + The standard element height. """ - def get_standard_element_length_from_name(standard_element_name: str) -> float: - """get standard element length from name - - Parameters: - standard_element_name: standard_element_name - - Returns: - float - """ - - -def get_last_error(error_code: int) -> str: - """get last error + """Gets the standard element length from name. Parameters: - error_code: error_code + standard_element_name: The standard element name. Returns: - str + The standard element length. """ diff --git a/src/list_controller/__init__.pyi b/src/list_controller/__init__.pyi index 710163d..5f92be7 100644 --- a/src/list_controller/__init__.pyi +++ b/src/list_controller/__init__.pyi @@ -1,185 +1,122 @@ from typing import List +from cadwork.api_types import ElementId, UnsignedInt -def get_last_error(error_code: int) -> str: - """Gets the last error +def export_production_list(element_id_list: List[ElementId], file_path: str) -> None: + """Exports a production list to the given file path. Parameters: - error_code: error_code - - Returns: - error string - """ - - -def export_production_list(element_id_list: List[int], file_path: str) -> None: - """Exports a production list - - Parameters: - element_id_list: element_id_list - file_path: file_path - - Returns: - None + element_id_list: The list of element IDs to be exported. + file_path: The path of the target file for the export. """ - -def export_part_list(element_id_list: List[int], file_path: str) -> None: - """Exports a part list +def export_part_list(element_id_list: List[ElementId], file_path: str) -> None: + """Exports a part list to the specified file path. Parameters: - element_id_list: element_id_list - file_path: file_path - - Returns: - None + element_id_list: The list of element IDs to be exported. + file_path: The path of the target file for the export. """ - -def check_position_numbers_production_list() -> List[int]: - """Checks the production list numbers and returns the element ids with discrepancies +def check_position_numbers_production_list() -> List[ElementId]: + """Checks the production list numbers and returns the element IDs that have discrepancies. Returns: - element ids with discrepancies + The element IDs with discrepancies. """ - -def check_position_numbers_part_list() -> List[int]: - """Checks the part list numbers and returns the element ids with discrepancies +def check_position_numbers_part_list() -> List[ElementId]: + """Checks the part list numbers and returns the element IDs that have discrepancies. Returns: - element ids with discrepancies + The element IDs with discrepancies. """ - def clear_errors() -> None: - """clear errors - - Returns: - None + """Clears all errors. """ - -def export_production_list_with_settings(element_id_list: List[int], file_path: str, settings_file_path: str) -> None: - """export production list with settings +def export_production_list_with_settings(element_id_list: List[ElementId], file_path: str, settings_file_path: str) -> None: + """Exports a production list using an additional settings file. Parameters: - element_id_list: element_id_list - file_path: file_path - settings_file_path: settings_file_path - - Returns: - None + element_id_list: The list of element IDs to be exported. + file_path: The path of the target file for the export. + settings_file_path: The path to the settings file to be used for export. """ - -def export_part_list_with_settings(element_id_list: List[int], file_path: str, settings_file_path: str) -> None: - """export part list with settings +def export_part_list_with_settings(element_id_list: List[ElementId], file_path: str, settings_file_path: str) -> None: + """Exports a part list using an additional settings file. Parameters: - element_id_list: element_id_list - file_path: file_path - settings_file_path: settings_file_path - - Returns: - None + element_id_list: The list of element IDs to be exported. + file_path: The path of the target file for the export. + settings_file_path: The path to the settings file to be used for export. """ - -def generate_new_production_list_numbers(elements: List[int]) -> None: - """generate new production list numbers +def generate_new_production_list_numbers(element_id_list: List[ElementId]) -> None: + """Generates new production list numbers for the specified elements. Parameters: - elements: elements - - Returns: - None + element_id_list: The list of elements to generate numbers for. """ - -def generate_new_part_list_numbers(elements: List[int]) -> None: - """generate new part list numbers +def generate_new_part_list_numbers(element_id_list: List[ElementId]) -> None: + """Generates new part list numbers for the specified elements. Parameters: - elements: elements - - Returns: - None + element_id_list: The list of elements to generate numbers for. """ - def load_production_list_calculation_settings(settings_file_path: str) -> None: - """load production list calculation settings + """Loads the production list calculation settings from a file. Parameters: - settings_file_path: settings_file_path - - Returns: - None + settings_file_path: The path to the settings file to be loaded. """ - def load_part_list_calculation_settings(settings_file_path: str) -> None: - """load part list calculation settings + """Loads the part list calculation settings from a file. Parameters: - settings_file_path: settings_file_path - - Returns: - None + settings_file_path: The path to the settings file to be loaded. """ - -def generate_new_production_list_silently(elements: List[int], starting_number: int, keep_existing_numbers: bool, +def generate_new_production_list_silently(element_id_list: List[ElementId], starting_number: UnsignedInt, keep_existing_numbers: bool, with_containers: bool) -> None: - """generate new production list silently + """Generates new production list numbers silently starting from a given number, optionally keeping existing numbers and considering container elements. Parameters: - elements: elements - starting_number: starting_number - keep_existing_numbers: keep_existing_numbers - with_containers: with_containers - - Returns: - None + element_id_list: The list of elements to generate numbers for. + starting_number: The number from which to start assigning new numbers. + keep_existing_numbers: Whether or not to retain already assigned numbers in the list. + with_containers: Whether to include container elements in the number generation. """ - -def generate_new_part_list_silently(elements: List[int], starting_number: int, keep_existing_numbers: bool, +def generate_new_part_list_silently(element_id_list: List[ElementId], starting_number: UnsignedInt, keep_existing_numbers: bool, with_containers: bool) -> None: - """generate new part list silently + """Generates new part list numbers silently starting from a given number, optionally keeping existing numbers and considering container elements. Parameters: - elements: elements - starting_number: starting_number - keep_existing_numbers: keep_existing_numbers - with_containers: with_containers - - Returns: - None + element_id_list: The list of elements to generate numbers for. + starting_number: The number from which to start assigning new numbers. + keep_existing_numbers: Whether or not to retain already assigned numbers in the list. + with_containers: Whether to include container elements in the number generation. """ - -def export_cover_list(element_id_list: List[int], file_path: str) -> None: - """Exports a Wall/Roof/Floor list +def export_cover_list(element_id_list: List[ElementId], file_path: str) -> None: + """Exports a Wall, Roof, or Floor list to the specified file path. Parameters: - element_id_list: element_id_list - file_path: file_path - - Returns: - None + element_id_list: The list of element IDs to be exported. + file_path: The path of the target file for the export. """ - -def export_cover_list_with_settings(element_id_list: List[int], file_path: str, settings_file_path: str) -> None: - """Exports a Wall/Roof/Floor list with settings file +def export_cover_list_with_settings(element_id_list: List[ElementId], file_path: str, settings_file_path: str) -> None: + """Exports a Wall, Roof, or Floor list to the specified file path using an additional settings file. Parameters: - element_id_list: element_id_list - file_path: file_path - settings_file_path: settings_file_path - - Returns: - None + element_id_list: The list of element IDs to be exported. + file_path: The path of the target file for the export. + settings_file_path: The path to the settings file to be used for export. """ diff --git a/src/machine_controller/__init__.pyi b/src/machine_controller/__init__.pyi index ce864ef..585ba29 100644 --- a/src/machine_controller/__init__.pyi +++ b/src/machine_controller/__init__.pyi @@ -1,23 +1,17 @@ from typing import List from cadwork import vertex_list +from cadwork.api_types import ElementId +from cadwork.btl_version import btl_version +from cadwork.hundegger_machine_type import hundegger_machine_type +from cadwork.weinmann_mfb_version import weinmann_mfb_version -def get_last_error(error_code: int) -> str: - """Gets the last error +def export_btl(btl_version: btl_version, file_path: str) -> None: + """Exports a BTL file. Parameters: - error_code: error_code - - Returns: - error string - """ - -def export_btl(btl_version: int, file_path: str) -> None: - """Exports a BTL file - - Parameters: - btl_version: btl_version - file_path: file_path + btl_version: The BTL version. + file_path: The export file path. Examples: >>> import cadwork @@ -26,32 +20,26 @@ def export_btl(btl_version: int, file_path: str) -> None: >>> btl_version = cadwork.btl_version.btlx_2_1.value >>> output_path = "C:/exports/timber_project.btlx" >>> mc.export_btl(btl_version, output_path) - - Returns: - None """ -def export_weinmann_mfb(mfb_version: int) -> None: - """Exports a WUP file +def export_weinmann_mfb(mfb_version: weinmann_mfb_version) -> None: + """Exports a Weinmann MFB file. Parameters: - mfb_version: mfb_version + mfb_version: The Weinmann MFB version. Examples: >>> import machine_controller as mc >>> mfb_version = cadwork.weinmann_mfb_version.wup_3_4.value >>> mc.export_weinmann_mfb(mfb_version) - - Returns: - None """ -def export_hundegger(hundeggertype: int) -> None: - """Exports a Hundegger file +def export_hundegger(hundeggertype: hundegger_machine_type) -> None: + """Exports a Hundegger file. Parameters: - hundeggertype: hundeggertype + hundeggertype: The Hundegger machine type. Examples: >>> import cadwork @@ -59,17 +47,14 @@ def export_hundegger(hundeggertype: int) -> None: >>> hundegger_type = cadwork.hundegger_machine_type.k2.value >>> mc.export_hundegger(hundegger_type) - - Returns: - None """ -def export_hundegger_with_file_path(hundeggertype: int, file_path: str) -> None: - """Exports a Hundegger file +def export_hundegger_with_file_path(hundeggertype: hundegger_machine_type, file_path: str) -> None: + """Exports a Hundegger file. Parameters: - hundeggertype: hundeggertype - file_path: file_path + hundeggertype: The Hundegger machine type. + file_path: The export file path. Examples: >>> import cadwork @@ -78,18 +63,15 @@ def export_hundegger_with_file_path(hundeggertype: int, file_path: str) -> None: >>> hundegger_type = cadwork.hundegger_machine_type.k2.value >>> output_path = "C:/exports/hundegger_project.k2" >>> mc.export_hundegger_with_file_path(hundegger_type, output_path) - - Returns: - None """ -def export_hundegger_with_file_path_and_presetting(hundeggertype: int, file_path: str, presetting: str) -> None: - """Exports a Hundegger file +def export_hundegger_with_file_path_and_presetting(hundeggertype: hundegger_machine_type, file_path: str, presetting: str) -> None: + """Exports a Hundegger file. Parameters: - hundeggertype: hundeggertype - file_path: file_path - presetting: presetting + hundeggertype: The Hundegger machine type. + file_path: The export file path. + presetting: The presetting file path (.xml). Examples: >>> import cadwork @@ -99,18 +81,15 @@ def export_hundegger_with_file_path_and_presetting(hundeggertype: int, file_path >>> output_path = r"C:/exports/hundegger_project.k2" >>> presetting_file = r"...3d/Machine/Hundegger/K2/hundegger_settings.xml" >>> mc.export_hundegger_with_file_path_and_presetting(hundegger_type, output_path, presetting_file) - - Returns: - None """ -def export_btl_with_presetting(btl_version: int, file_path: str, presetting: str) -> None: - """Exports a BTL file with a presetting file +def export_btl_with_presetting(btl_version: btl_version, file_path: str, presetting: str) -> None: + """Exports a BTL file with a presetting file. Parameters: - btl_version: btl_version - file_path: file_path - presetting: presetting + btl_version: The BTL version. + file_path: The export file path. + presetting: The presetting file path (.xml). Examples: >>> import cadwork @@ -120,17 +99,14 @@ def export_btl_with_presetting(btl_version: int, file_path: str, presetting: str >>> output_path = r"C:/exports/timber_project.btlx" >>> presetting_file = r"...3d/Machine/BTL/btl_settings.xml" >>> mc.export_btl_with_presetting(btl_version, output_path, presetting_file) - - Returns: - None """ -def calculate_btl_machine_data(elements: List[int], btl_version: int) -> None: - """Calculates the Machine Data for BTL +def calculate_btl_machine_data(element_id_list: List[ElementId], btl_version: btl_version) -> None: + """Calculates the Machine Data for BTL. Parameters: - elements: elements - btl_version: btl_version + element_id_list: The list of element Id. + btl_version: The BTL version. Examples: >>> import cadwork @@ -140,17 +116,14 @@ def calculate_btl_machine_data(elements: List[int], btl_version: int) -> None: >>> beam_elements = ec.get_all_identifiable_element_ids() >>> btl_version = cadwork.btl_version.btlx_2_1.value >>> mc.calculate_btl_machine_data(beam_elements, btl_version) - - Returns: - None """ -def calculate_hundegger_machine_data(elements: List[int], hunderggertype: int) -> None: - """Calculates the Machine Data for Hundegger +def calculate_hundegger_machine_data(element_id_list: List[ElementId], hundeggertype: hundegger_machine_type) -> None: + """Calculates the Machine Data for Hundegger. Parameters: - elements: elements - hunderggertype: hunderggertype + element_id_list: The list of element Id. + hundeggertype: The Hundegger machine type. Examples: >>> import cadwork @@ -160,28 +133,22 @@ def calculate_hundegger_machine_data(elements: List[int], hunderggertype: int) - >>> beam_elements = ec.get_all_identifiable_element_ids() >>> hundegger_type = cadwork.hundegger_machine_type.k2.value >>> mc.calculate_hundegger_machine_data(beam_elements, hundegger_type) - - Returns: - None """ -def load_hundegger_calculation_set(hundeggertype: int, file_path: str) -> None: - """load hundegger calculation set +def load_hundegger_calculation_set(hundeggertype: hundegger_machine_type, file_path: str) -> None: + """Loads the Hundegger calculation set. Parameters: - hundeggertype: hundeggertype - file_path: file_path - - Returns: - None + hundeggertype: The Hundegger machine type. + file_path: The file path of the calculation set. """ -def export_hundegger_with_file_path_silent(hundeggertype: int, file_path: str) -> None: - """Exports a Hundegger file silently +def export_hundegger_with_file_path_silent(hundeggertype: hundegger_machine_type, file_path: str) -> None: + """Exports a Hundegger file silently. Parameters: - hundeggertype: hundeggertype - file_path: file_path + hundeggertype: The Hundegger machine type. + file_path: The export file path. Examples: >>> import cadwork @@ -190,18 +157,15 @@ def export_hundegger_with_file_path_silent(hundeggertype: int, file_path: str) - >>> hundegger_type = cadwork.hundegger_machine_type.k2.value >>> output_path = r"C:/exports/hundegger_project.k2" >>> mc.export_hundegger_with_file_path_silent(hundegger_type, output_path) - - Returns: - None """ -def export_hundegger_with_file_path_and_presetting_silent(hundeggertype: int, file_path: str, presetting: str) -> None: - """Exports a Hundegger file silently +def export_hundegger_with_file_path_and_presetting_silent(hundeggertype: hundegger_machine_type, file_path: str, presetting: str) -> None: + """Exports a Hundegger file silently. Parameters: - hundeggertype: hundeggertype - file_path: file_path - presetting: presetting + hundeggertype: The Hundegger machine type. + file_path: The export file path. + presetting: The presetting file path (.xml). Examples: >>> import cadwork @@ -211,18 +175,15 @@ def export_hundegger_with_file_path_and_presetting_silent(hundeggertype: int, fi >>> output_path = r"C:/exports/hundegger_project.k2" >>> presetting_file = r"...3d/Machine/Hundegger/K2/hundegger_settings.xml" >>> mc.export_hundegger_with_file_path_and_presetting_silent(hundegger_type, output_path, presetting_file) - - Returns: - None """ -def get_element_hundegger_processings(element_id: int, hundeggertype: int) -> List[int]: - """Get Hundegger processing IDs for an element. +def get_element_hundegger_processings(element_id: ElementId, hundeggertype: hundegger_machine_type) -> List[ElementId]: + """Gets the list of Hundegger processings for a specific element. Parameters: - element_id: The element ID. - hundeggertype: The Hundegger type. + element_id: The element id. + hundeggertype: The Hundegger machine type. Examples: >>> import cadwork @@ -235,15 +196,15 @@ def get_element_hundegger_processings(element_id: int, hundeggertype: int) -> Li >>> print(f"Found {len(processings)} Hundegger processings") Returns: - List of processing IDs. + A list of element IDs representing the processings. """ -def get_element_btl_processings(element_id: int, btl_version: int) -> List[int]: - """Get BTL processing IDs for an element. +def get_element_btl_processings(element_id: ElementId, btl_version: btl_version) -> List[ElementId]: + """Gets the list of BTL processings for a specific element. Parameters: - element_id: The element ID. + element_id: The element id. btl_version: The BTL version. Examples: @@ -257,16 +218,16 @@ def get_element_btl_processings(element_id: int, btl_version: int) -> List[int]: >>> print(f"Found {len(processings)} BTL processings") Returns: - List of processing IDs. + A list of element IDs representing the processings. """ -def get_processing_name(reference_element_id: int, processing_id: int) -> str: - """Get the name of a processing. +def get_processing_name(reference_element_id: ElementId, processing_id: ElementId) -> str: + """Gets the name of a specific processing. Parameters: - reference_element_id: The reference element ID. - processing_id: The processing ID. + reference_element_id: The reference element id. + processing_id: The processing id. Examples: >>> import cadwork @@ -279,16 +240,16 @@ def get_processing_name(reference_element_id: int, processing_id: int) -> str: >>> name = mc.get_processing_name(element, processing) Returns: - The processing name. + The name of the processing. """ -def get_processing_code(reference_element_id: int, processing_id: int) -> str: - """Get the code of a processing. +def get_processing_code(reference_element_id: ElementId, processing_id: ElementId) -> str: + """Gets the code of a specific processing. Parameters: - reference_element_id: The reference element ID. - processing_id: The processing ID. + reference_element_id: The reference element id. + processing_id: The processing id. Examples: >>> import cadwork @@ -301,16 +262,16 @@ def get_processing_code(reference_element_id: int, processing_id: int) -> str: >>> code = mc.get_processing_code(element, processing) Returns: - The processing code. + The code of the processing. """ -def get_processing_points(reference_element_id: int, processing_id: int) -> vertex_list: - """Get the points of a processing. +def get_processing_points(reference_element_id: ElementId, processing_id: ElementId) -> vertex_list: + """Gets the points of a specific processing. Parameters: - reference_element_id: The reference element ID. - processing_id: The processing ID. + reference_element_id: The reference element id. + processing_id: The processing id. Examples: >>> import cadwork @@ -323,16 +284,16 @@ def get_processing_points(reference_element_id: int, processing_id: int) -> vert >>> points = mc.get_processing_points(element, processing) Returns: - A vertex_list of points. + A list of vertices representing the points of the processing. """ -def get_processing_btl_parameter_set(reference_element_id: int, processing_id: int) -> List[str]: - """Get the BTL parameter set for a processing. +def get_processing_btl_parameter_set(reference_element_id: ElementId, processing_id: ElementId) -> List[str]: + """Gets the BTL parameter set of a specific processing. Parameters: - reference_element_id: The reference element ID. - processing_id: The processing ID. + reference_element_id: The reference element id. + processing_id: The processing id. Examples: >>> import cadwork @@ -345,5 +306,5 @@ def get_processing_btl_parameter_set(reference_element_id: int, processing_id: i >>> parameters = mc.get_processing_btl_parameter_set(element, processing) Returns: - List of BTL parameter strings. - """ + A list of strings representing the BTL parameter set of the processing. + """ \ No newline at end of file diff --git a/src/material_controller/__init__.pyi b/src/material_controller/__init__.pyi index 9044e5c..7a905a4 100644 --- a/src/material_controller/__init__.pyi +++ b/src/material_controller/__init__.pyi @@ -1,884 +1,761 @@ from typing import List +from cadwork.api_types import MaterialId, UnsignedInt -def get_last_error(error_code: int) -> str: - """Gets the last error +def create_material(name: str) -> MaterialId: + """Creates new material. Parameters: - error_code: error_code + name: The material name. Returns: - error string + The material id. """ -def create_material(name: str) -> int: - """Creates new material +def set_name(material_id: MaterialId, name: str) -> None: + """Sets the material name. Parameters: - name: name - - Returns: - material ID + material_id: The material id. + name: The material name. """ -def set_name(material_id: int, name: str) -> None: - """Sets the material name +def set_group(material_id: MaterialId, group: str) -> None: + """Sets the material group. Parameters: - material_id: material_id - name: name - - Returns: - None + material_id: The material id. + group: The material group. """ -def set_group(material_id: int, group: str) -> None: - """Sets the material group +def set_code(material_id: MaterialId, code: str) -> None: + """Sets the material code. Parameters: - material_id: material_id - group: group - - Returns: - None + material_id: The material id. + code: The material code. """ -def set_code(material_id: int, code: str) -> None: - """Sets the material code +def set_modulus_elasticity_1(material_id: MaterialId, modulus_elasticity1: float) -> None: + """Sets the material modulus of elasticity 1. Parameters: - material_id: material_id - code: code - - Returns: - None + material_id: The material id. + modulus_elasticity1: The material modulus of elasticity 1. """ -def set_modulus_elasticity_1(material_id: int, modulus_elasticity1: float) -> None: - """Sets the material modulus of elasticity 1 +def set_modulus_elasticity_2(material_id: MaterialId, modulus_elasticity2: float) -> None: + """Sets the material modulus of elasticity 2. Parameters: - material_id: material_id - modulus_elasticity1: modulus_elasticity1 - - Returns: - None + material_id: The material id. + modulus_elasticity2: The material modulus of elasticity 2. """ -def set_modulus_elasticity_2(material_id: int, modulus_elasticity2: float) -> None: - """Sets the material modulus of elasticity 2 +def set_modulus_elasticity_3(material_id: MaterialId, modulus_elasticity3: float) -> None: + """Sets the material modulus of elasticity 3. Parameters: - material_id: material_id - modulus_elasticity2: modulus_elasticity2 - - Returns: - None + material_id: The material id. + modulus_elasticity3: The material modulus of elasticity 3. """ -def set_modulus_elasticity_3(material_id: int, modulus_elasticity3: float) -> None: - """Sets the material modulus of elasticity 3 +def set_shear_modulus_1(material_id: MaterialId, shear_modulus1: float) -> None: + """Sets the material shear modulus 1. Parameters: - material_id: material_id - modulus_elasticity3: modulus_elasticity3 - - Returns: - None + material_id: The material id. + shear_modulus1: The material shear modulus 1. """ -def set_shear_modulus_1(material_id: int, shear_modulus1: float) -> None: - """Sets the material shear modulus 1 +def set_shear_modulus_2(material_id: MaterialId, shear_modulus2: float) -> None: + """Sets the material shear modulus 2. Parameters: - material_id: material_id - shear_modulus1: shear_modulus1 - - Returns: - None + material_id: The material id. + shear_modulus2: The material shear modulus 2. """ -def set_shear_modulus_2(material_id: int, shear_modulus2: float) -> None: - """Sets the material shear modulus 2 +def set_price(material_id: MaterialId, price: float) -> None: + """Sets the material price. Parameters: - material_id: material_id - shear_modulus2: shear_modulus2 - - Returns: - None + material_id: The material id. + price: The material price. """ -def set_price(material_id: int, price: float) -> None: - """Sets the material price +def set_price_type(material_id: MaterialId, price_type: str) -> None: + """Sets the material price type. Parameters: - material_id: material_id - price: price - - Returns: - None + material_id: The material id. + price_type: The material price type. """ -def set_price_type(material_id: int, price_type: str) -> None: - """Sets the material price type +def set_thermal_conductivity(material_id: MaterialId, thermal_conductivity: float) -> None: + """Sets the material thermal conductivity. Parameters: - material_id: material_id - price_type: price_type - - Returns: - None + material_id: The material id. + thermal_conductivity: The material thermal conductivity. """ -def set_thermal_conductivity(material_id: int, thermal_conductivity: float) -> None: - """Sets the material thermal conductivity +def set_heat_capacity(material_id: MaterialId, heat_capacity: float) -> None: + """Sets the material heat capacity. Parameters: - material_id: material_id - thermal_conductivity: thermal_conductivity - - Returns: - None + material_id: The material id. + heat_capacity: The material heat capacity. """ -def set_heat_capacity(material_id: int, heat_capacity: float) -> None: - """Sets the material heat capacity +def set_u_min(material_id: MaterialId, u_min: float) -> None: + """Sets the material U min. Parameters: - material_id: material_id - heat_capacity: heat_capacity - - Returns: - None + material_id: The material id. + u_min: The material U min. """ -def set_u_min(material_id: int, u_min: float) -> None: - """Sets the material U min +def set_u_max(material_id: MaterialId, u_max: float) -> None: + """Sets the material U max. Parameters: - material_id: material_id - u_min: u_min - - Returns: - None + material_id: The material id. + u_max: The material U max. """ -def set_u_max(material_id: int, u_max: float) -> None: - """Sets the material U max +def set_fire_resistance_class(material_id: MaterialId, fire_resistance_class: str) -> None: + """Sets the material fire resistance class. Parameters: - material_id: material_id - u_max: u_max - - Returns: - None + material_id: The material id. + fire_resistance_class: The material fire resistance class. """ -def set_fire_resistance_class(material_id: int, fire_resistance_class: str) -> None: - """Sets the material fire resistance class +def set_smoke_class(material_id: MaterialId, smoke_class: str) -> None: + """Sets the material smoke class. Parameters: - material_id: material_id - fire_resistance_class: fire_resistance_class - - Returns: - None + material_id: The material id. + smoke_class: The material smoke class. """ -def set_smoke_class(material_id: int, smoke_class: str) -> None: - """Sets the material smoke class +def set_drop_forming_class(material_id: MaterialId, drop_forming_class: str) -> None: + """Sets the material drop forming class. Parameters: - material_id: material_id - smoke_class: smoke_class - - Returns: - None + material_id: The material id. + drop_forming_class: The material drop forming class. """ -def set_drop_forming_class(material_id: int, drop_forming_class: str) -> None: - """Sets the material drop forming class +def set_burn_off_rate(material_id: MaterialId, burn_off_rate: float) -> None: + """Sets the material burn-off rate. Parameters: - material_id: material_id - drop_forming_class: drop_forming_class - - Returns: - None + material_id: The material id. + burn_off_rate: The material burn off rate. """ -def set_burn_off_rate(material_id: int, burn_off_rate: float) -> None: - """Sets the material burn-off rate +def set_weight(material_id: MaterialId, weight: float) -> None: + """Sets the material weight. Parameters: - material_id: material_id - burn_off_rate: burn_off_rate - - Returns: - None + material_id: The material id. + weight: The material weight. """ -def set_weight(material_id: int, weight: float) -> None: - """Sets the material weight +def set_weight_type(material_id: MaterialId, weight_type: str) -> None: + """Sets the material weight type. Parameters: - material_id: material_id - weight: weight - - Returns: - None - """ - -def set_weight_type(material_id: int, weight_type: str) -> None: - """Sets the material weight type - - Parameters: - material_id: material_id - weight_type: weight_type - - Returns: - None + material_id: The material id. + weight_type: The material weight type. """ def clear_errors() -> None: - """clear errors - - Returns: - None + """Clears all errors. """ -def set_grade(material_id: int, grade: str) -> None: - """set grade +def set_grade(material_id: MaterialId, grade: str) -> None: + """Sets the grade of a material. Parameters: - material_id: material_id - grade: grade - - Returns: - None + material_id: The material id. + grade: The grade to set. """ -def set_quality(material_id: int, quality: str) -> None: - """set quality +def set_quality(material_id: MaterialId, quality: str) -> None: + """Sets the quality of a material. Parameters: - material_id: material_id - quality: quality - - Returns: - None + material_id: The material id. + quality: The quality to set. """ -def set_composition(material_id: int, composition: str) -> None: - """set composition +def set_composition(material_id: MaterialId, composition: str) -> None: + """Sets the composition of a material. Parameters: - material_id: material_id - composition: composition - - Returns: - None + material_id: The material id. + composition: The composition to set. """ -def get_material_id(material_name: str) -> int: - """Gets the material with a given name +def get_material_id(material_name: str) -> MaterialId: + """Gets the material with a given name. Parameters: - material_name: material_name + material_name: The material name. Returns: - material ID + The material id. """ -def get_name(material_id: int) -> str: - """Gets the material name +def get_name(material_id: MaterialId) -> str: + """Gets the material name. Parameters: - material_id: material_id + material_id: The material id. Returns: - material name + The material name. """ -def get_group(material_id: int) -> str: - """Gets the material group +def get_group(material_id: MaterialId) -> str: + """Gets the material group. Parameters: - material_id: material_id + material_id: The material id. Returns: - material group + The material group. """ -def get_code(material_id: int) -> str: - """Gets the material code +def get_code(material_id: MaterialId) -> str: + """Gets the material code. Parameters: - material_id: material_id + material_id: The material id. Returns: - material code + The material code. """ -def get_modulus_elasticity_1(material_id: int) -> float: - """Gets the material modulus of elasticity 1 +def get_modulus_elasticity_1(material_id: MaterialId) -> float: + """Gets the material modulus of elasticity 1. Parameters: - material_id: material_id + material_id: The material id. Returns: - material modulus of elasticity 1 + The material modulus of elasticity 1. """ -def get_modulus_elasticity_2(material_id: int) -> float: - """Gets the material modulus of elasticity 2 +def get_modulus_elasticity_2(material_id: MaterialId) -> float: + """Gets the material modulus of elasticity 2. Parameters: - material_id: material_id + material_id: The material id. Returns: - material modulus of elasticity 2 + The material modulus of elasticity 2. """ -def get_modulus_elasticity_3(material_id: int) -> float: - """Gets the material modulus of elasticity 3 +def get_modulus_elasticity_3(material_id: MaterialId) -> float: + """Gets the material modulus of elasticity 3. Parameters: - material_id: material_id + material_id: The material id. Returns: - material modulus of elasticity 3 + The material modulus of elasticity 3. """ -def get_shear_modulus_1(material_id: int) -> float: - """Gets the material shear modulus 1 +def get_shear_modulus_1(material_id: MaterialId) -> float: + """Gets the material shear modulus 1. Parameters: - material_id: material_id + material_id: The material id. Returns: - material shear modulus 1 + The material shear modulus 1. """ -def get_shear_modulus_2(material_id: int) -> float: - """Gets the material shear modulus 2 +def get_shear_modulus_2(material_id: MaterialId) -> float: + """Gets the material shear modulus 2. Parameters: - material_id: material_id + material_id: The material id. Returns: - material shear modulus 2 + The material shear modulus 2. """ -def get_price(material_id: int) -> float: - """Gets the material price +def get_price(material_id: MaterialId) -> float: + """Gets the material price. Parameters: - material_id: material_id + material_id: The material id. Returns: - material price + The material price. """ -def get_price_type(material_id: int) -> str: - """Sets the material price type +def get_price_type(material_id: MaterialId) -> str: + """Gets the material price type. Parameters: - material_id: material_id + material_id: The material id. Returns: - material price type + The material price type. """ -def get_thermal_conductivity(material_id: int) -> float: - """Gets the material thermal conductivity +def get_thermal_conductivity(material_id: MaterialId) -> float: + """Gets the material thermal conductivity. Parameters: - material_id: material_id + material_id: The material id. Returns: - material thermal conductivity + The material thermal conductivity. """ -def get_heat_capacity(material_id: int) -> float: - """Gets the material heat capacity +def get_heat_capacity(material_id: MaterialId) -> float: + """Gets the material heat capacity. Parameters: - material_id: material_id + material_id: The material id. Returns: - material heat capacity + The material heat capacity. """ -def get_u_min(material_id: int) -> float: - """Gets the material U min +def get_u_min(material_id: MaterialId) -> float: + """Gets the material U min. Parameters: - material_id: material_id + material_id: The material id. Returns: - material U min + The material U min. """ -def get_u_max(material_id: int) -> float: - """Gets the material U max +def get_u_max(material_id: MaterialId) -> float: + """Gets the material U max. Parameters: - material_id: material_id + material_id: The material id. Returns: - material U max + The material U max. """ -def get_fire_resistance_class(material_id: int) -> str: - """Gets the material fire resistance class +def get_fire_resistance_class(material_id: MaterialId) -> str: + """Gets the material fire resistance class. Parameters: - material_id: material_id + material_id: The material id. Returns: - material fire resistance class + The material fire resistance class. """ -def get_smoke_class(material_id: int) -> str: - """Gets the material smoke class +def get_smoke_class(material_id: MaterialId) -> str: + """Gets the material smoke class. Parameters: - material_id: material_id + material_id: The material id. Returns: - material smoke class + The material smoke class. """ -def get_drop_forming_class(material_id: int) -> str: - """Gets the material drop forming class +def get_drop_forming_class(material_id: MaterialId) -> str: + """Gets the material drop forming class. Parameters: - material_id: material_id + material_id: The material id. Returns: - material drop forming class + The material drop forming class. """ -def get_burn_off_rate(material_id: int) -> float: - """Gets the material burn-off rate +def get_burn_off_rate(material_id: MaterialId) -> float: + """Gets the material burn-off rate. Parameters: - material_id: material_id + material_id: The material id. Returns: - material burn off rate + The material burn off rate. """ -def get_weight(material_id: int) -> float: - """Gets the material weight +def get_weight(material_id: MaterialId) -> float: + """Gets the material weight. Parameters: - material_id: material_id + material_id: The material id. Returns: - material weight + The material weight. """ -def get_weight_type(material_id: int) -> str: - """Gets the material weight type +def get_weight_type(material_id: MaterialId) -> str: + """Gets the material weight type. Parameters: - material_id: material_id + material_id: The material id. Returns: - material weight type + The material weight type. """ -def get_all_materials() -> List[int]: - """Gets all the materials +def get_all_materials() -> List[MaterialId]: + """Retrieves a list of all materials. Returns: - material ID list + A list of all material id. """ -def get_grade(material_id: int) -> str: - """get grade +def get_grade(material_id: MaterialId) -> str: + """Gets the grade of a material. Parameters: - material_id: material_id + material_id: The material id. Returns: - str + The grade of the material. """ -def get_quality(material_id: int) -> str: - """get quality +def get_quality(material_id: MaterialId) -> str: + """Gets the quality of a material. Parameters: - material_id: material_id + material_id: The material id. Returns: - str + The quality of the material. """ -def get_composition(material_id: int) -> str: - """get composition +def get_composition(material_id: MaterialId) -> str: + """Gets the composition of a material. Parameters: - material_id: material_id + material_id: The material id. Returns: - str + The composition of the material. """ -def get_short_name(material_id: int) -> str: - """get short name +def get_short_name(material_id: MaterialId) -> str: + """Gets the short name of a material. Parameters: - material_id: material_id + material_id: The material id. Returns: - str + The short name of the material. """ -def get_all_material_groups() -> List[str]: - """Gets all the material groups +def get_all_material_groups() -> List[MaterialId]: + """Retrieves a list of all material groups. Returns: - group names + A list of all material group names. """ def get_parent_group(group: str) -> str: - """Gets the parent group of a material group + """Gets the parent group of a given group. Parameters: - group: group + group: The name of the group. Returns: - parent group name + The name of the parent group. """ -def get_material_color_assignment_for_nodes(color_nr: int) -> int: - """get material color assignment for nodes +def get_material_color_assignment_for_nodes(color_nb: UnsignedInt) -> MaterialId: + """Gets the material color assignment for nodes. Parameters: - color_nr: color_nr + color_nb: The color number. [1-255] Returns: - int + The material id assigned to the color number for nodes. """ -def set_material_color_assignment_for_nodes(color_nr: int, material_id: int) -> None: - """set material color assignment for nodes +def set_material_color_assignment_for_nodes(color_nb: UnsignedInt, material_id: MaterialId) -> None: + """Sets the material color assignment for nodes. Parameters: - color_nr: color_nr - material_id: material_id - - Returns: - None + color_nb: The color number. [1-255] + material_id: The material ID to assign to the color number for nodes. """ -def get_material_color_assignment_for_standard_axes(color_nr: int) -> int: - """get material color assignment for standard axes +def get_material_color_assignment_for_standard_axes(color_nb: UnsignedInt) -> MaterialId: + """Gets the material color assignment for standard axes. Parameters: - color_nr: color_nr + color_nb: The color number. [1-255] Returns: - int + The material id assigned to the color number for standard axes. """ -def set_material_color_assignment_for_standard_axes(color_nr: int, material_id: int) -> None: - """set material color assignment for standard axes +def set_material_color_assignment_for_standard_axes(color_nb: UnsignedInt, material_id: MaterialId) -> None: + """Sets the material color assignment for standard axes. Parameters: - color_nr: color_nr - material_id: material_id - - Returns: - None + color_nb: The color number. [1-255] + material_id: The material ID to assign to the color number for standard axes. """ -def get_material_color_assignment_for_drillings(color_nr: int) -> int: - """get material color assignment for drillings +def get_material_color_assignment_for_drillings(color_nb: UnsignedInt) -> MaterialId: + """Gets the material color assignment for drillings. Parameters: - color_nr: color_nr + color_nb: The color number. [1-255] Returns: - int + The material id assigned to the color number for drillings. """ -def set_material_color_assignment_for_drillings(color_nr: int, material_id: int) -> None: - """set material color assignment for drillings +def set_material_color_assignment_for_drillings(color_nb: UnsignedInt, material_id: MaterialId) -> None: + """Sets the material color assignment for drillings. Parameters: - color_nr: color_nr - material_id: material_id - - Returns: - None + color_nb: The color number. [1-255] + material_id: The material ID to assign to the color number for drillings. """ -def get_material_color_assignment_for_mep_axes(color_nr: int) -> int: - """get material color assignment for mep axes +def get_material_color_assignment_for_mep_axes(color_nb: UnsignedInt) -> MaterialId: + """Gets the material color assignment for MEP axes. Parameters: - color_nr: color_nr + color_nb: The color number. [1-255] Returns: - int + The material id assigned to the color number for MEP axes. """ -def set_material_color_assignment_for_mep_axes(color_nr: int, material_id: int) -> None: - """set material color assignment for mep axes +def set_material_color_assignment_for_mep_axes(color_nb: UnsignedInt, material_id: MaterialId) -> None: + """Sets the material color assignment for MEP axes. Parameters: - color_nr: color_nr - material_id: material_id - - Returns: - None + color_nb: The color number. [1-255] + material_id: The material ID to assign to the color number for MEP axes. """ -def get_material_color_assignment_for_beams(color_nr: int) -> int: - """get material color assignment for beams +def get_material_color_assignment_for_beams(color_nb: UnsignedInt) -> MaterialId: + """Gets the material color assignment for beams. Parameters: - color_nr: color_nr + color_nb: The color number. [1-255] Returns: - int + The material id assigned to the color number for beams. """ -def set_material_color_assignment_for_beams(color_nr: int, material_id: int) -> None: - """set material color assignment for beams +def set_material_color_assignment_for_beams(color_nb: UnsignedInt, material_id: MaterialId) -> None: + """Sets the material color assignment for beams. Parameters: - color_nr: color_nr - material_id: material_id - - Returns: - None + color_nb: The color number. [1-255] + material_id: The material ID to assign to the color number for beams. """ -def get_material_color_assignment_for_panels(color_nr: int) -> int: - """get material color assignment for panels +def get_material_color_assignment_for_panels(color_nb: UnsignedInt) -> MaterialId: + """Gets the material color assignment for panels. Parameters: - color_nr: color_nr + color_nb: The color number. [1-255] Returns: - int + The material id assigned to the color number for panels. """ -def set_material_color_assignment_for_panels(color_nr: int, material_id: int) -> None: - """set material color assignment for panels +def set_material_color_assignment_for_panels(color_nb: UnsignedInt, material_id: MaterialId) -> None: + """Sets the material color assignment for panels. Parameters: - color_nr: color_nr - material_id: material_id - - Returns: - None + color_nb: The color number. [1-255] + material_id: The material ID to assign to the color number for panels. """ -def get_material_color_assignment_for_auxiliary_elements(color_nr: int) -> int: - """get material color assignment for auxiliary elements +def get_material_color_assignment_for_auxiliary_elements(color_nb: UnsignedInt) -> MaterialId: + """Gets the material color assignment for auxiliary elements. Parameters: - color_nr: color_nr + color_nb: The color number. [1-255] Returns: - int + The material id assigned to the color number for auxiliary elements. """ -def set_material_color_assignment_for_auxiliary_elements(color_nr: int, material_id: int) -> None: - """set material color assignment for auxiliary elements +def set_material_color_assignment_for_auxiliary_elements(color_nb: UnsignedInt, material_id: MaterialId) -> None: + """Sets the material color assignment for auxiliary elements. Parameters: - color_nr: color_nr - material_id: material_id - - Returns: - None + color_nb: The color number. [1-255] + material_id: The material ID to assign to the color number for auxiliary elements. """ -def get_material_color_assignment_for_surfaces(color_nr: int) -> int: - """get material color assignment for surfaces +def get_material_color_assignment_for_surfaces(color_nb: UnsignedInt) -> MaterialId: + """Gets the material color assignment for surfaces. Parameters: - color_nr: color_nr + color_nb: The color number. [1-255] Returns: - int + The material id assigned to the color number for surfaces. """ -def set_material_color_assignment_for_surfaces(color_nr: int, material_id: int) -> None: - """set material color assignment for surfaces +def set_material_color_assignment_for_surfaces(color_nb: UnsignedInt, material_id: MaterialId) -> None: + """Sets the material color assignment for surfaces. Parameters: - color_nr: color_nr - material_id: material_id - - Returns: - None + color_nb: The color number. [1-255] + material_id: The material ID to assign to the color number for surfaces. """ -def get_texture_color(material_id: int) -> int: - """get texture color +def get_texture_color(material_id: MaterialId) -> int: + """Gets the texture color for a given material ID. Parameters: - material_id: material_id + material_id: The material id. Returns: - int + The color of the texture. [1-255] """ -def set_texture_color(color_nr: int, material_id: int) -> None: - """set texture color +def set_texture_color(color_nb: UnsignedInt, material_id: MaterialId) -> None: + """Sets the texture color for a given material ID. Parameters: - color_nr: color_nr - material_id: material_id - - Returns: - None + color_nb: The color to set for the texture. [1-255] + material_id: The material id. """ -def get_texture_transparency(material_id: int) -> int: - """get texture transparency +def get_texture_transparency(material_id: MaterialId) -> int: + """Gets the texture transparency for a given material ID. Parameters: - material_id: material_id + material_id: The material id. Returns: - int + The transparency of the texture. """ -def set_texture_transparency(color_nr: int, material_id: int) -> None: - """set texture transparency +def set_texture_transparency(color_nb: UnsignedInt, material_id: MaterialId) -> None: + """Sets the texture transparency for a given material ID. Parameters: - color_nr: color_nr - material_id: material_id - - Returns: - None + color_nb: The transparency to set for the texture. + material_id: The material id. """ -def get_texture_rotation_angle(material_id: int) -> float: - """get texture rotation angle +def get_texture_rotation_angle(material_id: MaterialId) -> float: + """Gets the texture rotation angle for a given material ID. Parameters: - material_id: material_id + material_id: The material id. Returns: - float + The rotation angle of the texture. """ -def set_texture_rotation_angle(material_id: int, angle: float) -> None: - """set texture rotation angle +def set_texture_rotation_angle(material_id: MaterialId, angle: float) -> None: + """Sets the texture rotation angle for a given material ID. Parameters: - material_id: material_id - angle: angle - - Returns: - None + material_id: The material id. + angle: The rotation angle to set for the texture. """ -def get_texture_length_alignment(material_id: int) -> bool: - """get texture length alignment +def get_texture_length_alignment(material_id: MaterialId) -> bool: + """Gets the texture length alignment for a given material ID. Parameters: - material_id: material_id + material_id: The material id. Returns: - bool + True if Texture Random Placement is enabled, false otherwise. """ -def set_texture_length_alignment(material_id: int, flag: bool) -> None: - """set texture length alignment +def set_texture_length_alignment(material_id: MaterialId, flag: bool) -> None: + """Sets the texture length alignment for a given material ID. Parameters: - material_id: material_id - flag: flag - - Returns: - None + material_id: The material id. + flag: True if Texture Random Placement is enabled, false otherwise. """ -def get_texture_zoom_x(material_id: int) -> float: - """get texture zoom x +def get_texture_zoom_x(material_id: MaterialId) -> float: + """Gets the texture zoom factor in the X direction for a given material ID. Parameters: - material_id: material_id + material_id: The material id. Returns: - float + The zoom factor of the texture in the X direction. """ -def set_texture_zoom_x(material_id: int, value: float) -> None: - """set texture zoom x +def set_texture_zoom_x(material_id: MaterialId, value: float) -> None: + """Sets the texture zoom factor in the X direction for a given material ID. Parameters: - material_id: material_id - value: value - - Returns: - None + material_id: The material id. + value: The zoom factor to set in the X direction. """ -def get_texture_zoom_y(material_id: int) -> float: - """get texture zoom y +def get_texture_zoom_y(material_id: MaterialId) -> float: + """Gets the texture zoom factor in the Y direction for a given material ID. Parameters: - material_id: material_id + material_id: The material id. Returns: - float + The zoom factor of the texture in the Y direction. """ -def set_texture_zoom_y(material_id: int, value: float) -> None: - """set texture zoom y +def set_texture_zoom_y(material_id: MaterialId, value: float) -> None: + """Sets the texture zoom factor in the Y direction for a given material ID. Parameters: - material_id: material_id - value: value - - Returns: - None - """ + material_id: The material id. + value: The zoom factor to set. + """ \ No newline at end of file diff --git a/src/menu_controller/__init__.pyi b/src/menu_controller/__init__.pyi index 20a125e..5bb45ef 100644 --- a/src/menu_controller/__init__.pyi +++ b/src/menu_controller/__init__.pyi @@ -2,12 +2,12 @@ from typing import List def display_simple_menu(menu_items: List[str]) -> str: - """display simple menu + """Displays a simple menu. Parameters: - menu_items: menu_items + menu_items: The menu items. Returns: - str + The selected menu item. """ diff --git a/src/multi_layer_cover_controller/__init__.pyi b/src/multi_layer_cover_controller/__init__.pyi index 4d8a358..ee46e45 100644 --- a/src/multi_layer_cover_controller/__init__.pyi +++ b/src/multi_layer_cover_controller/__init__.pyi @@ -1,111 +1,92 @@ from typing import List +from cadwork.api_types import * +from cadwork.multi_layer_type import multi_layer_type - -def set_element_multi_layer_set(element_id: int, set_id: int) -> None: - """Sets the multi layer set id of a cover +def set_element_multi_layer_set(element_id: ElementId, set_id: MultiLayerSetId) -> None: + """Sets the multi layer set id of a cover. Parameters: - element_id: element_id - set_id: set_id - + element_id: The element id of the cover. + set_id: The multi layer set id. + Examples: >>> cover_id = element.create_cover(points, normal_vector) >>> multi_layer_set_id = mlc.create_multi_layer_wall("Wall Type A") >>> mlc.set_element_multi_layer_set(cover_id, multi_layer_set_id) - - Returns: - None """ - -def set_multi_layer_set_name(set_id: int, set_name: str) -> None: - """Sets the name for a multi layer set +def set_multi_layer_set_name(set_id: MultiLayerSetId, set_name: str) -> None: + """Sets the name for a multi layer set. Parameters: - set_id: set_id - set_name: set_name - + set_id: The multi layer set id. + set_name: The multi layer set name. + Examples: >>> multi_layer_set_id = mlc.create_multi_layer_wall("Default Wall") >>> mlc.set_multi_layer_set_name(multi_layer_set_id, "Exterior Wall Type B") - - Returns: - None """ - -def set_cover_name(set_id: int, cover_name: str) -> None: - """Sets the cover name of the multi layer set +def set_cover_name(set_id: MultiLayerSetId, cover_name: str) -> None: + """Sets the cover name of the multi layer set. Parameters: - set_id: set_id - cover_name: cover_name - + set_id: The multi layer set id. + cover_name: The cover name. + Examples: >>> multi_layer_set_id = mlc.create_multi_layer_wall("Default Wall") >>> mlc.set_cover_name(multi_layer_set_id, "Exterior Facade") - - Returns: - None """ - -def set_cover_material(set_id: int, cover_material: int) -> None: - """Sets the cover material of the multi layer set +def set_cover_material(set_id: MultiLayerSetId, cover_material: MaterialId) -> None: + """Sets the cover material of the multi layer set. Parameters: - set_id: set_id - cover_material: cover_material - + set_id: The multi layer set id. + cover_material: The cover material. + Examples: >>> multi_layer_set_id = mlc.create_multi_layer_wall("Default Wall") >>> material_id = mc.get_material_id("Cement Board") >>> mlc.set_cover_material(multi_layer_set_id, material_id) - - Returns: - None """ - -def set_cover_thickness(set_id: int, cover_thickness: float) -> None: - """Sets the cover thickness of the multi layer set. Only allowed for simple walls (cover without layer) +def set_cover_thickness(set_id: MultiLayerSetId, cover_thickness: float) -> None: + """Sets the cover thickness of the multi layer set. Only allowed for simple walls (cover without layer). Parameters: - set_id: set_id - cover_thickness: cover_thickness - + set_id: The multi layer set id. + cover_thickness: The cover thickness. + Examples: >>> multi_layer_set_id = mlc.create_multi_layer_wall("Simple Wall") >>> mlc.set_cover_thickness(multi_layer_set_id, 150.0) - - Returns: - None """ -def create_multi_layer_wall(set_name: str) -> int: - """Creates a new multi layer wall with given name and default values +def create_multi_layer_wall(set_name: str) -> MultiLayerSetId: + """Creates a new multi layer wall with given name and default values. Parameters: - set_name: set_name - + set_name: The multi layer set name. + Examples: >>> wall_set_id = mlc.create_multi_layer_wall("Exterior Insulated Wall") >>> print(f"Created new multi-layer wall with ID: {wall_set_id}") Returns: - multiLayerSetID + The multi layer set id. """ - -def add_layer(set_id: int, layer_type: int, name: str, material_id: int, thickness: float) -> None: - """Adds a new layer to the multi layer set +def add_layer(set_id: MultiLayerSetId, layer_type: multi_layer_type, name: str, material_id: MaterialId, thickness: float) -> None: + """Adds a new layer to the multi layer set. Parameters: - set_id: set_id - layer_type: layer_type - name: name - material_id: material_id - thickness: thickness + set_id: The multi layer set id. + layer_type: The type of the layer. + name: The name of the layer. + material_id: The material id of the layer. + thickness: The thickness of the layer. Examples: >>> material_id_1 = mc.get_material_id("material_1") @@ -113,105 +94,82 @@ def add_layer(set_id: int, layer_type: int, name: str, material_id: int, thickne >>> multi_layer_set_id = mlc.create_multi_layer_wall("MultiLayerWall") >>> layer1_thickness = 200 >>> layer2_thickness = 15 - >>> mlc.add_layer(multi_layer_set_id, cadwork.multi_layer_type.structure.value,"Layer1", material_id_1, layer1_thickness) - >>> mlc.add_layer(multi_layer_set_id, cadwork.multi_layer_type.panel.value,"Layer2", material_id_2, layer2_thickness) - - Returns: - None + >>> mlc.add_layer(multi_layer_set_id, cadwork.multi_layer_type.structure.value, "Layer1", material_id_1, layer1_thickness) + >>> mlc.add_layer(multi_layer_set_id, cadwork.multi_layer_type.panel.value, "Layer2", material_id_2, layer2_thickness) """ - -def set_layer_name(set_id: int, layer_index: int, name: str) -> None: - """Sets the name of a layer of the multi layer set +def set_layer_name(set_id: MultiLayerSetId, layer_index: UnsignedInt, name: str) -> None: + """Sets the name of a layer of the multi layer set. Parameters: - set_id: set_id - layer_index: layer_index - name: name - + set_id: The multi layer set id. + layer_index: The layer index. + name: The name of the layer. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> mlc.set_layer_name(multi_layer_set_id, 0, "Exterior Cladding") >>> mlc.set_layer_name(multi_layer_set_id, 1, "Insulation Layer") - - Returns: - None """ - -def set_layer_material(set_id: int, layer_index: int, material_id: int) -> None: - """Sets the material of a layer of the multi layer set +def set_layer_material(set_id: MultiLayerSetId, layer_index: UnsignedInt, material_id: MaterialId) -> None: + """Sets the material of a layer of the multi layer set. Parameters: - set_id: set_id - layer_index: layer_index - material_id: material_id - + set_id: The multi layer set id. + layer_index: The layer index. + material_id: The material id of the layer. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> insulation_material_id = mc.get_material_id("Mineral Wool") >>> mlc.set_layer_material(multi_layer_set_id, 1, insulation_material_id) - - Returns: - None """ - -def set_layer_thickness(set_id: int, layer_index: int, thickness: float) -> None: - """Sets the thickness of a layer of the multi layer set +def set_layer_thickness(set_id: MultiLayerSetId, layer_index: UnsignedInt, thickness: float) -> None: + """Sets the thickness of a layer of the multi layer set. Parameters: - set_id: set_id - layer_index: layer_index - thickness: thickness - + set_id: The multi layer set id. + layer_index: The layer index. + thickness: The layer thickness. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> mlc.set_layer_thickness(multi_layer_set_id, 0, 25.0) # Set first layer to 25mm >>> mlc.set_layer_thickness(multi_layer_set_id, 1, 120.0) # Set second layer to 120mm - - Returns: - None """ - -def set_layer_type(set_id: int, layer_index: int, layer_type: int) -> None: - """Sets the type of a layer of the multi layer set +def set_layer_type(set_id: MultiLayerSetId, layer_index: UnsignedInt, layer_type: multi_layer_type) -> None: + """Sets the type of a layer of the multi layer set. Parameters: - set_id: set_id - layer_index: layer_index - layer_type: layer_type + set_id: The multi layer set id. + layer_index: The layer index. + layer_type: The layer type. Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> layer_count = mlc.get_layer_count(multi_layer_set_id) >>> layer_mid_point_idx = layer_count // 2 >>> mlc.set_layer_type(multi_layer_set_id, layer_mid_point_idx, cadwork.multi_layer_type.structure.value) - - Returns: - None """ - -def set_cover_color(set_id: int, cover_color: int) -> None: - """Sets the cover color of the multi layer set +def set_cover_color(set_id: MultiLayerSetId, cover_color: ColorId) -> None: + """Sets the cover color of the multi layer set. Parameters: - set_id: set_id - cover_color: cover_color - + set_id: The multi layer set id. + cover_color: The cover color. + Examples: >>> multi_layer_set_id = mlc.create_multi_layer_wall("Default Wall") >>> blue_color_id = vc.get_color_id("blue") >>> mlc.set_cover_color(multi_layer_set_id, blue_color_id) - - Returns: - None """ -def get_multi_layer_walls() -> List[int]: - """Gets all multi layer wall ids +def get_multi_layer_walls() -> List[MultiLayerSetId]: + """Gets all multi layer wall ids. Examples: >>> wall_ids = mlc.get_multi_layer_walls() @@ -221,31 +179,30 @@ def get_multi_layer_walls() -> List[int]: ... print(f"Wall ID: {wall_id}, Name: {name}") Returns: - List[int] + The multi layer wall ids. """ - -def get_multi_layer_set_name(set_id: int) -> str: - """Gets the name for a multi layer set +def get_multi_layer_set_name(set_id: MultiLayerSetId) -> str: + """Gets the name for a multi layer set. Parameters: - set_id: set_id - + set_id: The multi layer set id. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> set_name = mlc.get_multi_layer_set_name(multi_layer_set_id) >>> print(f"Element uses multi-layer definition: {set_name}") Returns: - string + The multi layer set name. """ -def get_element_multi_layer_set(element_id: int) -> int: - """Gets the multi layer set id of a cover +def get_element_multi_layer_set(element_id: ElementId) -> MultiLayerSetId: + """Gets the multi layer set id of a cover. Parameters: - element_id: element_id - + element_id: The element id of the cover. + Examples: >>> cover_ids = element.get_covers() >>> for cover_id in cover_ids: @@ -254,32 +211,30 @@ def get_element_multi_layer_set(element_id: int) -> int: ... print(f"Cover {cover_id} uses wall type: {set_name}") Returns: - multiLayerSetID + The multi layer set id. """ - -def get_cover_name(set_id: int) -> str: - """Gets the cover name defined in the multi layer set +def get_cover_name(set_id: MultiLayerSetId) -> str: + """Gets the cover name defined in the multi layer set. Parameters: - set_id: set_id - + set_id: The multi layer set id. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> cover_name = mlc.get_cover_name(multi_layer_set_id) >>> print(f"Cover name: {cover_name}") Returns: - string + The cover name. """ - -def get_cover_material(set_id: int) -> int: - """Gets the cover material defined in the multi layer set +def get_cover_material(set_id: MultiLayerSetId) -> MaterialId: + """Gets the cover material defined in the multi layer set. Parameters: - set_id: set_id - + set_id: The multi layer set id. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> material_id = mlc.get_cover_material(multi_layer_set_id) @@ -287,49 +242,46 @@ def get_cover_material(set_id: int) -> int: >>> print(f"Cover uses material: {material_name}") Returns: - materialID + The cover material. """ - -def get_cover_thickness(set_id: int) -> float: - """Gets the cover thickness of the multi layer set +def get_cover_thickness(set_id: MultiLayerSetId) -> float: + """Gets the cover thickness of the multi layer set. Parameters: - set_id: set_id - + set_id: The multi layer set id. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> thickness = mlc.get_cover_thickness(multi_layer_set_id) >>> print(f"Cover thickness: {thickness}mm") Returns: - double + The cover thickness. """ - -def get_layer_count(set_id: int) -> int: - """Gets the Number of Layers of the multi layer set +def get_layer_count(set_id: MultiLayerSetId) -> UnsignedInt: + """Gets the number of layers of the multi layer set. Parameters: - set_id: set_id - + set_id: The multi layer set id. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> count = mlc.get_layer_count(multi_layer_set_id) >>> print(f"Wall has {count} layers") Returns: - uint64_t + The number of layers. """ - -def get_layer_name(set_id: int, layer_index: int) -> str: - """Gets the name of a layer of the multi layer set +def get_layer_name(set_id: MultiLayerSetId, layer_index: UnsignedInt) -> str: + """Gets the name of a layer of the multi layer set. Parameters: - set_id: set_id - layer_index: layer_index - + set_id: The multi layer set id. + layer_index: The layer index. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> layer_count = mlc.get_layer_count(multi_layer_set_id) @@ -338,17 +290,16 @@ def get_layer_name(set_id: int, layer_index: int) -> str: ... print(f"Layer {i}: {layer_name}") Returns: - string + The layer name. """ - -def get_layer_thickness(set_id: int, layer_index: int) -> float: - """Gets the thickness of a layer of the multi layer set +def get_layer_thickness(set_id: MultiLayerSetId, layer_index: UnsignedInt) -> float: + """Gets the thickness of a layer of the multi layer set. Parameters: - set_id: set_id - layer_index: layer_index - + set_id: The multi layer set id. + layer_index: The layer index. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> layer_count = mlc.get_layer_count(multi_layer_set_id) @@ -360,17 +311,16 @@ def get_layer_thickness(set_id: int, layer_index: int) -> float: >>> print(f"Total wall thickness: {total_thickness}mm") Returns: - double + The layer thickness. """ - -def get_layer_material(set_id: int, layer_index: int) -> int: - """Gets the material of a layer of the multi layer set +def get_layer_material(set_id: MultiLayerSetId, layer_index: UnsignedInt) -> MaterialId: + """Gets the material of a layer of the multi layer set. Parameters: - set_id: set_id - layer_index: layer_index - + set_id: The multi layer set id. + layer_index: The layer index. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> layer_count = mlc.get_layer_count(multi_layer_set_id) @@ -380,17 +330,16 @@ def get_layer_material(set_id: int, layer_index: int) -> int: ... print(f"Layer {i} material: {material_name}") Returns: - string + The layer material. """ - -def get_layer_type(set_id: int, layer_index: int) -> int: - """Gets the type of a layer of the multi layer set +def get_layer_type(set_id: MultiLayerSetId, layer_index: UnsignedInt) -> multi_layer_type: + """Gets the type of a layer of the multi layer set. Parameters: - set_id: set_id - layer_index: layer_index - + set_id: The multi layer set id. + layer_index: The layer index. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> layer_count = mlc.get_layer_count(multi_layer_set_id) @@ -401,16 +350,15 @@ def get_layer_type(set_id: int, layer_index: int) -> int: ... print(f"Layer {i} ({layer_name}): Type = {type_str}") Returns: - multiLayerType + The layer type. """ - -def get_cover_color(set_id: int) -> int: - """Gets the cover color defined in the multi layer set +def get_cover_color(set_id: MultiLayerSetId) -> ColorId: + """Gets the cover color defined in the multi layer set. Parameters: - set_id: set_id - + set_id: The multi layer set id. + Examples: >>> multi_layer_set_id = mlc.get_element_multi_layer_set(element_id) >>> color_id = mlc.get_cover_color(multi_layer_set_id) @@ -418,5 +366,5 @@ def get_cover_color(set_id: int) -> int: >>> print(f"Cover uses color: {color_name}") Returns: - colorID + The cover color. """ diff --git a/src/roof_controller/__init__.pyi b/src/roof_controller/__init__.pyi index 4424bf2..73e22c0 100644 --- a/src/roof_controller/__init__.pyi +++ b/src/roof_controller/__init__.pyi @@ -1,47 +1,71 @@ from typing import List +from cadwork.api_types import ElementId -def get_profile_length(element_id: int) -> float: - """Gets the profile length +def get_profile_length(element_id: ElementId) -> float: + """Gets the profile length. Parameters: - element_id: element_id + element_id: The element id. Returns: - profile length + The profile length. """ -def get_edge_length(element_id: int, edge_type: str) -> float: - """Gets the edge length +def get_edge_length(element_id: ElementId, edge_type: str) -> float: + """Gets the edge length. Parameters: - element_id: element_id - edge_type: edge_type + element_id: The element id. + edge_type: The edge type : - Returns: - edge length - """ + + - "none" -def get_all_caddy_element_ids() -> List[int]: - """Gets all caddy elements + - "ridge" - Returns: - element ID list - """ + - "eave" -def get_last_error(a0: int) -> str: - """get last error + - "vergeright" + - "vergeleft" + - "vergeoblique" - Parameters: - a0: a0 + - "hip" + + - "valley" + + - "userdefined1" + - "userdefined2" + + - "userdefinedmitrejoint1" + - "userdefinedmitrejoint2" + + - "wallconnection" + - "wallconnectionright" + - "wallconnectionleft" + - "wallconnectiontop" + - "wallconnectionbottom" + + - "roofcutout" + - "roofcutoutright" + - "roofcutoutleft" + - "roofcutouttop" + - "roofcutoutbottom" + + - "roofedgeontoproofsurface" + - "roofedgeonbottomroofsurface" Returns: - str + The edge length. """ -def clear_errors() -> None: - """clear errors +def get_all_caddy_element_ids() -> List[ElementId]: + """Gets all caddy elements Returns: - None + The list of all caddy element id. + """ + +def clear_errors() -> None: + """Clears all errors. """ diff --git a/src/scene_controller/__init__.pyi b/src/scene_controller/__init__.pyi index a9ce1d3..9c48503 100644 --- a/src/scene_controller/__init__.pyi +++ b/src/scene_controller/__init__.pyi @@ -1,187 +1,160 @@ from typing import List - -def get_last_error(error_code: int) -> str: - """Gets the last error - - Parameters: - error_code: error_code - - Returns: - error string - """ +from cadwork.api_types import * def add_scene(name: str) -> bool: - """Adds a new scene + """Adds a new scene. Parameters: - name: name + name: The scene name. Returns: - did operation succeed + True if the operation succeeded, false otherwise. """ def rename_scene(old_name: str, new_name: str) -> bool: - """Renames a scene + """Renames a scene. Parameters: - old_name: old_name - new_name: new_name + old_name: The old scene name. + new_name: The new scene name. Returns: - did operation succeed + True if the operation succeeded, false otherwise. """ def delete_scene(name: str) -> bool: - """Deletes a scene + """Deletes a scene. Parameters: - name: name + name: The scene name. Returns: - did operation succeed + True if the operation succeeded, false otherwise. """ -def add_elements_to_scene(name: str, element_i_ds: List[int]) -> bool: - """Adds elements to a scene +def add_elements_to_scene(name: str, element_id_list: List[ElementId]) -> bool: + """Adds elements to a scene. Parameters: - name: name - element_i_ds: element_i_ds + name: The scene name. + element_id_list:: The element id list. Returns: - did operation succeed + True if the operation succeeded, false otherwise. """ -def remove_elements_from_scene(name: str, element_i_ds: List[int]) -> bool: - """Removes elements from a scene +def remove_elements_from_scene(name: str, element_id_list: List[ElementId]) -> bool: + """Removes elements from a scene. Parameters: - name: name - element_i_ds: element_i_ds + name: The scene name. + element_id_list:: The element id list. Returns: - did operation succeed + True if the operation succeeded, false otherwise. """ -def get_elements_from_scene(name: str) -> List[int]: - """Gets the elements from a scene +def get_elements_from_scene(name: str) -> List[ElementId]: + """Gets the elements from a scene. Parameters: - name: name + name: The scene name. Returns: - element ID list + The element id list. """ def activate_scene(name: str) -> bool: - """Activates a scene + """Activates a scene. Parameters: - name: name + name: The scene name. Returns: - did operation succeed + True if the operation succeeded, false otherwise. """ def clear_errors() -> None: - """clear errors - - Returns: - None + """Clears all errors. """ def get_scene_list() -> List[str]: - """get scene list + """Gets the list of scenes. Returns: - List[str] + The list of scene names. """ - -def group_scences(scene_names: List[str]) -> int: - """group scences +def group_scences(scene_names: List[str]) -> UnsignedInt: + """Groups the scenes to a scene group. Parameters: - scene_names: scene_names + scene_names: The scene names. Returns: - int + The index of the new group. """ - -def ungroup_scences(group_index: int) -> None: - """ungroup scences +def ungroup_scences(group_index: UnsignedInt) -> None: + """Deletes the group of scenes. Parameters: - group_index: group_index - - Returns: - None + group_index: The index of the group. """ def is_scene_present(name: str) -> bool: - """Queries of scene with name is present + """Checks if a scene is present. Parameters: - name: name + name: The name of the scene to check. Returns: - presence of scene + True if the scene is present, false otherwise. """ -def set_group_tab_color(scene_group_name: str, red: int, green: int, blue: int) -> None: - """set group tab color +def set_group_tab_color(scene_group_name: str, red: int, green: int, blue: int, alpha: int) -> None: + """Sets the group tab color. Parameters: - scene_group_name: scene_group_name - red: red - green: green - blue: blue - - Returns: - None + scene_group_name: The name of the scene group. + red: Red component. + green: Green component. + blue: Blue component. """ def rename_scene_group(old_name: str, new_name: str) -> None: - """rename scene group + """Renames a scene group. Parameters: - old_name: old_name - new_name: new_name - - Returns: - None + old_name: The old scene group name. + new_name: The new scene group name. """ -def get_group_index_by_name(scene_group_name: str) -> int: - """get group index by name +def get_group_index_by_name(scene_group_name: str) -> UnsignedInt: + """Gets the index of a scene group by its name. Parameters: - scene_group_name: scene_group_name + scene_group_name: The group name. Returns: - int + The index of the group, or a maximum uint64_t if not found. """ -def rename_scene_group_by_index(group_index: int, new_name: str) -> None: - """rename scene group by index +def rename_scene_group_by_index(group_index: UnsignedInt, new_name: str) -> None: + """Renames a scene group by its index. Parameters: - group_index: group_index - new_name: new_name - - Returns: - None + group_index: The index of the group. + new_name: The new scene group name. """ - -def group_scences_with_name(scene_names: List[str], group_name: str) -> int: - """group scences with name +def group_scences_with_name(scene_names: List[str], group_name: str) -> UnsignedInt: + """Groups the scenes to a scene group and sets the name of the new group. Parameters: - scene_names: scene_names - group_name: group_name + scene_names: The scene names to group. + group_name: The name of the new group. Returns: - int + The index of the new group. """ diff --git a/src/shop_drawing_controller/__init__.pyi b/src/shop_drawing_controller/__init__.pyi index 2e2015f..9b14315 100644 --- a/src/shop_drawing_controller/__init__.pyi +++ b/src/shop_drawing_controller/__init__.pyi @@ -1,203 +1,140 @@ from typing import List from cadwork.point_3d import point_3d +from cadwork.api_types import * -def get_last_error(error_code: int) -> str: - """Gets the last error - Parameters: - error_code: error_code - - Returns: - error string - """ - -def export_2d_wireframe_with_clipboard(clipboard_number: int, with_layout: bool) -> None: - """Exports a 2D wireframe to the clipboard +def export_2d_wireframe_with_clipboard(clipboard_number: UnsignedInt, with_layout: bool) -> None: + """Exports a 2D wireframe to the clipboard. Parameters: - clipboard_number: clipboard_number - with_layout: with_layout - - Returns: - None + clipboard_number: The clipboard number. + with_layout: Use layout, false by default. """ -def export_2d_hidden_lines_with_clipboard(clipboard_number: int, with_layout: bool) -> None: - """Exports a 2D hidden lines to the clipboard +def export_2d_hidden_lines_with_clipboard(clipboard_number: UnsignedInt, with_layout: bool) -> None: + """Exports a 2D hidden lines to the clipboard. Parameters: - clipboard_number: clipboard_number - with_layout: with_layout - - Returns: - None + clipboard_number: The clipboard number. + with_layout: Use layout, false by default. """ def export_2d_wireframe_with_2dc(file_path: str, with_layout: bool) -> None: - """Exports a 2D wireframe to a 2DC file + """Exports a 2D wireframe to a 2DC file. Parameters: - file_path: file_path - with_layout: with_layout - - Returns: - None + file_path: The export file path. + with_layout: Use layout, false by default. """ def export_2d_hidden_lines_with_2dc(file_path: str, with_layout: bool) -> None: - """Exports a 2D hidden lines to a 2DC file + """Exports a 2D hidden lines to a 2DC file. Parameters: - file_path: file_path - with_layout: with_layout - - Returns: - None + file_path: The export file path. + with_layout: Use layout, false by default. """ -def export_wall_with_clipboard(clipboard_number: int, element_id_list: List[int]) -> None: - """Exports a wall to the clipboard +def export_wall_with_clipboard(clipboard_number: UnsignedInt, element_id_list: List[ElementId]) -> None: + """Exports a wall to the clipboard. Parameters: - clipboard_number: clipboard_number - element_id_list: element_id_list - - Returns: - None + clipboard_number: The clipboard number. + element_id_list: The elements to export. """ -def export_export_solid_with_clipboard(clipboard_number: int, element_id_list: List[int]) -> None: - """Exports an export solid to the clipboard +def export_export_solid_with_clipboard(clipboard_number: UnsignedInt, element_id_list: List[ElementId]) -> None: + """Exports an export solid to the clipboard. Parameters: - clipboard_number: clipboard_number - element_id_list: element_id_list - - Returns: - None + clipboard_number: The clipboard number. + element_id_list: The elements to export. """ -def export_piece_by_piece_with_clipboard(clipboard_number: int, element_id_list: List[int]) -> None: - """Exports a piece-by-piece to the clipboard +def export_piece_by_piece_with_clipboard(clipboard_number: UnsignedInt, element_id_list: List[ElementId]) -> None: + """Exports a piece-by-piece to the clipboard. Parameters: - clipboard_number: clipboard_number - element_id_list: element_id_list - - Returns: - None + clipboard_number: The clipboard number. + element_id_list: The elements to export. """ -def assign_export_solid(ceo_element: List[int], element_id_list: List[int]) -> None: - """Assigns elements to an export solid +def assign_export_solid(ceo_element_id_list: List[ElementId], element_id_list: List[ElementId]) -> None: + """Assigns elements to an export solid. Parameters: - ceo_element: ceo_element - element_id_list: element_id_list - - Returns: - None + ceo_element_id_list: The export solid to assign. + element_id_list: The elements to assign. """ -def export_container_with_clipboard(clipboard_number: int, elements: List[int]) -> None: - """Export a container to the clipboard +def export_container_with_clipboard(clipboard_number: UnsignedInt, element_id_list: List[ElementId]) -> None: + """Export a container to the clipboard. Parameters: - clipboard_number: clipboard_number - elements: elements - - Returns: - None + clipboard_number: The clipboard number. + element_id_list: The elements to export. """ -def add_wall_section_horizontal(element: int, position: point_3d) -> None: - """Adds a horizontal wall section +def add_wall_section_horizontal(element_id: ElementId, position: point_3d) -> None: + """Adds a horizontal wall section. Parameters: - element: element - position: position - - Returns: - None + element_id: The element id. + position: The section position. """ -def add_wall_section_vertical(element: int, position: point_3d) -> None: - """Adds a vertical wall section +def add_wall_section_vertical(element_id: ElementId, position: point_3d) -> None: + """Adds a vertical wall section. Parameters: - element: element - position: position - - Returns: - None + element_id: The element id. + position: The section position. """ -def export_wall_with_clipboard_and_presetting(clipboard_number: int, element_id_list: List[int], presetting_file: str) -> None: - """Exports a wall to the clipboard +def export_wall_with_clipboard_and_presetting(clipboard_number: UnsignedInt, element_id_list: List[ElementId], presetting_file: str) -> None: + """Exports a wall to the clipboard. Parameters: - clipboard_number: clipboard_number - element_id_list: element_id_list - presetting_file: presetting_file - - Returns: - None + clipboard_number: The clipboard number. + element_id_list: The element id list to export. + presetting_file: The presetting file path. """ def load_export_piece_by_piece_settings(settings_file_path: str) -> None: - """Loads piece by piece export settings + """Loads piece by piece export settings. Parameters: - settings_file_path: settings_file_path - - Returns: - None + settings_file_path: The settings file path. """ def save_export_piece_by_piece_settings(settings_file_path: str) -> None: - """Saves piece by piece export settings + """Saves piece by piece export settings. Parameters: - settings_file_path: settings_file_path - - Returns: - None + settings_file_path: The settings file path. """ def clear_errors() -> None: - """clear errors - - Returns: - None + """Clears all errors. """ def load_export_wall_settings(settings_file_path: str) -> None: - """Loads wall export settings + """Loads wall export settings. Parameters: - settings_file_path: settings_file_path - - Returns: - None + settings_file_path: The settings file path. """ def load_export_solid_settings(settings_file_path: str) -> None: - """Loads export solid settings + """Loads export solid settings. Parameters: - settings_file_path: settings_file_path - - Returns: - None + settings_file_path: The settings file path. """ def load_export_container_settings(settings_file_path: str) -> None: - """Loads container export settings + """Loads container export settings. Parameters: - settings_file_path: settings_file_path - - Returns: - None - """ - + settings_file_path: The settings file path. + """ \ No newline at end of file diff --git a/src/utility_controller/__init__.pyi b/src/utility_controller/__init__.pyi index 9e5784a..a4edd95 100644 --- a/src/utility_controller/__init__.pyi +++ b/src/utility_controller/__init__.pyi @@ -1,352 +1,275 @@ from typing import List from typing import Tuple +from cadwork.api_types import ElementId from cadwork.point_3d import point_3d from cadwork.window_geometry import window_geometry from cadwork.shortcut_key import shortcut_key from cadwork.shortcut_key_modifier import shortcut_key_modifier -def get_last_error(error_code: int) -> str: - """Gets the last error - - Parameters: - error_code: error_code - - Returns: - error string - """ - - def get_3d_version() -> int: - """Gets the 3D version + """Gets the 3D version. Returns: - 3D version + The 3D version. """ - def get_3d_build() -> int: - """Gets the 3D build + """Gets the 3D build. Returns: - 3D build + The 3D build. """ - def get_3d_file_path() -> str: - """Gets the 3D file path + """Gets the 3D file path. Returns: - 3D file path + The 3D file path. """ - -def set_project_data(element_id: str, data: str) -> None: - """Sets the project data +def set_project_data(project_data_id: str, data: str) -> None: + """Sets the project data. Parameters: - element_id: element_id - data: data - - Returns: - None + project_data_id: The project data id. + data: The data to set. """ def print_error(message: str) -> None: - """Prints an error + """Prints an error. Parameters: - message: message - - Returns: - None + message: The error message. """ def get_language() -> str: - """Gets the 3D language + """Gets the 3D language. Returns: - 3D language + The language. """ def print_message(message: str, row: int, column: int) -> None: - """Prints a message + """Prints a message. Parameters: - message: message - row: row - column: column - - Returns: - None + message: The message to print. + row: The row to print the message in. + column: The column to print the message in. """ def get_user_int(message: str) -> int: - """Prompts the user for an integer + """Prompts the user for an integer. Parameters: - message: message + message: The message to display. Returns: - user integer + The user input integer. """ def get_user_double(message: str) -> float: - """Prompts the user for a double + """Prompts the user for a double. Parameters: - message: message + message: The message to display. Returns: - user double + The user input double. """ def get_user_bool(message: str, default_yes: bool) -> bool: - """Prompts the user for a boolean + """Prompts the user for a boolean. Parameters: - message: message - default_yes: default_yes + message: The message to display. + default_yes: The default value, True by default. Returns: - user boolean + The user input boolean. """ def get_user_string(message: str) -> str: - """Prompts the user for a string + """Prompts the user for a string. Parameters: - message: message + message: The message to display. Returns: - user string + The user input string. """ def set_project_name(project_name: str) -> None: - """Sets the project name + """Sets the project name. Parameters: - project_name: project_name - - Returns: - None + project_name: The project name. """ def set_project_number(project_number: str) -> None: - """Sets the project number + """Sets the project number. Parameters: - project_number: project_number - - Returns: - None + project_number: The project number. """ def set_project_part(project_part: str) -> None: - """Sets the project part + """Sets the project part. Parameters: - project_part: project_part - - Returns: - None + project_part: The project part. """ def set_project_architect(project_architect: str) -> None: - """Sets the project architect + """Sets the project architect. Parameters: - project_architect: project_architect - - Returns: - None + project_architect: The project architect. """ def set_project_customer(project_customer: str) -> None: - """Sets the project customer + """Sets the project customer. Parameters: - project_customer: project_customer - - Returns: - None + project_customer: The project customer. """ def set_project_designer(project_designer: str) -> None: - """Sets the project designer + """Sets the project designer. Parameters: - project_designer: project_designer - - Returns: - None + project_designer: The project designer. """ def set_project_deadline(project_deadline: str) -> None: - """Sets the project deadline + """Sets the project deadline. Parameters: - project_deadline: project_deadline - - Returns: - None + project_deadline: The project deadline. """ def set_project_user_attribute(number: int, user_attribute: str) -> None: - """Sets the project user attribute + """Sets the project user attribute. Parameters: - number: number - user_attribute: user_attribute - - Returns: - None + number: The project user attribute number. + user_attribute: The project user attribute. """ def set_project_user_attribute_name(number: int, user_attribute_name: str) -> None: - """Sets the project user attribute name + """Sets the project user attribute name. Parameters: - number: number - user_attribute_name: user_attribute_name - - Returns: - None + number: The project user attribute number. + user_attribute_name: The project user attribute name. """ def set_project_latitude(latitude: float) -> None: - """Sets the project latitude + """Sets the project latitude. Parameters: - latitude: latitude - - Returns: - None + latitude: The project latitude. """ def set_project_longitude(longitude: float) -> None: - """Sets the project longitude + """Sets the project longitude. Parameters: - longitude: longitude - - Returns: - None + longitude: The project longitude. """ def set_project_address(address: str) -> None: - """Sets the project address + """Sets the project address. Parameters: - address: address - - Returns: - None + address: The project address. """ def set_project_postal_code(postal_code: str) -> None: - """Sets the project postal code + """Sets the project postal code. Parameters: - postal_code: postal_code - - Returns: - None + postal_code: The project postal code. """ def set_project_city(city: str) -> None: - """Sets the project city + """Sets the project city. Parameters: - city: city - - Returns: - None + city: The project city. """ def set_project_country(country: str) -> None: - """Sets the project country + """Sets the project country. Parameters: - country: country - - Returns: - None + country: The project country. """ def get_user_file_from_dialog(name_filter: str) -> str: - """Gets a file with a dialog + """Gets a file with a dialog. Parameters: - name_filter: name_filter + name_filter: The dialog file filter. Returns: - file path + The file path. """ def get_client_number() -> str: - """Gets the client number + """Gets the client number. Returns: - client number + The client number. """ def get_user_point() -> point_3d: - """Gets a point from the user + """Gets a point from the user. Returns: - user point + The user point. """ def disable_auto_display_refresh() -> None: - """ - Disables the automatic refresh of the display. - - This function prevents the display from updating automatically, which can - significantly improve performance during operations that involve multiple - changes or computations. The display will remain static until explicitly - refreshed by the user. - - Returns: - None + """Disables automatic display refresh. + This function prevents the display from updating automatically, + which can significantly improve performance during operations that involve multiple changes or computations. + The display will remain static until explicitly refreshed by the user. """ def enable_auto_display_refresh() -> None: - """ - Enables the automatic refresh of the display. - This function restores the default behavior where the display updates - automatically after each operation. Use this function to resume normal - display updates after previously disabling them with disable_auto_display_refresh(). - It's recommended to call this function after completing operations that required - disabled display refreshing. - + """Enables automatic display refresh. + This function restores the default behavior where the display updates automatically after each operation. + Use this function to resume normal display updates after previously disabling them with disable_auto_display_refresh(). + It's recommended to call this function after completing operations that required disabled display refreshing. Examples: >>> import cadwork @@ -358,65 +281,56 @@ def enable_auto_display_refresh() -> None: >>> uc.enable_auto_display_refresh() >>> ec.recreate_elements(your_list_of_elements) - Note: If elements were created while display refresh was disabled, it's important to recreate these elements after enabling the display refresh to ensure they are properly visualized in cadwork. - - Returns: - None """ def create_new_guid() -> str: - """Creates a new GUID + """Creates a new GUID. Returns: - GUID + The new GUID. """ def print_to_console(message: str) -> None: - """Prints a message to the console + """Prints a message to the console. Parameters: - message: message - - Returns: - None + message: The message. """ def export_screen_to_image(file_path: str, factor: int) -> None: - """Exports the screen to an image + """Exports the screen to an image. Parameters: - file_path: file_path - factor: factor - - Returns: - None + file_path: The file path. + factor: The image factor. """ def get_new_user_file_from_dialog(name_filter: str) -> str: - """Gets a new file with a dialog + """Gets a new file with a dialog. Parameters: - name_filter: name_filter + name_filter: The dialog file filter. Returns: - file path + The file path. """ - + def api_autostart(api_name: str, option: int) -> int: - """Manages the autostart configuration for a specified API. + """Sets an API autostart option. Parameters: - api_name: Name of the API to be managed. - option: Determines the operation mode: + api_name: The name of the API be managed. + option: The autostart option to use. + - -1: Checks if API is configured for autostart without making changes. Returns 1 if API is found, 0 if not, or -1 in case of errors. - 1: Enables autostart for the specified API. @@ -427,7 +341,6 @@ def api_autostart(api_name: str, option: int) -> int: to manage the autostart state of the API. Examples: - >>> api_autostart("my_api", 1) # Enable autostart >>> api_autostart("my_api", 0) # Disable autostart >>> api_autostart("my_api", -1) # Check current autostart state @@ -438,846 +351,744 @@ def api_autostart(api_name: str, option: int) -> int: def enable_autostart(api_name: str) -> None: - """enable autostart + """Enables autostart for a given API. Parameters: - api_name: api_name - - Returns: - None + api_name: The name of the API for which to enable autostart. """ def disable_autostart(api_name: str) -> None: - """disable autostart + """Disables autostart for a given API. Parameters: - api_name: api_name - - Returns: - None + api_name: The name of the API for which to disable autostart. """ def check_autostart(api_name: str) -> bool: - """check autostart + """Checks if autostart is enabled for a given API. Parameters: - api_name: api_name + api_name: The name of the API to check. Returns: - bool + True if autostart is enabled, false otherwise. """ def delete_project_data(element_id: str) -> None: - """Deletes the project data + """Deletes the project data. Parameters: - element_id: element_id - - Returns: - None + element_id: The project data id. """ def run_external_program(name: str) -> bool: - """Runs a 3D external program + """Runs a 3D external program. Parameters: - name: name + name: The external program name. Returns: - external program return + False if the program could not be run, true otherwise. """ def save_3d_file_silently() -> None: - """Saves the 3D file silently - - Returns: - None + """Saves the 3D file silently. """ def get_licence_first_part() -> str: - """Gets the first part of the license + """Gets the first part of the licence. Returns: - first part of license + The first part of the licence. """ def get_licence_second_part() -> str: - """Gets the second part of the license + """Gets the second part of the licence. Returns: - second part of license + The second part of the licence. """ def show_progress_bar() -> None: - """Shows a ProgressBar in the CommandBar - - Returns: - None + """Shows a ProgressBar in the CommandBar. """ def update_progress_bar(value: int) -> None: - """Updates the ProgressBar with a value + """Updates the ProgressBar with a value. Parameters: - value: value - - Returns: - None + value: A value between 0 and 100. """ def hide_progress_bar() -> None: - """Hides the ProgressBar - - Returns: - None + """Hides the ProgressBar. """ def get_user_color(initial_color: int) -> int: - """Gets a color choosen by the user + """Gets a color choosen by the user. Parameters: - initial_color: initial_color + initial_color: The initial color. Returns: - the colornumber + The color number. """ def get_3d_linear_units() -> str: - """Gets the current linear units + """Gets the current linear units. Returns: - str + The current linear units. """ def get_3d_linear_display_units() -> str: - """Gets the current display units + """Gets the current display units. Returns: - str + The current display units. """ def get_3d_angular_units() -> str: - """Gets the current angular units + """Gets the current angular units. Returns: - str + The current angular units. """ def get_3d_angular_display_units() -> str: - """Gets the current angular display units + """Gets the current angular display units. Returns: - str + The current angular display units. """ def get_3d_build_date() -> str: - """Gets the current build date + """Gets the current build date. Returns: - str + The current build date. """ def set_project_elevation(elevation: float) -> None: - """Sets the project elevation + """Sets the project elevation. Parameters: - elevation: elevation - - Returns: - None + elevation: The project elevation. """ def clear_errors() -> None: - """clear errors - - Returns: - None + """Clears all errors. """ def push_check_and_query_data() -> None: - """push check and query data - - Returns: - None + """Pushes the current state of check and query data onto a stack. """ def pop_check_and_query_data() -> None: - """pop check and query data - - Returns: - None + """Pops the most recent state of check and query data from the stack. """ def change_check_and_query_data_to_no_queries() -> None: - """change check and query data to no queries - - Returns: - None + """Changes the current state of check and query data to no queries. """ def change_check_and_query_data_to_queries() -> None: - """change check and query data to queries - - Returns: - None + """Changes the current state of check and query data to allow queries. """ def is_direct_info_enabled() -> bool: - """is direct info enabled + """Checks if Direct Info is enabled. Returns: - bool + True if Direct Info is enabled, false otherwise. """ def enable_direct_info() -> None: - """enable direct info - - Returns: - None + """Enables Direct Info. """ def disable_direct_info() -> None: - """disable direct info - - Returns: - None + """Disables Direct Info. """ def load_attribute_display_settings(file_path: str) -> None: - """load attribute display settings + """Loads attribute display settings from a file. Parameters: - file_path: file_path - - Returns: - None + file_path: The path to the file containing the settings. """ def set_project_description(description: str) -> None: - """set project description + """Sets the project description. Parameters: - description: description - - Returns: - None + description: The new description for the project. """ def start_project_data_dialog() -> None: - """start project data dialog - - Returns: - None + """Starts the project data dialog. """ def init_LxSDK() -> None: - """init LxSDK - - Returns: - None + """Initializes the LxSDK. """ -def load_element_attribute_display_settings(file_path: str, elements: List[int]) -> None: - """load element attribute display settings +def load_element_attribute_display_settings(file_path: str, elements: List[ElementId]) -> None: + """Loads element attribute display settings from a file. Parameters: - file_path: file_path - elements: elements - - Returns: - None + file_path: The path to the file containing the settings. + elements: The element list for which to load the settings. """ def get_global_x_offset() -> float: - """get global x offset + """Gets the global X offset. Returns: - float + The global X offset. """ def set_global_x_offset(offset: float) -> None: - """set global x offset + """Sets the global X offset. Parameters: - offset: offset - - Returns: - None + offset: The new global X offset. """ def get_global_y_offset() -> float: - """get global y offset + """Gets the global Y offset. Returns: - float + The global Y offset. """ def set_global_y_offset(offset: float) -> None: - """set global y offset + """Sets the global Y offset. Parameters: - offset: offset - - Returns: - None + offset: The new global Y offset. """ def get_global_z_offset() -> float: - """get global z offset + """Gets the global Z offset. Returns: - float + The global Z offset. """ def set_global_z_offset(offset: float) -> None: - """set global z offset + """Sets the global Z offset. Parameters: - offset: offset - - Returns: - None + offset: The new global Z offset. """ def show_north_arrow() -> None: - """show north arrow - - Returns: - None + """Shows the north arrow on the 3D view. """ def hide_north_arrow() -> None: - """hide north arrow - - Returns: - None + """Hides the north arrow on the 3D view. """ def is_north_arrow_visible() -> bool: - """is north arrow visible + """Checks if the north arrow is visible on the 3D view. Returns: - bool + True if the north arrow is visible, false otherwise. """ def get_north_angle() -> float: - """get north angle + """Gets the angle of the north direction. Returns: - float + The angle of the north direction in degrees. """ def set_north_angle(north_angle: float) -> None: - """set north angle + """Sets the angle of the north direction. Parameters: - north_angle: north_angle - - Returns: - None + north_angle: The angle of the north direction in degrees. """ def get_user_file_from_dialog_in_path(name_filter: str, path: str) -> str: - """get user file from dialog in path + """Gets a user file from a dialog in a specified path. Parameters: - name_filter: name_filter - path: path + name_filter: The filter for the dialog. + path: The path in which to get the user file. Returns: - str + A string containing the user file. """ def get_new_user_file_from_dialog_in_path(name_filter: str, path: str) -> str: - """get new user file from dialog in path + """Gets a new user file from a dialog in a specified path. Parameters: - name_filter: name_filter - path: path + name_filter: The filter for the dialog. + path: The path in which to get the new user file. Returns: - str + A string containing the new user file. """ def enable_update_variant() -> None: - """enable update variant - - Returns: - None + """Enables the update variant. """ def disable_update_variant() -> None: - """disable update variant - - Returns: - None + """Disables the update variant. """ def get_user_points() -> List[point_3d]: - """get user points + """Gets user points. Returns: - List[point_3d] + A list of user points. """ def get_user_points_with_count(count: int) -> List[point_3d]: - """get user points with count + """Gets user points with a specified count. Parameters: - count: count + count: The number of user points to get. Returns: - List[point_3d] + A list of user points. """ def get_user_path_from_dialog() -> str: - """get user path from dialog + """Gets the user path from a dialog. Returns: - str + A string containing the user path. """ def get_user_path_from_dialog_in_path(path: str) -> str: - """get user path from dialog in path + """Gets the user path from a dialog in a specified path. Parameters: - path: path + path: The path in which to get the user path. Returns: - str + A string containing the user path. """ def execute_shortcut(shortcut_key_modifier: shortcut_key_modifier, shortcut_key: shortcut_key) -> None: - """execute shortcut + """Executes a shortcut. Parameters: - shortcut_key_modifier: shortcut_key_modifier - shortcut_key: shortcut_key - - Returns: - None + shortcut_key_modifier: The modifier key for the shortcut. + shortcut_key: The key for the shortcut. """ def run_external_program_from_custom_directory(file_path: str) -> bool: - """Runs a 3D external program from a custom file path + """Runs a 3D external program from a custom directory. Parameters: - file_path: file_path + file_path: The external program file path. Returns: - external program return + False if error, true otherwise. """ def get_3d_file_name() -> str: - """Gets the 3D file name + """Gets the 3D file name. Returns: - 3D file name + The 3D file name. """ def get_project_data(element_id: str) -> str: - """Gets the project data + """Gets the project data. Parameters: - element_id: element_id + element_id: The project data id. Returns: - project data + The project data. """ def get_project_name() -> str: - """Gets the project name + """Gets the project name. Returns: - project name + The project name. """ def get_project_part() -> str: - """Sets the project part + """Gets the project part. Returns: - project part + The project part. """ def get_project_architect() -> str: - """Gets the project architect + """Gets the project architect. Returns: - project architect + The project architect. """ def get_project_number() -> str: - """Gets the project number + """Gets the project number. Returns: - project number + The project number. """ def get_project_customer() -> str: - """Gets the project customer + """Gets the project customer. Returns: - project customer + The project customer. """ def get_project_designer() -> str: - """Gets the project designer + """Gets the project designer. Returns: - project designer + The project designer. """ def get_project_deadline() -> str: - """Gets the project deadline + """Gets the project deadline. Returns: - project deadline + The project deadline. """ def get_project_user_attribute(number: int) -> str: - """Gets the project user attribute + """Gets the project user attribute. Parameters: - number: number + number: The project user attribute number. Returns: - project user attribute + The project user attribute. """ def get_project_user_attribute_name(number: int) -> str: - """Gets the project user attribute name + """Gets the project user attribute name. Parameters: - number: number + number: The project user attribute number. Returns: - project user attribute name + The project user attribute name. """ def get_project_latitude() -> float: - """Gets the project latitude + """Gets the project latitude. Returns: - project latitude + The project latitude. """ def get_project_longitude() -> float: - """Gets the project longitude + """Gets the project longitude. Returns: - project longitude + The project longitude. """ def get_project_postal_code() -> str: - """Gets the project postal code + """Gets the project postal code. Returns: - project postal code + The project postal code. """ def get_project_address() -> str: - """Gets the project address + """Gets the project address. Returns: - project address + The project address. """ def get_project_city() -> str: - """Gets the project city + """Gets the project city. Returns: - project city + The project city. """ def get_project_country() -> str: - """Gets the project country + """Gets the project country. Returns: - project country + The project country. """ def get_project_elevation() -> float: - """Gets the project elevation + """Gets the project elevation. Returns: - project elevation + The project elevation. """ def get_project_description() -> str: - """get project description + """Gets the project description. Returns: - str + A string containing the project description. """ def get_project_guid() -> str: - """Gets the project GUID + """Gets the project GUID. Returns: - project GUID + The project GUID. """ def get_3d_userprofil_path() -> str: - """Gets the 3D userprofil path + """Gets the 3D userprofil path. Returns: - the 3D userprofil path + The 3D userprofil path. """ def get_plugin_path() -> str: - """get plugin path + """Gets the plugin path. Returns: - str + A string containing the plugin path. """ def get_millimetre_from_imperial_string(value: str) -> float: - """get millimetre from imperial string + """Converts an imperial string to millimetres. Parameters: - value: value + value: The imperial string to convert. Returns: - float + The value in millimetres. """ def get_imperial_string_from_millimetre(value: float) -> str: - """get imperial string from millimetre + """Converts a value in millimetres to an imperial string. Parameters: - value: value + value: The value in millimetres to convert. Returns: - str + The value as an imperial string. """ def get_user_catalog_path() -> str: - """get user catalog path + """Gets the user catalog path. Returns: - str + A string containing the user catalog path. """ def get_3d_hwnd() -> int: - """Gets the 3D HWND + """Gets the 3D HWND. Returns: - 3D HWND + The 3D HWND. """ def close_cadwork_document_saved() -> None: - """close cadwork saved - - Returns: - None + """close cadwork saved. """ def close_cadwork_document_unsaved() -> None: - """close cadwork document unsaved - - Returns: - None + """close cadwork unsaved. """ def get_use_of_global_coordinates() -> bool: - """get use of global coordinates + """Gets the use of global coordinates. Returns: - bool + True if global coordinates are used, false otherwise. """ def set_use_of_global_coordinates(use_of_global_coordinates: bool) -> None: - """Sets the use of global coordinates + """Sets the use of global coordinates. Parameters: - use_of_global_coordinates: use_of_global_coordinates - - Returns: - None + use_of_global_coordinates: True to use global coordinates, false otherwise. """ def get_global_origin() -> point_3d: - """Gets the global origin + """Gets the global origin. Returns: - global origin + The global origin. """ def set_global_origin(global_origin: point_3d) -> None: - """Sets the global origin + """Sets the global origin. Parameters: - global_origin: global_origin - - Returns: - None + global_origin: The global origin. """ def create_snapshot() -> str: - """get snapshot from screen + """Get snapshot from screen. Returns: - snapshot + The snapshot as a string. """ def get_3d_gui_upper_left_screen_coordinates() -> Tuple[int, int]: - """get 3d gui upper left screen coordinates + """Get the coordinates of the upper left corner of the 3D GUI. Returns: - coordinates of the upper left corner of the 3D GUI + The coordinates of the upper left corner of the 3D GUI. """ def get_3d_main_window_geometry() -> 'window_geometry': - """get 3d main window geometry + """Get the geometry of 3d main window. Returns: - window geometry + The geometry of the 3D main window. """ def get_project_data_keys() -> List[str]: - """get project data keys + """Gets all keys for project data. Returns: - List[str] + The list of project data keys. """ def get_user_int_with_default_value(message: str, default_value: int) -> int: - """get user int with default value + """Prompts the user for an integer with a default value. Parameters: - message: message - default_value: default_value + message: The message to display. + default_value: The default value. Returns: - int + The user integer. """ def get_user_double_with_default_value(message: str, default_value: float) -> float: - """get user double with default value + """Prompts the user for a double with a default value. Parameters: - message: message - default_value: default_value + message: The message to display. + default_value: The default value. Returns: - float + The user double. """ def get_user_string_with_default_value(message: str, default_value: str) -> str: - """get user string with default value + """Prompts the user for a string with a default value. Parameters: - message: message - default_value: default_value + message: The message to display. + default_value: The default value. Returns: - str + The user string. """ def get_3d_version_name() -> str: - """get 3d version name + """Gets the 3D version name. Returns: - str + The 3D version name. """ def redirect_python_output_to_logger() -> None: - """redirect python output to logger. - This function is used to redirect the output of the Python interpreter to the logger. - This is useful for debugging and logging purposes. - - Returns: - None + """Redirects output from Python's print function to the cadwork logger. + This function is used to redirect the output of the Python interpreter to the logger. + This is useful for debugging and logging purposes. """ diff --git a/src/visualization_controller/__init__.pyi b/src/visualization_controller/__init__.pyi index 1fc703c..6f61614 100644 --- a/src/visualization_controller/__init__.pyi +++ b/src/visualization_controller/__init__.pyi @@ -1,582 +1,436 @@ from typing import List from cadwork.camera_data import camera_data from cadwork.point_3d import point_3d +from cadwork.api_types import * +from cadwork.rgb_color import rgb_color -def get_last_error(error_code: int) -> str: - """Gets the last error +def set_color(element_id_list: List[ElementId], color_id: ColorId) -> None: + """Sets the element color. Parameters: - error_code: error_code - - Returns: - error string + element_id_list: The list of element id. + color_id: The color ID to set. """ -def set_color(element_id_list: List[int], color_id: int) -> None: - """Sets the element color +def set_opengl_color(element_id_list: List[ElementId], color: rgb_color) -> None: + """Sets the element OpenGL color. Parameters: - element_id_list: element_id_list - color_id: color_id - - Returns: - None + element_id_list: The list of element id. + color: The OpenGL color to set. """ -def set_opengl_color(element_id_list: List[int], color: None) -> None: - """Sets the element OpenGL color +def is_active(element_id: ElementId) -> bool: + """Tests if element is active. Parameters: - element_id_list: element_id_list - color: color + element_id: The element id. Returns: - None + True if the element is active, false otherwise. """ -def is_active(element_id: int) -> bool: - """Tests if element is active +def set_active(element_id_list: List[ElementId]) -> None: + """Sets element active. Parameters: - element_id: element_id - - Returns: - is element active + element_id_list: The list of element id. """ -def set_active(element_id_list: List[int]) -> None: - """Sets element active +def set_inactive(element_id_list: List[ElementId]) -> None: + """Sets the element inactive. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The list of element id. """ -def set_inactive(element_id_list: List[int]) -> None: - """Sets the element inactive +def is_visible(element_id: ElementId) -> bool: + """Tests if element is visible. Parameters: - element_id_list: element_id_list + element_id: The element id. Returns: - None + True if the element is visible, false otherwise. """ -def is_visible(element_id: int) -> bool: - """Tests if element is visible +def set_visible(element_id_list: List[ElementId]) -> None: + """Sets the element visible. Parameters: - element_id: element_id - - Returns: - is element visible + element_id_list: The list of element id. """ -def set_visible(element_id_list: List[int]) -> None: - """Sets the element visible +def set_invisible(element_id_list: List[ElementId]) -> None: + """Sets the element invisible. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The list of element id. """ -def set_invisible(element_id_list: List[int]) -> None: - """Sets the element invisible +def is_immutable(element_id: ElementId) -> bool: + """Tests if the element is immutable. Parameters: - element_id_list: element_id_list + element_id: The element id. Returns: - None + True if the element is immutable, false otherwise. """ -def is_immutable(element_id: int) -> bool: - """Tests if the element is immutable +def set_immutable(element_id_list: List[ElementId]) -> None: + """Sets the element immutable. Parameters: - element_id: element_id - - Returns: - is element immutable - """ - -def set_immutable(element_id_list: List[int]) -> None: - """Sets the element immutable - - Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The list of element id. """ -def set_mutable(element_id_list: List[int]) -> None: - """Sets the element mutable +def set_mutable(element_id_list: List[ElementId]) -> None: + """Sets the element mutable. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The list of element id. """ def show_all_elements() -> None: - """Shows all elements - - Returns: - None + """Shows all elements. """ def hide_all_elements() -> None: - """Hides all elements - - Returns: - None + """Hides all elements. """ def zoom_all_elements() -> None: - """Zooms on all elements - - Returns: - None + """Zooms on all elements. """ def zoom_active_elements() -> None: - """Zooms on all active elements - - Returns: - None + """Zooms on all active elements. """ def refresh() -> None: - """Refresh the drawing area - - Returns: - None + """Refresh the drawing area. """ -def set_material(element_id_list: List[int], element_id: int) -> None: - """Sets the element material +def set_material(element_id_list: List[ElementId], element_id: ElementId) -> None: + """Sets the element material. Parameters: - element_id_list: element_id_list - element_id: element_id - - Returns: - None + element_id_list: The list of element id. + element_id: The material ID to set. """ def save_visibility_state() -> "visibility_state": - """Saves the visibility state + """Saves the visibility state. Returns: - visibility state + The visibility state. """ def restore_visibility_state(state: None) -> None: - """Restores the visibility state + """Restores the visibility state. Parameters: - state: state - - Returns: - None + state: The visibility state to restore. """ def save_activation_state() -> "activation_state": - """Saves the activation state + """Saves the activation state. Returns: - activation state + The activation state. """ def restore_activation_state(state: None) -> None: - """Restores the activation state + """Restores the activation state. Parameters: - state: state - - Returns: - None + state: The activation state to restore. """ def show_view_positive_x() -> None: - """Sets the view to +X - - Returns: - None + """Sets the view to +X. """ def show_view_negative_x() -> None: - """Sets the view to -X - - Returns: - None + """Sets the view to -X. """ def show_view_positive_y() -> None: - """Sets the view to +Y - - Returns: - None + """Sets the view to +Y. """ def show_view_negative_y() -> None: - """Sets the view to -Y - - Returns: - None + """Sets the view to -Y. """ def show_view_positive_z() -> None: - """Sets the view to +Z - - Returns: - None + """Sets the view to +Z. """ def show_view_negative_z() -> None: - """Sets the view to -Z - - Returns: - None + """Sets the view to -Z. """ def show_view_standard_axo() -> None: - """Sets the view to standard axonometry - - Returns: - None + """Sets the view to standard axonometry. """ def show_view_wireframe() -> None: - """Sets the view to wireframe - - Returns: - None + """Sets the view to wireframe. """ def show_view_hidden_lines() -> None: - """Sets the view to hidden lines - - Returns: - None + """Sets the view to hidden lines. """ def show_view_dashed_hidden_lines() -> None: - """Sets the view to dashed hidden lines - - Returns: - None + """Sets the view to dashed hidden lines. """ def show_view_shaded2() -> None: - """Sets the view to shaded 2 - - Returns: - None + """Sets the view to shaded 2. """ def show_view_shaded1() -> None: - """Sets the view to shaded 1 - - Returns: - None + """Sets the view to shaded 1. """ -def is_selectable(element_id: int) -> bool: - """Returns if the element is selectable +def is_selectable(element_id: ElementId) -> bool: + """Returns if the element is selectable. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is selectable, false otherwise. """ -def set_unselectable(element_id_list: List[int]) -> None: - """Sets a list of elements unselectable +def set_unselectable(element_id_list: List[ElementId]) -> None: + """Sets a list of elements unselectable. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The list of element id. """ -def set_selectable(element_id_list: List[int]) -> None: - """Sets a list of elements selectable +def set_selectable(element_id_list: List[ElementId]) -> None: + """Sets a list of elements selectable. Parameters: - element_id_list: element_id_list - - Returns: - None + element_id_list: The list of element id. """ def clear_errors() -> None: - """clear errors - - Returns: - None + """Clears all errors. """ def load_marking_settings(settings_file_path: str) -> None: - """Loads marking settings file + """Loads marking settings file. Parameters: - settings_file_path: settings_file_path - - Returns: - None + settings_file_path: The path to the settings file. """ def is_plane_2d() -> bool: - """returns if plane 2d is active + """returns if plane 2d is active. Returns: - bool + True if plane 2D is active, false otherwise. """ def set_camera(position: point_3d, target: point_3d) -> None: """Sets the position of the camera, pointing to a target. Parameters: - position: position - target: target - - Returns: - None + position: The position of the camera. + target: The target the camera is pointing at. """ def show_perspective_central() -> None: - """changes the viewmode to Perpective - - Returns: - None + """changes the viewmode to Perspective. """ -def set_color_without_material(elements: List[int], color_id: int) -> None: - """set color without material +def set_color_without_material(element_id_list: List[ElementId], color_id: ColorId) -> None: + """Sets the color of a list of elements without changing their material. Parameters: - elements: elements - color_id: color_id - - Returns: - None + element_id_list: A list of element id. + color_id: The color ID to set. """ -def set_texture_rotated(elements: List[int], flag: bool) -> None: - """set texture rotated +def set_texture_rotated(element_id_list: List[ElementId], flag: bool) -> None: + """Sets the rotation of the texture for a list of elements. Parameters: - elements: elements - flag: flag - - Returns: - None + element_id_list: A list of element id. + flag: True to rotate the texture, false to not rotate it. """ def show_reference_side_beam(show: bool) -> None: - """show reference side beam + """Shows or hides the reference side beam. Parameters: - show: show - - Returns: - None + show: True to show the reference side beam, false to hide it. """ def show_reference_side_panel(show: bool) -> None: - """show reference side panel + """Shows or hides the reference side panel. Parameters: - show: show - - Returns: - None + show: True to show the reference side panel, false to hide it. """ def show_reference_side_wall(show: bool) -> None: - """show reference side wall + """Shows or hides the reference side wall. Parameters: - show: show - - Returns: - None + show: True to show the reference side wall, false to hide it. """ def show_view_axo() -> None: - """changes the viewmode to Axo - - Returns: - None + """changes the viewmode to Axo. """ -def get_color(element_id: int) -> int: - """Gets the element color +def get_color(element_id: ElementId) -> int: + """Gets the element color. Parameters: - element_id: element_id + element_id: The element id. Returns: - color ID + The color ID of the element. """ -def get_opengl_color(element_id: int) -> 'rgb_color': - """Gets the element OpenGL color +def get_opengl_color(element_id: ElementId) -> rgb_color: + """Gets the element OpenGL color. Parameters: - element_id: element_id + element_id: The element id. Returns: - RBG color + The OpenGL color of the element. """ -def get_material(element_id: int) -> int: - """Gets the element material +def get_material(element_id: ElementId) -> MaterialId: + """Gets the element material. Parameters: - element_id: element_id + element_id: The element id. Returns: - material ID + The material id. """ -def get_rgb_from_cadwork_color_id(color_id: int) -> 'rgb_color': - """get rgb from cadwork color id +def get_rgb_from_cadwork_color_id(color_id: ColorId) -> rgb_color: + """Gets the RGB color from a Cadwork color ID. Parameters: - color_id: color_id + color_id: The Cadwork color ID. Returns: - colorRGB + The RGB color corresponding to the Cadwork color ID. """ -def is_texture_rotated(element_id: int) -> bool: - """is texture rotated +def is_texture_rotated(element_id: ElementId) -> bool: + """Checks if the texture of an element is rotated. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the texture is rotated, false otherwise. """ def get_camera_data() -> camera_data: - """Get the camera data + """Get the camera data. Returns: - camera data + The camera data. """ def set_camera_data(camera_data: camera_data) -> None: - """Set the camera data - this will override the current camera data + """Set the camera data - this will override the current camera data. Parameters: - camera_data: camera_data - - Returns: - None + camera_data: The camera data to set. """ def is_cadwork_window_in_light_mode() -> bool: - """Check if Cadwork window is in light mode + """Check if Cadwork window is in light mode. Returns: - window is in light mode + True if the window is in light mode, false otherwise. """ def is_cadwork_window_in_dark_mode() -> bool: - """Check if Cadwork window is in dark mode + """Check if Cadwork window is in dark mode. Returns: - window is in dark mode + True if the window is in dark mode, false otherwise. """ def enter_working_plane(plane_normal: point_3d, plane_origin: point_3d) ->None: - """enter working plane + """Enter 2d working plane. Parameters: - plane_normal: plane_normal - plane_origin: plane_origin - - Returns: - None + plane_normal: A normalized plane vector. + plane_origin: A plane origin. """ -def get_element_transparency(element_id: int) ->int: - """get element transparency +def get_element_transparency(element_id: ElementId) ->int: + """Gets the element transparency. Parameters: - element_id: element_id + element_id: The element id. Returns: - int + Transparency value as percentage. """ -def set_element_transparency(element_id_list: List[int], value: int) -> None: - """set element transparency +def set_element_transparency(element_id_list: List[ElementId], value: int) -> None: + """Sets the element transparency. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: Transparency value as percentage. """ -def get_use_material_texture(element_id: int) -> bool: - """get use material texture +def get_use_material_texture(element_id: ElementId) -> bool: + """Check if element is using material texture. Parameters: - element_id: element_id + element_id: The element id. Returns: - bool + True if the element is using material texture, false otherwise. """ -def set_use_material_texture(element_id_list: List[int], value: bool) -> None: - """set use material texture +def set_use_material_texture(element_id_list: List[ElementId], value: bool) -> None: + """Sets element to use material texture. Parameters: - element_id_list: element_id_list - value: value - - Returns: - None + element_id_list: The element id list. + value: True to use material texture, false otherwise. """ def display_bitmaps_as_texture_representation_in_shaded1(flag: bool) -> None: - """display bitmaps as texture representation in shaded1 + """Set the graphic option to display bitmaps as textures in shaded 1. Parameters: - flag: flag - - Returns: - None + flag: True to display bitmaps as textures in shaded 1, false otherwise. """ def display_bitmaps_as_texture_representation_in_shaded2(flag: bool) -> None: - """display bitmaps as texture representation in shaded2 + """Set the graphic option to display bitmaps as textures in shaded 2. Parameters: - flag: flag - - Returns: - None - """ + flag: True to display bitmaps as textures in shaded 2, false otherwise. + """ \ No newline at end of file From e6f4ac7f9096122d5951147995a1955a694f4825 Mon Sep 17 00:00:00 2001 From: BobillierCaddev Date: Fri, 26 Sep 2025 07:35:50 +0200 Subject: [PATCH 23/52] [API-529] Corrected shoulder geometry enum values (#276) --- src/cadwork/heel_shoulder_beam_geometry.pyi | 8 +++++--- src/cadwork/shoulder_beam_geometry.pyi | 19 ++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/cadwork/heel_shoulder_beam_geometry.pyi b/src/cadwork/heel_shoulder_beam_geometry.pyi index a0789d9..d07fca2 100644 --- a/src/cadwork/heel_shoulder_beam_geometry.pyi +++ b/src/cadwork/heel_shoulder_beam_geometry.pyi @@ -10,9 +10,11 @@ class heel_shoulder_beam_geometry(IntEnum): normal """ normal = 0 - """""" - straight = 1 - """""" + """NormalHeel + """ + straight = 3 + """StraightHeel + """ def __int__(self) -> int: return self.value diff --git a/src/cadwork/shoulder_beam_geometry.pyi b/src/cadwork/shoulder_beam_geometry.pyi index 9f31c6f..28deb23 100644 --- a/src/cadwork/shoulder_beam_geometry.pyi +++ b/src/cadwork/shoulder_beam_geometry.pyi @@ -9,14 +9,19 @@ class shoulder_beam_geometry(IntEnum): >>> cadwork.shoulder_beam_geometry.bisector bisector """ + bisector = 0 - """""" - perpendicular_to_strut = 1 - """""" - perpendicular_to_counter_part = 2 - """""" - birdsmouth = 3 - """""" + """Bisector + """ + birdsmouth = 2 + """PerpBirdmouth + """ + perpendicular_to_strut = 3 + """PerpShoulder + """ + perpendicular_to_counter_part = 4 + """PerpChord + """ def __int__(self) -> int: return self.value From 812e59010412df9dede457c03df140a648c78fc3 Mon Sep 17 00:00:00 2001 From: BobillierCaddev Date: Fri, 26 Sep 2025 07:51:46 +0200 Subject: [PATCH 24/52] Bugfix/api 529 corrected shoulder geometry enum values (#281) Updated the documentation version to 32.298.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3801c22..6ac64a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.297.0" +version = "32.298.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' From fffca86b2b70a73a3a64f009846b956ef44c5ff0 Mon Sep 17 00:00:00 2001 From: BobillierCaddev Date: Mon, 29 Sep 2025 08:30:07 +0200 Subject: [PATCH 25/52] [API-482] Corrected glide element description (#282) --- pyproject.toml | 2 +- src/element_controller/__init__.pyi | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6ac64a4..758afb6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.298.0" +version = "32.299.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' diff --git a/src/element_controller/__init__.pyi b/src/element_controller/__init__.pyi index f0f59bc..fd99946 100644 --- a/src/element_controller/__init__.pyi +++ b/src/element_controller/__init__.pyi @@ -618,12 +618,12 @@ def clear_errors() -> None: """Clears all errors. """ -def glide_elements(element_id_list: List[ElementId], glide_point: point_3d) -> None: +def glide_elements(element_id_list: List[ElementId], glide_origin_point: point_3d) -> None: """Glides elements to a specified point. Parameters: element_id_list: The elements to glide. - glide_point: The glide destination point. + glide_origin_point: The glide origin point. """ def cut_elements_with_miter(first_id: ElementId, second_id: ElementId) -> bool: From 6557e977e8e8c282842b195486e71766086ba87f Mon Sep 17 00:00:00 2001 From: BobillierCaddev Date: Mon, 27 Oct 2025 15:27:51 +0100 Subject: [PATCH 26/52] [API-533] Added major release note to the doc (#284) --- docs/release_notes_major.md | 136 ++++++++++++++++++++++++++++++++++++ mkdocs.yml | 4 +- 2 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 docs/release_notes_major.md diff --git a/docs/release_notes_major.md b/docs/release_notes_major.md new file mode 100644 index 0000000..8d80e25 --- /dev/null +++ b/docs/release_notes_major.md @@ -0,0 +1,136 @@ +# New methods added between the latest version of v30 and v32 + +## New methods in class: + +### Class: connector_axis_controller + +* get_counterbore_depth_for_end_side +* get_counterbore_depth_for_start_side +* get_counterbore_diameter_for_end_side +* get_counterbore_diameter_for_start_side +* get_counterbore_is_conical_for_end_side +* get_counterbore_is_conical_for_start_side +* get_intersection_count +* get_item_guids_at_intersection +* get_section_length +* get_section_oblong_drilling_angle +* get_section_oblong_drilling_is_enabled +* get_section_oblong_drilling_negative_value +* get_section_oblong_drilling_positive_value +* set_counterbore_for_end_side +* set_counterbore_for_start_side +* set_item_guids_at_intersection +* set_section_oblong_drilling_is_disabled +* set_section_oblong_drilling_is_enabled + +### Class: dimension_controller + +* get_dimension_base_format + +### Class: element_controller + +* cast_ray_and_get_element_intersections +* filter_elements +* map_elements + +### Class: file_controller + +* export_dstv_file +* export_dxf_file + +### Class: machine_controller + +* get_element_btl_processings +* get_element_hundegger_processings +* get_processing_btl_parameter_set +* get_processing_code +* get_processing_name +* get_processing_points + +### Class: utility_controller + +* get_3d_version_name +* redirect_python_output_to_logger + +## New classes + +### Class: dimension_base_format + +* __int__ + +### Class: dxf_export_version + +* __int__ + +### Class: dxf_layer_format_type + +* __int__ + +### Class: element_filter + +* set_comment +* set_group +* set_name +* set_part_number +* set_production_number +* set_sku +* set_subgroup +* set_user_attribute + +### Class: element_map_query + +* set_by_building +* set_by_comment +* set_by_group +* set_by_name +* set_by_part_number +* set_by_production_number +* set_by_sku +* set_by_storey +* set_by_subgroup +* set_by_user_attribute + +### Class: hit_result + +* get_hit_element_ids +* get_hit_vertices_by_element + +### Class: ifc_options_properties + +* get_export_quantity_sets +* set_export_quantity_sets + +### Class: point + +* __init__ + +### Class: point_3d + +* __add__ +* __eq__ +* __getitem__ +* __iadd__ +* __imul__ +* __isub__ +* __itruediv__ +* __mul__ +* __ne__ +* __neg__ +* __repr__ +* __rmul__ +* __setitem__ +* __sub__ +* __truediv__ + +### Class: text_object_options + +* get_draw_on_top +* set_draw_on_top + +### Class: vba_catalog_item_type + +* __int__ + +### Class: window_geometry + +* __init__ diff --git a/mkdocs.yml b/mkdocs.yml index db73c89..ae9fd93 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -107,7 +107,9 @@ nav: - auto_attributes.md - About: - About Guide: about.md - - Release Notes: release_notes.md + - Release Notes: + - Minor Release Notes: release_notes.md + - Major Release Notes: release_notes_major.md markdown_extensions: - admonition From b4bf87c96732cdd870cba6a5c36c532afc8d7e88 Mon Sep 17 00:00:00 2001 From: BobillierCaddev Date: Tue, 28 Oct 2025 09:06:44 +0100 Subject: [PATCH 27/52] Updated version to v32.300.0 (#285) Updated version to v32.300.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 758afb6..b602db4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.299.0" +version = "32.300.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' From b9d12bb2be808562bce0bdafae167e6469be1e8a Mon Sep 17 00:00:00 2001 From: BobillierCaddev Date: Thu, 13 Nov 2025 14:40:28 +0100 Subject: [PATCH 28/52] [API-482] Improved dimension controller and added a code snippet (#288) --- pyproject.toml | 2 +- src/dimension_controller/__init__.pyi | 44 +++++++++++++++++++++------ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b602db4..ae78ed4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.300.0" +version = "32.301.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' diff --git a/src/dimension_controller/__init__.pyi b/src/dimension_controller/__init__.pyi index 03e7bf1..f802513 100644 --- a/src/dimension_controller/__init__.pyi +++ b/src/dimension_controller/__init__.pyi @@ -4,13 +4,37 @@ from cadwork.dimension_base_format import dimension_base_format from cadwork.api_types import * def create_dimension(xl: point_3d, plane_normal: point_3d, distance: point_3d, dimension_points: List[point_3d]) -> ElementId: - """Creates a dimension element. - - Parameters: - xl: The x direction of the dimension. - plane_normal: The normal vector of the dimension plane. - distance: The distance vector from the anchor point to the dimension reference point. - dimension_points: A list of dimension points. + """Creates a dimension element to measure distances on 3D parts. + The dimension is drawn on a plane + defined by its normal and offset distance. Points added to the dimension are projected + onto this plane, and dimension segments are automatically created between consecutive points. + + Parameters: + xl: The direction vector defining the dimension line axis (the direction of the measurement arrow). Can be aligned with X, Y, Z axes or any 3D direction. + plane_normal: The normal vector defining the orientation of the dimension plane. + distance: The offset vector from the dimensioned geometry to where the dimension line is drawn. Can offset in any direction. + dimension_points: A list of dimension points to measure. At least 2 points are needed for a valid dimension measurement, but the points can be added later using addSegment(). Points are projected onto the dimension plane. + + Examples: + >>> import cadwork + >>> import dimension_controller as dc + + >>> # Create a list of dimension points + >>> list_points = [] + >>> list_points.append(cadwork.point_3d(0., 0., 0.)) + >>> list_points.append(cadwork.point_3d(1000., 0., 0.)) + >>> list_points.append(cadwork.point_3d(2000., 500., 0.)) + >>> list_points.append(cadwork.point_3d(3000., 200., 0.)) + >>> list_points.append(cadwork.point_3d(4000., 360., 0.)) + >>> list_points.append(cadwork.point_3d(6000., 451., 0.)) + + >>> # Create the dimension element + >>> id_dimension = dc.create_dimension( + >>> cadwork.point_3d(1., 0., 0.), # xl - dimension arrow direction + >>> cadwork.point_3d(0., 1., 0.), # plane_normal + >>> cadwork.point_3d(0., 0., 500.), # distance - offset from geometry + >>> list_points # dimension_points + >>> ) Returns: The element id of the created dimension element. @@ -26,11 +50,13 @@ def set_orientation(element_id_list: List[ElementId], view_dir: point_3d, view_d """ def add_segment(element_id: ElementId, segment: point_3d) -> None: - """Adds a segment to a dimension element. + """Adds a new point to a dimension's point list. A dimension segment is automatically + created between this point and the previous point. This method can be called multiple times + to progressively add more measurement points to the dimension. Parameters: element_id: The element id. - segment: The segment to add. + segment: The point to add to the dimension (despite the parameter name, this is a point, not a segment). """ def set_precision(element_id_list: List[ElementId], precision: UnsignedInt) -> None: From 48c765f1da12f812f8495a743367cf6f540c110b Mon Sep 17 00:00:00 2001 From: BobillierCaddev Date: Wed, 7 Jan 2026 15:30:01 +0100 Subject: [PATCH 29/52] [API-482] Updated version and documentation for multi layer cover controller (#294) * [API-482] Updated version and documentation for multi layer cover controller * [API-482] [API-560] Updated api version and removed irrelevant C++ oriented method --- docs/documentation/enums.md | 16 +- pyproject.toml | 2 +- src/cadwork/multi_layer_cover_type.pyi | 29 +++ src/cadwork/multi_layer_subtype.pyi | 33 +++ src/multi_layer_cover_controller/__init__.pyi | 226 ++++++++++++++++++ 5 files changed, 304 insertions(+), 2 deletions(-) create mode 100644 src/cadwork/multi_layer_cover_type.pyi create mode 100644 src/cadwork/multi_layer_subtype.pyi diff --git a/docs/documentation/enums.md b/docs/documentation/enums.md index 614bb71..8b127f0 100644 --- a/docs/documentation/enums.md +++ b/docs/documentation/enums.md @@ -60,13 +60,27 @@ show_root_heading: false show_source: true -## Multi Layer Cover Type +## Multi Layer Type ::: cadwork.multi_layer_type rendering: show_root_heading: false show_source: true +## Multi Layer Cover Subtype + +::: cadwork.multi_layer_subtype + rendering: + show_root_heading: false + show_source: true + +## Multi Layer Cover Type + +::: cadwork.multi_layer_cover_type + rendering: + show_root_heading: false + show_source: true + ## BIMteam upload ::: cadwork.bim_team_upload_result_code diff --git a/pyproject.toml b/pyproject.toml index ae78ed4..d16d272 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.301.0" +version = "32.401.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' diff --git a/src/cadwork/multi_layer_cover_type.pyi b/src/cadwork/multi_layer_cover_type.pyi new file mode 100644 index 0000000..c632e97 --- /dev/null +++ b/src/cadwork/multi_layer_cover_type.pyi @@ -0,0 +1,29 @@ +from enum import IntEnum, unique + + +@unique +class multi_layer_cover_type(IntEnum): + """multi layer cover type + + Examples: + >>> cadwork.multi_layer_cover_type.framedWall + framedWall + """ + framedWall = 0 + """""" + solidWall = 1 + """""" + logWall = 2 + """""" + framedRoof = 3 + """""" + solidRoof = 4 + """""" + framedFloor = 5 + """""" + solidFloor = 6 + """""" + + def __int__(self) -> int: + return self.value + diff --git a/src/cadwork/multi_layer_subtype.pyi b/src/cadwork/multi_layer_subtype.pyi new file mode 100644 index 0000000..05ad725 --- /dev/null +++ b/src/cadwork/multi_layer_subtype.pyi @@ -0,0 +1,33 @@ +from enum import IntEnum, unique + + +@unique +class multi_layer_subtype(IntEnum): + """multi layer subtype + + Examples: + >>> cadwork.multi_layer_subtype.undefined + undefined + """ + undefined = 0 + """""" + loadBearingFrameStructure = 1 + """""" + solidStructure = 2 + """""" + straightEdge = 3 + """""" + biasEdge = 4 + """""" + vertical = 5 + """""" + horizontal = 6 + """""" + air = 7 + """""" + nonLoadBearingFrameStructure = 8 + """""" + + def __int__(self) -> int: + return self.value + diff --git a/src/multi_layer_cover_controller/__init__.pyi b/src/multi_layer_cover_controller/__init__.pyi index ee46e45..5f84e71 100644 --- a/src/multi_layer_cover_controller/__init__.pyi +++ b/src/multi_layer_cover_controller/__init__.pyi @@ -1,4 +1,5 @@ from typing import List +from cadwork import multi_layer_cover_type from cadwork.api_types import * from cadwork.multi_layer_type import multi_layer_type @@ -368,3 +369,228 @@ def get_cover_color(set_id: MultiLayerSetId) -> ColorId: Returns: The cover color. """ + +def get_multi_layer_framed_floors() -> List[MultiLayerSetId]: + """Gets all framed multi layer floor ids. + + Examples: + >>> floor_ids = mlc.get_multi_layer_framed_floors() + >>> print(f"Found {len(floor_ids)} multi-layer floor definitions") + >>> for floor_id in floor_ids: + ... name = mlc.get_multi_layer_set_name(floor_id) + ... print(f"Floor ID: {floor_id}, Name: {name}") + + Returns: + The multi layer floor ids. + """ + +def create_multi_layer_framed_floor(set_name: str) -> MultiLayerSetId: + """Creates a new multi layer floor with given name and default values. + + Parameters: + set_name: The multi layer set name. + + Examples: + >>> set_id = mlc.create_multi_layer_framed_floor("Standard Floor") + >>> print(f"Created new multi-layer floor with ID: {set_id}") + + Returns: + The multi layer set id. + """ + +def get_multi_layer_framed_roofs() -> List[MultiLayerSetId]: + """Gets all multi layer roof ids. + + Examples: + >>> roof_ids = mlc.get_multi_layer_framed_roofs() + >>> print(f"Found {len(roof_ids)} multi-layer roof definitions") + >>> for roof_id in roof_ids: + ... name = mlc.get_multi_layer_set_name(roof_id) + ... print(f"Roof ID: {roof_id}, Name: {name}") + + Returns: + The multi layer roof ids. + """ + +def get_multi_layer_solid_floors() -> List[MultiLayerSetId]: + """Gets all solid multi layer floor ids. + + Examples: + >>> floor_ids = mlc.get_multi_layer_solid_floors() + >>> print(f"Found {len(floor_ids)} multi-layer floor definitions") + >>> for floor_id in floor_ids: + ... name = mlc.get_multi_layer_set_name(floor_id) + ... print(f"Floor ID: {floor_id}, Name: {name}") + + Returns: + The multi layer floor ids. + """ + +def create_multi_layer_solid_floor(set_name: str) -> MultiLayerSetId: + """Creates a new multi layer solid floor with given name and default values. + + Parameters: + set_name: The multi layer set name. + + Examples: + >>> set_id = mlc.create_multi_layer_solid_floor("Standard Solid Floor") + >>> print(f"Created new multi-layer solid floor with ID: {set_id}") + + Returns: + The multi layer set id. + """ + +def create_multi_layer_framed_roof(set_name: str) -> MultiLayerSetId: + """Creates a new multi layer roof with given name and default values. + + Parameters: + set_name: The multi layer set name. + + Examples: + >>> set_id = mlc.create_multi_layer_framed_roof("Pitched Roof") + >>> print(f"Created new multi-layer roof with ID: {set_id}") + + Returns: + The multi layer set id. + """ + +def create_multi_layer_framed_wall(set_name: str) -> MultiLayerSetId: + """Creates a new multi layer wall with given name and default values. + + Parameters: + set_name: The multi layer set name. + + Examples: + >>> set_id = mlc.create_multi_layer_framed_wall("Standard Wall") + >>> print(f"Created new multi-layer wall with ID: {set_id}") + + Returns: + The multi layer set id. + """ + +def get_multi_layer_sets() -> List[MultiLayerSetId]: + """Gets all multi layer set ids of all types. + + Examples: + >>> all_ids = mlc.get_multi_layer_sets() + >>> print(f"Found {len(all_ids)} multi-layer definitions in total") + >>> for set_id in all_ids: + ... name = mlc.get_multi_layer_set_name(set_id) + ... print(f"Set ID: {set_id}, Name: {name}") + + Returns: + The multi layer set ids. + """ + +def create_multi_layer_by_cover_type(set_name: str, cover_type: multi_layer_cover_type) -> MultiLayerSetId: + """Creates a new multi layer set of specified type with given name and default values. + + Parameters: + set_name: The multi layer set name. + cover_type: The cover type. + + Examples: + >>> set_id = mlc.create_multi_layer_by_cover_type("Custom Solid Wall", cadwork.multi_layer_cover_type.solidWall) + >>> print(f"Created new multi-layer set with ID: {set_id}") + + Returns: + The multi layer set id. + """ + +def get_multi_layer_sets_for_cover_type(cover_type: multi_layer_cover_type) -> List[MultiLayerSetId]: + """Gets all multi layer set ids of specified cover type. + + Parameters: + cover_type: The cover type. + + Examples: + >>> set_ids = mlc.get_multi_layer_sets_for_cover_type(cadwork.multi_layer_cover_type.solidWall) + + Returns: + The multi layer set ids. + """ + + +def get_multi_layer_log_walls() -> List[MultiLayerSetId]: + """Gets all multi layer log wall ids. + + Examples: + >>> log_wall_ids = mlc.get_multi_layer_log_walls() + >>> print(f"Found {len(log_wall_ids)} multi-layer log wall definitions") + >>> for log_wall_id in log_wall_ids: + ... name = mlc.get_multi_layer_set_name(log_wall_id) + ... print(f"Log Wall ID: {log_wall_id}, Name: {name}") + + Returns: + The multi layer log wall ids. + """ + +def create_multi_layer_log_wall(set_name: str) -> MultiLayerSetId: + """Creates a new multi layer log wall with given name and default values. + + Parameters: + set_name: The multi layer set name. + + Examples: + >>> set_id = mlc.create_multi_layer_log_wall("Standard Log Wall") + >>> print(f"Created new multi-layer log wall with ID: {set_id}") + + Returns: + The multi layer set id. + """ + +def get_multi_layer_solid_roofs() -> List[MultiLayerSetId]: + """Gets all multi layer solid roof ids. + + Examples: + >>> solid_roof_ids = mlc.get_multi_layer_solid_roofs() + >>> print(f"Found {len(solid_roof_ids)} multi-layer solid roof definitions") + >>> for solid_roof_id in solid_roof_ids: + ... name = mlc.get_multi_layer_set_name(solid_roof_id) + ... print(f"Solid Roof ID: {solid_roof_id}, Name: {name}") + + Returns: + The multi layer solid roof ids. + """ + +def create_multi_layer_solid_roof(set_name: str) -> MultiLayerSetId: + """Creates a new multi layer solid roof with given name and default values. + + Parameters: + set_name: The multi layer set name. + + Examples: + >>> set_id = mlc.create_multi_layer_solid_roof("Standard Solid Roof") + >>> print(f"Created new multi-layer solid roof with ID: {set_id}") + + Returns: + The multi layer set id. + """ + +def get_multi_layer_solid_walls() -> List[MultiLayerSetId]: + """Gets all multi layer solid wall ids. + + Examples: + >>> solid_wall_ids = mlc.get_multi_layer_solid_walls() + >>> print(f"Found {len(solid_wall_ids)} multi-layer solid wall definitions") + >>> for solid_wall_id in solid_wall_ids: + ... name = mlc.get_multi_layer_set_name(solid_wall_id) + ... print(f"Solid Wall ID: {solid_wall_id}, Name: {name}") + + Returns: + The multi layer solid wall ids. + """ + +def create_multi_layer_solid_wall(set_name: str) -> MultiLayerSetId: + """Creates a new multi layer solid wall with given name and default values. + + Parameters: + set_name: The multi layer set name. + + Examples: + >>> set_id = mlc.create_multi_layer_solid_wall("Standard Solid Wall") + >>> print(f"Created new multi-layer solid wall with ID: {set_id}") + + Returns: + The multi layer set id. + """ \ No newline at end of file From 4414f13ba095ef8518db94fb1b413039cc590e13 Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Sun, 18 Jan 2026 22:55:13 +0100 Subject: [PATCH 30/52] [AICW-110] add mcp documentation for mkdocs --- docs/img/mcp/mcp.svg | 1 + docs/img/mcp/mcp_cgpt_app.png | Bin 0 -> 30430 bytes docs/mcp.md | 76 ++++++++++++++++++++++++++++++++++ mkdocs.yml | 3 ++ 4 files changed, 80 insertions(+) create mode 100644 docs/img/mcp/mcp.svg create mode 100644 docs/img/mcp/mcp_cgpt_app.png create mode 100644 docs/mcp.md diff --git a/docs/img/mcp/mcp.svg b/docs/img/mcp/mcp.svg new file mode 100644 index 0000000..dea2577 --- /dev/null +++ b/docs/img/mcp/mcp.svg @@ -0,0 +1 @@ +ModelContextProtocol \ No newline at end of file diff --git a/docs/img/mcp/mcp_cgpt_app.png b/docs/img/mcp/mcp_cgpt_app.png new file mode 100644 index 0000000000000000000000000000000000000000..34997299164c9f3914026a89f9fd0611bf2f8261 GIT binary patch literal 30430 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 `Connectors` > `Add custom connectors` + + [Claude MCP Documentation](https://modelcontextprotocol.io/docs/develop/connect-remote-servers){target=_blank} + +??? note "Claude Code (CLI)" + Claude Code supports MCP servers natively. Add the server using: + + ```bash + claude mcp add cadwork-pyapi https://cadwork-mcp-pyapi.com/mcp + ``` + + [Claude Code MCP Guide](https://docs.anthropic.com/en/docs/claude-code/mcp){target=_blank} + +??? note "ChatGPT" + ChatGPT does support MCP servers connector (they are called App) but only on *developer mode*. You need to activate it first and then: + + `Settings` > `Apps` > `Create app` (Developer mode: on) > `Create app` + +
+ ![Screenshot](img/mcp/mcp_cgpt_app.png){width=300} +
+ + [OpenAI Plugins Documentation](https://help.openai.com/en/articles/11487775-apps-in-chatgpt#building-your-own-app){target=_blank} + +??? note "VS Code (GitHub Copilot)" + Add the following to your VS Code settings file (`.vscode/mcp.json` in your workspace or user settings): + + ```json + { + "servers": { + "cadwork-pyapi": { + "type": "http", + "url": "https://cadwork-mcp-pyapi.com/mcp" + } + } + } + ``` + + [VS Code MCP Documentation](https://code.visualstudio.com/docs/copilot/chat/mcp-servers){target=_blank} + +## Usage + +Once configured, prompt your request to your AI coding assistant and it will automatically query the Cadwork Python API documentation to help you write grounded scripts to our Cadwork Python API. diff --git a/mkdocs.yml b/mkdocs.yml index ae9fd93..8e7f4a0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -105,6 +105,8 @@ nav: - videos.md - Auto Attributes: - auto_attributes.md + - MCP: + - mcp.md - About: - About Guide: about.md - Release Notes: @@ -113,6 +115,7 @@ nav: markdown_extensions: - admonition + - pymdownx.details - attr_list - footnotes - md_in_html From 4d7898848c8b73eefc89d0f2720fa0e73f543325 Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Wed, 21 Jan 2026 09:04:47 +0100 Subject: [PATCH 31/52] [AICW-110] bumped version minor --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d16d272..9b3dda3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.401.0" +version = "32.402.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' From df3877dbab424298cb35ab8246dd2189c6b950d6 Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Wed, 21 Jan 2026 18:33:24 +0100 Subject: [PATCH 32/52] [AICW-110] new domain pointing to pyapi.mcp.cadwork.dev --- docs/mcp.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/mcp.md b/docs/mcp.md index 0d5fbc5..abcff23 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -6,7 +6,7 @@ hide: # ![mcp_icon](img/mcp/mcp.svg){: style="height: 32px; vertical-align: middle;" } MCP Cadwork Python API Server -**MCP URL:** `https://cadwork-mcp-pyapi.com/mcp` +**MCP URL:** `https://pyapi.mcp.cadwork.dev/mcp` ## What is MCP? @@ -39,7 +39,7 @@ To use the Cadwork Python API documentation as an MCP server, you need to config Claude Code supports MCP servers natively. Add the server using: ```bash - claude mcp add cadwork-pyapi https://cadwork-mcp-pyapi.com/mcp + claude mcp add cadwork-pyapi https://pyapi.mcp.cadwork.dev/mcp ``` [Claude Code MCP Guide](https://docs.anthropic.com/en/docs/claude-code/mcp){target=_blank} @@ -63,7 +63,7 @@ To use the Cadwork Python API documentation as an MCP server, you need to config "servers": { "cadwork-pyapi": { "type": "http", - "url": "https://cadwork-mcp-pyapi.com/mcp" + "url": "https://pyapi.mcp.cadwork.dev/mcp" } } } From bb20cd82173f4a84e5996170ed8624cc70272cd8 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Wed, 28 Jan 2026 17:03:40 +0100 Subject: [PATCH 33/52] Add `active_point_result` class and getter function Signed-off-by: Michael Brunner --- docs/documentation/active_point_result.md | 6 ++++++ mkdocs.yml | 1 + pyproject.toml | 2 +- src/cadwork/active_point_result.py | 12 ++++++++++++ src/element_controller/__init__.pyi | 22 ++++++++++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 docs/documentation/active_point_result.md create mode 100644 src/cadwork/active_point_result.py diff --git a/docs/documentation/active_point_result.md b/docs/documentation/active_point_result.md new file mode 100644 index 0000000..ae56849 --- /dev/null +++ b/docs/documentation/active_point_result.md @@ -0,0 +1,6 @@ +# active_point_result + +::: cadwork.active_point_result +rendering: +show_root_heading: false +show_source: true diff --git a/mkdocs.yml b/mkdocs.yml index 8e7f4a0..79ca2f3 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -64,6 +64,7 @@ nav: - Element Map Query: documentation/element_map_query.md - Hit Result: documentation/hit_result.md - Coordinate System Data: documentation/coordinate_system_data.md + - Active Point Result: documentation/active_point_result.md - Connector Axis Controller: documentation/connector_axis_controller.md - Dimension Controller: documentation/dimension_controller.md - Element Controller: documentation/element_controller.md diff --git a/pyproject.toml b/pyproject.toml index 9b3dda3..1ce9c7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.402.0" +version = "32.443.0" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' diff --git a/src/cadwork/active_point_result.py b/src/cadwork/active_point_result.py new file mode 100644 index 0000000..d4ec1f5 --- /dev/null +++ b/src/cadwork/active_point_result.py @@ -0,0 +1,12 @@ +from dataclasses import dataclass +from typing import Optional +from cadwork import point_3d + + +@dataclass(frozen=True) +class active_point_result: + has_point: bool + point: Optional["point_3d"] = None + + def __bool__(self) -> bool: + return self.has_point diff --git a/src/element_controller/__init__.pyi b/src/element_controller/__init__.pyi index fd99946..ba88b37 100644 --- a/src/element_controller/__init__.pyi +++ b/src/element_controller/__init__.pyi @@ -9,6 +9,7 @@ from cadwork.coordinate_system_data import coordinate_system_data from cadwork.element_map_query import element_map_query from cadwork.element_filter import element_filter from cadwork.hit_result import hit_result +from cadwork.active_point_result import active_point_result from cadwork.vertex_list import vertex_list from cadwork.shoulder_options import shoulder_options from cadwork.heel_shoulder_options import heel_shoulder_options @@ -2278,3 +2279,24 @@ def cast_ray_and_get_element_intersections(element_id_list: List[ElementId], ray Returns: Contains list of elements that were hit by the ray and list of vertices that are queried via ElementID. """ + + +def get_element_active_point(element_id: ElementId) -> active_point_result: + """Gets the active point associated with an element. + + Parameters: + element_id: The element id. + + Examples: + >>> import cadwork + >>> import element_controller as ec + >>> [element_id] = ec.get_active_identifiable_element_ids() + >>> result = ec.get_element_active_point(element_id) + >>> if result: + ... ec.create_node(result.point) + ... else: + ... print("No active point set for element.") + + Returns: + True/False plus point data when available. + """ From d37fcb0cb37ac014356a4095c9634ca1d85e63e5 Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Fri, 30 Jan 2026 15:24:03 +0100 Subject: [PATCH 34/52] [UNSIGNED] fix for the correct claude code installation --- docs/mcp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mcp.md b/docs/mcp.md index abcff23..837bbb7 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -39,7 +39,7 @@ To use the Cadwork Python API documentation as an MCP server, you need to config Claude Code supports MCP servers natively. Add the server using: ```bash - claude mcp add cadwork-pyapi https://pyapi.mcp.cadwork.dev/mcp + claude mcp add --transport http cadwork-pyapi https://pyapi.mcp.cadwork.dev/mcp ``` [Claude Code MCP Guide](https://docs.anthropic.com/en/docs/claude-code/mcp){target=_blank} From a8338b3a1eee077790c34a5bdc8bf5814902f50a Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Sat, 31 Jan 2026 17:32:49 +0100 Subject: [PATCH 35/52] Add Gemini CLI integration guide for MCP servers in documentation --- docs/img/console.gif | Bin 425529 -> 131 bytes docs/img/mcp/gemini-mcp.gif | 3 +++ docs/mcp.md | 29 +++++++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 docs/img/mcp/gemini-mcp.gif diff --git a/docs/img/console.gif b/docs/img/console.gif index 716c43e94e990792c5a478fc04ec5fc8b0dd9ef2..2ff83df9d3022aedc795af245682b06a56a2cf3b 100644 GIT binary patch literal 131 zcmWN?K@!3s3;@78uiyg~0;GlhhJ;j@QRxWw;OliSd&zsW{?c{MbL__4+q^xFvHY(e zTDU*WIEBpxs<)y?%?{VyM?nglkpU7}*dkGhX|vuTTkAl;3T|Fj%ydX7nF}Uhh{>;1 NvKs9xIygj^)DH(WC%FIs literal 425529 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
+ ![Gemini MCP Demo](img/mcp/gemini-mcp.gif){width=600} +
-Once configured, prompt your request to your AI coding assistant and it will automatically query the Cadwork Python API documentation to help you write grounded scripts to our Cadwork Python API. + [Gemini MCP Guide](https://geminicli.com/docs/tools/mcp-server){target=_blank} From 3b5448d0552b3ce6cf311c7b103c8ab15e567bf1 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Sat, 31 Jan 2026 17:33:16 +0100 Subject: [PATCH 36/52] Configure Git LFS for .gif files in .gitattributes --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d41a940 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.gif filter=lfs diff=lfs merge=lfs -text From bc1127fde627fc98da88bf837d14cc7e278824e9 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Sat, 31 Jan 2026 17:37:34 +0100 Subject: [PATCH 37/52] Revert Usage section --- docs/mcp.md | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/docs/mcp.md b/docs/mcp.md index bf72186..cf6b0b3 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -10,33 +10,41 @@ hide: ## What is MCP? -The **Model Context Protocol (MCP)** is an open standard that enables AI assistants to securely connect to external context. Think of it as a bridge that allows AI models to access real-time, specialized information beyond their training data. +The **Model Context Protocol (MCP)** is an open standard that enables AI assistants to securely connect to external +context. Think of it as a bridge that allows AI models to access real-time, specialized information beyond their +training data. -When you connect an AI assistant to an MCP server, it gains the ability to query that server for relevant context, making responses more accurate and up-to-date. +When you connect an AI assistant to an MCP server, it gains the ability to query that server for relevant context, +making responses more accurate and up-to-date. ## How MCP helps you learn and use the Cadwork Python API -The Cadwork Python API documentation is available as an MCP server, which transforms how you can learn and work with the API: - -- **Contextual Answers**: Ask questions in natural language and get responses that reference the actual API documentation, including function signatures, parameters, and code examples. -- **Code Generation**: Request script snippets for specific tasks. The AI can generate code using the correct Cadwork API functions because it has direct access to the documentation. -- **Discovery**: Explore available modules and functions by simply asking "What functions are available for geometry operations?" or "How do I work with elements?" -- **Troubleshooting**: Describe an error or unexpected behavior, and get help that's grounded in the actual API specifications. +The Cadwork Python API documentation is available as an MCP server, which transforms how you can learn and work with the +API: +- **Contextual Answers**: Ask questions in natural language and get responses that reference the actual API + documentation, including function signatures, parameters, and code examples. +- **Code Generation**: Request script snippets for specific tasks. The AI can generate code using the correct Cadwork + API functions because it has direct access to the documentation. +- **Discovery**: Explore available modules and functions by simply asking "What functions are available for geometry + operations?" or "How do I work with elements?" +- **Troubleshooting**: Describe an error or unexpected behavior, and get help that's grounded in the actual API + specifications. ## Setup instructions -To use the Cadwork Python API documentation as an MCP server, you need to configure your AI assistant to connect to it. Here are the most common ai code assistants and how to configure them: +To use the Cadwork Python API documentation as an MCP server, you need to configure your AI assistant to connect to it. +Here are the most common ai code assistants and how to configure them: ??? note "Claude Desktop" - Add the following to your Claude Desktop configuration file via the UI: +Add the following to your Claude Desktop configuration file via the UI: `Settings` > `Connectors` > `Add custom connectors` [Claude MCP Documentation](https://modelcontextprotocol.io/docs/develop/connect-remote-servers){target=_blank} ??? note "Claude Code (CLI)" - Claude Code supports MCP servers natively. Add the server using: +Claude Code supports MCP servers natively. Add the server using: ```bash claude mcp add --transport http cadwork-pyapi https://pyapi.mcp.cadwork.dev/mcp @@ -45,7 +53,8 @@ To use the Cadwork Python API documentation as an MCP server, you need to config [Claude Code MCP Guide](https://docs.anthropic.com/en/docs/claude-code/mcp){target=_blank} ??? note "ChatGPT" - ChatGPT does support MCP servers connector (they are called App) but only on *developer mode*. You need to activate it first and then: +ChatGPT does support MCP servers connector (they are called App) but only on *developer mode*. You need to activate it +first and then: `Settings` > `Apps` > `Create app` (Developer mode: on) > `Create app` @@ -56,7 +65,7 @@ To use the Cadwork Python API documentation as an MCP server, you need to config [OpenAI Plugins Documentation](https://help.openai.com/en/articles/11487775-apps-in-chatgpt#building-your-own-app){target=_blank} ??? note "VS Code (GitHub Copilot)" - Add the following to your VS Code settings file (`.vscode/mcp.json` in your workspace or user settings): +Add the following to your VS Code settings file (`.vscode/mcp.json` in your workspace or user settings): ```json { @@ -72,8 +81,8 @@ To use the Cadwork Python API documentation as an MCP server, you need to config [VS Code MCP Documentation](https://code.visualstudio.com/docs/copilot/chat/mcp-servers){target=_blank} ??? note "Gemini CLI" - Gemini CLI supports MCP servers natively through its command-line interface. - +Gemini CLI supports MCP servers natively through its command-line interface. + **Prerequisites**: Install the Gemini CLI first: ```bash @@ -99,3 +108,8 @@ To use the Cadwork Python API documentation as an MCP server, you need to config [Gemini MCP Guide](https://geminicli.com/docs/tools/mcp-server){target=_blank} + +## Usage + +Once configured, prompt your request to your AI coding assistant and it will automatically query the Cadwork Python API +documentation to help you write grounded scripts to our Cadwork Python API. \ No newline at end of file From 479a3446d31c9e3964fd5cfabdf0fb895171fb97 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Sun, 1 Feb 2026 11:17:22 +0100 Subject: [PATCH 38/52] Enhance MCP documentation with detailed setup instructions for Gemini CLI and add a demo section --- docs/mcp.md | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/docs/mcp.md b/docs/mcp.md index cf6b0b3..f68581a 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -37,14 +37,16 @@ To use the Cadwork Python API documentation as an MCP server, you need to config Here are the most common ai code assistants and how to configure them: ??? note "Claude Desktop" -Add the following to your Claude Desktop configuration file via the UI: + + Add the following to your Claude Desktop configuration file via the UI: `Settings` > `Connectors` > `Add custom connectors` [Claude MCP Documentation](https://modelcontextprotocol.io/docs/develop/connect-remote-servers){target=_blank} ??? note "Claude Code (CLI)" -Claude Code supports MCP servers natively. Add the server using: + + Claude Code supports MCP servers natively. Add the server using: ```bash claude mcp add --transport http cadwork-pyapi https://pyapi.mcp.cadwork.dev/mcp @@ -53,8 +55,9 @@ Claude Code supports MCP servers natively. Add the server using: [Claude Code MCP Guide](https://docs.anthropic.com/en/docs/claude-code/mcp){target=_blank} ??? note "ChatGPT" -ChatGPT does support MCP servers connector (they are called App) but only on *developer mode*. You need to activate it -first and then: + + ChatGPT does support MCP servers connector (they are called App) but only on *developer mode*. You need to activate it + first and then: `Settings` > `Apps` > `Create app` (Developer mode: on) > `Create app` @@ -65,7 +68,8 @@ first and then: [OpenAI Plugins Documentation](https://help.openai.com/en/articles/11487775-apps-in-chatgpt#building-your-own-app){target=_blank} ??? note "VS Code (GitHub Copilot)" -Add the following to your VS Code settings file (`.vscode/mcp.json` in your workspace or user settings): + + Add the following to your VS Code settings file (`.vscode/mcp.json` in your workspace or user settings): ```json { @@ -81,14 +85,15 @@ Add the following to your VS Code settings file (`.vscode/mcp.json` in your work [VS Code MCP Documentation](https://code.visualstudio.com/docs/copilot/chat/mcp-servers){target=_blank} ??? note "Gemini CLI" -Gemini CLI supports MCP servers natively through its command-line interface. + + Gemini CLI supports MCP servers natively through its command-line interface. **Prerequisites**: Install the Gemini CLI first: - + ```bash npm install -g @google/gemini-cli@latest ``` - + **Add the server**: ```bash @@ -103,12 +108,16 @@ Gemini CLI supports MCP servers natively through its command-line interface. Once added, the Cadwork Python API documentation will be automatically available when you interact with Gemini CLI. -
- ![Gemini MCP Demo](img/mcp/gemini-mcp.gif){width=600} -
- [Gemini MCP Guide](https://geminicli.com/docs/tools/mcp-server){target=_blank} +## Demo + +See how easy it is to use the Cadwork Python API with an MCP-enabled AI assistant: + +
+![MCP Demo with Gemini CLI](img/mcp/gemini-mcp.gif){width=600} +
+ ## Usage Once configured, prompt your request to your AI coding assistant and it will automatically query the Cadwork Python API From ab39daa111b683170baa48f9c2459be6c9b18776 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Mon, 2 Feb 2026 07:40:52 +0100 Subject: [PATCH 39/52] Update image display format in MCP documentation Signed-off-by: Michael Brunner --- docs/mcp.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/mcp.md b/docs/mcp.md index f68581a..6077ec4 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -114,9 +114,7 @@ Here are the most common ai code assistants and how to configure them: See how easy it is to use the Cadwork Python API with an MCP-enabled AI assistant: -
-![MCP Demo with Gemini CLI](img/mcp/gemini-mcp.gif){width=600} -
+MCP Demo with Gemini CLI ## Usage From e4a947b1d05a5085354429b489846e9e73dc1b34 Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Mon, 2 Feb 2026 13:59:57 +0100 Subject: [PATCH 40/52] [UNASSIGNED] more importance to demo, moved up and simplified intro --- docs/mcp.md | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/docs/mcp.md b/docs/mcp.md index 6077ec4..98f222e 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -17,10 +17,13 @@ training data. When you connect an AI assistant to an MCP server, it gains the ability to query that server for relevant context, making responses more accurate and up-to-date. -## How MCP helps you learn and use the Cadwork Python API +## Demo + +See how easy it is to use the Cadwork Python API with an MCP-enabled AI assistant: + +MCP Demo with Gemini CLI -The Cadwork Python API documentation is available as an MCP server, which transforms how you can learn and work with the -API: +You can use the Cadwork Python MCP for: - **Contextual Answers**: Ask questions in natural language and get responses that reference the actual API documentation, including function signatures, parameters, and code examples. @@ -36,6 +39,8 @@ API: To use the Cadwork Python API documentation as an MCP server, you need to configure your AI assistant to connect to it. Here are the most common ai code assistants and how to configure them: + + ??? note "Claude Desktop" Add the following to your Claude Desktop configuration file via the UI: @@ -108,15 +113,4 @@ Here are the most common ai code assistants and how to configure them: Once added, the Cadwork Python API documentation will be automatically available when you interact with Gemini CLI. - [Gemini MCP Guide](https://geminicli.com/docs/tools/mcp-server){target=_blank} - -## Demo - -See how easy it is to use the Cadwork Python API with an MCP-enabled AI assistant: - -MCP Demo with Gemini CLI - -## Usage - -Once configured, prompt your request to your AI coding assistant and it will automatically query the Cadwork Python API -documentation to help you write grounded scripts to our Cadwork Python API. \ No newline at end of file + [Gemini MCP Guide](https://geminicli.com/docs/tools/mcp-server){target=_blank} \ No newline at end of file From d36eeca928f677a9b556827c17334068ea168914 Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Mon, 2 Feb 2026 14:59:54 +0100 Subject: [PATCH 41/52] [UNASSIGNED] hjacked pr for adding scheme of functioning --- docs/img/mcp/mcp_python_api_v1.drawio.png | Bin 0 -> 175425 bytes docs/mcp.md | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 docs/img/mcp/mcp_python_api_v1.drawio.png diff --git a/docs/img/mcp/mcp_python_api_v1.drawio.png b/docs/img/mcp/mcp_python_api_v1.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..d5e1e38eb394df773c0f7ae94b44528c305f8b18 GIT binary patch literal 175425 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 literal 0 HcmV?d00001 diff --git a/docs/mcp.md b/docs/mcp.md index 98f222e..0daca08 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -17,11 +17,13 @@ training data. When you connect an AI assistant to an MCP server, it gains the ability to query that server for relevant context, making responses more accurate and up-to-date. +![Screenshot](img/mcp/mcp_python_api_v1.drawio.png){width="1200" style="display: block; margin: 0 auto;"} + ## Demo See how easy it is to use the Cadwork Python API with an MCP-enabled AI assistant: -MCP Demo with Gemini CLI +![MCP Demo with Gemini CLI](img/mcp/gemini-mcp.gif){width=900} You can use the Cadwork Python MCP for: From 3df90b778024063237b68f0157011761e833c265 Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Mon, 2 Feb 2026 16:41:59 +0100 Subject: [PATCH 42/52] [UNASSIGNED] gif not rendered in online deployed fixed --- docs/mcp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mcp.md b/docs/mcp.md index 0daca08..466d987 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -23,7 +23,7 @@ making responses more accurate and up-to-date. See how easy it is to use the Cadwork Python API with an MCP-enabled AI assistant: -![MCP Demo with Gemini CLI](img/mcp/gemini-mcp.gif){width=900} +MCP Demo with Gemini CLI You can use the Cadwork Python MCP for: From 322f394abe271ef3dd48dc5b5061191404399d4a Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Mon, 2 Feb 2026 16:57:49 +0100 Subject: [PATCH 43/52] [UNASSIGNED] tried with absolute path to fix gif render --- docs/mcp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mcp.md b/docs/mcp.md index 466d987..ab175ba 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -23,7 +23,7 @@ making responses more accurate and up-to-date. See how easy it is to use the Cadwork Python API with an MCP-enabled AI assistant: -MCP Demo with Gemini CLI +MCP Demo with Gemini CLI You can use the Cadwork Python MCP for: From 1f91bc48de5afa9e6f926c106ab2692a0e930e96 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Fri, 20 Feb 2026 15:52:00 +0100 Subject: [PATCH 44/52] Update type hints in `polygon_list` class methods Signed-off-by: Michael Brunner --- src/cadwork/polygon_list.pyi | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/cadwork/polygon_list.pyi b/src/cadwork/polygon_list.pyi index 8055c95..6b9cf32 100644 --- a/src/cadwork/polygon_list.pyi +++ b/src/cadwork/polygon_list.pyi @@ -1,21 +1,20 @@ -from cadwork import point_3d +from cadwork import vertex_list + class polygon_list: - + def count(self) -> int: """count - Returns: - int + Returns: int """ - def at(self, index: int) -> point_3d: + def at(self, index: int) -> vertex_list: """at Parameters: index: index Returns: - point_3d + vertex_list: vertex_list """ - From 7ec5e7d3b46461c48a5408be9c6a3dc9086af391 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Fri, 20 Feb 2026 15:52:43 +0100 Subject: [PATCH 45/52] Update version to 32.443.1 Signed-off-by: Michael Brunner --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1ce9c7c..1912917 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.443.0" +version = "32.443.1" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' From e6008fdce82bcba9300c2d680fdc71290d07e835 Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Sun, 22 Feb 2026 20:56:29 +0100 Subject: [PATCH 46/52] [UNASSIGNED] extra verbose for the docstring --- src/cadwork/polygon_list.pyi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cadwork/polygon_list.pyi b/src/cadwork/polygon_list.pyi index 6b9cf32..bdf1f38 100644 --- a/src/cadwork/polygon_list.pyi +++ b/src/cadwork/polygon_list.pyi @@ -4,17 +4,17 @@ from cadwork import vertex_list class polygon_list: def count(self) -> int: - """count + """Returns the number of polygons in the list. Returns: int """ def at(self, index: int) -> vertex_list: - """at + """Returns the polygon vertices at the given index. Parameters: - index: index + index: The zero-based polygon index. Returns: - vertex_list: vertex_list + vertex_list: The ordered vertices defining the polygon. """ From 9a844c75675100a549afff7d9d90ca6730ee15e7 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Thu, 26 Feb 2026 10:46:36 +0100 Subject: [PATCH 47/52] Add display_attribute class and WebGL hierarchy function Signed-off-by: Michael Brunner --- docs/documentation/display_attribute.md | 6 ++ mkdocs.yml | 1 + pyproject.toml | 2 +- src/cadwork/__init__.pyi | 2 + src/cadwork/display_attribute.pyi | 130 ++++++++++++++++++++++++ src/file_controller/__init__.pyi | 10 ++ 6 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 docs/documentation/display_attribute.md create mode 100644 src/cadwork/display_attribute.pyi diff --git a/docs/documentation/display_attribute.md b/docs/documentation/display_attribute.md new file mode 100644 index 0000000..f884963 --- /dev/null +++ b/docs/documentation/display_attribute.md @@ -0,0 +1,6 @@ +# display_attribute + +::: cadwork.display_attribute +rendering: +show_root_heading: false +show_source: true diff --git a/mkdocs.yml b/mkdocs.yml index 79ca2f3..ca6d2e8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -65,6 +65,7 @@ nav: - Hit Result: documentation/hit_result.md - Coordinate System Data: documentation/coordinate_system_data.md - Active Point Result: documentation/active_point_result.md + - Display Attribute: documentation/display_attribute.md - Connector Axis Controller: documentation/connector_axis_controller.md - Dimension Controller: documentation/dimension_controller.md - Element Controller: documentation/element_controller.md diff --git a/pyproject.toml b/pyproject.toml index 1912917..31e5417 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.443.1" +version = "32.443.2" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' diff --git a/src/cadwork/__init__.pyi b/src/cadwork/__init__.pyi index 42ae349..aef0f2d 100644 --- a/src/cadwork/__init__.pyi +++ b/src/cadwork/__init__.pyi @@ -52,6 +52,7 @@ from .hit_result import hit_result from .dimension_base_format import dimension_base_format from .dxf_layer_format_type import dxf_layer_format_type from .dxf_export_version import dxf_export_version +from .display_attribute import display_attribute from typing import List # These assignments make each type accessible through both import styles: @@ -114,6 +115,7 @@ dimension_base_format = dimension_base_format dxf_layer_format_type = dxf_layer_format_type dxf_export_version = dxf_export_version rgb_color = rgb_color +display_attribute = display_attribute def get_auto_attribute_elements() -> List[int]: diff --git a/src/cadwork/display_attribute.pyi b/src/cadwork/display_attribute.pyi new file mode 100644 index 0000000..d0a870a --- /dev/null +++ b/src/cadwork/display_attribute.pyi @@ -0,0 +1,130 @@ +class display_attribute: + """ + A wrapper class for managing element display states. + These methods update the internal state of the attribute + object without requiring external parameters. + """ + + def __init__(self) -> None: + """Initializes a new display_attribute instance.""" + + def set_none(self) -> None: + """Resets or clears the current display attribute state. + + Returns: + None + """ + + def set_name(self) -> None: + """Triggers the assignment of the name attribute. + + Returns: + None + """ + + def set_group(self) -> None: + """Triggers the assignment of the group attribute. + + Returns: + None + """ + + def set_subgroup(self) -> None: + """Triggers the assignment of the subgroup attribute. + + Returns: + None + """ + + def set_comment(self) -> None: + """Triggers the assignment of the comment attribute. + + Returns: + None + """ + + def set_edv_code(self) -> None: + """Triggers the assignment of the EDV/ERP code. + + Returns: + None + """ + + def set_material(self) -> None: + """Triggers the assignment of the material attribute. + + Returns: + None + """ + + def set_material_group(self) -> None: + """Triggers the assignment of the material group attribute. + + Returns: + None + """ + + def set_user1(self) -> None: + """Triggers the assignment of custom user field 1.""" + + def set_user2(self) -> None: + """Triggers the assignment of custom user field 2.""" + + def set_user3(self) -> None: + """Triggers the assignment of custom user field 3.""" + + def set_user4(self) -> None: + """Triggers the assignment of custom user field 4.""" + + def set_user5(self) -> None: + """Triggers the assignment of custom user field 5.""" + + def set_user6(self) -> None: + """Triggers the assignment of custom user field 6.""" + + def set_user7(self) -> None: + """Triggers the assignment of custom user field 7.""" + + def set_user8(self) -> None: + """Triggers the assignment of custom user field 8.""" + + def set_user9(self) -> None: + """Triggers the assignment of custom user field 9.""" + + def set_user10(self) -> None: + """Triggers the assignment of custom user field 10.""" + + def set_production_number(self) -> None: + """Triggers the assignment of the production/fabrication number. + + Returns: + None + """ + + def set_timber_number(self) -> None: + """Triggers the assignment of the timber-specific member number. + + Returns: + None + """ + + def set_assembly_number(self) -> None: + """Triggers the assignment of the assembly/unit number. + + Returns: + None + """ + + def set_ifc_building(self) -> None: + """Triggers the assignment of the IFC building attribute. + + Returns: + None + """ + + def set_ifc_storey(self) -> None: + """Triggers the assignment of the IFC storey/level attribute. + + Returns: + None + """ diff --git a/src/file_controller/__init__.pyi b/src/file_controller/__init__.pyi index 2cb38d0..5324d4a 100644 --- a/src/file_controller/__init__.pyi +++ b/src/file_controller/__init__.pyi @@ -4,6 +4,7 @@ from cadwork.point_3d import point_3d from cadwork.bim_team_upload_result import bim_team_upload_result from cadwork.dxf_layer_format_type import dxf_layer_format_type from cadwork.dxf_export_version import dxf_export_version +from cadwork.display_attribute import display_attribute from cadwork.api_types import * def export_stl_file(element_id_list: List[ElementId], file_path: str) -> None: @@ -584,3 +585,12 @@ def export_dstv_file(file_path: str) -> bool: Returns: True on successful export, false otherwise. """ + + +def set_webgl_hierarchy(stage: int, attribute: display_attribute) -> None: + """Sets the WebGL hierarchy based on the given stage and attribute. + + Parameters: + stage: The hierarchy stage to set. + attribute: The display attribute to use for the hierarchy. + """ From 72cc233ce186e1ea61a1e9f2ac3974d22eac8511 Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Fri, 27 Feb 2026 17:27:59 +0100 Subject: [PATCH 48/52] [UNASSIGNED] improved docstrings for display_attribute --- pyproject.toml | 2 +- src/cadwork/display_attribute.pyi | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 31e5417..a85f135 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.443.2" +version = "32.443.3" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' diff --git a/src/cadwork/display_attribute.pyi b/src/cadwork/display_attribute.pyi index d0a870a..dea133f 100644 --- a/src/cadwork/display_attribute.pyi +++ b/src/cadwork/display_attribute.pyi @@ -1,8 +1,14 @@ class display_attribute: """ - A wrapper class for managing element display states. - These methods update the internal state of the attribute - object without requiring external parameters. + A wrapper class for managing element display states for WebGL hierarchy display settings (not in Cadwork 3d). + These methods update the internal state of the attribute object without requiring external parameters. + + Used exclusively with `set_webgl_hierarchy` to define visibility and display + properties for elements in the WebGL. + + .. deprecated:: + This class supports legacy local WebGL workflows. + It will be deprecated. """ def __init__(self) -> None: From 3d5041ee606bd6c5fbfdd58f9bb07d117365b692 Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Tue, 17 Mar 2026 08:47:44 +0100 Subject: [PATCH 49/52] [UNASSIGNED] improved docstrings for uttility controller prints --- pyproject.toml | 2 +- src/utility_controller/__init__.pyi | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a85f135..fd32665 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.443.3" +version = "32.443.4" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' diff --git a/src/utility_controller/__init__.pyi b/src/utility_controller/__init__.pyi index a4edd95..e779f49 100644 --- a/src/utility_controller/__init__.pyi +++ b/src/utility_controller/__init__.pyi @@ -38,7 +38,11 @@ def set_project_data(project_data_id: str, data: str) -> None: def print_error(message: str) -> None: - """Prints an error. + """Prints an error to the bottom toolbar of Cadwork 3d. + + Notes: + Attention, this function is blocking. User will need to click to + continue the process. Parameters: message: The error message. @@ -54,7 +58,12 @@ def get_language() -> str: def print_message(message: str, row: int, column: int) -> None: - """Prints a message. + """Prints a message that will be visualized in the bottom toolbar of the + 3D view. You can arrange the message in the desired position by specifying the row and column. + + Examples: + >>> import utility_controller as uc + >>> uc.print_message("Hello World!", 1, 1) Parameters: message: The message to print. @@ -297,7 +306,7 @@ def create_new_guid() -> str: def print_to_console(message: str) -> None: - """Prints a message to the console. + """Prints a message to the Cadwork debug console. Parameters: message: The message. From 06d8cb58499fbde93e7b00ac2783d3726f2cea4a Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Fri, 20 Mar 2026 08:23:36 +0100 Subject: [PATCH 50/52] Add `set_machine_calculation_set` function with usage examples Signed-off-by: Michael Brunner --- src/attribute_controller/__init__.pyi | 166 +++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 2 deletions(-) diff --git a/src/attribute_controller/__init__.pyi b/src/attribute_controller/__init__.pyi index 5b947a4..d072d71 100644 --- a/src/attribute_controller/__init__.pyi +++ b/src/attribute_controller/__init__.pyi @@ -1,4 +1,6 @@ from typing import List + +from cadwork.api_types import * from cadwork.attribute_display_settings import attribute_display_settings from cadwork.element_grouping_type import element_grouping_type from cadwork.element_type import element_type @@ -6,7 +8,7 @@ from cadwork.extended_settings import extended_settings from cadwork.layer_settings import layer_settings from cadwork.node_symbol import node_symbol from cadwork.process_type import process_type -from cadwork.api_types import * + def set_name(element_id_list: List[ElementId], name: str) -> None: """Sets the element name. @@ -16,6 +18,7 @@ def set_name(element_id_list: List[ElementId], name: str) -> None: name: The element name. """ + def set_group(element_id_list: List[ElementId], group: str) -> None: """Sets the element group. @@ -24,6 +27,7 @@ def set_group(element_id_list: List[ElementId], group: str) -> None: group: The element group. """ + def set_subgroup(element_id_list: List[ElementId], subgroup: str) -> None: """Sets the element subgroup. @@ -32,6 +36,7 @@ def set_subgroup(element_id_list: List[ElementId], subgroup: str) -> None: subgroup: The element subgroup. """ + def set_comment(element_id_list: List[ElementId], comment: str) -> None: """Sets the element comment. @@ -40,6 +45,7 @@ def set_comment(element_id_list: List[ElementId], comment: str) -> None: comment: The element comment. """ + def set_user_attribute(element_id_list: List[ElementId], number: UserAttributeId, user_attribute: str) -> None: """Sets the element user attribute. @@ -49,6 +55,7 @@ def set_user_attribute(element_id_list: List[ElementId], number: UserAttributeId user_attribute: The user attribute. """ + def set_sku(element_id_list: List[ElementId], sku: str) -> None: """Sets the element SKU. @@ -57,6 +64,7 @@ def set_sku(element_id_list: List[ElementId], sku: str) -> None: sku: The element SKU. """ + def set_production_number(element_id_list: List[ElementId], production_number: UnsignedInt) -> None: """Sets the element production number. @@ -65,6 +73,7 @@ def set_production_number(element_id_list: List[ElementId], production_number: U production_number: The element production number. """ + def set_part_number(element_id_list: List[ElementId], part_number: UnsignedInt) -> None: """Sets the element part number. @@ -73,6 +82,7 @@ def set_part_number(element_id_list: List[ElementId], part_number: UnsignedInt) part_number: The element part number. """ + def set_additional_data(element_id_list: List[ElementId], data_id: str, data_text: str) -> None: """Sets the element additional data. @@ -82,6 +92,7 @@ def set_additional_data(element_id_list: List[ElementId], data_id: str, data_tex data_text: The element additional data. """ + def delete_additional_data(element_id_list: List[ElementId], data_id: str) -> None: """Deletes the element additional data. @@ -90,6 +101,7 @@ def delete_additional_data(element_id_list: List[ElementId], data_id: str) -> No data_id: The data id. """ + def set_user_attribute_name(number: UserAttributeId, user_attribute_name: str) -> None: """Sets the user attribute name. @@ -98,6 +110,7 @@ def set_user_attribute_name(number: UserAttributeId, user_attribute_name: str) - user_attribute_name: The user attribute name. """ + def set_process_type_and_extended_settings_from_name(element_id_list: List[ElementId]) -> None: """Sets the element process type and extended settings from the element name. @@ -105,6 +118,7 @@ def set_process_type_and_extended_settings_from_name(element_id_list: List[Eleme element_id_list: The element id list. """ + def set_name_process_type(name: str, process_type: process_type) -> None: """Sets the process type for an element name. @@ -113,6 +127,7 @@ def set_name_process_type(name: str, process_type: process_type) -> None: process_type: The process type. """ + def set_name_extended_settings(name: str, extended_settings: extended_settings) -> None: """Sets the extended settings for an element name. @@ -121,6 +136,7 @@ def set_name_extended_settings(name: str, extended_settings: extended_settings) extended_settings: The extended settings. """ + def set_output_type(element_id_list: List[ElementId], process_type: process_type) -> None: """Sets the element output type. @@ -129,6 +145,7 @@ def set_output_type(element_id_list: List[ElementId], process_type: process_type process_type: The process type. """ + def set_extended_settings(element_id_list: List[ElementId], extended_settings: extended_settings) -> None: """Sets the element extended settings. @@ -137,6 +154,7 @@ def set_extended_settings(element_id_list: List[ElementId], extended_settings: e extended_settings: The extended settings. """ + def set_wall(element_id_list: List[ElementId]) -> None: """Sets the element to wall. @@ -158,6 +176,7 @@ def set_floor(element_id_list: List[ElementId]) -> None: element_id_list: The element id list. """ + def set_opening(element_id_list: List[ElementId]) -> None: """Sets the element to opening. @@ -165,6 +184,7 @@ def set_opening(element_id_list: List[ElementId]) -> None: element_id_list: The element id list. """ + def set_fastening_attribute(element_id_list: List[ElementId], value: str) -> None: """Sets the element fastening attribute. @@ -173,6 +193,7 @@ def set_fastening_attribute(element_id_list: List[ElementId], value: str) -> Non value: The fastening attribute value. """ + def set_element_material(element_id_list: List[ElementId], material: MaterialId) -> None: """Sets the element material. @@ -181,6 +202,7 @@ def set_element_material(element_id_list: List[ElementId], material: MaterialId) material: The element material id. """ + def set_assembly_number(element_id_list: List[ElementId], assembly_number: str) -> None: """set assembly number. @@ -189,6 +211,7 @@ def set_assembly_number(element_id_list: List[ElementId], assembly_number: str) assembly_number: The assembly number. """ + def set_list_quantity(element_id_list: List[ElementId], list_quantity: UnsignedInt) -> None: """Set list quantity. @@ -197,6 +220,7 @@ def set_list_quantity(element_id_list: List[ElementId], list_quantity: UnsignedI list_quantity: The list quantity. """ + def set_layer_settings(element_id_list: List[ElementId], layer_settings: layer_settings) -> None: """Set layer settings. @@ -205,6 +229,7 @@ def set_layer_settings(element_id_list: List[ElementId], layer_settings: layer_s layer_settings: The layer settings. """ + def set_ignore_in_vba_calculation(element_id_list: List[ElementId], ignore: bool) -> None: """Sets if the element should be ignored in VBA Calculation. @@ -213,10 +238,12 @@ def set_ignore_in_vba_calculation(element_id_list: List[ElementId], ignore: bool ignore: True if the element should be ignored in VBA calculation, false otherwise. """ + def clear_errors() -> None: """clear all errors. """ + def set_reference_wall_2dc(element_id_list: List[ElementId], _2dc_file_path: str) -> None: """Applies a new 2dc reference wall to an element. @@ -225,6 +252,7 @@ def set_reference_wall_2dc(element_id_list: List[ElementId], _2dc_file_path: str _2dc_file_path: The 2dc file path. """ + def get_user_attribute_count() -> UnsignedInt: """Get user attribute count. @@ -232,6 +260,7 @@ def get_user_attribute_count() -> UnsignedInt: The count of user attributes. """ + def set_standard_part(element_id_list: List[ElementId]) -> None: """Sets covers (wall,opening or floor) to standard part. @@ -239,6 +268,7 @@ def set_standard_part(element_id_list: List[ElementId]) -> None: element_id_list: The element id list. """ + def set_solid_wall(element_id_list: List[ElementId]) -> None: """Sets elements to solid wall. @@ -246,6 +276,7 @@ def set_solid_wall(element_id_list: List[ElementId]) -> None: element_id_list: The element id list. """ + def set_log_wall(element_id_list: List[ElementId]) -> None: """Sets elements to log wall. @@ -253,6 +284,7 @@ def set_log_wall(element_id_list: List[ElementId]) -> None: element_id_list: The element id list. """ + def set_solid_floor(element_id_list: List[ElementId]) -> None: """Sets elements to solid floor. @@ -271,6 +303,7 @@ def set_roof(element_id_list: List[ElementId]) -> None: element_id_list: The element id list. """ + def set_solid_roof(element_id_list: List[ElementId]) -> None: """Sets elements to solid roof cover. @@ -278,6 +311,7 @@ def set_solid_roof(element_id_list: List[ElementId]) -> None: element_id_list: The element id list. """ + def get_node_symbol(element_id: ElementId) -> node_symbol: """Get node symbol. @@ -288,6 +322,7 @@ def get_node_symbol(element_id: ElementId) -> node_symbol: The node symbol of the element. """ + def set_node_symbol(element_id_list: List[ElementId], symbol: node_symbol) -> None: """Set node symbol. @@ -296,14 +331,17 @@ def set_node_symbol(element_id_list: List[ElementId], symbol: node_symbol) -> No symbol: The node symbol. """ + def enable_attribute_display() -> None: """Enable attribute display. """ + def disable_attribute_display() -> None: """Disable attribute display. """ + def is_attribute_display_enabled() -> bool: """Is attribute display enabled. @@ -311,6 +349,7 @@ def is_attribute_display_enabled() -> bool: True if attribute display is enabled, false otherwise. """ + def update_auto_attribute() -> None: """Update the auto attribute. """ @@ -325,6 +364,7 @@ def set_additional_guid(element_id_list: List[ElementId], data_id: str, guid: st guid: The guid to set. """ + def add_item_to_group_list(item: str) -> None: """Add item to group list. @@ -340,6 +380,7 @@ def add_item_to_subgroup_list(item: str) -> None: item: The item to add in the subgroup list. """ + def add_item_to_comment_list(item: str) -> None: """Add item to comment list. @@ -373,6 +414,7 @@ def set_container_number(element_id_list: List[ElementId], number: UnsignedInt) number: The container number. """ + def get_name_list_items() -> List[str]: """Retrieve a list of name for all items @@ -492,6 +534,7 @@ def set_attribute_display_settings_for_container(settings: attribute_display_set settings: The display settings to apply. """ + def set_attribute_display_settings_for_export_solid(settings: attribute_display_settings) -> None: """Set attribute display settings for export solid. @@ -571,6 +614,7 @@ def set_attribute_display_settings_for_log_wall_panel(settings: attribute_displa settings: The display settings to apply. """ + def set_attribute_display_settings_for_machine(settings: attribute_display_settings) -> None: """Set attribute display settings for machine. @@ -626,6 +670,7 @@ def set_attribute_display_settings_for_solid_wall_panel(settings: attribute_disp settings: The display settings to apply. """ + def set_framed_floor(element_id_list: List[ElementId]) -> None: """Sets the elements to framed floor. @@ -633,6 +678,7 @@ def set_framed_floor(element_id_list: List[ElementId]) -> None: element_id_list: The element id list. """ + def set_framed_roof(element_id_list: List[ElementId]) -> None: """Sets the elements to framed roof. @@ -640,6 +686,7 @@ def set_framed_roof(element_id_list: List[ElementId]) -> None: element_id_list: The element id list. """ + def set_framed_wall(element_id_list: List[ElementId]) -> None: """Sets the element to framed wall. @@ -658,6 +705,7 @@ def get_name_list_items_by_element_type(element_type: element_type) -> List[str] The list of names for the specified element type. """ + def get_name(element_id: ElementId) -> str: """Gets the element name. @@ -668,6 +716,7 @@ def get_name(element_id: ElementId) -> str: The element name. """ + def get_group(element_id: ElementId) -> str: """Gets the element group. @@ -678,6 +727,7 @@ def get_group(element_id: ElementId) -> str: The element group. """ + def get_subgroup(element_id: ElementId) -> str: """Gets the element subgroup. @@ -688,6 +738,7 @@ def get_subgroup(element_id: ElementId) -> str: The element subgroup. """ + def get_comment(element_id: ElementId) -> str: """Gets the element comment. @@ -698,6 +749,7 @@ def get_comment(element_id: ElementId) -> str: The element comment. """ + def get_user_attribute(element_id: ElementId, number: UserAttributeId) -> str: """Gets the element user attribute. @@ -709,6 +761,7 @@ def get_user_attribute(element_id: ElementId, number: UserAttributeId) -> str: The element user attribute. """ + def get_sku(element_id: ElementId) -> str: """Gets the element SKU. @@ -719,6 +772,7 @@ def get_sku(element_id: ElementId) -> str: The element SKU. """ + def get_production_number(element_id: ElementId) -> UnsignedInt: """Gets the element production number. @@ -729,6 +783,7 @@ def get_production_number(element_id: ElementId) -> UnsignedInt: The element production number. """ + def get_part_number(element_id: ElementId) -> UnsignedInt: """Gets the element part number. @@ -739,6 +794,7 @@ def get_part_number(element_id: ElementId) -> UnsignedInt: The element part number. """ + def get_additional_data(element_id: ElementId, data_id: str) -> str: """Gets the element additional data. @@ -750,6 +806,7 @@ def get_additional_data(element_id: ElementId, data_id: str) -> str: The element additional data. """ + def get_user_attribute_name(number: UserAttributeId) -> str: """Gets the user attribute name. @@ -760,6 +817,7 @@ def get_user_attribute_name(number: UserAttributeId) -> str: The user attribute name. """ + def get_wall_situation(element_id: ElementId) -> str: """Gets the element wall situation. @@ -770,6 +828,7 @@ def get_wall_situation(element_id: ElementId) -> str: The element wall situation. """ + def get_element_material_name(element_id: ElementId) -> str: """Gets the element material name. @@ -780,6 +839,7 @@ def get_element_material_name(element_id: ElementId) -> str: The element material name. """ + def get_prefab_layer(element_id: ElementId) -> str: """Gets the element prefab layer. @@ -790,6 +850,7 @@ def get_prefab_layer(element_id: ElementId) -> str: The element prefab layer. """ + def get_machine_calculation_set(element_id: ElementId) -> str: """Gets the element machine calculation set. @@ -800,6 +861,7 @@ def get_machine_calculation_set(element_id: ElementId) -> str: The element machine calculation set. """ + def get_cutting_set(element_id: ElementId) -> str: """Gets the element cutting set. @@ -810,6 +872,7 @@ def get_cutting_set(element_id: ElementId) -> str: The element cutting set. """ + def get_name_process_type(name: str) -> process_type: """Gets the process type for an element name. @@ -820,6 +883,7 @@ def get_name_process_type(name: str) -> process_type: The process type. """ + def get_name_extended_settings(name: str) -> extended_settings: """Gets the extended settings for an element name. @@ -830,6 +894,7 @@ def get_name_extended_settings(name: str) -> extended_settings: The extended settings. """ + def get_output_type(element_id: ElementId) -> process_type: """Gets the element output type. @@ -840,6 +905,7 @@ def get_output_type(element_id: ElementId) -> process_type: The element output type. """ + def get_extended_settings(element_id: ElementId) -> extended_settings: """Gets the element extended settings. @@ -850,6 +916,7 @@ def get_extended_settings(element_id: ElementId) -> extended_settings: The element extended settings. """ + def get_element_type(element_id: ElementId) -> element_type: """Gets the element type. @@ -860,6 +927,7 @@ def get_element_type(element_id: ElementId) -> element_type: The element type. """ + def get_fastening_attribute(element_id: ElementId) -> str: """Get the element fastening attribute. @@ -870,6 +938,7 @@ def get_fastening_attribute(element_id: ElementId) -> str: The element fastening attribute. """ + def get_assembly_number(element_id: ElementId) -> str: """Get assembly number. @@ -880,6 +949,7 @@ def get_assembly_number(element_id: ElementId) -> str: The assembly number. """ + def get_list_quantity(element_id: ElementId) -> UnsignedInt: """Get list quantity. @@ -890,6 +960,7 @@ def get_list_quantity(element_id: ElementId) -> UnsignedInt: The list quantity. """ + def get_ignore_in_vba_calculation(element_id: ElementId) -> bool: """Get ignore in vba calculation. @@ -900,6 +971,7 @@ def get_ignore_in_vba_calculation(element_id: ElementId) -> bool: True if the element is ignored in VBA calculation, false otherwise. """ + def get_standard_element_name(element_id: ElementId) -> str: """Get standard element name. @@ -910,6 +982,7 @@ def get_standard_element_name(element_id: ElementId) -> str: The standard element name. """ + def get_steel_shape_name(element_id: ElementId) -> str: """Get steel shape name. @@ -920,6 +993,7 @@ def get_steel_shape_name(element_id: ElementId) -> str: The steel shape name. """ + def is_beam(element_id: ElementId) -> bool: """Tests if element is beam. @@ -930,6 +1004,7 @@ def is_beam(element_id: ElementId) -> bool: True if the element is a beam, false otherwise. """ + def is_panel(element_id: ElementId) -> bool: """Tests if element is panel. @@ -940,6 +1015,7 @@ def is_panel(element_id: ElementId) -> bool: True if the element is a panel, false otherwise. """ + def is_opening(element_id: ElementId) -> bool: """Tests if element is opening. @@ -950,6 +1026,7 @@ def is_opening(element_id: ElementId) -> bool: True if the element is an opening, false otherwise. """ + def is_wall(element_id: ElementId) -> bool: """Tests if element is wall. @@ -960,6 +1037,7 @@ def is_wall(element_id: ElementId) -> bool: True if the element is a wall, false otherwise. """ + def is_floor(element_id: ElementId) -> bool: """Tests if element is floor. @@ -970,6 +1048,7 @@ def is_floor(element_id: ElementId) -> bool: True if the element is a floor, false otherwise. """ + def is_roof(element_id: ElementId) -> bool: """Tests if element is roof. @@ -980,6 +1059,7 @@ def is_roof(element_id: ElementId) -> bool: True if the element is a roof, false otherwise. """ + def is_metal(element_id: ElementId) -> bool: """Tests if element is metal. @@ -990,6 +1070,7 @@ def is_metal(element_id: ElementId) -> bool: True if the element is metal, false otherwise. """ + def is_export_solid(element_id: ElementId) -> bool: """Tests if element is export solid. @@ -1000,6 +1081,7 @@ def is_export_solid(element_id: ElementId) -> bool: True if the element is an export solid, false otherwise. """ + def is_container(element_id: ElementId) -> bool: """Tests if element is container. @@ -1010,6 +1092,7 @@ def is_container(element_id: ElementId) -> bool: True if the element is a container, false otherwise. """ + def is_connector_axis(element_id: ElementId) -> bool: """Tests if element is connector axis. @@ -1020,6 +1103,7 @@ def is_connector_axis(element_id: ElementId) -> bool: True if the element is a connector axis, false otherwise. """ + def is_drilling(element_id: ElementId) -> bool: """Tests if element is drilling. @@ -1030,6 +1114,7 @@ def is_drilling(element_id: ElementId) -> bool: True if the element is drilling, false otherwise. """ + def is_node(element_id: ElementId) -> bool: """Tests if element is node. @@ -1040,6 +1125,7 @@ def is_node(element_id: ElementId) -> bool: True if the element is a node, false otherwise. """ + def is_auxiliary(element_id: ElementId) -> bool: """Tests if element is auxiliary. @@ -1050,6 +1136,7 @@ def is_auxiliary(element_id: ElementId) -> bool: True if the element is auxiliary, false otherwise. """ + def is_roof_surface(element_id: ElementId) -> bool: """Tests if the element is roof surface. @@ -1060,6 +1147,7 @@ def is_roof_surface(element_id: ElementId) -> bool: True if the element is a roof surface, false otherwise. """ + def is_caddy_object(element_id: ElementId) -> bool: """Tests if the element is caddy object. @@ -1070,6 +1158,7 @@ def is_caddy_object(element_id: ElementId) -> bool: True if the element is a caddy object, false otherwise. """ + def is_envelope(element_id: ElementId) -> bool: """Tests if the element is an envelope. @@ -1080,6 +1169,7 @@ def is_envelope(element_id: ElementId) -> bool: True if the element is an envelope, false otherwise. """ + def is_architecture_wall_2dc(element_id: ElementId) -> bool: """Tests if the element is a 2dc reference wall. @@ -1090,6 +1180,7 @@ def is_architecture_wall_2dc(element_id: ElementId) -> bool: True if the element is a 2dc reference wall, false otherwise. """ + def is_architecture_wall_xml(element_id: ElementId) -> bool: """Tests if the element is a xml reference wall. @@ -1100,6 +1191,7 @@ def is_architecture_wall_xml(element_id: ElementId) -> bool: True if the element is a xml reference wall, false otherwise. """ + def is_surface(element_id: ElementId) -> bool: """Tests if the element is a Surface. @@ -1110,6 +1202,7 @@ def is_surface(element_id: ElementId) -> bool: True if the element is a Surface, false otherwise. """ + def is_line(element_id: ElementId) -> bool: """Tests if the element is a Line. @@ -1120,6 +1213,7 @@ def is_line(element_id: ElementId) -> bool: True if the element is a Line, false otherwise. """ + def get_auto_attribute(element_id: ElementId, number: UnsignedInt) -> str: """Get auto attribute. @@ -1131,6 +1225,7 @@ def get_auto_attribute(element_id: ElementId, number: UnsignedInt) -> str: The auto attribute value. """ + def get_auto_attribute_name(number: UnsignedInt) -> str: """Get auto attribute name. @@ -1141,6 +1236,7 @@ def get_auto_attribute_name(number: UnsignedInt) -> str: The auto attribute name. """ + def is_framed_wall(element_id: ElementId) -> bool: """Tests if the element is a framed wall. @@ -1151,6 +1247,7 @@ def is_framed_wall(element_id: ElementId) -> bool: True if the element is a framed wall, false otherwise. """ + def is_solid_wall(element_id: ElementId) -> bool: """Tests if the element is a solid wall. @@ -1161,6 +1258,7 @@ def is_solid_wall(element_id: ElementId) -> bool: True if the element is a solid wall, false otherwise. """ + def is_log_wall(element_id: ElementId) -> bool: """Tests if the element is a log wall. @@ -1171,6 +1269,7 @@ def is_log_wall(element_id: ElementId) -> bool: True if the element is a log wall, false otherwise. """ + def is_framed_floor(element_id: ElementId) -> bool: """Tests if the element is a framed floor. @@ -1181,6 +1280,7 @@ def is_framed_floor(element_id: ElementId) -> bool: True if the element is a framed floor, false otherwise. """ + def is_solid_floor(element_id: ElementId) -> bool: """Tests if the element is a solid floor. @@ -1191,6 +1291,7 @@ def is_solid_floor(element_id: ElementId) -> bool: True if the element is a solid floor, false otherwise. """ + def is_framed_roof(element_id: ElementId) -> bool: """Tests if the element is a framed roof. @@ -1201,6 +1302,7 @@ def is_framed_roof(element_id: ElementId) -> bool: True if the element is a framed roof, false otherwise. """ + def is_solid_roof(element_id: ElementId) -> bool: """Tests if the element is a solid roof. @@ -1300,6 +1402,7 @@ def get_container_number_with_prefix(element_id: ElementId) -> str: The container number with prefix associated with the element. """ + def get_group_list_items() -> List[str]: """Get group list items. @@ -1307,6 +1410,7 @@ def get_group_list_items() -> List[str]: The list of group list items. """ + def get_subgroup_list_items() -> List[str]: """Get subgroup list items. @@ -1314,6 +1418,7 @@ def get_subgroup_list_items() -> List[str]: The list of subgroup list items. """ + def get_comment_list_items() -> List[str]: """Get comment list items. @@ -1321,6 +1426,7 @@ def get_comment_list_items() -> List[str]: The list of comment list items. """ + def get_sku_list_items() -> List[str]: """Get sku list items. @@ -1361,6 +1467,7 @@ def is_rectangular_mep(element_id: ElementId) -> bool: True if the element is a rectangular mep, false otherwise. """ + def get_machine_calculation_state(element_id: ElementId) -> str: """Get machine calculation state. @@ -1382,6 +1489,7 @@ def get_machine_calculation_set_machine_type(element_id: ElementId) -> str: The machine calculation set machine type of the element. """ + def is_btl_processing_group(element_id: ElementId) -> bool: """Test if element is btl processing group. @@ -1392,6 +1500,7 @@ def is_btl_processing_group(element_id: ElementId) -> bool: True if the element is a btl processing group, false otherwise. """ + def is_hundegger_processing_group(element_id: ElementId) -> bool: """Test if element is hundegger processing group. @@ -1402,6 +1511,7 @@ def is_hundegger_processing_group(element_id: ElementId) -> bool: True if the element is a hundegger processing group, false otherwise. """ + def get_element_grouping_type() -> element_grouping_type: """Get the element grouping type (group, subgroup). @@ -1409,6 +1519,7 @@ def get_element_grouping_type() -> element_grouping_type: The element grouping type. """ + def set_element_grouping_type(element_grouping_type: element_grouping_type) -> None: """Set the element grouping type (group, subgroup). @@ -1416,6 +1527,7 @@ def set_element_grouping_type(element_grouping_type: element_grouping_type) -> N element_grouping_type: The element grouping type to set. """ + def get_associated_nesting_name(element_id: ElementId) -> str: """Get associated nesting name @@ -1426,6 +1538,7 @@ def get_associated_nesting_name(element_id: ElementId) -> str: The associated nesting name. """ + def get_associated_nesting_number(element_id: ElementId) -> str: """Get associated nesting number. @@ -1436,6 +1549,7 @@ def get_associated_nesting_number(element_id: ElementId) -> str: The associated nesting number. """ + def get_attribute_display_settings_for_2d() -> attribute_display_settings: """Get attribute display settings for 2d. @@ -1443,6 +1557,7 @@ def get_attribute_display_settings_for_2d() -> attribute_display_settings: The attribute display settings for 2d. """ + def get_attribute_display_settings_for_2d_with_layout() -> attribute_display_settings: """Get attribute display settings for 2d with layout. @@ -1450,6 +1565,7 @@ def get_attribute_display_settings_for_2d_with_layout() -> attribute_display_set The attribute display settings for 2d with layout. """ + def get_attribute_display_settings_for_2d_without_layout() -> attribute_display_settings: """Get attribute display settings for 2d without layout. @@ -1457,6 +1573,7 @@ def get_attribute_display_settings_for_2d_without_layout() -> attribute_display_ The attribute display settings for 2d without layout. """ + def get_attribute_display_settings_for_3d() -> attribute_display_settings: """Get attribute display settings for 3d. @@ -1464,6 +1581,7 @@ def get_attribute_display_settings_for_3d() -> attribute_display_settings: The attribute display settings for 3d. """ + def get_attribute_display_settings_for_container() -> attribute_display_settings: """Get attribute display settings for container. @@ -1471,6 +1589,7 @@ def get_attribute_display_settings_for_container() -> attribute_display_settings The attribute display settings for container. """ + def get_attribute_display_settings_for_export_solid() -> attribute_display_settings: """Get attribute display settings for export solid. @@ -1478,6 +1597,7 @@ def get_attribute_display_settings_for_export_solid() -> attribute_display_setti The attribute display settings for export solid. """ + def get_attribute_display_settings_for_framed_wall_axis() -> attribute_display_settings: """Get attribute display settings for framed wall axis. @@ -1485,6 +1605,7 @@ def get_attribute_display_settings_for_framed_wall_axis() -> attribute_display_s The attribute display settings for framed wall axis. """ + def get_attribute_display_settings_for_framed_wall_beam() -> attribute_display_settings: """Get attribute display settings for framed wall beam. @@ -1492,6 +1613,7 @@ def get_attribute_display_settings_for_framed_wall_beam() -> attribute_display_s The attribute display settings for framed wall beam. """ + def get_attribute_display_settings_for_framed_wall_opening() -> attribute_display_settings: """Get attribute display settings for framed wall opening. @@ -1499,6 +1621,7 @@ def get_attribute_display_settings_for_framed_wall_opening() -> attribute_displa The attribute display settings for framed wall opening. """ + def get_attribute_display_settings_for_framed_wall_panel() -> attribute_display_settings: """Get attribute display settings for framed wall panel. @@ -1506,6 +1629,7 @@ def get_attribute_display_settings_for_framed_wall_panel() -> attribute_display_ The attribute display settings for framed wall panel. """ + def get_attribute_display_settings_for_log_wall_axis() -> attribute_display_settings: """Get attribute display settings for log wall axis. @@ -1513,6 +1637,7 @@ def get_attribute_display_settings_for_log_wall_axis() -> attribute_display_sett The attribute display settings for log wall axis. """ + def get_attribute_display_settings_for_log_wall_beam() -> attribute_display_settings: """Get attribute display settings for log wall beam. @@ -1520,6 +1645,7 @@ def get_attribute_display_settings_for_log_wall_beam() -> attribute_display_sett The attribute display settings for log wall beam. """ + def get_attribute_display_settings_for_log_wall_opening() -> attribute_display_settings: """Get attribute display settings for log wall opening. @@ -1527,6 +1653,7 @@ def get_attribute_display_settings_for_log_wall_opening() -> attribute_display_s The attribute display settings for log wall opening. """ + def get_attribute_display_settings_for_log_wall_panel() -> attribute_display_settings: """Get attribute display settings for log wall panel. @@ -1534,6 +1661,7 @@ def get_attribute_display_settings_for_log_wall_panel() -> attribute_display_set The attribute display settings for log wall panel. """ + def get_attribute_display_settings_for_machine() -> attribute_display_settings: """Get attribute display settings for machine. @@ -1541,6 +1669,7 @@ def get_attribute_display_settings_for_machine() -> attribute_display_settings: The attribute display settings for machine. """ + def get_attribute_display_settings_for_nesting_element() -> attribute_display_settings: """Get attribute display settings for nesting element. @@ -1548,6 +1677,7 @@ def get_attribute_display_settings_for_nesting_element() -> attribute_display_se The attribute display settings for nesting element. """ + def get_attribute_display_settings_for_nesting_volume() -> attribute_display_settings: """Get attribute display settings for nesting volume. @@ -1555,6 +1685,7 @@ def get_attribute_display_settings_for_nesting_volume() -> attribute_display_set The attribute display settings for nesting volume. """ + def get_attribute_display_settings_for_solid_wall_axis() -> attribute_display_settings: """Get attribute display settings for solid wall axis. @@ -1562,6 +1693,7 @@ def get_attribute_display_settings_for_solid_wall_axis() -> attribute_display_se The attribute display settings for solid wall axis. """ + def get_attribute_display_settings_for_solid_wall_beam() -> attribute_display_settings: """Get attribute display settings for solid wall beam. @@ -1569,6 +1701,7 @@ def get_attribute_display_settings_for_solid_wall_beam() -> attribute_display_se The attribute display settings for solid wall beam. """ + def get_attribute_display_settings_for_solid_wall_opening() -> attribute_display_settings: """Get attribute display settings for solid wall opening. @@ -1576,6 +1709,7 @@ def get_attribute_display_settings_for_solid_wall_opening() -> attribute_display The attribute display settings for solid wall opening. """ + def get_attribute_display_settings_for_solid_wall_panel() -> attribute_display_settings: """Get attribute display settings for solid wall panel. @@ -1583,6 +1717,7 @@ def get_attribute_display_settings_for_solid_wall_panel() -> attribute_display_s The attribute display settings for solid wall panel. """ + def is_processing(element_id: ElementId) -> bool: """Tests if element is processing. @@ -1593,6 +1728,7 @@ def is_processing(element_id: ElementId) -> bool: True if the element is processing, false otherwise. """ + def delete_user_attribute(number: UserAttributeId) -> bool: """Delete user attribute from attribute list. The attribute is only deleted when the attribute is not used. @@ -1603,6 +1739,7 @@ def delete_user_attribute(number: UserAttributeId) -> bool: True if the attribute was successfully deleted, false otherwise. """ + def is_attribute_visible_in_modify_window(number: UnsignedInt) -> bool: """Test if attribute is visible in modify window. @@ -1613,6 +1750,7 @@ def is_attribute_visible_in_modify_window(number: UnsignedInt) -> bool: True if the attribute is visible in the modify window, false otherwise. """ + def set_attribute_visibility_in_modify_window(number: UnsignedInt, visibility: bool) -> None: """Set attribute visibility in modify window. @@ -1621,6 +1759,7 @@ def set_attribute_visibility_in_modify_window(number: UnsignedInt, visibility: b visibility: The visibility state. """ + def set_cutting_set(element_id_list: List[ElementId], cutting_set_name: str) -> bool: """Set cutting set. @@ -1632,6 +1771,7 @@ def set_cutting_set(element_id_list: List[ElementId], cutting_set_name: str) -> True if the cutting set was successfully set, false otherwise. """ + def get_standard_element_material_id(element_id: ElementId) -> int: """Get standard element material id. @@ -1640,4 +1780,26 @@ def get_standard_element_material_id(element_id: ElementId) -> int: Returns: The standard element material id. - """ \ No newline at end of file + """ + + +def set_machine_calculation_set(element_ids: List[ElementId], name: str) -> bool: + """Set machine calculation set for a list of elements. + + Note: + If multiple sets share the same name, the first matching set is used. + + Parameters: + element_ids: The list of element ids. + name: The name of the machine calculation set to apply. + + Examples: + >>> import attribute_controller as ac + >>> import element_controller as ec + >>> [element] = ec.get_active_identifiable_element_ids() + >>> current_set = ac.get_machine_calculation_set(element) + >>> success = ac.set_machine_calculation_set([element], "xyz_hundegger K2_BVN") + + Returns: + True if the machine calculation set was successfully applied, false otherwise. + """ From a0b73f702dd6d080b6f245145dde304b93056810 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Fri, 20 Mar 2026 08:24:25 +0100 Subject: [PATCH 51/52] Update version to 32.443.5 Signed-off-by: Michael Brunner --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fd32665..c2d2fb1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.443.4" +version = "32.443.5" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' From e6d2eda7a94434d51f64eb73a275bbd83e23750a Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Tue, 14 Apr 2026 15:52:44 +0200 Subject: [PATCH 52/52] Improve stub package for PEP 561 compliance and better IDE autocompletion - Add `py.typed` marker files to all packages - Fix `cadwork/__init__.pyi` re-exports using `from .x import x as x` syntax - Add `__all__` to `cadwork/__init__.pyi` and `api_types.pyi` - Replace deprecated `typing.List`/`Dict`/`Tuple` with built-in generics (Python 3.12+) - Use `TypeAlias` for type aliases in `api_types.pyi` - Add `py.typed` and `*.pyi` to setuptools package-data in `pyproject.toml` --- pyproject.toml | 7 +- src/attribute_controller/__init__.pyi | 95 +++--- src/attribute_controller/py.typed | 0 src/bim_controller/__init__.pyi | 29 +- src/bim_controller/py.typed | 0 src/cadwork/__init__.pyi | 304 ++++++++++-------- src/cadwork/active_point_result.pyi | 17 + src/cadwork/api_types.pyi | 45 +-- src/cadwork/hit_result.pyi | 17 +- src/cadwork/ifc_options.pyi | 36 +-- src/cadwork/py.typed | 0 src/cadwork/rgb_color.pyi | 21 ++ src/connector_axis_controller/__init__.pyi | 11 +- src/connector_axis_controller/py.typed | 0 src/dimension_controller/__init__.pyi | 25 +- src/dimension_controller/py.typed | 0 src/element_controller/__init__.pyi | 235 +++++++------- src/element_controller/py.typed | 0 src/endtype_controller/__init__.pyi | 11 +- src/endtype_controller/py.typed | 0 src/file_controller/__init__.pyi | 51 ++- src/file_controller/py.typed | 0 src/geometry_controller/__init__.pyi | 79 +++-- src/geometry_controller/py.typed | 0 src/list_controller/__init__.pyi | 26 +- src/list_controller/py.typed | 0 src/machine_controller/__init__.pyi | 11 +- src/machine_controller/py.typed | 0 src/material_controller/__init__.pyi | 5 +- src/material_controller/py.typed | 0 src/menu_controller/__init__.pyi | 5 +- src/menu_controller/py.typed | 0 src/multi_layer_cover_controller/__init__.pyi | 19 +- src/multi_layer_cover_controller/py.typed | 0 src/roof_controller/__init__.pyi | 3 +- src/roof_controller/py.typed | 0 src/scene_controller/__init__.pyi | 13 +- src/scene_controller/py.typed | 0 src/shop_drawing_controller/__init__.pyi | 13 +- src/shop_drawing_controller/py.typed | 0 src/utility_controller/__init__.pyi | 14 +- src/utility_controller/py.typed | 0 src/visualization_controller/__init__.pyi | 31 +- src/visualization_controller/py.typed | 0 44 files changed, 597 insertions(+), 526 deletions(-) create mode 100644 src/attribute_controller/py.typed create mode 100644 src/bim_controller/py.typed create mode 100644 src/cadwork/active_point_result.pyi create mode 100644 src/cadwork/py.typed create mode 100644 src/cadwork/rgb_color.pyi create mode 100644 src/connector_axis_controller/py.typed create mode 100644 src/dimension_controller/py.typed create mode 100644 src/element_controller/py.typed create mode 100644 src/endtype_controller/py.typed create mode 100644 src/file_controller/py.typed create mode 100644 src/geometry_controller/py.typed create mode 100644 src/list_controller/py.typed create mode 100644 src/machine_controller/py.typed create mode 100644 src/material_controller/py.typed create mode 100644 src/menu_controller/py.typed create mode 100644 src/multi_layer_cover_controller/py.typed create mode 100644 src/roof_controller/py.typed create mode 100644 src/scene_controller/py.typed create mode 100644 src/shop_drawing_controller/py.typed create mode 100644 src/utility_controller/py.typed create mode 100644 src/visualization_controller/py.typed diff --git a/pyproject.toml b/pyproject.toml index c2d2fb1..5dc45e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cwapi3d" -version = "32.443.5" +version = "32.443.6" authors = [{ name = "Cadwork", email = "it@cadwork.ca" }] requires-python = ">= 3.12" description = 'Python bindings for CwAPI3D' @@ -49,5 +49,8 @@ packages = [ ] package-dir = { "" = "src" } +[tool.setuptools.package-data] +"*" = ["*.pyi", "py.typed"] + [tool.setuptools.exclude-package-data] -"*" = [".py"] +"*" = ["*.py"] diff --git a/src/attribute_controller/__init__.pyi b/src/attribute_controller/__init__.pyi index d072d71..b078e5f 100644 --- a/src/attribute_controller/__init__.pyi +++ b/src/attribute_controller/__init__.pyi @@ -1,4 +1,3 @@ -from typing import List from cadwork.api_types import * from cadwork.attribute_display_settings import attribute_display_settings @@ -10,7 +9,7 @@ from cadwork.node_symbol import node_symbol from cadwork.process_type import process_type -def set_name(element_id_list: List[ElementId], name: str) -> None: +def set_name(element_id_list: list[ElementId], name: str) -> None: """Sets the element name. Parameters: @@ -19,7 +18,7 @@ def set_name(element_id_list: List[ElementId], name: str) -> None: """ -def set_group(element_id_list: List[ElementId], group: str) -> None: +def set_group(element_id_list: list[ElementId], group: str) -> None: """Sets the element group. Parameters: @@ -28,7 +27,7 @@ def set_group(element_id_list: List[ElementId], group: str) -> None: """ -def set_subgroup(element_id_list: List[ElementId], subgroup: str) -> None: +def set_subgroup(element_id_list: list[ElementId], subgroup: str) -> None: """Sets the element subgroup. Parameters: @@ -37,7 +36,7 @@ def set_subgroup(element_id_list: List[ElementId], subgroup: str) -> None: """ -def set_comment(element_id_list: List[ElementId], comment: str) -> None: +def set_comment(element_id_list: list[ElementId], comment: str) -> None: """Sets the element comment. Parameters: @@ -46,7 +45,7 @@ def set_comment(element_id_list: List[ElementId], comment: str) -> None: """ -def set_user_attribute(element_id_list: List[ElementId], number: UserAttributeId, user_attribute: str) -> None: +def set_user_attribute(element_id_list: list[ElementId], number: UserAttributeId, user_attribute: str) -> None: """Sets the element user attribute. Parameters: @@ -56,7 +55,7 @@ def set_user_attribute(element_id_list: List[ElementId], number: UserAttributeId """ -def set_sku(element_id_list: List[ElementId], sku: str) -> None: +def set_sku(element_id_list: list[ElementId], sku: str) -> None: """Sets the element SKU. Parameters: @@ -65,7 +64,7 @@ def set_sku(element_id_list: List[ElementId], sku: str) -> None: """ -def set_production_number(element_id_list: List[ElementId], production_number: UnsignedInt) -> None: +def set_production_number(element_id_list: list[ElementId], production_number: UnsignedInt) -> None: """Sets the element production number. Parameters: @@ -74,7 +73,7 @@ def set_production_number(element_id_list: List[ElementId], production_number: U """ -def set_part_number(element_id_list: List[ElementId], part_number: UnsignedInt) -> None: +def set_part_number(element_id_list: list[ElementId], part_number: UnsignedInt) -> None: """Sets the element part number. Parameters: @@ -83,7 +82,7 @@ def set_part_number(element_id_list: List[ElementId], part_number: UnsignedInt) """ -def set_additional_data(element_id_list: List[ElementId], data_id: str, data_text: str) -> None: +def set_additional_data(element_id_list: list[ElementId], data_id: str, data_text: str) -> None: """Sets the element additional data. Parameters: @@ -93,7 +92,7 @@ def set_additional_data(element_id_list: List[ElementId], data_id: str, data_tex """ -def delete_additional_data(element_id_list: List[ElementId], data_id: str) -> None: +def delete_additional_data(element_id_list: list[ElementId], data_id: str) -> None: """Deletes the element additional data. Parameters: @@ -111,7 +110,7 @@ def set_user_attribute_name(number: UserAttributeId, user_attribute_name: str) - """ -def set_process_type_and_extended_settings_from_name(element_id_list: List[ElementId]) -> None: +def set_process_type_and_extended_settings_from_name(element_id_list: list[ElementId]) -> None: """Sets the element process type and extended settings from the element name. Parameters: @@ -137,7 +136,7 @@ def set_name_extended_settings(name: str, extended_settings: extended_settings) """ -def set_output_type(element_id_list: List[ElementId], process_type: process_type) -> None: +def set_output_type(element_id_list: list[ElementId], process_type: process_type) -> None: """Sets the element output type. Parameters: @@ -146,7 +145,7 @@ def set_output_type(element_id_list: List[ElementId], process_type: process_type """ -def set_extended_settings(element_id_list: List[ElementId], extended_settings: extended_settings) -> None: +def set_extended_settings(element_id_list: list[ElementId], extended_settings: extended_settings) -> None: """Sets the element extended settings. Parameters: @@ -155,7 +154,7 @@ def set_extended_settings(element_id_list: List[ElementId], extended_settings: e """ -def set_wall(element_id_list: List[ElementId]) -> None: +def set_wall(element_id_list: list[ElementId]) -> None: """Sets the element to wall. Deprecated : @@ -166,7 +165,7 @@ def set_wall(element_id_list: List[ElementId]) -> None: """ -def set_floor(element_id_list: List[ElementId]) -> None: +def set_floor(element_id_list: list[ElementId]) -> None: """Set floor. Deprecated : @@ -177,7 +176,7 @@ def set_floor(element_id_list: List[ElementId]) -> None: """ -def set_opening(element_id_list: List[ElementId]) -> None: +def set_opening(element_id_list: list[ElementId]) -> None: """Sets the element to opening. Parameters: @@ -185,7 +184,7 @@ def set_opening(element_id_list: List[ElementId]) -> None: """ -def set_fastening_attribute(element_id_list: List[ElementId], value: str) -> None: +def set_fastening_attribute(element_id_list: list[ElementId], value: str) -> None: """Sets the element fastening attribute. Parameters: @@ -194,7 +193,7 @@ def set_fastening_attribute(element_id_list: List[ElementId], value: str) -> Non """ -def set_element_material(element_id_list: List[ElementId], material: MaterialId) -> None: +def set_element_material(element_id_list: list[ElementId], material: MaterialId) -> None: """Sets the element material. Parameters: @@ -203,7 +202,7 @@ def set_element_material(element_id_list: List[ElementId], material: MaterialId) """ -def set_assembly_number(element_id_list: List[ElementId], assembly_number: str) -> None: +def set_assembly_number(element_id_list: list[ElementId], assembly_number: str) -> None: """set assembly number. Parameters: @@ -212,7 +211,7 @@ def set_assembly_number(element_id_list: List[ElementId], assembly_number: str) """ -def set_list_quantity(element_id_list: List[ElementId], list_quantity: UnsignedInt) -> None: +def set_list_quantity(element_id_list: list[ElementId], list_quantity: UnsignedInt) -> None: """Set list quantity. Parameters: @@ -221,7 +220,7 @@ def set_list_quantity(element_id_list: List[ElementId], list_quantity: UnsignedI """ -def set_layer_settings(element_id_list: List[ElementId], layer_settings: layer_settings) -> None: +def set_layer_settings(element_id_list: list[ElementId], layer_settings: layer_settings) -> None: """Set layer settings. Parameters: @@ -230,7 +229,7 @@ def set_layer_settings(element_id_list: List[ElementId], layer_settings: layer_s """ -def set_ignore_in_vba_calculation(element_id_list: List[ElementId], ignore: bool) -> None: +def set_ignore_in_vba_calculation(element_id_list: list[ElementId], ignore: bool) -> None: """Sets if the element should be ignored in VBA Calculation. Parameters: @@ -244,7 +243,7 @@ def clear_errors() -> None: """ -def set_reference_wall_2dc(element_id_list: List[ElementId], _2dc_file_path: str) -> None: +def set_reference_wall_2dc(element_id_list: list[ElementId], _2dc_file_path: str) -> None: """Applies a new 2dc reference wall to an element. Parameters: @@ -261,7 +260,7 @@ def get_user_attribute_count() -> UnsignedInt: """ -def set_standard_part(element_id_list: List[ElementId]) -> None: +def set_standard_part(element_id_list: list[ElementId]) -> None: """Sets covers (wall,opening or floor) to standard part. Parameters: @@ -269,7 +268,7 @@ def set_standard_part(element_id_list: List[ElementId]) -> None: """ -def set_solid_wall(element_id_list: List[ElementId]) -> None: +def set_solid_wall(element_id_list: list[ElementId]) -> None: """Sets elements to solid wall. Parameters: @@ -277,7 +276,7 @@ def set_solid_wall(element_id_list: List[ElementId]) -> None: """ -def set_log_wall(element_id_list: List[ElementId]) -> None: +def set_log_wall(element_id_list: list[ElementId]) -> None: """Sets elements to log wall. Parameters: @@ -285,7 +284,7 @@ def set_log_wall(element_id_list: List[ElementId]) -> None: """ -def set_solid_floor(element_id_list: List[ElementId]) -> None: +def set_solid_floor(element_id_list: list[ElementId]) -> None: """Sets elements to solid floor. Parameters: @@ -293,7 +292,7 @@ def set_solid_floor(element_id_list: List[ElementId]) -> None: """ -def set_roof(element_id_list: List[ElementId]) -> None: +def set_roof(element_id_list: list[ElementId]) -> None: """Set roof. Deprecated : @@ -304,7 +303,7 @@ def set_roof(element_id_list: List[ElementId]) -> None: """ -def set_solid_roof(element_id_list: List[ElementId]) -> None: +def set_solid_roof(element_id_list: list[ElementId]) -> None: """Sets elements to solid roof cover. Parameters: @@ -323,7 +322,7 @@ def get_node_symbol(element_id: ElementId) -> node_symbol: """ -def set_node_symbol(element_id_list: List[ElementId], symbol: node_symbol) -> None: +def set_node_symbol(element_id_list: list[ElementId], symbol: node_symbol) -> None: """Set node symbol. Parameters: @@ -355,7 +354,7 @@ def update_auto_attribute() -> None: """ -def set_additional_guid(element_id_list: List[ElementId], data_id: str, guid: str) -> None: +def set_additional_guid(element_id_list: list[ElementId], data_id: str, guid: str) -> None: """Set additional guid. Parameters: @@ -406,7 +405,7 @@ def add_item_to_user_attribute_list(attribute_number: UserAttributeId, item: str """ -def set_container_number(element_id_list: List[ElementId], number: UnsignedInt) -> None: +def set_container_number(element_id_list: list[ElementId], number: UnsignedInt) -> None: """Set container number. Parameters: @@ -415,7 +414,7 @@ def set_container_number(element_id_list: List[ElementId], number: UnsignedInt) """ -def get_name_list_items() -> List[str]: +def get_name_list_items() -> list[str]: """Retrieve a list of name for all items Returns: @@ -671,7 +670,7 @@ def set_attribute_display_settings_for_solid_wall_panel(settings: attribute_disp """ -def set_framed_floor(element_id_list: List[ElementId]) -> None: +def set_framed_floor(element_id_list: list[ElementId]) -> None: """Sets the elements to framed floor. Parameters: @@ -679,7 +678,7 @@ def set_framed_floor(element_id_list: List[ElementId]) -> None: """ -def set_framed_roof(element_id_list: List[ElementId]) -> None: +def set_framed_roof(element_id_list: list[ElementId]) -> None: """Sets the elements to framed roof. Parameters: @@ -687,7 +686,7 @@ def set_framed_roof(element_id_list: List[ElementId]) -> None: """ -def set_framed_wall(element_id_list: List[ElementId]) -> None: +def set_framed_wall(element_id_list: list[ElementId]) -> None: """Sets the element to framed wall. Parameters: @@ -695,7 +694,7 @@ def set_framed_wall(element_id_list: List[ElementId]) -> None: """ -def get_name_list_items_by_element_type(element_type: element_type) -> List[str]: +def get_name_list_items_by_element_type(element_type: element_type) -> list[str]: """Get name list items by element type. Parameters: @@ -1326,7 +1325,7 @@ def get_additional_guid(element_id: ElementId, data_id: str) -> str: """ -def get_prefab_layer_all_assigned(element_id: ElementId) -> List[int]: +def get_prefab_layer_all_assigned(element_id: ElementId) -> list[int]: """Get all assigned prefab layers. Parameters: @@ -1337,7 +1336,7 @@ def get_prefab_layer_all_assigned(element_id: ElementId) -> List[int]: """ -def get_prefab_layer_with_dimensions(element_id: ElementId) -> List[int]: +def get_prefab_layer_with_dimensions(element_id: ElementId) -> list[int]: """Get prefab layer with dimensions. Parameters: @@ -1348,7 +1347,7 @@ def get_prefab_layer_with_dimensions(element_id: ElementId) -> List[int]: """ -def get_prefab_layer_without_dimensions(element_id: ElementId) -> List[int]: +def get_prefab_layer_without_dimensions(element_id: ElementId) -> list[int]: """Get prefab layer without dimensions. Parameters: @@ -1403,7 +1402,7 @@ def get_container_number_with_prefix(element_id: ElementId) -> str: """ -def get_group_list_items() -> List[str]: +def get_group_list_items() -> list[str]: """Get group list items. Returns: @@ -1411,7 +1410,7 @@ def get_group_list_items() -> List[str]: """ -def get_subgroup_list_items() -> List[str]: +def get_subgroup_list_items() -> list[str]: """Get subgroup list items. Returns: @@ -1419,7 +1418,7 @@ def get_subgroup_list_items() -> List[str]: """ -def get_comment_list_items() -> List[str]: +def get_comment_list_items() -> list[str]: """Get comment list items. Returns: @@ -1427,7 +1426,7 @@ def get_comment_list_items() -> List[str]: """ -def get_sku_list_items() -> List[str]: +def get_sku_list_items() -> list[str]: """Get sku list items. Returns: @@ -1435,7 +1434,7 @@ def get_sku_list_items() -> List[str]: """ -def get_user_attribute_list_items(element_id: ElementId) -> List[str]: +def get_user_attribute_list_items(element_id: ElementId) -> list[str]: """Get user attribute list items. Parameters: @@ -1760,7 +1759,7 @@ def set_attribute_visibility_in_modify_window(number: UnsignedInt, visibility: b """ -def set_cutting_set(element_id_list: List[ElementId], cutting_set_name: str) -> bool: +def set_cutting_set(element_id_list: list[ElementId], cutting_set_name: str) -> bool: """Set cutting set. Parameters: @@ -1783,7 +1782,7 @@ def get_standard_element_material_id(element_id: ElementId) -> int: """ -def set_machine_calculation_set(element_ids: List[ElementId], name: str) -> bool: +def set_machine_calculation_set(element_ids: list[ElementId], name: str) -> bool: """Set machine calculation set for a list of elements. Note: diff --git a/src/attribute_controller/py.typed b/src/attribute_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/bim_controller/__init__.pyi b/src/bim_controller/__init__.pyi index 3a2f864..723a8f8 100644 --- a/src/bim_controller/__init__.pyi +++ b/src/bim_controller/__init__.pyi @@ -1,4 +1,3 @@ -from typing import List from cadwork.ifc_2x3_element_type import ifc_2x3_element_type from cadwork.ifc_options import ifc_options from cadwork.ifc_predefined_type import ifc_predefined_type @@ -43,7 +42,7 @@ def get_ifc2x3_element_type(element_id: ElementId) -> ifc_2x3_element_type: """ -def set_ifc2x3_element_type(element_id_list: List[ElementId], ifc_type: ifc_2x3_element_type) -> None: +def set_ifc2x3_element_type(element_id_list: list[ElementId], ifc_type: ifc_2x3_element_type) -> None: """Set ifc2x3 element type. Parameters: @@ -115,7 +114,7 @@ def export_bcf(file_path: str) -> bool: True if the export was successful, false otherwise. """ -def export_ifc(element_id_list: List[ElementId], file_path: str) -> bool: +def export_ifc(element_id_list: list[ElementId], file_path: str) -> bool: """Export IFC file. Parameters: @@ -136,7 +135,7 @@ def export_ifc(element_id_list: List[ElementId], file_path: str) -> bool: True if the export was successful, false otherwise. """ -def import_ifc_return_exchange_objects(file_path: str) -> List[ElementId]: +def import_ifc_return_exchange_objects(file_path: str) -> list[ElementId]: """Imports an IFC File and returns the ids of the Exchange Objects. Parameters: @@ -163,7 +162,7 @@ def set_storey_height(building: str, storey: str, height: float) -> None: >>> bc.set_storey_height(building_name, storey_name, height_millimeters) """ -def convert_exchange_objects(exchange_objects: List[ElementId]) -> List[ElementId]: +def convert_exchange_objects(exchange_objects: list[ElementId]) -> list[ElementId]: """Converts a list of Exchange Objects to Cadwork Elements. Parameters: @@ -173,7 +172,7 @@ def convert_exchange_objects(exchange_objects: List[ElementId]) -> List[ElementI The list of Cadwork Element ids. """ -def export_ifc2x3_silently(element_id_list: List[ElementId], file_path: str) -> bool: +def export_ifc2x3_silently(element_id_list: list[ElementId], file_path: str) -> bool: """Export IFC2x3 silently. Parameters: @@ -184,7 +183,7 @@ def export_ifc2x3_silently(element_id_list: List[ElementId], file_path: str) -> True if the export was successful, false otherwise. """ -def export_ifc4_silently(element_id_list: List[ElementId], file_path: str) -> bool: +def export_ifc4_silently(element_id_list: list[ElementId], file_path: str) -> bool: """Exports IFC4 silently. Parameters: @@ -195,7 +194,7 @@ def export_ifc4_silently(element_id_list: List[ElementId], file_path: str) -> bo True if the export was successful, false otherwise. """ -def export_ifc2x3_silently_with_options(element_id_list: List[ElementId], file_path: str, options: ifc_options) -> bool: +def export_ifc2x3_silently_with_options(element_id_list: list[ElementId], file_path: str, options: ifc_options) -> bool: """Exports IFC2x3 silently with options. Parameters: @@ -207,7 +206,7 @@ def export_ifc2x3_silently_with_options(element_id_list: List[ElementId], file_p True if the export was successful, false otherwise. """ -def export_ifc4_silently_with_options(element_id_list: List[ElementId], file_path: str, options: ifc_options) -> bool: +def export_ifc4_silently_with_options(element_id_list: list[ElementId], file_path: str, options: ifc_options) -> bool: """Exports IFC4 silently with options. Parameters: @@ -219,14 +218,14 @@ def export_ifc4_silently_with_options(element_id_list: List[ElementId], file_pat True if the export was successful, false otherwise. """ -def update_bmt_structure_created_elements(element_id_list: List[ElementId]) -> None: +def update_bmt_structure_created_elements(element_id_list: list[ElementId]) -> None: """This function takes the specified elements and inserts them into the BMT structure and adds them to the active building and storey. Parameters: element_id_list: The list of element ids to be updated in the BMT structure. """ -def update_bmt_structure_building_storey(element_id_list: List[ElementId]) -> None: +def update_bmt_structure_building_storey(element_id_list: list[ElementId]) -> None: """This function takes the specified elements and inserts them into the BMT structure and adds them to the assigned Building and Storey. Parameters: @@ -240,7 +239,7 @@ def get_ifc_options() -> ifc_options: The IfcOptions object containing the current settings. """ -def set_building_and_storey(element_id_list: List[ElementId], building: str, storey: str) -> None: +def set_building_and_storey(element_id_list: list[ElementId], building: str, storey: str) -> None: """Set building and storey. Parameters: @@ -311,14 +310,14 @@ def get_ifc2x3_element_type_display_string(entity_type: ifc_2x3_element_type) -> The display string representation of the IFC2x3 element type. """ -def get_all_buildings() -> List[str]: +def get_all_buildings() -> list[str]: """Get all buildings. Returns: A list of all building. """ -def get_all_storeys(building: str) -> List[str]: +def get_all_storeys(building: str) -> list[str]: """Get all storeys. Parameters: @@ -360,7 +359,7 @@ def get_ifc_predefined_type(element_id: ElementId) -> 'ifc_predefined_type': """ -def set_ifc_predefined_type(element_id_list: List[ElementId], predefined_type: ifc_predefined_type) -> None: +def set_ifc_predefined_type(element_id_list: list[ElementId], predefined_type: ifc_predefined_type) -> None: """Set a predefined type to elements. Attention, if you change the PredefinedType of the elements, you are responsible for ensuring that valid types are set. Parameters: diff --git a/src/bim_controller/py.typed b/src/bim_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/cadwork/__init__.pyi b/src/cadwork/__init__.pyi index aef0f2d..6339dc0 100644 --- a/src/cadwork/__init__.pyi +++ b/src/cadwork/__init__.pyi @@ -1,136 +1,186 @@ -from cadwork.rgb_color import rgb_color -from .attribute_display_settings import attribute_display_settings -from .bim_team_upload_result import bim_team_upload_result -from .bim_team_upload_result_code import bim_team_upload_result_code -from .btl_version import btl_version -from .camera_data import camera_data -from .coordinate_system_data import coordinate_system_data -from .division_zone_direction import division_zone_direction -from .double_shoulder_options import double_shoulder_options -from .edge_list import edge_list -from .element_grouping_type import element_grouping_type -from .element_module_detail import element_module_detail -from .element_module_properties import element_module_properties -from .element_type import element_type -from .extended_settings import extended_settings -from .facet_list import facet_list -from .heel_shoulder_beam_geometry import heel_shoulder_beam_geometry -from .heel_shoulder_options import heel_shoulder_options -from .hundegger_machine_type import hundegger_machine_type -from .ifc_2x3_element_type import ifc_2x3_element_type -from .ifc_element_combine_behaviour import ifc_element_combine_behaviour -from .ifc_material_definition import ifc_material_definition -from .ifc_options import ifc_options -from .ifc_options_aggregation import ifc_options_aggregation -from .ifc_options_level_of_detail import ifc_options_level_of_detail -from .ifc_options_project_data import ifc_options_project_data -from .ifc_options_properties import ifc_options_properties -from .ifc_predefined_type import ifc_predefined_type -from .import_3dc_options import import_3dc_options -from .layer_settings import layer_settings -from .multi_layer_type import multi_layer_type -from .node_symbol import node_symbol -from .point_3d import point_3d -from .polygon_list import polygon_list -from .process_type import process_type -from .projection_type import projection_type -from .rhino_options import rhino_options -from .shortcut_key import shortcut_key -from .shortcut_key_modifier import shortcut_key_modifier -from .shoulder_beam_geometry import shoulder_beam_geometry -from .shoulder_drilling_orientation import shoulder_drilling_orientation -from .shoulder_options import shoulder_options -from .standard_element_type import standard_element_type -from .text_element_type import text_element_type -from .text_object_options import text_object_options -from .vertex_list import vertex_list -from .weinmann_mfb_version import weinmann_mfb_version -from .window_geometry import window_geometry -from .element_map_query import element_map_query -from .element_filter import element_filter -from .hit_result import hit_result -from .dimension_base_format import dimension_base_format -from .dxf_layer_format_type import dxf_layer_format_type -from .dxf_export_version import dxf_export_version -from .display_attribute import display_attribute -from typing import List +"""cadwork Python API type definitions. -# These assignments make each type accessible through both import styles: -# 1. Direct import: from cadwork import point_3d -# 2. Module access: import cadwork; cadwork.point_3d(...) -# Without these assignments, the classes would be imported but not exposed as callable attributes -# of the cadwork module, resulting in "not callable" errors/warnings when using the module access style. +This module re-exports all cadwork data types, enumerations, and utility classes. -attribute_display_settings = attribute_display_settings -bim_team_upload_result = bim_team_upload_result -bim_team_upload_result_code = bim_team_upload_result_code -btl_version = btl_version -camera_data = camera_data -coordinate_system_data = coordinate_system_data -division_zone_direction = division_zone_direction -double_shoulder_options = double_shoulder_options -edge_list = edge_list -element_grouping_type = element_grouping_type -element_module_detail = element_module_detail -element_module_properties = element_module_properties -element_type = element_type -extended_settings = extended_settings -facet_list = facet_list -heel_shoulder_beam_geometry = heel_shoulder_beam_geometry -heel_shoulder_options = heel_shoulder_options -hundegger_machine_type = hundegger_machine_type -ifc_2x3_element_type = ifc_2x3_element_type -ifc_element_combine_behaviour = ifc_element_combine_behaviour -ifc_material_definition = ifc_material_definition -ifc_options = ifc_options -ifc_options_aggregation = ifc_options_aggregation -ifc_options_level_of_detail = ifc_options_level_of_detail -ifc_options_project_data = ifc_options_project_data -ifc_options_properties = ifc_options_properties -ifc_predefined_type = ifc_predefined_type -import_3dc_options = import_3dc_options -layer_settings = layer_settings -multi_layer_type = multi_layer_type -node_symbol = node_symbol -point_3d = point_3d -polygon_list = polygon_list -process_type = process_type -projection_type = projection_type -rhino_options = rhino_options -shortcut_key = shortcut_key -shortcut_key_modifier = shortcut_key_modifier -shoulder_beam_geometry = shoulder_beam_geometry -shoulder_drilling_orientation = shoulder_drilling_orientation -shoulder_options = shoulder_options -standard_element_type = standard_element_type -text_element_type = text_element_type -text_object_options = text_object_options -vertex_list = vertex_list -weinmann_mfb_version = weinmann_mfb_version -window_geometry = window_geometry -element_map_query = element_map_query -element_filter = element_filter -hit_result = hit_result -dimension_base_format = dimension_base_format -dxf_layer_format_type = dxf_layer_format_type -dxf_export_version = dxf_export_version -rgb_color = rgb_color -display_attribute = display_attribute +Usage:: + from cadwork import point_3d, element_type, rgb_color -def get_auto_attribute_elements() -> List[int]: - """Get ontly the elements of the selected types in the attribute manager dialog. All other elements will - get an empty attribute value. - - Returns: - List[int]: element IDs + # or + import cadwork + p = cadwork.point_3d(0.0, 0.0, 0.0) """ +# --- Type aliases --- +from .api_types import AxisId as AxisId +from .api_types import ColorId as ColorId +from .api_types import ElementId as ElementId +from .api_types import EndtypeId as EndtypeId +from .api_types import MaterialId as MaterialId +from .api_types import MenuIndex as MenuIndex +from .api_types import MultiLayerSetId as MultiLayerSetId +from .api_types import ReferenceSide as ReferenceSide +from .api_types import UnsignedInt as UnsignedInt +from .api_types import UserAttributeId as UserAttributeId + +# --- Data classes --- +from .active_point_result import active_point_result as active_point_result +from .attribute_display_settings import attribute_display_settings as attribute_display_settings +from .bim_team_upload_result import bim_team_upload_result as bim_team_upload_result +from .camera_data import camera_data as camera_data +from .coordinate_system_data import coordinate_system_data as coordinate_system_data +from .double_shoulder_options import double_shoulder_options as double_shoulder_options +from .edge_list import edge_list as edge_list +from .element_filter import element_filter as element_filter +from .element_map_query import element_map_query as element_map_query +from .element_module_detail import element_module_detail as element_module_detail +from .element_module_properties import element_module_properties as element_module_properties +from .extended_settings import extended_settings as extended_settings +from .facet_list import facet_list as facet_list +from .heel_shoulder_beam_geometry import heel_shoulder_beam_geometry as heel_shoulder_beam_geometry +from .heel_shoulder_options import heel_shoulder_options as heel_shoulder_options +from .hit_result import hit_result as hit_result +from .ifc_material_definition import ifc_material_definition as ifc_material_definition +from .ifc_options import ifc_options as ifc_options +from .ifc_options_aggregation import ifc_options_aggregation as ifc_options_aggregation +from .ifc_options_level_of_detail import ifc_options_level_of_detail as ifc_options_level_of_detail +from .ifc_options_project_data import ifc_options_project_data as ifc_options_project_data +from .ifc_options_properties import ifc_options_properties as ifc_options_properties +from .import_3dc_options import import_3dc_options as import_3dc_options +from .layer_settings import layer_settings as layer_settings +from .point import point as point +from .point_3d import point_3d as point_3d +from .polygon_list import polygon_list as polygon_list +from .rhino_options import rhino_options as rhino_options +from .rgb_color import rgb_color as rgb_color +from .shoulder_beam_geometry import shoulder_beam_geometry as shoulder_beam_geometry +from .shoulder_options import shoulder_options as shoulder_options +from .text_object_options import text_object_options as text_object_options +from .vertex_list import vertex_list as vertex_list +from .window_geometry import window_geometry as window_geometry + +# --- Enumerations --- +from .bim_team_upload_result_code import bim_team_upload_result_code as bim_team_upload_result_code +from .btl_version import btl_version as btl_version +from .dimension_base_format import dimension_base_format as dimension_base_format +from .display_attribute import display_attribute as display_attribute +from .division_zone_direction import division_zone_direction as division_zone_direction +from .dxf_export_version import dxf_export_version as dxf_export_version +from .dxf_layer_format_type import dxf_layer_format_type as dxf_layer_format_type +from .element_grouping_type import element_grouping_type as element_grouping_type +from .element_type import element_type as element_type +from .hundegger_machine_type import hundegger_machine_type as hundegger_machine_type +from .ifc_2x3_element_type import ifc_2x3_element_type as ifc_2x3_element_type +from .ifc_element_combine_behaviour import ifc_element_combine_behaviour as ifc_element_combine_behaviour +from .ifc_predefined_type import ifc_predefined_type as ifc_predefined_type +from .multi_layer_cover_type import multi_layer_cover_type as multi_layer_cover_type +from .multi_layer_subtype import multi_layer_subtype as multi_layer_subtype +from .multi_layer_type import multi_layer_type as multi_layer_type +from .node_symbol import node_symbol as node_symbol +from .process_type import process_type as process_type +from .projection_type import projection_type as projection_type +from .shortcut_key import shortcut_key as shortcut_key +from .shortcut_key_modifier import shortcut_key_modifier as shortcut_key_modifier +from .shoulder_drilling_orientation import shoulder_drilling_orientation as shoulder_drilling_orientation +from .standard_element_type import standard_element_type as standard_element_type +from .text_element_type import text_element_type as text_element_type +from .vba_catalog_item_type import vba_catalog_item_type as vba_catalog_item_type +from .weinmann_mfb_version import weinmann_mfb_version as weinmann_mfb_version + +__all__ = [ + # Type aliases + "AxisId", + "ColorId", + "ElementId", + "EndtypeId", + "MaterialId", + "MenuIndex", + "MultiLayerSetId", + "ReferenceSide", + "UnsignedInt", + "UserAttributeId", + # Data classes + "active_point_result", + "attribute_display_settings", + "bim_team_upload_result", + "camera_data", + "coordinate_system_data", + "double_shoulder_options", + "edge_list", + "element_filter", + "element_map_query", + "element_module_detail", + "element_module_properties", + "extended_settings", + "facet_list", + "heel_shoulder_beam_geometry", + "heel_shoulder_options", + "hit_result", + "ifc_material_definition", + "ifc_options", + "ifc_options_aggregation", + "ifc_options_level_of_detail", + "ifc_options_project_data", + "ifc_options_properties", + "import_3dc_options", + "layer_settings", + "point", + "point_3d", + "polygon_list", + "rhino_options", + "rgb_color", + "shoulder_beam_geometry", + "shoulder_options", + "text_object_options", + "vertex_list", + "window_geometry", + # Enumerations + "bim_team_upload_result_code", + "btl_version", + "dimension_base_format", + "display_attribute", + "division_zone_direction", + "dxf_export_version", + "dxf_layer_format_type", + "element_grouping_type", + "element_type", + "hundegger_machine_type", + "ifc_2x3_element_type", + "ifc_element_combine_behaviour", + "ifc_predefined_type", + "multi_layer_cover_type", + "multi_layer_subtype", + "multi_layer_type", + "node_symbol", + "process_type", + "projection_type", + "shortcut_key", + "shortcut_key_modifier", + "shoulder_drilling_orientation", + "standard_element_type", + "text_element_type", + "vba_catalog_item_type", + "weinmann_mfb_version", + # Module-level functions + "get_auto_attribute_elements", + "set_auto_attribute", +] + + +def get_auto_attribute_elements() -> list[int]: + """Get only the elements of the selected types in the attribute manager dialog. + + All other elements will get an empty attribute value. + + Returns: + list[int]: element IDs + """ + -def set_auto_attribute(elements: List[int], value: str) -> None: - """Set the auto attribute to the selected element types. +def set_auto_attribute(elements: list[int], value: str) -> None: + """Set the auto attribute to the selected element types. - Args: - elements (List[int]): element IDs - value (str): attribute + Parameters: + elements: element IDs + value: attribute value """ diff --git a/src/cadwork/active_point_result.pyi b/src/cadwork/active_point_result.pyi new file mode 100644 index 0000000..a97b157 --- /dev/null +++ b/src/cadwork/active_point_result.pyi @@ -0,0 +1,17 @@ +from dataclasses import dataclass +from cadwork.point_3d import point_3d + +@dataclass(frozen=True) +class active_point_result: + """Result of an active point query. + + Attributes: + has_point: Whether a valid point was found. + point: The point coordinates, or None if no point was found. + """ + + has_point: bool + point: point_3d | None = None + + def __bool__(self) -> bool: + """Returns True if a valid point was found.""" diff --git a/src/cadwork/api_types.pyi b/src/cadwork/api_types.pyi index 7e1d19d..19531d6 100644 --- a/src/cadwork/api_types.pyi +++ b/src/cadwork/api_types.pyi @@ -1,22 +1,25 @@ -from typing import Annotated +from typing import TypeAlias -UnsignedInt = Annotated[int, "Must be >= 0"] -"""""" -MaterialId = Annotated[int, "Must be >= 0"] -"""""" -ColorId = Annotated[int, "Must be >= 0"] -"""""" -EndtypeId = Annotated[int, "Must be >= 0"] -"""""" -AxisId = Annotated[int, "Must be >= 0"] -"""""" -MenuIndex = Annotated[int, "Normal int"] -"""""" -ReferenceSide = Annotated[int, "Must be >= 0"] -"""""" -MultiLayerSetId = Annotated[int, "Must be >= 0"] -"""""" -UserAttributeId = Annotated[int, "Must be >= 0"] -"""""" -ElementId = Annotated[int, "Must be >= 0"] -"""""" \ No newline at end of file +UnsignedInt: TypeAlias = int +MaterialId: TypeAlias = int +ColorId: TypeAlias = int +EndtypeId: TypeAlias = int +AxisId: TypeAlias = int +MenuIndex: TypeAlias = int +ReferenceSide: TypeAlias = int +MultiLayerSetId: TypeAlias = int +UserAttributeId: TypeAlias = int +ElementId: TypeAlias = int + +__all__ = [ + "UnsignedInt", + "MaterialId", + "ColorId", + "EndtypeId", + "AxisId", + "MenuIndex", + "ReferenceSide", + "MultiLayerSetId", + "UserAttributeId", + "ElementId", +] diff --git a/src/cadwork/hit_result.pyi b/src/cadwork/hit_result.pyi index ab4918d..1272559 100644 --- a/src/cadwork/hit_result.pyi +++ b/src/cadwork/hit_result.pyi @@ -1,22 +1,21 @@ -from typing import List -from cadwork import point_3d +from cadwork.point_3d import point_3d class hit_result: - def get_hit_element_ids(self) -> List[int]: - """get hit element ids + def get_hit_element_ids(self) -> list[int]: + """Get hit element IDs. Returns: - List[int] + list[int]: element IDs that were hit. """ - def get_hit_vertices_by_element(self, element_id: int) -> List[point_3d]: - """get hit vertices by element + def get_hit_vertices_by_element(self, element_id: int) -> list[point_3d]: + """Get hit vertices for a specific element. Parameters: - element_id: element_id + element_id: The element ID. Returns: - List[point_3d] + list[point_3d]: vertices hit on the element. """ diff --git a/src/cadwork/ifc_options.pyi b/src/cadwork/ifc_options.pyi index 471d5d2..18ec643 100644 --- a/src/cadwork/ifc_options.pyi +++ b/src/cadwork/ifc_options.pyi @@ -1,35 +1,35 @@ -from cadwork import ifc_options_aggregation -from cadwork import ifc_options_level_of_detail -from cadwork import ifc_options_project_data -from cadwork import ifc_options_properties +from cadwork.ifc_options_aggregation import ifc_options_aggregation +from cadwork.ifc_options_level_of_detail import ifc_options_level_of_detail +from cadwork.ifc_options_project_data import ifc_options_project_data +from cadwork.ifc_options_properties import ifc_options_properties + class ifc_options: - - def get_ifc_options_properties(self) -> 'ifc_options_properties': - """get ifc options properties + + def get_ifc_options_properties(self) -> ifc_options_properties: + """Get IFC options properties. Returns: - 'ifc_options_properties' + ifc_options_properties: The IFC properties options. """ - def get_ifc_options_project_data(self) -> 'ifc_options_project_data': - """get ifc options project data + def get_ifc_options_project_data(self) -> ifc_options_project_data: + """Get IFC options project data. Returns: - 'ifc_options_project_data' + ifc_options_project_data: The IFC project data options. """ - def get_ifc_options_aggregation(self) -> 'ifc_options_aggregation': - """get ifc options aggregation + def get_ifc_options_aggregation(self) -> ifc_options_aggregation: + """Get IFC options aggregation. Returns: - 'ifc_options_aggregation' + ifc_options_aggregation: The IFC aggregation options. """ - def get_ifc_options_level_of_detail(self) -> 'ifc_options_level_of_detail': - """get ifc options level of detail + def get_ifc_options_level_of_detail(self) -> ifc_options_level_of_detail: + """Get IFC options level of detail. Returns: - 'ifc_options_level_of_detail' + ifc_options_level_of_detail: The IFC level of detail options. """ - diff --git a/src/cadwork/py.typed b/src/cadwork/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/cadwork/rgb_color.pyi b/src/cadwork/rgb_color.pyi new file mode 100644 index 0000000..cadba6e --- /dev/null +++ b/src/cadwork/rgb_color.pyi @@ -0,0 +1,21 @@ +class rgb_color: + """RGB color representation. + + Attributes: + r: Red component (0-255). + g: Green component (0-255). + b: Blue component (0-255). + """ + + r: int + g: int + b: int + + def __init__(self, r: int, g: int, b: int) -> None: + """Initialize an RGB color. + + Parameters: + r: Red component (0-255). + g: Green component (0-255). + b: Blue component (0-255). + """ diff --git a/src/connector_axis_controller/__init__.pyi b/src/connector_axis_controller/__init__.pyi index 9208955..5146280 100644 --- a/src/connector_axis_controller/__init__.pyi +++ b/src/connector_axis_controller/__init__.pyi @@ -1,4 +1,3 @@ -from typing import List from cadwork.point_3d import point_3d from cadwork.api_types import * from cadwork.vba_catalog_item_type import vba_catalog_item_type @@ -69,7 +68,7 @@ def clear_errors() -> None: """ -def update_axis_cutting_ability(axis_id_list: List[ElementId]) -> None: +def update_axis_cutting_ability(axis_id_list: list[ElementId]) -> None: """Updates the Connection Config (CuttingAbility) of Axis/VBAs. Parameters: @@ -189,7 +188,7 @@ def get_section_diameter(axis_id: ElementId, section_index: UnsignedInt) -> floa """ -def get_axis_items_guids(axis_id: ElementId) -> List[str]: +def get_axis_items_guids(axis_id: ElementId) -> list[str]: """Returns a list of GUIDs of all axis items. Parameters: @@ -323,7 +322,7 @@ def get_bolt_diameter(axis_id: ElementId) -> float: The bolt diameter. """ -def get_standard_connector_list() -> List[str]: +def get_standard_connector_list() -> list[str]: """Returns a list of all standard connectors. Returns: @@ -441,7 +440,7 @@ def get_intersection_count(intersection_index: UnsignedInt) -> int: The intersection count. """ -def get_item_guids_at_intersection(axis_id: ElementId, intersection_index: UnsignedInt) -> List[str]: +def get_item_guids_at_intersection(axis_id: ElementId, intersection_index: UnsignedInt) -> list[str]: """Get item GUIDs at intersection. Parameters: @@ -453,7 +452,7 @@ def get_item_guids_at_intersection(axis_id: ElementId, intersection_index: Unsig """ -def set_item_guids_at_intersection(axis_id: ElementId, intersection_index: UnsignedInt, item_guids: List[str]) -> None: +def set_item_guids_at_intersection(axis_id: ElementId, intersection_index: UnsignedInt, item_guids: list[str]) -> None: """Sets item GUIDs at intersection. Parameters: diff --git a/src/connector_axis_controller/py.typed b/src/connector_axis_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/dimension_controller/__init__.pyi b/src/dimension_controller/__init__.pyi index f802513..c276360 100644 --- a/src/dimension_controller/__init__.pyi +++ b/src/dimension_controller/__init__.pyi @@ -1,9 +1,8 @@ -from typing import List from cadwork.point_3d import point_3d from cadwork.dimension_base_format import dimension_base_format from cadwork.api_types import * -def create_dimension(xl: point_3d, plane_normal: point_3d, distance: point_3d, dimension_points: List[point_3d]) -> ElementId: +def create_dimension(xl: point_3d, plane_normal: point_3d, distance: point_3d, dimension_points: list[point_3d]) -> ElementId: """Creates a dimension element to measure distances on 3D parts. The dimension is drawn on a plane defined by its normal and offset distance. Points added to the dimension are projected @@ -40,7 +39,7 @@ def create_dimension(xl: point_3d, plane_normal: point_3d, distance: point_3d, d The element id of the created dimension element. """ -def set_orientation(element_id_list: List[ElementId], view_dir: point_3d, view_dir_up: point_3d) -> None: +def set_orientation(element_id_list: list[ElementId], view_dir: point_3d, view_dir_up: point_3d) -> None: """Sets the orientation of dimension elements. Parameters: @@ -59,7 +58,7 @@ def add_segment(element_id: ElementId, segment: point_3d) -> None: segment: The point to add to the dimension (despite the parameter name, this is a point, not a segment). """ -def set_precision(element_id_list: List[ElementId], precision: UnsignedInt) -> None: +def set_precision(element_id_list: list[ElementId], precision: UnsignedInt) -> None: """Sets the precision/decimal places of a dimension element. Parameters: @@ -67,7 +66,7 @@ def set_precision(element_id_list: List[ElementId], precision: UnsignedInt) -> N precision: The precision/decimal places to set. """ -def set_text_size(element_id_list: List[ElementId], text_size: float) -> None: +def set_text_size(element_id_list: list[ElementId], text_size: float) -> None: """Sets the text size of a dimension element. Parameters: @@ -75,7 +74,7 @@ def set_text_size(element_id_list: List[ElementId], text_size: float) -> None: text_size: The text size to set. """ -def set_line_thickness(element_id_list: List[ElementId], thickness: float) -> None: +def set_line_thickness(element_id_list: list[ElementId], thickness: float) -> None: """Sets the line thickness of a dimension element. Parameters: @@ -83,7 +82,7 @@ def set_line_thickness(element_id_list: List[ElementId], thickness: float) -> No thickness: The line thickness to set. """ -def set_total_dimension(element_id_list: List[ElementId], total: bool) -> None: +def set_total_dimension(element_id_list: list[ElementId], total: bool) -> None: """Set whether the visualisation of the overall dimension is set for a dimension element. Parameters: @@ -91,7 +90,7 @@ def set_total_dimension(element_id_list: List[ElementId], total: bool) -> None: total: True if the visualisation is set, false otherwise. """ -def set_text_color(element_id_list: List[ElementId], color_id: ColorId) -> None: +def set_text_color(element_id_list: list[ElementId], color_id: ColorId) -> None: """Sets the text color of a dimension element. Parameters: @@ -99,7 +98,7 @@ def set_text_color(element_id_list: List[ElementId], color_id: ColorId) -> None: color_id: The color id to set. """ -def set_line_color(element_id_list: List[ElementId], color_id: ColorId) -> None: +def set_line_color(element_id_list: list[ElementId], color_id: ColorId) -> None: """Sets the line color of a dimension element. Parameters: @@ -107,7 +106,7 @@ def set_line_color(element_id_list: List[ElementId], color_id: ColorId) -> None: color_id: The color id to set. """ -def set_default_anchor_length(element_id_list: List[ElementId], length: float) -> None: +def set_default_anchor_length(element_id_list: list[ElementId], length: float) -> None: """Sets the default anchor length of a dimension element. Parameters: @@ -115,7 +114,7 @@ def set_default_anchor_length(element_id_list: List[ElementId], length: float) - length: The default anchor length to set. """ -def set_distance(element_id_list: List[ElementId], distance: point_3d) -> None: +def set_distance(element_id_list: list[ElementId], distance: point_3d) -> None: """Sets the distance vector between the points and the line. Parameters: @@ -123,7 +122,7 @@ def set_distance(element_id_list: List[ElementId], distance: point_3d) -> None: distance: The distance vector to set. """ -def shift_distance_and_texts(element_id_list: List[ElementId], shifted: bool) -> None: +def shift_distance_and_texts(element_id_list: list[ElementId], shifted: bool) -> None: """Sets if distance and texts are shifted. Parameters: @@ -131,7 +130,7 @@ def shift_distance_and_texts(element_id_list: List[ElementId], shifted: bool) -> shifted: True if distance and texts are shifted, false otherwise. """ -def get_dimension_points(element_id: ElementId) -> List[point_3d]: +def get_dimension_points(element_id: ElementId) -> list[point_3d]: """Gets all dimension points ordered by dimension direction. Parameters: diff --git a/src/dimension_controller/py.typed b/src/dimension_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/element_controller/__init__.pyi b/src/element_controller/__init__.pyi index ba88b37..83d0038 100644 --- a/src/element_controller/__init__.pyi +++ b/src/element_controller/__init__.pyi @@ -1,4 +1,3 @@ -from typing import List, Dict from cadwork.edge_list import edge_list from cadwork.element_module_properties import element_module_properties from cadwork.facet_list import facet_list @@ -16,21 +15,21 @@ from cadwork.heel_shoulder_options import heel_shoulder_options from cadwork.double_shoulder_options import double_shoulder_options from cadwork.api_types import * -def delete_elements(element_id_list: List[ElementId]) -> None: +def delete_elements(element_id_list: list[ElementId]) -> None: """Deletes the specified elements. Parameters: element_id_list: The element id list. """ -def join_elements(element_id_list: List[ElementId]) -> None: +def join_elements(element_id_list: list[ElementId]) -> None: """Joins the specified elements together. Parameters: element_id_list: The element id list. """ -def join_top_level_elements(element_id_list: List[ElementId]) -> None: +def join_top_level_elements(element_id_list: list[ElementId]) -> None: """Joins the specified top-level elements together. Parameters: @@ -310,7 +309,7 @@ def create_node(node_position: point_3d) -> ElementId: The ID of the created node. """ -def solder_elements(element_id_list: List[ElementId]) -> List[ElementId]: +def solder_elements(element_id_list: list[ElementId]) -> list[ElementId]: """Solders elements together. Parameters: @@ -320,35 +319,35 @@ def solder_elements(element_id_list: List[ElementId]) -> List[ElementId]: The list of soldered element IDs. """ -def convert_beam_to_panel(element_id_list: List[ElementId]) -> None: +def convert_beam_to_panel(element_id_list: list[ElementId]) -> None: """Converts beams to panels. Parameters: element_id_list: The element id list. """ -def convert_panel_to_beam(element_id_list: List[ElementId]) -> None: +def convert_panel_to_beam(element_id_list: list[ElementId]) -> None: """Converts panels to beams. Parameters: element_id_list: The element id list. """ -def delete_all_element_end_types(element_id_list: List[ElementId]) -> None: +def delete_all_element_end_types(element_id_list: list[ElementId]) -> None: """Deletes all end types of the elements. Parameters: element_id_list: The element id list. """ -def delete_all_element_processes(element_id_list: List[ElementId]) -> None: +def delete_all_element_processes(element_id_list: list[ElementId]) -> None: """Deletes all processes of the elements. Parameters: element_id_list: The element id list. """ -def move_element(element_id_list: List[ElementId], move_vector: point_3d) -> None: +def move_element(element_id_list: list[ElementId], move_vector: point_3d) -> None: """Moves the provided element by a specified vector. Parameters: @@ -403,7 +402,7 @@ def create_text_object(text: str, position: point_3d, x_local_direction: point_3 The ID of the created text object. """ -def copy_elements(element_id_list: List[ElementId], copy_vector: point_3d) -> List[int]: +def copy_elements(element_id_list: list[ElementId], copy_vector: point_3d) -> list[int]: """Copy a list of elements. Parameters: @@ -414,7 +413,7 @@ def copy_elements(element_id_list: List[ElementId], copy_vector: point_3d) -> Li The IDs of the copied elements. """ -def rotate_elements(element_id_list: List[ElementId], origin: point_3d, rotation_axis: point_3d, rotation_angle: float) -> None: +def rotate_elements(element_id_list: list[ElementId], origin: point_3d, rotation_axis: point_3d, rotation_angle: float) -> None: """Rotate the provided elements around a specified axis. Parameters: @@ -424,7 +423,7 @@ def rotate_elements(element_id_list: List[ElementId], origin: point_3d, rotation rotation_angle: The angle by which to rotate the elements un degree. """ -def subtract_elements(hard_elements: List[ElementId], soft_elements: List[ElementId]) -> List[ElementId]: +def subtract_elements(hard_elements: list[ElementId], soft_elements: list[ElementId]) -> list[ElementId]: """Subtracts a list of "soft" elements from a list of "hard" elements. Parameters: @@ -445,7 +444,7 @@ def check_element_id(element_id: ElementId) -> bool: True if the element ID exists, false otherwise. """ -def start_element_module_calculation(covers: List[ElementId]) -> None: +def start_element_module_calculation(covers: list[ElementId]) -> None: """Starts the calculation of the element module for a list of covers. Parameters: @@ -469,7 +468,7 @@ def get_element_from_cadwork_guid(cadwork_guid: str) -> ElementId: The element ID. """ -def add_elements_to_undo(element_id_list: List[ElementId], cmd: int) -> None: +def add_elements_to_undo(element_id_list: list[ElementId], cmd: int) -> None: """Add elements to the undo stack. Parameters: @@ -485,28 +484,28 @@ def make_redo() -> None: """Performs a redo operation, reapplying the last undone change. """ -def split_elements(element_id_list: List[ElementId]) -> None: +def split_elements(element_id_list: list[ElementId]) -> None: """Splits elements. Parameters: element_id_list: The elements to split. """ -def set_line_to_marking_line(element_id_list: List[ElementId]) -> None: +def set_line_to_marking_line(element_id_list: list[ElementId]) -> None: """Sets the line to the marking line. Parameters: element_id_list: The elements to modify. """ -def set_line_to_normal_line(element_id_list: List[ElementId]) -> None: +def set_line_to_normal_line(element_id_list: list[ElementId]) -> None: """Sets the line to the normal line. Parameters: element_id_list: The elements to modify. """ -def create_auto_export_solid_from_standard(element_id_list: List[ElementId], output_name: str, standard_element_name: str) -> ElementId: +def create_auto_export_solid_from_standard(element_id_list: list[ElementId], output_name: str, standard_element_name: str) -> ElementId: """Creates an auto export solid from a standard element. Parameters: @@ -518,7 +517,7 @@ def create_auto_export_solid_from_standard(element_id_list: List[ElementId], out The element ID of the created solid. """ -def set_element_module_properties_for_elements(element_id_list: List[ElementId], properties: element_module_properties) -> None: +def set_element_module_properties_for_elements(element_id_list: list[ElementId], properties: element_module_properties) -> None: """Sets the element module properties for elements. Parameters: @@ -550,7 +549,7 @@ def create_text_object_with_font(text: str, position: point_3d, x_local_directio The element ID of the created text object. """ -def apply_transformation_coordinate(element_id_list: List[ElementId], old_point: point_3d, old_x_local_direction: point_3d, old_y_local_direction: point_3d, new_point: point_3d, new_x_local_direction: point_3d, new_y_local_direction: point_3d) -> None: +def apply_transformation_coordinate(element_id_list: list[ElementId], old_point: point_3d, old_x_local_direction: point_3d, old_y_local_direction: point_3d, new_point: point_3d, new_x_local_direction: point_3d, new_y_local_direction: point_3d) -> None: """Apply transformation coordinate to elements. Parameters: @@ -563,49 +562,49 @@ def apply_transformation_coordinate(element_id_list: List[ElementId], old_point: new_y_local_direction: The new Y local direction. """ -def delete_elements_with_undo(element_id_list: List[ElementId]) -> None: +def delete_elements_with_undo(element_id_list: list[ElementId]) -> None: """Deletes the provided elements with undo functionality. Parameters: element_id_list: The elements to delete. """ -def add_created_elements_to_undo(element_id_list: List[ElementId]) -> None: +def add_created_elements_to_undo(element_id_list: list[ElementId]) -> None: """Adds created elements to the undo stack. Parameters: element_id_list: The elements to add. """ -def add_modified_elements_to_undo(element_id_list: List[ElementId]) -> None: +def add_modified_elements_to_undo(element_id_list: list[ElementId]) -> None: """Adds modified elements to the undo stack. Parameters: element_id_list: The elements to add. """ -def recreate_elements(element_id_list: List[ElementId]) -> None: +def recreate_elements(element_id_list: list[ElementId]) -> None: """Recreate elements based on the provided list. Parameters: element_id_list: The elements to recreate. """ -def create_multi_wall(element_id_list: List[ElementId]) -> None: +def create_multi_wall(element_id_list: list[ElementId]) -> None: """Creates a multi-wall structure. Parameters: element_id_list: The elements to use in the multi-wall structure. """ -def get_user_element_ids() -> List[ElementId]: +def get_user_element_ids() -> list[ElementId]: """Gets a list of user element IDs. Returns: The user element IDs. """ -def get_user_element_ids_with_existing(element_id_list: List[ElementId]) -> List[ElementId]: +def get_user_element_ids_with_existing(element_id_list: list[ElementId]) -> list[ElementId]: """Retrieve a list of user element IDs that exist in the provided list. Parameters: @@ -619,7 +618,7 @@ def clear_errors() -> None: """Clears all errors. """ -def glide_elements(element_id_list: List[ElementId], glide_origin_point: point_3d) -> None: +def glide_elements(element_id_list: list[ElementId], glide_origin_point: point_3d) -> None: """Glides elements to a specified point. Parameters: @@ -667,7 +666,7 @@ def cut_element_with_plane(element_id: ElementId, cut_plane_normal_vector: point True if the cut operation was successful, false otherwise. """ -def create_circular_mep(diameter: float, points: List[point_3d]) -> ElementId: +def create_circular_mep(diameter: float, points: list[point_3d]) -> ElementId: """Create a circular MEP (Mechanical, Electrical, and Plumbing) element. Parameters: @@ -678,7 +677,7 @@ def create_circular_mep(diameter: float, points: List[point_3d]) -> ElementId: The ID of the created circular MEP element. """ -def create_rectangular_mep(width: float, depth: float, points: List[point_3d]) -> ElementId: +def create_rectangular_mep(width: float, depth: float, points: list[point_3d]) -> ElementId: """Create a rectangular MEP (Mechanical, Electrical, and Plumbing) element. Parameters: @@ -727,7 +726,7 @@ def slice_element_with_plane(element_id: ElementId, cut_plane_normal_vector: poi True if the slicing operation was successful, false otherwise. """ -def create_auto_container_from_standard(element_id_list: List[ElementId], output_name: str, standard_element_name: str) -> ElementId: +def create_auto_container_from_standard(element_id_list: list[ElementId], output_name: str, standard_element_name: str) -> ElementId: """Create an auto container from a standard element. Parameters: @@ -739,7 +738,7 @@ def create_auto_container_from_standard(element_id_list: List[ElementId], output The id of the created auto container element. """ -def create_auto_export_solid_from_standard_with_reference(element_id_list: List[ElementId], output_name: str, standard_element_name: str, reference_id: ElementId) -> ElementId: +def create_auto_export_solid_from_standard_with_reference(element_id_list: list[ElementId], output_name: str, standard_element_name: str, reference_id: ElementId) -> ElementId: """Creates an auto export solid from a standard element with a reference. Parameters: @@ -752,7 +751,7 @@ def create_auto_export_solid_from_standard_with_reference(element_id_list: List[ The id of the created auto export solid element. """ -def create_auto_container_from_standard_with_reference(element_id_list: List[ElementId], output_name: str, standard_element_name: str, reference_id: ElementId) -> ElementId: +def create_auto_container_from_standard_with_reference(element_id_list: list[ElementId], output_name: str, standard_element_name: str, reference_id: ElementId) -> ElementId: """Creates an auto container from a standard element with a reference. Parameters: @@ -785,7 +784,7 @@ def create_surface(surface_vertices: vertex_list) -> ElementId: The ID of the created surface element. """ -def stretch_start_facet(element_id_list: List[ElementId], stretch_vector: point_3d) -> None: +def stretch_start_facet(element_id_list: list[ElementId], stretch_vector: point_3d) -> None: """Stretch the start facet of the given elements. Parameters: @@ -793,7 +792,7 @@ def stretch_start_facet(element_id_list: List[ElementId], stretch_vector: point_ stretch_vector: A vector that defines the stretch direction and distance. """ -def stretch_end_facet(element_id_list: List[ElementId], stretch_vector: point_3d) -> None: +def stretch_end_facet(element_id_list: list[ElementId], stretch_vector: point_3d) -> None: """Stretch the end facet of the given elements. Parameters: @@ -801,7 +800,7 @@ def stretch_end_facet(element_id_list: List[ElementId], stretch_vector: point_3d stretch_vector: A vector that defines the stretch direction and distance. """ -def set_export_solid_contents(export_solid_id: ElementId, element_id_list: List[ElementId]) -> None: +def set_export_solid_contents(export_solid_id: ElementId, element_id_list: list[ElementId]) -> None: """Sets the contents of an export solid. Parameters: @@ -809,7 +808,7 @@ def set_export_solid_contents(export_solid_id: ElementId, element_id_list: List[ element_id_list: The list of element IDs to set as the contents of the export solid. """ -def set_container_contents(container_id: ElementId, element_id_list: List[ElementId]) -> None: +def set_container_contents(container_id: ElementId, element_id_list: list[ElementId]) -> None: """Sets the contents of a container. Parameters: @@ -817,7 +816,7 @@ def set_container_contents(container_id: ElementId, element_id_list: List[Elemen element_id_list: The list of element IDs to set as the contents of the container. """ -def set_parent_opening_variants_opening_angle(element_id_list: List[ElementId], angle: float) -> None: +def set_parent_opening_variants_opening_angle(element_id_list: list[ElementId], angle: float) -> None: """Sets the opening angle of the parent opening variants. Parameters: @@ -825,7 +824,7 @@ def set_parent_opening_variants_opening_angle(element_id_list: List[ElementId], angle: The opening angle to set. """ -def mirror_move_elements(element_id_list: List[ElementId], plane: point_3d, plane_distance: float) -> None: +def mirror_move_elements(element_id_list: list[ElementId], plane: point_3d, plane_distance: float) -> None: """Mirrors and moves elements across a plane. Parameters: @@ -834,7 +833,7 @@ def mirror_move_elements(element_id_list: List[ElementId], plane: point_3d, plan plane_distance: The distance from the plane. """ -def mirror_copy_elements(element_id_list: List[ElementId], plane: point_3d, plane_distance: float) -> List[ElementId]: +def mirror_copy_elements(element_id_list: list[ElementId], plane: point_3d, plane_distance: float) -> list[ElementId]: """Copies elements by mirroring them across a plane. Parameters: @@ -989,7 +988,7 @@ def create_standard_steel_vectors(standard_element_name: str, length: float, sta The id of the created standard steel element. """ -def move_element_with_undo(element_id_list: List[ElementId], vector: point_3d) -> None: +def move_element_with_undo(element_id_list: list[ElementId], vector: point_3d) -> None: """Moves an element with undo functionality. Parameters: @@ -1031,7 +1030,7 @@ def create_normal_axis_vectors(length: float, starting_point: point_3d, axis_dir The id of the created normal axis. """ -def convert_bolt_to_standardconnector(element_id_list: List[ElementId], standard_element_name: str) -> None: +def convert_bolt_to_standardconnector(element_id_list: list[ElementId], standard_element_name: str) -> None: """Converts bolts to standard connectors. Parameters: @@ -1072,14 +1071,14 @@ def extrude_surface_to_beam_vector(surface: ElementId, vector: point_3d) -> Elem The id of the created beam element. """ -def convert_container_to_container_block(element_id_list: List[ElementId]) -> None: +def convert_container_to_container_block(element_id_list: list[ElementId]) -> None: """Converts a container to a container block. Parameters: element_id_list: The list of elements to convert. """ -def create_bounding_box_local(reference_element: ElementId, element_id_list: List[ElementId]) -> ElementId: +def create_bounding_box_local(reference_element: ElementId, element_id_list: list[ElementId]) -> ElementId: """Creates a local bounding box for a list of elements relative to a reference element. Parameters: @@ -1090,7 +1089,7 @@ def create_bounding_box_local(reference_element: ElementId, element_id_list: Lis The ID of the created bounding box element. """ -def create_bounding_box_global(element_id_list: List[ElementId]) -> ElementId: +def create_bounding_box_global(element_id_list: list[ElementId]) -> ElementId: """Creates a global bounding box for a list of elements. Parameters: @@ -1100,28 +1099,28 @@ def create_bounding_box_global(element_id_list: List[ElementId]) -> ElementId: The ID of the created bounding box element. """ -def convert_auxiliary_to_panel(element_id_list: List[ElementId]) -> None: +def convert_auxiliary_to_panel(element_id_list: list[ElementId]) -> None: """Converts auxiliary elements to panel. Parameters: element_id_list: The list of elements to convert. """ -def convert_auxiliary_to_beam(element_id_list: List[ElementId]) -> None: +def convert_auxiliary_to_beam(element_id_list: list[ElementId]) -> None: """Converts auxiliary elements to beams. Parameters: element_id_list: The list of elements to convert. """ -def auto_set_rough_volume_situation(element_id_list: List[ElementId]) -> None: +def auto_set_rough_volume_situation(element_id_list: list[ElementId]) -> None: """Automatically sets the rough volume situation for a list of elements. Parameters: element_id_list: The list of elements to process. """ -def rough_volume_situation_manual(cover: ElementId, add_partner: List[ElementId], remove_partner: List[ElementId]) -> None: +def rough_volume_situation_manual(cover: ElementId, add_partner: list[ElementId], remove_partner: list[ElementId]) -> None: """Manually sets the rough volume situation for a cover element. Parameters: @@ -1130,14 +1129,14 @@ def rough_volume_situation_manual(cover: ElementId, add_partner: List[ElementId] remove_partner: The list of partner element IDs to remove. """ -def auto_set_parts_situation(element_id_list: List[ElementId]) -> None: +def auto_set_parts_situation(element_id_list: list[ElementId]) -> None: """Automatically sets the parts situation for a list of elements. Parameters: element_id_list: The list of elements to process. """ -def parts_situation_manual(cover: ElementId, add_childs: List[ElementId], remove_childs: List[ElementId]) -> None: +def parts_situation_manual(cover: ElementId, add_childs: list[ElementId], remove_childs: list[ElementId]) -> None: """Manually sets the parts situation for a cover element. Parameters: @@ -1146,21 +1145,21 @@ def parts_situation_manual(cover: ElementId, add_childs: List[ElementId], remove remove_childs: The list of child element IDs to remove. """ -def activate_rv_without_situation() -> List[ElementId]: +def activate_rv_without_situation() -> list[ElementId]: """Activates the rough volume situation for elements without a situation. Returns: The list of IDs of the elements for which the rough volume situation was activated. """ -def activate_parts_without_situation() -> List[ElementId]: +def activate_parts_without_situation() -> list[ElementId]: """Activates the parts situation for elements without a situation. Returns: The list of IDs of the elements for which the parts situation was activated. """ -def add_elements_to_detail(element_id_list: List[ElementId], detail: int) -> None: +def add_elements_to_detail(element_id_list: list[ElementId], detail: int) -> None: """Adds elements to a detail. Parameters: @@ -1168,7 +1167,7 @@ def add_elements_to_detail(element_id_list: List[ElementId], detail: int) -> Non detail: The ID of the detail. """ -def subtract_elements_with_undo(hard_element_id_list: List[ElementId], soft_element_id_list: List[ElementId], with_undo: bool) -> List[ElementId]: +def subtract_elements_with_undo(hard_element_id_list: list[ElementId], soft_element_id_list: list[ElementId], with_undo: bool) -> list[ElementId]: """Subtracts a list of "soft" elements from a list of "hard" elements with undo functionality. Parameters: @@ -1180,7 +1179,7 @@ def subtract_elements_with_undo(hard_element_id_list: List[ElementId], soft_elem The list of elements resulting from the subtraction. """ -def create_linear_optimization(element_id_list: List[ElementId], optimization_number: int, total_length: float, start_cut: float, end_cut: float, saw_kerf: float, is_production_list: bool) -> ElementId: +def create_linear_optimization(element_id_list: list[ElementId], optimization_number: int, total_length: float, start_cut: float, end_cut: float, saw_kerf: float, is_production_list: bool) -> ElementId: """create linear optimization Parameters: @@ -1196,14 +1195,14 @@ def create_linear_optimization(element_id_list: List[ElementId], optimization_nu The ID of the created linear optimization element. """ -def start_element_module_calculation_silently(covers: List[ElementId]) -> None: +def start_element_module_calculation_silently(covers: list[ElementId]) -> None: """Starts the calculation of the element module for a list of covers silently (without user interaction). Parameters: covers: The list of covers for which to start the element module calculation. """ -def replace_physical_drillings_with_drilling_axes(element_id_list: List[ElementId], mininum_diameter: float, maximum_diameter: float) -> List[ElementId]: +def replace_physical_drillings_with_drilling_axes(element_id_list: list[ElementId], mininum_diameter: float, maximum_diameter: float) -> list[ElementId]: """Replaces physical drillings with drilling axes based on diameter range. Parameters: @@ -1223,7 +1222,7 @@ def cut_element_with_processing_group(soft_element: ElementId, processing: Eleme processing: The ID of the processing group. """ -def add_element_to_detail(element_id_list: List[ElementId], detail: int) -> None: +def add_element_to_detail(element_id_list: list[ElementId], detail: int) -> None: """Adds elements to a detail. Parameters: @@ -1231,7 +1230,7 @@ def add_element_to_detail(element_id_list: List[ElementId], detail: int) -> None detail: The ID of the detail. """ -def convert_elements_to_auxiliary_elements(element_id_list: List[ElementId]) -> None: +def convert_elements_to_auxiliary_elements(element_id_list: list[ElementId]) -> None: """Converts elements to auxiliary elements. Parameters: @@ -1305,7 +1304,7 @@ def create_polygon_panel(polygon_vertices: vertex_list, thickness: float, x_loca The ID of the created polygon panel element. """ -def cut_elements_with_overmeasure(hard_element_id_list: List[ElementId], soft_element_id_list: List[ElementId]) -> None: +def cut_elements_with_overmeasure(hard_element_id_list: list[ElementId], soft_element_id_list: list[ElementId]) -> None: """Cuts elements with overmeasure. Parameters: @@ -1313,7 +1312,7 @@ def cut_elements_with_overmeasure(hard_element_id_list: List[ElementId], soft_el soft_element_id_list: The list of soft elements. """ -def cut_log_corner_joint(settings_name: str, element_id_list: List[ElementId]) -> None: +def cut_log_corner_joint(settings_name: str, element_id_list: list[ElementId]) -> None: """Cuts log corner joint. Parameters: @@ -1321,7 +1320,7 @@ def cut_log_corner_joint(settings_name: str, element_id_list: List[ElementId]) - element_id_list: The list of elements to be cut. """ -def get_edge_selection(element_id_list: List[ElementId]) -> edge_list: +def get_edge_selection(element_id_list: list[ElementId]) -> edge_list: """Retrieves the edge selection of the provided elements. Parameters: @@ -1331,7 +1330,7 @@ def get_edge_selection(element_id_list: List[ElementId]) -> edge_list: The list of edges selected. """ -def get_facets_with_lasso(element_id_list: List[ElementId]) -> facet_list: +def get_facets_with_lasso(element_id_list: list[ElementId]) -> facet_list: """Retrieves the facets of elements within a lasso selection. Parameters: @@ -1388,14 +1387,14 @@ def chamfer_edge(element_id: ElementId, edge_start: point_3d, edge_end: point_3d length: The length of the chamfer. """ -def convert_drilling_to_circular_beam(element_id_list: List[ElementId]) -> None: +def convert_drilling_to_circular_beam(element_id_list: list[ElementId]) -> None: """Converts drilling to circular beam. Parameters: element_id_list: The list of element IDs to convert. """ -def convert_lines_to_surfaces(element_id_list: List[ElementId]) -> List[ElementId]: +def convert_lines_to_surfaces(element_id_list: list[ElementId]) -> list[ElementId]: """Converts lines to surfaces. Parameters: @@ -1405,7 +1404,7 @@ def convert_lines_to_surfaces(element_id_list: List[ElementId]) -> List[ElementI The list of element IDs that were converted. """ -def convert_surfaces_to_volume(element_id_list: List[ElementId]) -> ElementId: +def convert_surfaces_to_volume(element_id_list: list[ElementId]) -> ElementId: """Converts surfaces to volume. Parameters: @@ -1415,7 +1414,7 @@ def convert_surfaces_to_volume(element_id_list: List[ElementId]) -> ElementId: The ID of the created volume element. """ -def cut_corner_lap(element_id_list: List[ElementId], depth: float, clearance_base: float, clearance_side: float, backcut: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: +def cut_corner_lap(element_id_list: list[ElementId], depth: float, clearance_base: float, clearance_side: float, backcut: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: """Cuts a corner-lap joint with specific parameters. Parameters: @@ -1429,7 +1428,7 @@ def cut_corner_lap(element_id_list: List[ElementId], depth: float, clearance_bas drilling_tolerance: The tolerance applied to the hole size for bolt head clearance or easier insertion. """ -def cut_t_lap(element_id_list: List[ElementId], depth: float, clearance_base: float, clearance_side: float, backcut: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: +def cut_t_lap(element_id_list: list[ElementId], depth: float, clearance_base: float, clearance_side: float, backcut: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: """Cuts a T-lap joint with specific parameters. Parameters: @@ -1443,7 +1442,7 @@ def cut_t_lap(element_id_list: List[ElementId], depth: float, clearance_base: fl drilling_tolerance: The tolerance applied to the hole size for bolt head clearance or easier insertion. """ -def cut_cross_lap(element_id_list: List[ElementId], depth: float, clearance_base: float, clearance_side: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: +def cut_cross_lap(element_id_list: list[ElementId], depth: float, clearance_base: float, clearance_side: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: """Cuts a cross-lap joint with specific parameters. Parameters: @@ -1456,7 +1455,7 @@ def cut_cross_lap(element_id_list: List[ElementId], depth: float, clearance_base drilling_tolerance: The tolerance applied to the hole size for bolt head clearance or easier insertion. """ -def delete_processes_keep_cutting_bodies(element_id_list: List[ElementId], keep_cutting_elements_only: bool) -> List[ElementId]: +def delete_processes_keep_cutting_bodies(element_id_list: list[ElementId], keep_cutting_elements_only: bool) -> list[ElementId]: """Gets the cutting bodies of all processes (and deletes processes), like Ctrl+D Action Parameters: @@ -1467,7 +1466,7 @@ def delete_processes_keep_cutting_bodies(element_id_list: List[ElementId], keep_ The id list of all removed geometry, cuttings bodies. """ -def cut_double_tenon(element_id_list: List[ElementId], depth1: float, depth2: float, clearance: float, backcut: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: +def cut_double_tenon(element_id_list: list[ElementId], depth1: float, depth2: float, clearance: float, backcut: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: """Cut a double tenon joint with specific parameters. Parameters: @@ -1492,7 +1491,7 @@ def get_coordinate_system_data_nesting_child(nesting_parent_id: ElementId, nesti A global element coordinate-system of the nested child element consisting of a Point1, a Point2 and a Point3. You can get the local placement by subtracting the parent coordinate - system with child coordinate - system. """ -def cut_half_lap(element_id_list: List[ElementId], length: float, clearance_length: float, clearance_depth: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: +def cut_half_lap(element_id_list: list[ElementId], length: float, clearance_length: float, clearance_depth: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: """Cut a half-lap joint with specific parameters. Parameters: @@ -1505,7 +1504,7 @@ def cut_half_lap(element_id_list: List[ElementId], length: float, clearance_leng drilling_tolerance: The tolerance applied to the hole size for bolt head clearance or easier insertion. """ -def cut_simple_scarf(element_id_list: List[ElementId], length: float, depth: float, clearance_length: float, clearance_depth: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: +def cut_simple_scarf(element_id_list: list[ElementId], length: float, depth: float, clearance_length: float, clearance_depth: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: """Cut a simple scarf joint with specific parameters. Parameters: @@ -1519,7 +1518,7 @@ def cut_simple_scarf(element_id_list: List[ElementId], length: float, depth: flo drilling_tolerance: The tolerance applied to the hole size, typically for fitting the bolt head or allowing easier assembly. """ -def cut_diagonal_cut(element_id_list: List[ElementId], length: float, clearance_length: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: +def cut_diagonal_cut(element_id_list: list[ElementId], length: float, clearance_length: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: """Cut a diagonal cut joint with specific parameters. Parameters: @@ -1531,42 +1530,42 @@ def cut_diagonal_cut(element_id_list: List[ElementId], length: float, clearance_ drilling_tolerance: The tolerance applied to the hole size for bolt head clearance or easier insertion. """ -def get_all_identifiable_element_ids() -> List[ElementId]: +def get_all_identifiable_element_ids() -> list[ElementId]: """Retrieves a list of all identifiable elements. Returns: A list of all identifiable element IDs. """ -def get_visible_identifiable_element_ids() -> List[ElementId]: +def get_visible_identifiable_element_ids() -> list[ElementId]: """Get a list of all visible identifiable elements. Returns: A list of IDs of all visible identifiable elements. """ -def get_invisible_identifiable_element_ids() -> List[ElementId]: +def get_invisible_identifiable_element_ids() -> list[ElementId]: """Get a list of all invisible identifiable elements. Returns: A list of IDs of all invisible identifiable elements. """ -def get_active_identifiable_element_ids() -> List[ElementId]: +def get_active_identifiable_element_ids() -> list[ElementId]: """Get a list of all active identifiable elements. Returns: A list of IDs of all active identifiable elements. """ -def get_inactive_all_identifiable_element_ids() -> List[ElementId]: +def get_inactive_all_identifiable_element_ids() -> list[ElementId]: """Get a list of all inactive identifiable elements. Returns: A list of IDs of all inactive identifiable elements. """ -def get_inactive_visible_identifiable_element_ids() -> List[ElementId]: +def get_inactive_visible_identifiable_element_ids() -> list[ElementId]: """Get a list of all inactive visible identifiable elements. Returns: @@ -1606,7 +1605,7 @@ def get_element_contact_facets(first_id: ElementId, second_id: ElementId) -> fac The list of contact facets between the two elements. """ -def get_element_raw_interface_vertices(first_id: ElementId, second_id: ElementId) -> List[point_3d]: +def get_element_raw_interface_vertices(first_id: ElementId, second_id: ElementId) -> list[point_3d]: """Get the raw interface vertices between two elements. Parameters: @@ -1617,35 +1616,35 @@ def get_element_raw_interface_vertices(first_id: ElementId, second_id: ElementId The list of raw interface vertices between the two elements. """ -def get_standard_export_solid_list() -> List[str]: +def get_standard_export_solid_list() -> list[str]: """Retrieves a list of standard export solid names. Returns: The list of standard export solid names. """ -def get_standard_container_list() -> List[str]: +def get_standard_container_list() -> list[str]: """Retrieves a list of standard container names. Returns: The list of standard container names. """ -def get_standard_beam_list() -> List[str]: +def get_standard_beam_list() -> list[str]: """Retrieves a list of standard beam names. Returns: The list of standard beam names. """ -def get_standard_panel_list() -> List[str]: +def get_standard_panel_list() -> list[str]: """Retrieves a list of standard panel names. Returns: The list of standard panel names. """ -def get_variant_sibling_element_ids(element_id: ElementId) -> List[ElementId]: +def get_variant_sibling_element_ids(element_id: ElementId) -> list[ElementId]: """Retrieves a list of variant sibling element IDs. Parameters: @@ -1665,7 +1664,7 @@ def get_reference_element(element_id: ElementId) -> ElementId: The reference element ID. """ -def get_element_contact_vertices(first_id: ElementId, second_id: ElementId) -> List[point_3d]: +def get_element_contact_vertices(first_id: ElementId, second_id: ElementId) -> list[point_3d]: """Get the contact vertices between two elements. Parameters: @@ -1728,7 +1727,7 @@ def get_element_type_description(element_id: ElementId) -> str: The type description of the element. """ -def get_opening_variant_ids(element_id_list: List[ElementId], opening_type: int) -> List[int]: +def get_opening_variant_ids(element_id_list: list[ElementId], opening_type: int) -> list[int]: """Get the opening variant IDs for a list of elements. Parameters: @@ -1749,7 +1748,7 @@ def get_parent_container_id(element_id: ElementId) -> ElementId: The ID of the parent element. """ -def get_export_solid_content_elements(element_id: ElementId) -> List[ElementId]: +def get_export_solid_content_elements(element_id: ElementId) -> list[ElementId]: """Get the content elements of an export solid. Parameters: @@ -1759,7 +1758,7 @@ def get_export_solid_content_elements(element_id: ElementId) -> List[ElementId]: The list of content elements. """ -def get_container_content_elements(element_id: ElementId) -> List[ElementId]: +def get_container_content_elements(element_id: ElementId) -> list[ElementId]: """Get the content elements of a container. Parameters: @@ -1786,7 +1785,7 @@ def get_element_cadwork_guid(element_id: ElementId) -> str: The Cadwork GUID of the element. """ -def get_bounding_box_vertices_local(reference_element: ElementId, element_id_list: List[ElementId]) -> List[point_3d]: +def get_bounding_box_vertices_local(reference_element: ElementId, element_id_list: list[ElementId]) -> list[point_3d]: """Retrieves the local bounding box vertices for a list of elements relative to a reference element. Parameters: @@ -1797,7 +1796,7 @@ def get_bounding_box_vertices_local(reference_element: ElementId, element_id_lis The list of vertices representing the local bounding box of the elements. """ -def get_bounding_box_vertices_global(element_id_list: List[ElementId]) -> List[point_3d]: +def get_bounding_box_vertices_global(element_id_list: list[ElementId]) -> list[point_3d]: """Get the global bounding box vertices for a list of elements. Parameters: @@ -1807,14 +1806,14 @@ def get_bounding_box_vertices_global(element_id_list: List[ElementId]) -> List[p The list of vertices representing the global bounding box of the elements. """ -def get_all_nesting_raw_parts() -> List[ElementId]: +def get_all_nesting_raw_parts() -> list[ElementId]: """Get a list of all raw parts in a nesting operation. Returns: The list of IDs of all raw parts in a nesting operation. """ -def get_joined_elements(element_id: ElementId) -> List[ElementId]: +def get_joined_elements(element_id: ElementId) -> list[ElementId]: """Retrieves the IDs of elements that have been joined with the specified element. Parameters: @@ -1824,7 +1823,7 @@ def get_joined_elements(element_id: ElementId) -> List[ElementId]: The list of IDs of the joined elements. """ -def check_element_duplicates(element_id_list: List[ElementId]) -> List[ElementId]: +def check_element_duplicates(element_id_list: list[ElementId]) -> list[ElementId]: """Checks for duplicate elements in the provided list. Parameters: @@ -1834,7 +1833,7 @@ def check_element_duplicates(element_id_list: List[ElementId]) -> List[ElementId The list of duplicate elements. """ -def get_elements_in_contact(element_id: ElementId) -> List[ElementId]: +def get_elements_in_contact(element_id: ElementId) -> list[ElementId]: """Retrieves a list of elements in contact with a specific element. Parameters: @@ -1868,7 +1867,7 @@ def create_text_object_with_options(position: point_3d, x_local_direction: point The ID of the created text object. """ -def convert_surfaces_to_roof_surfaces(element_id_list: List[ElementId], roof_name: str) -> None: +def convert_surfaces_to_roof_surfaces(element_id_list: list[ElementId], roof_name: str) -> None: """Converts surfaces to roof surfaces. Parameters: @@ -1921,7 +1920,7 @@ def remove_standard_export_solid(guid: str) -> None: guid: The unique identifier of the standard export solid to be removed. """ -def get_user_element_ids_with_count(count: int) -> List[ElementId]: +def get_user_element_ids_with_count(count: int) -> list[ElementId]: """Retrieves a list of user element IDs. Parameters: @@ -1931,7 +1930,7 @@ def get_user_element_ids_with_count(count: int) -> List[ElementId]: The list of user element IDs. """ -def cut_scarf_straight(element_id_list: List[ElementId], length: float, depth: float, clearance_length: float, clearance_depth: float, clearance_hook: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: +def cut_scarf_straight(element_id_list: list[ElementId], length: float, depth: float, clearance_length: float, clearance_depth: float, clearance_hook: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: """Cuts a straight scarf joint (lengthwise) with specific parameters. Parameters: @@ -1946,7 +1945,7 @@ def cut_scarf_straight(element_id_list: List[ElementId], length: float, depth: f drilling_tolerance: The tolerance added to the hole size for easier assembly or bolt head fitting. """ -def cut_scarf_diagonal(element_id_list: List[ElementId], length: float, depth: float, clearance_length: float, clearance_depth: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: +def cut_scarf_diagonal(element_id_list: list[ElementId], length: float, depth: float, clearance_length: float, clearance_depth: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: """Cuts a diagonal scarf joint (lengthwise) with specific parameters. Parameters: @@ -1960,7 +1959,7 @@ def cut_scarf_diagonal(element_id_list: List[ElementId], length: float, depth: f drilling_tolerance: Tolerance added to the hole diameter for ease of insertion or head fit. """ -def cut_scarf_with_wedge(element_id_list: List[ElementId], length: float, depth: float, clearance_length: float, clearance_depth: float, wedge_width: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: +def cut_scarf_with_wedge(element_id_list: list[ElementId], length: float, depth: float, clearance_length: float, clearance_depth: float, wedge_width: float, drilling_count: UnsignedInt, drilling_diameter: float, drilling_tolerance: float) -> None: """Cuts a diagonal scarf joint with an added wedge, using specific parameters. Parameters: @@ -1975,7 +1974,7 @@ def cut_scarf_with_wedge(element_id_list: List[ElementId], length: float, depth: drilling_tolerance: Tolerance applied to the hole size, often used for easier bolt fitting or head clearance. """ -def cut_beam_end_profile(element_id_list: List[ElementId], profile_name: str, on_start_face: bool, on_end_face: bool) -> None: +def cut_beam_end_profile(element_id_list: list[ElementId], profile_name: str, on_start_face: bool, on_end_face: bool) -> None: """Add end profile to beam elements. Parameters: @@ -2055,7 +2054,7 @@ def create_spline_line(spline_points: vertex_list) -> ElementId: The ID of the created spline. """ -def unjoin_elements(element_id_list: List[ElementId]) -> bool: +def unjoin_elements(element_id_list: list[ElementId]) -> bool: """Unjoins the specified elements. Parameters: @@ -2065,7 +2064,7 @@ def unjoin_elements(element_id_list: List[ElementId]) -> bool: True if the operation was successful, false if an error occured. """ -def unjoin_top_level_elements(element_id_list: List[ElementId]) -> bool: +def unjoin_top_level_elements(element_id_list: list[ElementId]) -> bool: """Unjoins the specified top-level elements. Parameters: @@ -2083,14 +2082,14 @@ def set_element_group_multi_select_mode() -> None: """Switches the current element group selection mode so that all elements of a group are selected when selecting one of it. """ -def convert_circular_beam_to_drilling(element_id_list: List[ElementId]) -> None: +def convert_circular_beam_to_drilling(element_id_list: list[ElementId]) -> None: """Converts circular beams to drillings. Parameters: element_id_list: The list of element IDs to convert. """ -def slice_elements_with_plane_and_get_new_elements(element_id: ElementId, cut_plane_normal_vector: point_3d, distance_from_global_origin: float) -> List[ElementId]: +def slice_elements_with_plane_and_get_new_elements(element_id: ElementId, cut_plane_normal_vector: point_3d, distance_from_global_origin: float) -> list[ElementId]: """Slices an element with a plane and returns the new elements. Parameters: @@ -2128,7 +2127,7 @@ def slice_elements_with_plane_and_get_new_elements(element_id: ElementId, cut_pl The list of IDs of the new elements created by the slicing operation. """ -def get_elements_in_collision(element_id: ElementId) -> List[ElementId]: +def get_elements_in_collision(element_id: ElementId) -> list[ElementId]: """Retrieves a list of elements in collision with a specific element. Parameters: @@ -2186,8 +2185,8 @@ def set_double_shoulder_options(options: double_shoulder_options) -> None: options: The double shoulder options to set. """ -def cut_shoulder(element_id_list: List[ElementId], connecting_element_id_list: - List[ElementId]) ->None: +def cut_shoulder(element_id_list: list[ElementId], connecting_element_id_list: + list[ElementId]) ->None: """Cuts shoulder with current 3D options. Parameters: @@ -2195,8 +2194,8 @@ def cut_shoulder(element_id_list: List[ElementId], connecting_element_id_list: connecting_element_id_list: The list of elements that intersect or connect with the cut elements, used to determine the cutting geometry. """ -def cut_heel_shoulder(element_id_list: List[ElementId], - connecting_element_id_list: List[ElementId]) ->None: +def cut_heel_shoulder(element_id_list: list[ElementId], + connecting_element_id_list: list[ElementId]) ->None: """Cuts heel with current 3D options Parameters: @@ -2204,8 +2203,8 @@ def cut_heel_shoulder(element_id_list: List[ElementId], connecting_element_id_list: The list of elements that intersect or connect with the cut elements, used to determine the cutting geometry. """ -def cut_double_shoulder(element_id_list: List[ElementId], - connecting_element_id_list: List[ElementId]) ->None: +def cut_double_shoulder(element_id_list: list[ElementId], + connecting_element_id_list: list[ElementId]) ->None: """Cuts a double shoulder joint using the current 3D cutting options. Parameters: @@ -2214,7 +2213,7 @@ def cut_double_shoulder(element_id_list: List[ElementId], """ -def filter_elements(element_id_list: List[ElementId], element_filter: element_filter) -> List[ElementId]: +def filter_elements(element_id_list: list[ElementId], element_filter: element_filter) -> list[ElementId]: """Filters a list of elements based on a provided filter. Parameters: @@ -2234,7 +2233,7 @@ def filter_elements(element_id_list: List[ElementId], element_filter: element_fi """ -def map_elements(element_id_list: List[ElementId], map_query: element_map_query) -> Dict[str, List[ElementId]]: +def map_elements(element_id_list: list[ElementId], map_query: element_map_query) -> dict[str, list[ElementId]]: """Maps a list of elements based on a provided map query. Parameters: @@ -2254,7 +2253,7 @@ def map_elements(element_id_list: List[ElementId], map_query: element_map_query) """ -def cast_ray_and_get_element_intersections(element_id_list: List[ElementId], ray_start_position: point_3d, +def cast_ray_and_get_element_intersections(element_id_list: list[ElementId], ray_start_position: point_3d, ray_end_position: point_3d, radius: float) -> hit_result: """Casts a ray through the 3D model and calculates all intersection points between the ray and specified elements. This function performs ray casting against each specified element to find intersection points.For each element hit by the ray, it returns the element ID and all points where the ray intersects with that element. The ray is defined by a start point, end point, and radius. diff --git a/src/element_controller/py.typed b/src/element_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/endtype_controller/__init__.pyi b/src/endtype_controller/__init__.pyi index 1fccb18..3013e8c 100644 --- a/src/endtype_controller/__init__.pyi +++ b/src/endtype_controller/__init__.pyi @@ -1,4 +1,3 @@ -from typing import List from cadwork.api_types import * def get_endtype_id(name: str) -> EndtypeId: @@ -299,7 +298,7 @@ def get_endtype_name_facet(element_id: ElementId, face_number: int) -> str: The endtype name of the face. """ -def get_existing_tenon_ids() -> List[EndtypeId]: +def get_existing_tenon_ids() -> list[EndtypeId]: """Get the existing tenon endtype id list. Examples: @@ -312,7 +311,7 @@ def get_existing_tenon_ids() -> List[EndtypeId]: List of existing tenon endtype id. """ -def get_existing_lengthening_ids() -> List[EndtypeId]: +def get_existing_lengthening_ids() -> list[EndtypeId]: """Get the existing lengthening endtype id list. Examples: @@ -325,7 +324,7 @@ def get_existing_lengthening_ids() -> List[EndtypeId]: List of existing lengthening endtype id. """ -def get_existing_dovetail_ids() -> List[EndtypeId]: +def get_existing_dovetail_ids() -> list[EndtypeId]: """Get the existing dovetail endtype id list. Examples: @@ -338,7 +337,7 @@ def get_existing_dovetail_ids() -> List[EndtypeId]: List of existing dovetail endtype id. """ -def get_existing_dovetail_dado_ids() -> List[EndtypeId]: +def get_existing_dovetail_dado_ids() -> list[EndtypeId]: """Get the existing dado endtype id list. Examples: @@ -351,7 +350,7 @@ def get_existing_dovetail_dado_ids() -> List[EndtypeId]: List of existing dado endtype id. """ -def get_existing_japanese_tenon_ids() -> List[EndtypeId]: +def get_existing_japanese_tenon_ids() -> list[EndtypeId]: """Get the existing japanese-tenon endtype id list. Examples: diff --git a/src/endtype_controller/py.typed b/src/endtype_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/file_controller/__init__.pyi b/src/file_controller/__init__.pyi index 5324d4a..ba7d6fe 100644 --- a/src/file_controller/__init__.pyi +++ b/src/file_controller/__init__.pyi @@ -1,4 +1,3 @@ -from typing import List from cadwork.import_3dc_options import import_3dc_options from cadwork.point_3d import point_3d from cadwork.bim_team_upload_result import bim_team_upload_result @@ -7,7 +6,7 @@ from cadwork.dxf_export_version import dxf_export_version from cadwork.display_attribute import display_attribute from cadwork.api_types import * -def export_stl_file(element_id_list: List[ElementId], file_path: str) -> None: +def export_stl_file(element_id_list: list[ElementId], file_path: str) -> None: """Exports an STL file. Parameters: @@ -24,7 +23,7 @@ def export_stl_file(element_id_list: List[ElementId], file_path: str) -> None: """ -def import_step_file(file_path: str, scale_factor: float) -> List[ElementId]: +def import_step_file(file_path: str, scale_factor: float) -> list[ElementId]: """Imports a STEP file. Parameters: @@ -36,7 +35,7 @@ def import_step_file(file_path: str, scale_factor: float) -> List[ElementId]: """ -def import_step_file_with_message_option(file_path: str, scale_factor: float, hide_message: bool) -> List[ElementId]: +def import_step_file_with_message_option(file_path: str, scale_factor: float, hide_message: bool) -> list[ElementId]: """Imports a STEP file with message option. Parameters: @@ -49,7 +48,7 @@ def import_step_file_with_message_option(file_path: str, scale_factor: float, hi """ -def export_webgl(element_id_list: List[ElementId], file_path: str) -> bool: +def export_webgl(element_id_list: list[ElementId], file_path: str) -> bool: """Exports a WebGL file. Parameters: @@ -71,7 +70,7 @@ def export_webgl(element_id_list: List[ElementId], file_path: str) -> bool: """ -def export_3d_file(element_id_list: List[ElementId], file_path: str) -> bool: +def export_3d_file(element_id_list: list[ElementId], file_path: str) -> bool: """Exports a 3D file. Parameters: @@ -93,7 +92,7 @@ def export_3d_file(element_id_list: List[ElementId], file_path: str) -> bool: """ -def import_sat_file(file_path: str, scale_factor: float, binary: bool) -> List[ElementId]: +def import_sat_file(file_path: str, scale_factor: float, binary: bool) -> list[ElementId]: """Imports an SAT file. Parameters: @@ -106,7 +105,7 @@ def import_sat_file(file_path: str, scale_factor: float, binary: bool) -> List[E """ -def import_3dc_file(file_path: str) -> List[ElementId]: +def import_3dc_file(file_path: str) -> list[ElementId]: """Imports a 3DC file. Parameters: @@ -117,7 +116,7 @@ def import_3dc_file(file_path: str) -> List[ElementId]: """ -def import_rhino_file(file_path: str, without_dialog: bool) -> List[ElementId]: +def import_rhino_file(file_path: str, without_dialog: bool) -> list[ElementId]: """Imports a Rhino file. Parameters: @@ -129,7 +128,7 @@ def import_rhino_file(file_path: str, without_dialog: bool) -> List[ElementId]: """ -def export_step_file(element_id_list: List[ElementId], file_path: str, scale_factor: float, version: int, +def export_step_file(element_id_list: list[ElementId], file_path: str, scale_factor: float, version: int, text_mode: bool) -> None: """Exports a STEP file. @@ -163,7 +162,7 @@ def import_3dz_file(file_path: str) -> None: """ -def export_obj_file(element_id_list: List[ElementId], file_path: str) -> None: +def export_obj_file(element_id_list: list[ElementId], file_path: str) -> None: """Exports a OBJ file. Parameters: @@ -180,7 +179,7 @@ def export_obj_file(element_id_list: List[ElementId], file_path: str) -> None: """ -def import_sat_file_silently(file_path: str, scale_factor: float, binary: bool) -> List[ElementId]: +def import_sat_file_silently(file_path: str, scale_factor: float, binary: bool) -> list[ElementId]: """Imports a SAT File without messages. Parameters: @@ -193,7 +192,7 @@ def import_sat_file_silently(file_path: str, scale_factor: float, binary: bool) """ -def export_fbx_file(element_id_list: List[ElementId], file_path: str, fbx_format: int) -> None: +def export_fbx_file(element_id_list: list[ElementId], file_path: str, fbx_format: int) -> None: """Exports a FBX file. Parameters: @@ -231,7 +230,7 @@ def clear_errors() -> None: """ -def import_3dc_file_with_glide(file_path: str) -> List[ElementId]: +def import_3dc_file_with_glide(file_path: str) -> list[ElementId]: """Imports a 3DC file with glide. Parameters: @@ -250,7 +249,7 @@ def import_btl_file(file_path: str) -> None: """ -def export_3dc_file(element_id_list: List[ElementId], file_path: str) -> None: +def export_3dc_file(element_id_list: list[ElementId], file_path: str) -> None: """Exports a 3D file. Parameters: @@ -289,7 +288,7 @@ def export_btl_file_for_nesting(file_path: str) -> None: """ -def export_rhino_file(element_id_list: List[ElementId], file_path: str, version: int, use_default_assignment: bool, +def export_rhino_file(element_id_list: list[ElementId], file_path: str, version: int, use_default_assignment: bool, write_standard_attributes: bool) -> None: """Exports a 3dm rhino file. @@ -319,7 +318,7 @@ def export_rhino_file(element_id_list: List[ElementId], file_path: str, version: """ -def import_bxf_file(file_path: str, insert_position: point_3d) -> List[ElementId]: +def import_bxf_file(file_path: str, insert_position: point_3d) -> list[ElementId]: """Imports a BXF file. Parameters: @@ -347,7 +346,7 @@ def set_blum_export_path(path: str) -> None: """ -def export_sat_file(element_id_list: List[ElementId], file_path: str, scale_factor: float, binary: bool, version: int) -> None: +def export_sat_file(element_id_list: list[ElementId], file_path: str, scale_factor: float, binary: bool, version: int) -> None: """Exports a SAT File. Parameters: @@ -375,7 +374,7 @@ def export_sat_file(element_id_list: List[ElementId], file_path: str, scale_fact """ -def export_glb_file(element_id_list: List[ElementId], file_path: str) -> None: +def export_glb_file(element_id_list: list[ElementId], file_path: str) -> None: """Exports a GLB File. Parameters: @@ -392,7 +391,7 @@ def export_glb_file(element_id_list: List[ElementId], file_path: str) -> None: """ -def import_variant_file(file_path: str, insert_position: point_3d) -> List[ElementId]: +def import_variant_file(file_path: str, insert_position: point_3d) -> list[ElementId]: """Imports a variant (.val-File). Parameters: @@ -416,7 +415,7 @@ def import_element_light(file_path: str, insert_position: point_3d) -> int: """ -def export_rhino_file_with_options(element_id_list: List[ElementId], file_path: str, version: int, +def export_rhino_file_with_options(element_id_list: list[ElementId], file_path: str, version: int, use_default_assignment: bool, write_standard_attributes: bool, rhino_options: None) -> None: """Exports elements to a rhino 3dm file based on the export options. @@ -449,7 +448,7 @@ def export_rhino_file_with_options(element_id_list: List[ElementId], file_path: """ -def import_3dc_file_with_options(file_path: str, import_3dc_options: import_3dc_options) -> List[ElementId]: +def import_3dc_file_with_options(file_path: str, import_3dc_options: import_3dc_options) -> list[ElementId]: """Imports a 3d or a 3dc file depending on the import options. Parameters: @@ -477,7 +476,7 @@ def load_webgl_preset_file(file_path: str) -> None: """ -def export_step_file_extrude_drillings(element_id_list: List[ElementId], file_path: str, scale_factor: float, version: int, +def export_step_file_extrude_drillings(element_id_list: list[ElementId], file_path: str, scale_factor: float, version: int, text_mode: bool, imperial_units: bool) -> None: """Exports a STEP file with extruded drillings. @@ -505,7 +504,7 @@ def export_step_file_extrude_drillings(element_id_list: List[ElementId], file_pa """ -def export_step_file_cut_drillings(element_id_list: List[ElementId], file_path: str, scale_factor: float, version: int, +def export_step_file_cut_drillings(element_id_list: list[ElementId], file_path: str, scale_factor: float, version: int, text_mode: bool, imperial_units: bool) -> None: """Exports a STEP file with extruded drillings. @@ -533,7 +532,7 @@ def export_step_file_cut_drillings(element_id_list: List[ElementId], file_path: """ -def export_sat_file_cut_drillings(element_id_list: List[ElementId], file_path: str, +def export_sat_file_cut_drillings(element_id_list: list[ElementId], file_path: str, scale_factor: float, binary: bool, version: int) -> None: """Exports a SAT File with extruded drillings (cut drilling holes into bodies). @@ -551,7 +550,7 @@ def export_sat_file_cut_drillings(element_id_list: List[ElementId], file_path: s """ -def upload_to_bim_team_and_create_share_link(element_id_list: List[ElementId]) -> bim_team_upload_result: +def upload_to_bim_team_and_create_share_link(element_id_list: list[ElementId]) -> bim_team_upload_result: """Exports the elements to BIMteam and creates a share link. Parameters: diff --git a/src/file_controller/py.typed b/src/file_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/geometry_controller/__init__.pyi b/src/geometry_controller/__init__.pyi index 35323b9..e81d50d 100644 --- a/src/geometry_controller/__init__.pyi +++ b/src/geometry_controller/__init__.pyi @@ -1,24 +1,23 @@ -from typing import List from cadwork.api_types import ElementId, UnsignedInt from cadwork.facet_list import facet_list from cadwork.point_3d import point_3d -def rotate_height_axis_90(element_id_list: List[ElementId]) -> None: +def rotate_height_axis_90(element_id_list: list[ElementId]) -> None: """Rotates the element height axis 90 degrees. Parameters: element_id_list: The element id list. """ -def rotate_height_axis_180(element_id_list: List[ElementId]) -> None: +def rotate_height_axis_180(element_id_list: list[ElementId]) -> None: """Rotates the element height axis 180 degrees. Parameters: element_id_list: The element id list. """ -def set_over_width(element_id_list: List[ElementId], value: float) -> None: +def set_over_width(element_id_list: list[ElementId], value: float) -> None: """Sets the element overwidth. Parameters: @@ -26,7 +25,7 @@ def set_over_width(element_id_list: List[ElementId], value: float) -> None: value: The element overwidth. """ -def set_over_height(element_id_list: List[ElementId], value: float) -> None: +def set_over_height(element_id_list: list[ElementId], value: float) -> None: """Sets the element overheight. Parameters: @@ -34,7 +33,7 @@ def set_over_height(element_id_list: List[ElementId], value: float) -> None: value: The element overheight. """ -def set_over_length(element_id_list: List[ElementId], value: float) -> None: +def set_over_length(element_id_list: list[ElementId], value: float) -> None: """Sets the element overlength. Parameters: @@ -42,7 +41,7 @@ def set_over_length(element_id_list: List[ElementId], value: float) -> None: value: The element overlength. """ -def set_rounding_width(element_id_list: List[ElementId], value: float) -> None: +def set_rounding_width(element_id_list: list[ElementId], value: float) -> None: """Sets the element rounding width. Parameters: @@ -50,7 +49,7 @@ def set_rounding_width(element_id_list: List[ElementId], value: float) -> None: value: The element rounding width. """ -def set_rounding_height(element_id_list: List[ElementId], value: float) -> None: +def set_rounding_height(element_id_list: list[ElementId], value: float) -> None: """Sets the element rounding height. Parameters: @@ -58,7 +57,7 @@ def set_rounding_height(element_id_list: List[ElementId], value: float) -> None: value: The element rounding height. """ -def set_rounding_length(element_id_list: List[ElementId], value: float) -> None: +def set_rounding_length(element_id_list: list[ElementId], value: float) -> None: """Sets the element rounding length. Parameters: @@ -66,7 +65,7 @@ def set_rounding_length(element_id_list: List[ElementId], value: float) -> None: value: The element rounding length. """ -def set_cross_correction_negative_width(element_id_list: List[ElementId], value: float) -> None: +def set_cross_correction_negative_width(element_id_list: list[ElementId], value: float) -> None: """Sets the element negative width cross correction. Parameters: @@ -74,7 +73,7 @@ def set_cross_correction_negative_width(element_id_list: List[ElementId], value: value: The element negative width cross correction. """ -def set_cross_correction_positive_width(element_id_list: List[ElementId], value: float) -> None: +def set_cross_correction_positive_width(element_id_list: list[ElementId], value: float) -> None: """Sets the element positive width cross correction. Parameters: @@ -82,7 +81,7 @@ def set_cross_correction_positive_width(element_id_list: List[ElementId], value: value: The element positive width cross correction. """ -def set_cross_correction_negative_height(element_id_list: List[ElementId], value: float) -> None: +def set_cross_correction_negative_height(element_id_list: list[ElementId], value: float) -> None: """Sets the element negative height cross correction. Parameters: @@ -90,7 +89,7 @@ def set_cross_correction_negative_height(element_id_list: List[ElementId], value value: The element negative height cross correction. """ -def set_cross_correction_positive_height(element_id_list: List[ElementId], value: float) -> None: +def set_cross_correction_positive_height(element_id_list: list[ElementId], value: float) -> None: """Sets the element positive height cross correction. Parameters: @@ -98,7 +97,7 @@ def set_cross_correction_positive_height(element_id_list: List[ElementId], value value: The element positive height cross correction. """ -def set_cross_correction_negative_length(element_id_list: List[ElementId], value: float) -> None: +def set_cross_correction_negative_length(element_id_list: list[ElementId], value: float) -> None: """Sets the element negative length cross correction. Parameters: @@ -106,7 +105,7 @@ def set_cross_correction_negative_length(element_id_list: List[ElementId], value value: The element negative length cross correction. """ -def set_cross_correction_positive_length(element_id_list: List[ElementId], value: float) -> None: +def set_cross_correction_positive_length(element_id_list: list[ElementId], value: float) -> None: """Sets the element positive length cross correction. Parameters: @@ -114,7 +113,7 @@ def set_cross_correction_positive_length(element_id_list: List[ElementId], value value: The element positive length cross correction. """ -def apply_global_scale(element_id_list: List[ElementId], scale: float, origin: point_3d) -> None: +def apply_global_scale(element_id_list: list[ElementId], scale: float, origin: point_3d) -> None: """Applies a global scale to element. Parameters: @@ -123,35 +122,35 @@ def apply_global_scale(element_id_list: List[ElementId], scale: float, origin: p origin: The scaling origin. """ -def auto_regenerate_axes(element_id_list: List[ElementId]) -> None: +def auto_regenerate_axes(element_id_list: list[ElementId]) -> None: """Automatically regenerates axes on element. Parameters: element_id_list: The element id list. """ -def rotate_length_axis_90(element_id_list: List[ElementId]) -> None: +def rotate_length_axis_90(element_id_list: list[ElementId]) -> None: """Rotates element length axis 90 degrees. Parameters: element_id_list: The element id list. """ -def rotate_length_axis_180(element_id_list: List[ElementId]) -> None: +def rotate_length_axis_180(element_id_list: list[ElementId]) -> None: """Rotates element length axis 180 degrees. Parameters: element_id_list: The element id list. """ -def invert_model(element_id_list: List[ElementId]) -> None: +def invert_model(element_id_list: list[ElementId]) -> None: """Inverts element model. Parameters: element_id_list: The element id list. """ -def set_width_real(element_id_list: List[ElementId], width: float) -> None: +def set_width_real(element_id_list: list[ElementId], width: float) -> None: """Sets the element real width. Parameters: @@ -159,7 +158,7 @@ def set_width_real(element_id_list: List[ElementId], width: float) -> None: width: The element real width. """ -def set_height_real(element_id_list: List[ElementId], height: float) -> None: +def set_height_real(element_id_list: list[ElementId], height: float) -> None: """Sets the element real height. Parameters: @@ -167,7 +166,7 @@ def set_height_real(element_id_list: List[ElementId], height: float) -> None: height: The element real height. """ -def set_length_real(element_id_list: List[ElementId], length: float) -> None: +def set_length_real(element_id_list: list[ElementId], length: float) -> None: """Sets the element real length. Parameters: @@ -175,7 +174,7 @@ def set_length_real(element_id_list: List[ElementId], length: float) -> None: length: The element real length. """ -def rotate_height_axis_2_points(element_id_list: List[ElementId], point1: point_3d, point2: point_3d) -> None: +def rotate_height_axis_2_points(element_id_list: list[ElementId], point1: point_3d, point2: point_3d) -> None: """Rotates the element height axis via 2 points. Parameters: @@ -188,7 +187,7 @@ def clear_errors() -> None: """Clears all errors. """ -def set_drilling_tolerance(element_id_list: List[ElementId], tolerance: float) -> None: +def set_drilling_tolerance(element_id_list: list[ElementId], tolerance: float) -> None: """Sets the drilling tolerance of the axis. Parameters: @@ -196,14 +195,14 @@ def set_drilling_tolerance(element_id_list: List[ElementId], tolerance: float) - tolerance: The new drilling tolerance. """ -def auto_regenerate_axes_silently(element_id_list: List[ElementId]) -> None: +def auto_regenerate_axes_silently(element_id_list: list[ElementId]) -> None: """Automatically regenerates axes on elements without any user interaction. Parameters: element_id_list: The list of element IDs for which the axes will be regenerated. """ -def rotate_length_axis_2_points(element_id_list: List[ElementId], point1: point_3d, point2: point_3d) -> None: +def rotate_length_axis_2_points(element_id_list: list[ElementId], point1: point_3d, point2: point_3d) -> None: """Rotates the element length axis via 2 points. Parameters: @@ -522,7 +521,7 @@ def get_reference_side(element_id: ElementId) -> int: The element reference side. """ -def get_element_vertices(element_id: ElementId) -> List[point_3d]: +def get_element_vertices(element_id: ElementId) -> list[point_3d]: """Gets the element vertices. Parameters: @@ -603,7 +602,7 @@ def get_area_of_front_face(element_id: ElementId) -> float: The element front face area. """ -def get_door_surface(element_id_list: List[ElementId]) -> float: +def get_door_surface(element_id_list: list[ElementId]) -> float: """Gets the element door surface. Parameters: @@ -613,7 +612,7 @@ def get_door_surface(element_id_list: List[ElementId]) -> float: The element door surface. """ -def get_window_surface(element_id_list: List[ElementId]) -> float: +def get_window_surface(element_id_list: list[ElementId]) -> float: """Gets the element window surface. Parameters: @@ -654,7 +653,7 @@ def get_drilling_tolerance(element_id: ElementId) -> float: The drilling tolerance. """ -def get_element_reference_face_vertices(element_id: ElementId) -> List[point_3d]: +def get_element_reference_face_vertices(element_id: ElementId) -> list[point_3d]: """Gets the vertices of the reference side. Parameters: @@ -674,7 +673,7 @@ def get_element_reference_face_area(element_id: ElementId) -> float: The area(size) of reference face. """ -def get_center_of_gravity_for_list(element_id_list: List[ElementId]) -> point_3d: +def get_center_of_gravity_for_list(element_id_list: list[ElementId]) -> point_3d: """Gets the center of gravity for a list of elements. Parameters: @@ -684,7 +683,7 @@ def get_center_of_gravity_for_list(element_id_list: List[ElementId]) -> point_3d The center of gravity as a vector3D. """ -def get_center_of_gravity_for_list_considering_materials(element_id_list: List[ElementId]) -> point_3d: +def get_center_of_gravity_for_list_considering_materials(element_id_list: list[ElementId]) -> point_3d: """Gets the center of gravity for a list of elements, considering their materials. Parameters: @@ -734,7 +733,7 @@ def get_actual_physical_volume(element_id: ElementId) -> float: The actual physical volume. """ -def are_facets_coplanar(first_facet: List[point_3d], second_facet: List[point_3d]) -> bool: +def are_facets_coplanar(first_facet: list[point_3d], second_facet: list[point_3d]) -> bool: """Tests if facets are coplanar. Parameters: @@ -755,7 +754,7 @@ def get_round_machine_rough_part_negative_width(element_id: ElementId) -> bool: The option RoundMachineRoughPartNegativeWidth value. """ -def set_round_machine_rough_part_negative_width(element_id_list: List[ElementId], value: bool) -> None: +def set_round_machine_rough_part_negative_width(element_id_list: list[ElementId], value: bool) -> None: """Sets the value of option RoundMachineRoughPartNegativeWidth. Parameters: @@ -773,7 +772,7 @@ def get_round_machine_rough_part_positive_width(element_id: ElementId) -> bool: The option RoundMachineRoughPartPositiveWidth value. """ -def set_round_machine_rough_part_positive_width(element_id_list: List[ElementId], value: bool) -> None: +def set_round_machine_rough_part_positive_width(element_id_list: list[ElementId], value: bool) -> None: """Sets the value of option RoundMachineRoughPartPositiveWidth. Parameters: @@ -791,7 +790,7 @@ def get_round_machine_rough_part_negative_height(element_id: ElementId) -> bool: The option RoundMachineRoughPartNegativeHeight value. """ -def set_round_machine_rough_part_negative_height(element_id_list: List[ElementId], value: bool) -> None: +def set_round_machine_rough_part_negative_height(element_id_list: list[ElementId], value: bool) -> None: """Sets the value of option RoundMachineRoughPartNegativeHeight. Parameters: @@ -809,7 +808,7 @@ def get_round_machine_rough_part_positive_height(element_id: ElementId) -> bool: The option RoundMachineRoughPartPositiveHeight value. """ -def set_round_machine_rough_part_positive_height(element_id_list: List[ElementId], value: bool) -> None: +def set_round_machine_rough_part_positive_height(element_id_list: list[ElementId], value: bool) -> None: """Sets the value of option RoundMachineRoughPartPositiveHeight. Parameters: @@ -827,7 +826,7 @@ def get_round_machine_rough_part_negative_length(element_id: ElementId) -> bool: The option RoundMachineRoughPartNegativeLength value. """ -def set_round_machine_rough_part_negative_length(element_id_list: List[ElementId], value: bool) -> None: +def set_round_machine_rough_part_negative_length(element_id_list: list[ElementId], value: bool) -> None: """Sets the value of option RoundMachineRoughPartNegativeLength. Parameters: @@ -845,7 +844,7 @@ def get_round_machine_rough_part_positive_length(element_id: ElementId) -> bool: The option RoundMachineRoughPartPositiveLength value. """ -def set_round_machine_rough_part_positive_length(element_id_list: List[ElementId], value: bool) -> None: +def set_round_machine_rough_part_positive_length(element_id_list: list[ElementId], value: bool) -> None: """Sets the value of option RoundMachineRoughPartPositiveLength. Parameters: diff --git a/src/geometry_controller/py.typed b/src/geometry_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/list_controller/__init__.pyi b/src/list_controller/__init__.pyi index 5f92be7..3f33c97 100644 --- a/src/list_controller/__init__.pyi +++ b/src/list_controller/__init__.pyi @@ -1,8 +1,6 @@ -from typing import List - from cadwork.api_types import ElementId, UnsignedInt -def export_production_list(element_id_list: List[ElementId], file_path: str) -> None: +def export_production_list(element_id_list: list[ElementId], file_path: str) -> None: """Exports a production list to the given file path. Parameters: @@ -10,7 +8,7 @@ def export_production_list(element_id_list: List[ElementId], file_path: str) -> file_path: The path of the target file for the export. """ -def export_part_list(element_id_list: List[ElementId], file_path: str) -> None: +def export_part_list(element_id_list: list[ElementId], file_path: str) -> None: """Exports a part list to the specified file path. Parameters: @@ -18,14 +16,14 @@ def export_part_list(element_id_list: List[ElementId], file_path: str) -> None: file_path: The path of the target file for the export. """ -def check_position_numbers_production_list() -> List[ElementId]: +def check_position_numbers_production_list() -> list[ElementId]: """Checks the production list numbers and returns the element IDs that have discrepancies. Returns: The element IDs with discrepancies. """ -def check_position_numbers_part_list() -> List[ElementId]: +def check_position_numbers_part_list() -> list[ElementId]: """Checks the part list numbers and returns the element IDs that have discrepancies. Returns: @@ -36,7 +34,7 @@ def clear_errors() -> None: """Clears all errors. """ -def export_production_list_with_settings(element_id_list: List[ElementId], file_path: str, settings_file_path: str) -> None: +def export_production_list_with_settings(element_id_list: list[ElementId], file_path: str, settings_file_path: str) -> None: """Exports a production list using an additional settings file. Parameters: @@ -45,7 +43,7 @@ def export_production_list_with_settings(element_id_list: List[ElementId], file_ settings_file_path: The path to the settings file to be used for export. """ -def export_part_list_with_settings(element_id_list: List[ElementId], file_path: str, settings_file_path: str) -> None: +def export_part_list_with_settings(element_id_list: list[ElementId], file_path: str, settings_file_path: str) -> None: """Exports a part list using an additional settings file. Parameters: @@ -54,14 +52,14 @@ def export_part_list_with_settings(element_id_list: List[ElementId], file_path: settings_file_path: The path to the settings file to be used for export. """ -def generate_new_production_list_numbers(element_id_list: List[ElementId]) -> None: +def generate_new_production_list_numbers(element_id_list: list[ElementId]) -> None: """Generates new production list numbers for the specified elements. Parameters: element_id_list: The list of elements to generate numbers for. """ -def generate_new_part_list_numbers(element_id_list: List[ElementId]) -> None: +def generate_new_part_list_numbers(element_id_list: list[ElementId]) -> None: """Generates new part list numbers for the specified elements. Parameters: @@ -82,7 +80,7 @@ def load_part_list_calculation_settings(settings_file_path: str) -> None: settings_file_path: The path to the settings file to be loaded. """ -def generate_new_production_list_silently(element_id_list: List[ElementId], starting_number: UnsignedInt, keep_existing_numbers: bool, +def generate_new_production_list_silently(element_id_list: list[ElementId], starting_number: UnsignedInt, keep_existing_numbers: bool, with_containers: bool) -> None: """Generates new production list numbers silently starting from a given number, optionally keeping existing numbers and considering container elements. @@ -93,7 +91,7 @@ def generate_new_production_list_silently(element_id_list: List[ElementId], star with_containers: Whether to include container elements in the number generation. """ -def generate_new_part_list_silently(element_id_list: List[ElementId], starting_number: UnsignedInt, keep_existing_numbers: bool, +def generate_new_part_list_silently(element_id_list: list[ElementId], starting_number: UnsignedInt, keep_existing_numbers: bool, with_containers: bool) -> None: """Generates new part list numbers silently starting from a given number, optionally keeping existing numbers and considering container elements. @@ -104,7 +102,7 @@ def generate_new_part_list_silently(element_id_list: List[ElementId], starting_n with_containers: Whether to include container elements in the number generation. """ -def export_cover_list(element_id_list: List[ElementId], file_path: str) -> None: +def export_cover_list(element_id_list: list[ElementId], file_path: str) -> None: """Exports a Wall, Roof, or Floor list to the specified file path. Parameters: @@ -112,7 +110,7 @@ def export_cover_list(element_id_list: List[ElementId], file_path: str) -> None: file_path: The path of the target file for the export. """ -def export_cover_list_with_settings(element_id_list: List[ElementId], file_path: str, settings_file_path: str) -> None: +def export_cover_list_with_settings(element_id_list: list[ElementId], file_path: str, settings_file_path: str) -> None: """Exports a Wall, Roof, or Floor list to the specified file path using an additional settings file. Parameters: diff --git a/src/list_controller/py.typed b/src/list_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/machine_controller/__init__.pyi b/src/machine_controller/__init__.pyi index 585ba29..8ff0020 100644 --- a/src/machine_controller/__init__.pyi +++ b/src/machine_controller/__init__.pyi @@ -1,4 +1,3 @@ -from typing import List from cadwork import vertex_list from cadwork.api_types import ElementId from cadwork.btl_version import btl_version @@ -101,7 +100,7 @@ def export_btl_with_presetting(btl_version: btl_version, file_path: str, presett >>> mc.export_btl_with_presetting(btl_version, output_path, presetting_file) """ -def calculate_btl_machine_data(element_id_list: List[ElementId], btl_version: btl_version) -> None: +def calculate_btl_machine_data(element_id_list: list[ElementId], btl_version: btl_version) -> None: """Calculates the Machine Data for BTL. Parameters: @@ -118,7 +117,7 @@ def calculate_btl_machine_data(element_id_list: List[ElementId], btl_version: bt >>> mc.calculate_btl_machine_data(beam_elements, btl_version) """ -def calculate_hundegger_machine_data(element_id_list: List[ElementId], hundeggertype: hundegger_machine_type) -> None: +def calculate_hundegger_machine_data(element_id_list: list[ElementId], hundeggertype: hundegger_machine_type) -> None: """Calculates the Machine Data for Hundegger. Parameters: @@ -178,7 +177,7 @@ def export_hundegger_with_file_path_and_presetting_silent(hundeggertype: hundegg """ -def get_element_hundegger_processings(element_id: ElementId, hundeggertype: hundegger_machine_type) -> List[ElementId]: +def get_element_hundegger_processings(element_id: ElementId, hundeggertype: hundegger_machine_type) -> list[ElementId]: """Gets the list of Hundegger processings for a specific element. Parameters: @@ -200,7 +199,7 @@ def get_element_hundegger_processings(element_id: ElementId, hundeggertype: hund """ -def get_element_btl_processings(element_id: ElementId, btl_version: btl_version) -> List[ElementId]: +def get_element_btl_processings(element_id: ElementId, btl_version: btl_version) -> list[ElementId]: """Gets the list of BTL processings for a specific element. Parameters: @@ -288,7 +287,7 @@ def get_processing_points(reference_element_id: ElementId, processing_id: Elemen """ -def get_processing_btl_parameter_set(reference_element_id: ElementId, processing_id: ElementId) -> List[str]: +def get_processing_btl_parameter_set(reference_element_id: ElementId, processing_id: ElementId) -> list[str]: """Gets the BTL parameter set of a specific processing. Parameters: diff --git a/src/machine_controller/py.typed b/src/machine_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/material_controller/__init__.pyi b/src/material_controller/__init__.pyi index 7a905a4..5c39c8b 100644 --- a/src/material_controller/__init__.pyi +++ b/src/material_controller/__init__.pyi @@ -1,4 +1,3 @@ -from typing import List from cadwork.api_types import MaterialId, UnsignedInt def create_material(name: str) -> MaterialId: @@ -412,7 +411,7 @@ def get_weight_type(material_id: MaterialId) -> str: The material weight type. """ -def get_all_materials() -> List[MaterialId]: +def get_all_materials() -> list[MaterialId]: """Retrieves a list of all materials. Returns: @@ -463,7 +462,7 @@ def get_short_name(material_id: MaterialId) -> str: The short name of the material. """ -def get_all_material_groups() -> List[MaterialId]: +def get_all_material_groups() -> list[MaterialId]: """Retrieves a list of all material groups. Returns: diff --git a/src/material_controller/py.typed b/src/material_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/menu_controller/__init__.pyi b/src/menu_controller/__init__.pyi index 5bb45ef..39ca11f 100644 --- a/src/menu_controller/__init__.pyi +++ b/src/menu_controller/__init__.pyi @@ -1,7 +1,4 @@ -from typing import List - - -def display_simple_menu(menu_items: List[str]) -> str: +def display_simple_menu(menu_items: list[str]) -> str: """Displays a simple menu. Parameters: diff --git a/src/menu_controller/py.typed b/src/menu_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/multi_layer_cover_controller/__init__.pyi b/src/multi_layer_cover_controller/__init__.pyi index 5f84e71..5e0a32e 100644 --- a/src/multi_layer_cover_controller/__init__.pyi +++ b/src/multi_layer_cover_controller/__init__.pyi @@ -1,4 +1,3 @@ -from typing import List from cadwork import multi_layer_cover_type from cadwork.api_types import * from cadwork.multi_layer_type import multi_layer_type @@ -169,7 +168,7 @@ def set_cover_color(set_id: MultiLayerSetId, cover_color: ColorId) -> None: >>> mlc.set_cover_color(multi_layer_set_id, blue_color_id) """ -def get_multi_layer_walls() -> List[MultiLayerSetId]: +def get_multi_layer_walls() -> list[MultiLayerSetId]: """Gets all multi layer wall ids. Examples: @@ -370,7 +369,7 @@ def get_cover_color(set_id: MultiLayerSetId) -> ColorId: The cover color. """ -def get_multi_layer_framed_floors() -> List[MultiLayerSetId]: +def get_multi_layer_framed_floors() -> list[MultiLayerSetId]: """Gets all framed multi layer floor ids. Examples: @@ -398,7 +397,7 @@ def create_multi_layer_framed_floor(set_name: str) -> MultiLayerSetId: The multi layer set id. """ -def get_multi_layer_framed_roofs() -> List[MultiLayerSetId]: +def get_multi_layer_framed_roofs() -> list[MultiLayerSetId]: """Gets all multi layer roof ids. Examples: @@ -412,7 +411,7 @@ def get_multi_layer_framed_roofs() -> List[MultiLayerSetId]: The multi layer roof ids. """ -def get_multi_layer_solid_floors() -> List[MultiLayerSetId]: +def get_multi_layer_solid_floors() -> list[MultiLayerSetId]: """Gets all solid multi layer floor ids. Examples: @@ -468,7 +467,7 @@ def create_multi_layer_framed_wall(set_name: str) -> MultiLayerSetId: The multi layer set id. """ -def get_multi_layer_sets() -> List[MultiLayerSetId]: +def get_multi_layer_sets() -> list[MultiLayerSetId]: """Gets all multi layer set ids of all types. Examples: @@ -497,7 +496,7 @@ def create_multi_layer_by_cover_type(set_name: str, cover_type: multi_layer_cove The multi layer set id. """ -def get_multi_layer_sets_for_cover_type(cover_type: multi_layer_cover_type) -> List[MultiLayerSetId]: +def get_multi_layer_sets_for_cover_type(cover_type: multi_layer_cover_type) -> list[MultiLayerSetId]: """Gets all multi layer set ids of specified cover type. Parameters: @@ -511,7 +510,7 @@ def get_multi_layer_sets_for_cover_type(cover_type: multi_layer_cover_type) -> L """ -def get_multi_layer_log_walls() -> List[MultiLayerSetId]: +def get_multi_layer_log_walls() -> list[MultiLayerSetId]: """Gets all multi layer log wall ids. Examples: @@ -539,7 +538,7 @@ def create_multi_layer_log_wall(set_name: str) -> MultiLayerSetId: The multi layer set id. """ -def get_multi_layer_solid_roofs() -> List[MultiLayerSetId]: +def get_multi_layer_solid_roofs() -> list[MultiLayerSetId]: """Gets all multi layer solid roof ids. Examples: @@ -567,7 +566,7 @@ def create_multi_layer_solid_roof(set_name: str) -> MultiLayerSetId: The multi layer set id. """ -def get_multi_layer_solid_walls() -> List[MultiLayerSetId]: +def get_multi_layer_solid_walls() -> list[MultiLayerSetId]: """Gets all multi layer solid wall ids. Examples: diff --git a/src/multi_layer_cover_controller/py.typed b/src/multi_layer_cover_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/roof_controller/__init__.pyi b/src/roof_controller/__init__.pyi index 73e22c0..60cee98 100644 --- a/src/roof_controller/__init__.pyi +++ b/src/roof_controller/__init__.pyi @@ -1,4 +1,3 @@ -from typing import List from cadwork.api_types import ElementId def get_profile_length(element_id: ElementId) -> float: @@ -58,7 +57,7 @@ def get_edge_length(element_id: ElementId, edge_type: str) -> float: The edge length. """ -def get_all_caddy_element_ids() -> List[ElementId]: +def get_all_caddy_element_ids() -> list[ElementId]: """Gets all caddy elements Returns: diff --git a/src/roof_controller/py.typed b/src/roof_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/scene_controller/__init__.pyi b/src/scene_controller/__init__.pyi index 9c48503..76970e0 100644 --- a/src/scene_controller/__init__.pyi +++ b/src/scene_controller/__init__.pyi @@ -1,4 +1,3 @@ -from typing import List from cadwork.api_types import * def add_scene(name: str) -> bool: @@ -32,7 +31,7 @@ def delete_scene(name: str) -> bool: True if the operation succeeded, false otherwise. """ -def add_elements_to_scene(name: str, element_id_list: List[ElementId]) -> bool: +def add_elements_to_scene(name: str, element_id_list: list[ElementId]) -> bool: """Adds elements to a scene. Parameters: @@ -43,7 +42,7 @@ def add_elements_to_scene(name: str, element_id_list: List[ElementId]) -> bool: True if the operation succeeded, false otherwise. """ -def remove_elements_from_scene(name: str, element_id_list: List[ElementId]) -> bool: +def remove_elements_from_scene(name: str, element_id_list: list[ElementId]) -> bool: """Removes elements from a scene. Parameters: @@ -54,7 +53,7 @@ def remove_elements_from_scene(name: str, element_id_list: List[ElementId]) -> b True if the operation succeeded, false otherwise. """ -def get_elements_from_scene(name: str) -> List[ElementId]: +def get_elements_from_scene(name: str) -> list[ElementId]: """Gets the elements from a scene. Parameters: @@ -78,14 +77,14 @@ def clear_errors() -> None: """Clears all errors. """ -def get_scene_list() -> List[str]: +def get_scene_list() -> list[str]: """Gets the list of scenes. Returns: The list of scene names. """ -def group_scences(scene_names: List[str]) -> UnsignedInt: +def group_scences(scene_names: list[str]) -> UnsignedInt: """Groups the scenes to a scene group. Parameters: @@ -148,7 +147,7 @@ def rename_scene_group_by_index(group_index: UnsignedInt, new_name: str) -> None new_name: The new scene group name. """ -def group_scences_with_name(scene_names: List[str], group_name: str) -> UnsignedInt: +def group_scences_with_name(scene_names: list[str], group_name: str) -> UnsignedInt: """Groups the scenes to a scene group and sets the name of the new group. Parameters: diff --git a/src/scene_controller/py.typed b/src/scene_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/shop_drawing_controller/__init__.pyi b/src/shop_drawing_controller/__init__.pyi index 9b14315..d7e3ba9 100644 --- a/src/shop_drawing_controller/__init__.pyi +++ b/src/shop_drawing_controller/__init__.pyi @@ -1,4 +1,3 @@ -from typing import List from cadwork.point_3d import point_3d from cadwork.api_types import * @@ -35,7 +34,7 @@ def export_2d_hidden_lines_with_2dc(file_path: str, with_layout: bool) -> None: with_layout: Use layout, false by default. """ -def export_wall_with_clipboard(clipboard_number: UnsignedInt, element_id_list: List[ElementId]) -> None: +def export_wall_with_clipboard(clipboard_number: UnsignedInt, element_id_list: list[ElementId]) -> None: """Exports a wall to the clipboard. Parameters: @@ -43,7 +42,7 @@ def export_wall_with_clipboard(clipboard_number: UnsignedInt, element_id_list: L element_id_list: The elements to export. """ -def export_export_solid_with_clipboard(clipboard_number: UnsignedInt, element_id_list: List[ElementId]) -> None: +def export_export_solid_with_clipboard(clipboard_number: UnsignedInt, element_id_list: list[ElementId]) -> None: """Exports an export solid to the clipboard. Parameters: @@ -51,7 +50,7 @@ def export_export_solid_with_clipboard(clipboard_number: UnsignedInt, element_id element_id_list: The elements to export. """ -def export_piece_by_piece_with_clipboard(clipboard_number: UnsignedInt, element_id_list: List[ElementId]) -> None: +def export_piece_by_piece_with_clipboard(clipboard_number: UnsignedInt, element_id_list: list[ElementId]) -> None: """Exports a piece-by-piece to the clipboard. Parameters: @@ -59,7 +58,7 @@ def export_piece_by_piece_with_clipboard(clipboard_number: UnsignedInt, element_ element_id_list: The elements to export. """ -def assign_export_solid(ceo_element_id_list: List[ElementId], element_id_list: List[ElementId]) -> None: +def assign_export_solid(ceo_element_id_list: list[ElementId], element_id_list: list[ElementId]) -> None: """Assigns elements to an export solid. Parameters: @@ -67,7 +66,7 @@ def assign_export_solid(ceo_element_id_list: List[ElementId], element_id_list: L element_id_list: The elements to assign. """ -def export_container_with_clipboard(clipboard_number: UnsignedInt, element_id_list: List[ElementId]) -> None: +def export_container_with_clipboard(clipboard_number: UnsignedInt, element_id_list: list[ElementId]) -> None: """Export a container to the clipboard. Parameters: @@ -91,7 +90,7 @@ def add_wall_section_vertical(element_id: ElementId, position: point_3d) -> None position: The section position. """ -def export_wall_with_clipboard_and_presetting(clipboard_number: UnsignedInt, element_id_list: List[ElementId], presetting_file: str) -> None: +def export_wall_with_clipboard_and_presetting(clipboard_number: UnsignedInt, element_id_list: list[ElementId], presetting_file: str) -> None: """Exports a wall to the clipboard. Parameters: diff --git a/src/shop_drawing_controller/py.typed b/src/shop_drawing_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/utility_controller/__init__.pyi b/src/utility_controller/__init__.pyi index e779f49..6863d3e 100644 --- a/src/utility_controller/__init__.pyi +++ b/src/utility_controller/__init__.pyi @@ -1,5 +1,3 @@ -from typing import List -from typing import Tuple from cadwork.api_types import ElementId from cadwork.point_3d import point_3d from cadwork.window_geometry import window_geometry @@ -286,7 +284,7 @@ def enable_auto_display_refresh() -> None: >>> import element_controller as ec >>> uc.disable_auto_display_refresh() >>> # Perform operations that require disabled display refresh - >>> your_list_of_elements: List[int] = [] + >>> your_list_of_elements: list[int] = [] >>> uc.enable_auto_display_refresh() >>> ec.recreate_elements(your_list_of_elements) @@ -572,7 +570,7 @@ def init_LxSDK() -> None: """ -def load_element_attribute_display_settings(file_path: str, elements: List[ElementId]) -> None: +def load_element_attribute_display_settings(file_path: str, elements: list[ElementId]) -> None: """Loads element attribute display settings from a file. Parameters: @@ -697,7 +695,7 @@ def disable_update_variant() -> None: """ -def get_user_points() -> List[point_3d]: +def get_user_points() -> list[point_3d]: """Gets user points. Returns: @@ -705,7 +703,7 @@ def get_user_points() -> List[point_3d]: """ -def get_user_points_with_count(count: int) -> List[point_3d]: +def get_user_points_with_count(count: int) -> list[point_3d]: """Gets user points with a specified count. Parameters: @@ -1028,7 +1026,7 @@ def create_snapshot() -> str: """ -def get_3d_gui_upper_left_screen_coordinates() -> Tuple[int, int]: +def get_3d_gui_upper_left_screen_coordinates() -> tuple[int, int]: """Get the coordinates of the upper left corner of the 3D GUI. Returns: @@ -1044,7 +1042,7 @@ def get_3d_main_window_geometry() -> 'window_geometry': """ -def get_project_data_keys() -> List[str]: +def get_project_data_keys() -> list[str]: """Gets all keys for project data. Returns: diff --git a/src/utility_controller/py.typed b/src/utility_controller/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/visualization_controller/__init__.pyi b/src/visualization_controller/__init__.pyi index 6f61614..69a36dd 100644 --- a/src/visualization_controller/__init__.pyi +++ b/src/visualization_controller/__init__.pyi @@ -1,10 +1,9 @@ -from typing import List from cadwork.camera_data import camera_data from cadwork.point_3d import point_3d from cadwork.api_types import * from cadwork.rgb_color import rgb_color -def set_color(element_id_list: List[ElementId], color_id: ColorId) -> None: +def set_color(element_id_list: list[ElementId], color_id: ColorId) -> None: """Sets the element color. Parameters: @@ -12,7 +11,7 @@ def set_color(element_id_list: List[ElementId], color_id: ColorId) -> None: color_id: The color ID to set. """ -def set_opengl_color(element_id_list: List[ElementId], color: rgb_color) -> None: +def set_opengl_color(element_id_list: list[ElementId], color: rgb_color) -> None: """Sets the element OpenGL color. Parameters: @@ -30,14 +29,14 @@ def is_active(element_id: ElementId) -> bool: True if the element is active, false otherwise. """ -def set_active(element_id_list: List[ElementId]) -> None: +def set_active(element_id_list: list[ElementId]) -> None: """Sets element active. Parameters: element_id_list: The list of element id. """ -def set_inactive(element_id_list: List[ElementId]) -> None: +def set_inactive(element_id_list: list[ElementId]) -> None: """Sets the element inactive. Parameters: @@ -54,14 +53,14 @@ def is_visible(element_id: ElementId) -> bool: True if the element is visible, false otherwise. """ -def set_visible(element_id_list: List[ElementId]) -> None: +def set_visible(element_id_list: list[ElementId]) -> None: """Sets the element visible. Parameters: element_id_list: The list of element id. """ -def set_invisible(element_id_list: List[ElementId]) -> None: +def set_invisible(element_id_list: list[ElementId]) -> None: """Sets the element invisible. Parameters: @@ -78,14 +77,14 @@ def is_immutable(element_id: ElementId) -> bool: True if the element is immutable, false otherwise. """ -def set_immutable(element_id_list: List[ElementId]) -> None: +def set_immutable(element_id_list: list[ElementId]) -> None: """Sets the element immutable. Parameters: element_id_list: The list of element id. """ -def set_mutable(element_id_list: List[ElementId]) -> None: +def set_mutable(element_id_list: list[ElementId]) -> None: """Sets the element mutable. Parameters: @@ -112,7 +111,7 @@ def refresh() -> None: """Refresh the drawing area. """ -def set_material(element_id_list: List[ElementId], element_id: ElementId) -> None: +def set_material(element_id_list: list[ElementId], element_id: ElementId) -> None: """Sets the element material. Parameters: @@ -206,14 +205,14 @@ def is_selectable(element_id: ElementId) -> bool: True if the element is selectable, false otherwise. """ -def set_unselectable(element_id_list: List[ElementId]) -> None: +def set_unselectable(element_id_list: list[ElementId]) -> None: """Sets a list of elements unselectable. Parameters: element_id_list: The list of element id. """ -def set_selectable(element_id_list: List[ElementId]) -> None: +def set_selectable(element_id_list: list[ElementId]) -> None: """Sets a list of elements selectable. Parameters: @@ -251,7 +250,7 @@ def show_perspective_central() -> None: """ -def set_color_without_material(element_id_list: List[ElementId], color_id: ColorId) -> None: +def set_color_without_material(element_id_list: list[ElementId], color_id: ColorId) -> None: """Sets the color of a list of elements without changing their material. Parameters: @@ -260,7 +259,7 @@ def set_color_without_material(element_id_list: List[ElementId], color_id: Color """ -def set_texture_rotated(element_id_list: List[ElementId], flag: bool) -> None: +def set_texture_rotated(element_id_list: list[ElementId], flag: bool) -> None: """Sets the rotation of the texture for a list of elements. Parameters: @@ -393,7 +392,7 @@ def get_element_transparency(element_id: ElementId) ->int: Transparency value as percentage. """ -def set_element_transparency(element_id_list: List[ElementId], value: int) -> None: +def set_element_transparency(element_id_list: list[ElementId], value: int) -> None: """Sets the element transparency. Parameters: @@ -411,7 +410,7 @@ def get_use_material_texture(element_id: ElementId) -> bool: True if the element is using material texture, false otherwise. """ -def set_use_material_texture(element_id_list: List[ElementId], value: bool) -> None: +def set_use_material_texture(element_id_list: list[ElementId], value: bool) -> None: """Sets element to use material texture. Parameters: diff --git a/src/visualization_controller/py.typed b/src/visualization_controller/py.typed new file mode 100644 index 0000000..e69de29

PTGf-w-acLzb26+>cz#eQGN>`+2l&yB1>JDN|azuq@jkOys5e$9>H9c zka)?$p@=qalc8PjQ=;L?!(72E+Zkvg;{S>#_~YNfHNHw+?bV5AsqE3hEAuJ|2{u92^FX zl}Q|yOS~@iS!9 zKu3LX7uWmKDxSEtKsH90HRN19B+io=kzDo5XR3=xXv~9G^CG%@_^=fGB)>lIMdi4M zZxWKn)!cBNK$6x)@UmowF9PLoI(5W!^EtH05OQM8r7J079#CXbt!0f2xll^EXId+o zIcmw`{-oNgS_Rt0H(Q=*uj!N+zI}v3rn9bBa!4RO8mCiChDXQ0;oEO-Ea%U~li|m7 z4&mY(EP?srdu2wLbQmLEc|5v|ANV9}f@K@`+T?v`FU;O`7OI~LG!gTJqEh@-;j?Wy zTx?hewc4RVW~H3Wy1T}2ZIBX74?V6lmAV^BPH2xnd0DRU9K|__RxFUI!RJg^;thHO zw|iSy@8gM+3pIavgwQ1aONCERXFzF?-^S#9r><-!+O>nriVSO=SQzx&_?aQ4{)q0j zI4k^zjD8E!{Y*JMOwoDizNjpm&GYM*UdUchm*tit)HQh_cX6ueKGm_Pc~{+ut1nmM zW|gFmaHp&&ryzO^u~a&N*ECaAI9(^Ve_&Ob7vd~thEXV;f7Y77S1*}OInFv{9#!r( zx|gavedR3jBuf2i>{XENGR_*!dT7Lxw|f2IgQIaC{i-s>U?zk(!tR}~Ffn%qft}`M zn(O)lR>IY!4%#FBq^?R$!msHZ)z!o0_^;oMyIXPHtOb!z>y^AAPL0{~7Jhx}%7uyv zn=ii91`pbBM)-u^$_W@cjNGj>bb24XVd%1yU3t^(b4z8j^S6b{Tb?H_=rUKb#2^`ed8Fh8zKUc~y<$jyDLijM&zHm?aC-E7``ZWX!jur~bWe%%Qw z`L$Xk#v0ouJjMsM%@@sT9<-@lJ9^N;m|OETpSDuezDHn5l&)I@P3+-2EVMX-_X-MP z4nuQcI+m7+t9A}!X1U2T!`U8&jIyD{Yn`Ls2Zp@!MM-6jbKwdfW?$x*b_Gw$%=&o0 zb)StG*eg&MciX58cXhEibi1h|Y)$w82glII*caDiHNs_*0UoFrvvJd)W-0fu^_rC}xtC|f%HHpHQdVqA3+=#NHN>SdDQ=X?F zGO-b@ZI0lblM=QDQSlNTx7Rs^>zW}9as=(K{p zDv6&yA!8b0Fbz%3a79&s!>1K99nYU>N&Mo~V4cAX&4gt+zUr%CsPvf>C>DwW2UjCw z2eZ)VSCq7?2Xt~`vN`=Na1BYXJsT!);dy0o#UZ#lk+~;V0>x6pUsx*x)F&y(S!zD5 z*2>`@%2)Td)XEmtF3=e&&~35Qc~z}l;y6@z3+0|(i?B{v>`;-J+`St^)jAawL&f*~ z?-?uz>sAjBl{mHB1MXs|Ztc#{b59g2BNP$6Mxx=;KshU8!Z&)Y{KGH8{jE&sMXq=1 z441{VSef#@x!&tI{4y2A+FVZL#z5?Fd9IwbrS_W}!xh7?p8H!{z2D*+A0Do#Y_Ya+ zU}YcM8NMU9ZEahLX)r@HQqat2W0x6hu)rUe-|b-YFdWlxMW-@n@Rg0@^J`#$R z_2Q6OxT_Yl2ke@+Kxtd&A5pe)Pe_uBle~!t=P$p49w8)(Im$vy$!+%;(w+@*h;A0j zctAnf(n79FVlDCs zn^fPpUC?xyno-Nl#Z-=5`$b>JrRKQ|R*x1(==ga3mCZpScWWDwuWSo<%`01`Bsaq* zCeMpGRk!KcI6x~8AFMk%)tp1S?=m7{yH(*-yB%=fW7o~*XveAE!9dIB;^Z`%f^$D| zt!;q72;{JPuZPZl0b9q_ZNSdadB!{LBVz4Y3;)tfvFYsK-a-+afbrk zHnm>-|g>u$3f&ZCOj*xZCLL z5|z7m|LFLN=F$Gb$nBQWzN&TmE!Lh=uAq(vzMY&98N%`R2aDf~LYwMbnWMQBr5U~~ zy*nZM7DRGD5GVFb0I9Dp5lt#4|7P5Fm8#?i;Z*1?v8zvb*_7(G&hZ7Md2zYbEqC#c zcwcCnDAOVfM+!yx3u~89 zrzM0&*RP34YQB4QPPI-23FCra9cptjnra<3GM#~I6b_TOa6>l5JRdqay^09Em^ZCh z5QBbtX}v9!Pg^*L+V9ouOhe$4y4Y#PgF+YbJI(S|ZxsBR%cGl> zc;5he=|xksYI(KVyllZ*zTbtGt8^`z1kcoETeP%Vv`t!c9=7QEwdlpPT+eE`QQo58 z++r};VmRM&bF1YRa;p(R>utJLW8T&~vaKdst#?gYO&_+J`L&wIv|41fT9&uoYi_j~ zY_*|_>5Y}jQ*z~&@r#KekMoO^B{VuylMoBB zmHjmkUmYnomUlLUsH9@6)@LcD*s5}uD%Y2*CeUFfYjsC#c7=C$i$Z)oH4vY4tF~#O zLuC@DQj}%|4B5*HvE|_;NKkOaa>RMGT$`DoVYgYQ|u9zt6OO1{= z7xMVSydp-i%D930SXMU{VK=f^|J-EXJaPvDdpAG2##D^bP;(aoeSec>M_e}&Xbor= zRU1QA_h0Tf98@MHRDRa1TA0<_=&pD;*gdo5ONpaNzKtCz$&f zBRZ)sQ0slNd-uZVRcsHHDz=X3?kntf-(@QHEe@&(@(sR|(ZcrVWAk_~A1bDt{o1cw ztF%iip=nUfy8OzvmJrgA#;dZc^h4x4L)W%THF#Te9ENo11-1PP9I}RPywWa-9?Df7 zGDv=IxS+lDb?6r1b0b2X&$PqFLnU|Qbk;P7?>;RtbK%BQoqK;xb6`;5`#hf$%=U9La~0>LTYw z+1=%Ib8@WTw~&iTL)pvw zMGs%8Lr=7@mdrB!;sE`(F6yb3>^Q~qgH2*oPjDL~#c`A)@SlZ{j@LGCa*IWVq;K#M z^XM~gT@M_HPBY{vV-L}+7N?=35ALt~cr{~&TF*)QdT1zj@B0kqnT(6>JYOKVqVF#I z3mUvs%er96y_UdNVLhQa&DhwI~8165Lk zWQQp2^B?dnqRx}nnK*N>KMM42^BBA1#rDY9p=LOQW1 zUB8B*f4CL3sjr;SWany#@H!V^JXiSkv_SW?J_1+EHjaO`?zNz)d5xgh<(G)V%=Z?8 z?Hz7A84!`A%vAWykX~MCYwokGt+Q;yv+Rqr96Pg|sB>IIbKDGbm-**-}!bWQkLY|ig~kR`cd2@ zi(R-Vk7p3JU?{#Ia^ZRe`wP(q!a7B&NcQ?rLUFOew~5Q6?A)oy18@0R7O|9TF)c0` zJ>uX)3VQA_{wn#EbG4xfzgL!A5Rvqf77I}U&UC5u$LAFKHa80%up4ke2eK3k)6gzR zy*{488koRDyywRpD@*SIR|-fITq>XLhJ#Eolu@4eNTW!YJ)L$#_UT5n)j zZ{%NZl3#DuS#L32Z*^R63s`TDUGK5`b9a(LiBJUE2FVo|dlq*o4mxX0)T&okQDnEF$B zQmN5HFPMk-#jEGOPx-WZF8R|waa{6z2g6;7%HkXIhKo3PpO+nddtjO`bRhs zb(I&B&EnIg5bPetts_#pF)94CB4WVkT9=c3Z|vk*-by|~66f-D+J3&v1EfmMES$6W zB-jhLlY&AiMQ%O|(o}U+wY~FVkg4j0hPXazN zLcC{%n==K+7pmtMM3oYdbQjwA7c)5*B?uBE^%r;BT?ohfC>wi0-+NK6a8bTyQK5Tr z-}s{9%Ayj%k}}3%WXZ`mL=?o`^v(A?$Ig)GLgjwV(Q zj8-lNVtqD~iE{=`@~;jSV9IKb*}K-$XW0@z1>L7=m}LlLTQl!D6Y|+JW%k)uL)knf zHqYKy@7!LBeU|D_ab2O|h;a}1`PE3P*eJTS zGX6_~N|#2%M)q2*#qeg{3|WhdUAvvO7GJn_r)Djodo6K%Eoo)#F2Q;--TFP=_4_jG zDH`h!^w%F+t*5%Lr-iJi$F66jt!EalKdM>J>Rx|5zW!uoJ)7W54&9er-YuixHOx%Y=x+F+_R|WW?{2u@gPw-o!8^lFU3k; z6|*<1**2bsY}CeXl!R>5@NR_0c{ZeZ*7166zFFC5%JzD_o2tg=OKsZ5n`W=}@r|hT zjkdd9B}!gZAz!=Py;>b9dI`QZ`fRkjf9=@q-9@+2qyKd<_Ui!Ml|H)Y=2-86X7Ax| z-c9Cj9!1AXEdJfRcH&*{m|~8!apMTXOT48YCo&*ZAf* z4g}M49PF5w=ci@Yt#sv(rZ zwo81+;_;)!&rdD!ccdRnJNDRiS)eP+u+U|OVQSf~`np-o4Pm>_LcLFIyYtRZe-`df z!NNd)z`l)cSZU)m7aZ*a# zNaUzJ(!fL9G*H|kO#ED=xXmqbyEs|<7$t|B+Rjm@T*J<|`q{dAIl6gXyySh^%i9a= zW%>Ak#Vmh+|3I*u6&xHI3P=NCz@QYw7V-lObz=lfAb=qRfB}NWfS_0)5DWw+6QJEp zZ)^vc2nVqZ1-S{P!_fhQLBN^_9B76CyfOmwK)?_=2uuP9m??+H%3E%_#tFvoU>+X@ScLT=X=GzUv z`H|^0z<)H{q^uZcd2TqHJO{Dqk9BqggXsnNHnRIgNWL`jY~LF-6tFu9iNH3K#D0yy z(Ifo9f(T-IaWh)f`jZ-_ja(It*G1s4(6{+v<5`;%G81la`4S0;u)o6zCR}UA*?mak z0f!+e`@2Z_&xAbJ_V6Y9Mk+H}_#+HnP5=ucG!MW6pOWw@sa*2d9mg2miU?a|jtZ7O zZe9hBpR1EEp<{?ygQBJe2*ikJaM8x!@x%7B_xsC)g=dL**zVQv^yhe?HqkJ3PYB@rR zJN70oG>As(R#0#eBK;dRn4K#qkmVZ{SZ3)P5(L=HSO>6Wc*&P2@UA6GH1B();NRwQ zhz$RY3v!=o$G!{w^Ib-eZzBrjdbF?=zkw`srl60LnjE*^r7$DFJIBl#8s%C%X_Zh} z;JOR)ZDc2}z?mtyoBPO>B%!i0T4Cc8*KP%;Qx#b3t0M0Z&u2GvX7dB0e5tK8b@mY& z5j%ZhNI0(KISu#%FIT=>5RF~scsFv|5vizc>*A08M1C&ov*vP~otYM_{2#C(VD5$o5!q%GdEAbR_9w|`Wy zY$JqnRW)9l3)xgAy^ppaV!ltdf838-4vc_b<0Ma1t`;!-!Gh?N5hqop=4&HDPs9j)!3a2kRxNr2{8TLu=g?n~XC9y|h=|1r;u;_9k*TXg zqg;FH5F;d5OzaN@Am2u}WB57Oenh#RYM48biD=_Th=yo2S}^9v2x_K^$AS@Xxy9Qp zD3t4AD}NDZK}}y*${au2%Zqo0NUbDJtG#iFUrgBP+o;uixpy&Xb+a)|5#`&sco#vo z!?zKQa^>CP0W_r_klEqexb%SU@b6Hr?)B}zL%HtoZOp_(xz-%)`W?y@@@@Pb%Jr8# zfO9epzvBTEe}0w|vH2SwfK!O}?|1-)E5*O%0sO`aU){?v10YUsh|BgLCnM z554E4V#uRKTHRnPIpZSzJXhzO?oB%R4^w)3bM=#s#OyBl;N$u{$9PlRyz1H+p4jIJ z7OXWx06;EPupBHw|BL2a6Rt~mZx3+%rO8&JWw$MXD(1Q2LuFwx)}iSK+?36qE7> zSD&EVMDI|7f)dn`pmqdRBPbL>i3sXKusQkjS~OhJfl3ZkZ=h%cg&HW%;Iiz$hlCsY z6%q~t8K9AH+Z=;WXpjM#;stw0VUl2B$0&Gp5~>RyBAx?IRMb#;03p>TReBCbRWK2o zssf+0g?cC*i_7g$WQuAeg^Y`lK@NBAUwp?QYs#PMLTD`-y&4GCqK*G)izswm2v!57 z?Ao~Nqp8(ha1SkHn_UeN+tX!TG++CI2h-f`-}&Ss#U+rE(qdA3#bgx3WEGKeDoFYL zq6!B@6}3c^w1t%p3n?EFQq~nzIVz}fOaRK`{Hh@J;N(+1@nfFkQ$^)|eZKwry!#EH zR6E71X2`2<#CyPGkA~SEO$#2av)tM?T!$SvbX?evU1HVqVLlniXb?tkc%9bhCY5Od zxy6HBXEI37Jt48mgVH*m#2UQjkwTeEW}UmsI)~gko6`CTmGxs9n=E>pOeUKQR@*cV zyHswwhkW)aLg()x9qvjwCdxS_C^^TgUx?FojXCOe)4=0~>E)<%-q#&`BHaA0UI`5Q z&&dT#(gVO~We~Dj`JX+x8Hm?jl~HN+44pE$h$9t0>PfEfgUL4XzncKHE$1ZIx>3>*Q>5fJd2|1V#`?*H!s zU`pTsWB>pwfq5k`tOO>Nz+52!6#_&dfD-~BAwUuOXZS&SMi#mzw%X<{8kUz;&-y7^ zh057PO4-GTolg*UxF_J4w#Vrar%Mi-%QNN+&*@#uXfIY!U92K^d%er8j>N5j$o&n0 zdo#X!E3SJxwtEMbdndxZYb!mv5guJ2u{^r4JvwnbI`BN&2|U_}JX%ORn#nG`p}5pY zeW{-QaxIhRYc|hU++LOZ-sPfK$|QY?<$McO{GMq9j!6_5c7XHy(9mtr`I!O>-2gB>^!|*T=3~dIV9NP zS|Uina@;SgW&#kup@01WCIq3sz~KeWST1fso;_f`2+7MQ29l3o9F-FM{1W^E=#=Ca zkQ5O7o`OP>+bJa^3?+&UCM7B=jYLX|iOGmd$Vf`cN=xsRm6h8IL4^QN=x?BZ0rD3> zeYso!TrUqd_e&lgo|i6rUH0_$^t$5Z<>Te;>wU%ViVsMCkUqWvAbtG;LHhZF48lzR zfFS>XU^qj=u0}=zM95801jofe%x9>xyWP!2*T37GT2KT-0rzjAVt6|+nz*1ih61yf zi++#l>3)AfcXu)0K-^@E*wOEWOKenq4ROdoSq%zm&_o3sThIsvwe!ECYKFghzk`$k zkz{P_7xb@f7RlD(1xFY5T!o#m{zU)sN1X40LCOJoEDH4dThfB?E$8ZRbJOT$jBc!3jqGZ5jzInm8inl+(o?P$Y&(;(w)Bs*x}{a#>EEkft~~$vBhJ!)uPmGK6wRo6;*9bE#1>b zrr`4pD0SO}IzMomLn|M!>hbd>4k#L!N(PWL;0qlrV_=FI;C{CwfTRHemNYP5QR>DI z^2Q&ej-Ns2nBoT-v9se1I8N}1+M$cUr|aj}t@DQZv3=tH^mF?(ZvBK02_LSZEaXfQx=$%9;M3JQzBB^O+9xA^A3^%|VXf6-+YT@gbJA%G4- zv4Va$mheq>8!L^b13_Fq6qOHUfxHT04HL%)qi&$fY%AhhQ~Yvva%I3bO@6gd-5dM0 zNXdxfWyMCy_tHxoP^iisWe7G_4JQqY3a^Xi-7S6!TxL}`k(Tw`$L2x+=jQxoUuAxp zPSS3@e)@w?Cn5+q^*Rjdp9WVFY~HAkJJ>md?X#&!ZB%*7PKDIqYa%;swtY{wdG!sc ztI{(D1>Y)CPk8D&7Ol+0IyS zZ3HnLU0G0~e!X!o*=SA;+X7GQOa6hEBUW~shNoXia|Ve8V79CXa8CeNa}`7y;F<$S zB_K@#KpkkDz#=0!VX%M*L__#Ufzty{3^*dN*atr8;8P5LY{3T+eEi@K6!@foPXzcl zzC0FLC2|COJA1^j_u{vzgIME?Qs=D!qMG^^Hsu`8wME^x~Ek3Y~&*`v3f zo!R;58@}ed;#&eIvkWN;5ahmQ2!wi3=Ece7N1ZtYHTNIt<5u)P^Ux`{ct>j30E=qk zuX(_RNRiQL=_7uLkXD?eyj6ZzdEo>BEDU7SknOxD2 zFyuujb24fDh4;*nin;G)PFHcbIZ09(gYr;sa3mEQOa4-Kd$k{~?pLhy@19oJ?d~uk z*Yc&c%-!UDab#st`HiM>_5o89iN%;VmFw#Ahzj4idxC%;MTGmShov|jq2wC44_aPoa=3r-@P!o@ty@YIml+x0shT~jcds}yk4Vkx1?0gsvCtF zP~7afXn9s|LBH$VfmFI)MNf^Ozg+)XFd6M9Krc~7nG`aS_9 zzblls=~_OlnSAPDB2yFlBNPSr4@RF9IC?b>LYpVJ*%}^Cf~3rQ_~ug?>8Y7hnOOx> zQ;#6D`84cmp0Sxc{iO8s)O2m(G5!a_vnrgf{;;SG5CePF6Lv zMYBRlnS5z5&1#{6BY=0Yam&>_Yw?Z33T#j0+9W`IeyLRxWltnCv(&!rN-5RGf9CPF zt2tWAv`%|0-M!~2a5aa}<~v*|W%{{sMOKFb=^S>rQtln*&;vB9IIAZ+Tq)(o*d9Dt zhiO(hH6jqr3U;NGpJrM5grZsPaHUk3V^#w+s}6m~ZC6VD-O5<+LPUWp<<;`awF!u3 z^|5ev^9$rkx$Z`TgzSm3zkOxc=}Jk;j@ZCLU~@yR=E=BJ9)84zbN=*=5X}l@PsH9h zgw3GoOCAqsR);tUg)6>GnVMCMz@7-n%t7P~+Y@a{C-|bJ%tQB4_C$Ou% zmB>+S13t&rG%L-TEmunBCQa3S>+_Mm zq-R(-l)p=vbtrqH(Dz(K99k$>^Ke(+AEZpJ`eT=m-B`+r8HF~FK9~u)QpOW2Q;_3qNtt%1ra65X)0ZEckzu$h zLLEO_#9>4lP}y*BfWAgZKmc7x0E3g1lw#K|DnQ~SC#R*Lpr@o{prmA^qGF<^W~QcQ zp`iiEN<+g&OA9AE%6tjjOyK08qvN2b-%17s4h9BJCMGUs7H(G7J#6f}92|U{ocvr| z0^Fdlz$3)VC&Dj)6ciE{7M4UJWh5l!!Rb}m^}x@XZ!+r|GIN*hXM0~#BU*h;|lqqwB3q!i=}a1SXhD+dX=Exo9CQC?AwDltKU ziCJ1=7L~sA9B`JFJ})n?eEz(; zva*Kq!(Ly5AmFfe2GNbb{sC?bUq^m?h0B&lpyTI+QrZO2jw}iWcox-R&;%C!{Qdor z%=^Qcd&s%>M{^&~Yz#eS-f#O z6K!dS?;i9v$jPk8fB?kx&mMJWn^j=~hzlO~6=EuFTN7A4PYh||EHkTuq>>E11jJq+ zi{g-vkdSj?@wRNvTVL0|JO>uK-F!1{fXv5rNvQ- z@YA9qWnWfEq*ncXbgQnf%}K46+$~q|Sy^8T8T7y+jx+JYKN(`?Uno2gDfg{%ELmw( zP16wX!`V0vS&2EUJ}k!I^d_Pl{wR*UADVLfcL}@g8j5DeH|!lFXe-!DfENO-=sYDUJXwtZovlj!-RbNtR51Y^2E zzzZASdm%2jChp+*cBUWWeJ&BD5*>UZRsP78y~?RpYgPPMCI^TG?x)17`KG101wB-z ze6Vh5`{*2&Zbj_VcpCl`f6R6>RMA->&i$(03=|+@V&MC-Yu7Fca&jsPN*XFEI_j;q zG7D%Z(=)I!FtRf;aWFA)GBb0rK-C%#D;rd>v4iB`tU2(tSY92MWIJQt!`29{iAW{<)$%@Cxg% z`>&vx`cmsw^O^`?DY0bW3})&%mBjVJ!0gm59`KO76!lQ`j^u^lS7A|UZ|*W%VzXqn zjw_|8MemUe*ULDTdL-qtkmj?Djz|BsiVlZ_^-$42@sMN`Dsug+JtH{l^0U#dCk$2B zAA3lje^ubf^ycv$Wg@TUYOdp|RyTYbO_1PcQGlKxhsT zJ%orBvfxD?w44PLEjXa<9aO-}JLo}0u)Kr0zXLk+aQwWygOJ#RyX@0vZ7<=Kj3D15^Vze%{>K zv9<&6>wxJ?I;|lg# zrK{F)uHs*qI%rr_Ym|UzKQ7 z1ex`p1nPtW~WdXShTQ=zfsl z|Mko2Z2Mqyc{xDp7l}62a%i)uufZUIjIhfBP z5Pty&ivec$vDz`;g5uTq)m{lsXbauT^8vofvCnd_5vXYLbg zzz&~8XE}mut)t`_a*ko$GID#af-s==55lu|wHdo@?ZS_Zdp31)?2hrC3~pTR3Y+mn zkFgBiBwvIDkBWhtuI1f8N`Yzw2Q{%KAz}kZ`96mNxnD{cwuPTElThzO%2h?D*9^qE znG@*`Vu(W%E`*z*+u%5sAT%7!DqSFciO^jVIDpME(W-)N;fqkttqE@x zqGl#-5Xxg$U=PM)qQ7dN4cg%6v(xL^?o8NPYCF_~X=34Hg>L8E>{SB`dvZ0CA$v<@xy)ihzA{UP*M&FoN<%6s*jRIw4Zz`Z zsez#ZHxfr%>HKo1ffZR0vyD>1HHKNzCny^wdV`) z2|ZdqZ}#DIKlaCRxGN0W;8d*74$aEyu8v%j`2MCz7ThzSpdDzLGZ^ zGIf|OT{QKYA6KDK18s0qYa}^=Df3qygp})S1?7lnrJwSU`=IrDrfBXfEbODcUm;Tm z^&1NaB$3iCS2M`eAsIoSS@F$Ag`{0V6K_{7%G3eg=usg~<@LEdS|g9I3%9{ZIdC88 z25rQ(C~{+N^q7<4_*M!in=$N}@+EbL+u-v;f&M$&;L->LE4c-JA6C{L)JBg5?Yo-q zZE$F#hvFK!HGvYL6EJlEZE(pHiZOH>9JSH2K7XBqz5-8St_HQyv&2PC3%9|euE85U zD2GqfM$dt%q3C4NhkP2K4IaO6GyM>}(Nnx|D~I$0={YT6>aY+~1WX;=>l#ef7h)?& zQ;}e!$FN{1uJ+K5jh-f3!^QZwhsKBs>Y5x-8$CPQ;0~C!PQfaCx}FYN4`unQ&ZLHR37 zJK$*dPg&Z@%I}lery`@MF0HI7rJ^ml|A?g8Q3>_q;s;KMYv?023`I0egtW{Av@8S; zTJj$}3#Im10qwJb+Gm6hokbq9kT`5Eeb`L)h?$&@se-Pl(os{DV3zlLijS`kdVvEJO+i7Z32?CYd^PN9MEJGqS0f^?Mnqk^{#Qigjq6d-U{(#- zQvzd3u)h3%Z+D}=zaKUG{lnn*dw9-e478b{Sr?QCC0N}6&1Tg7WaiThyte_HPlDF- z@-kEepsD~+2cT{vsMhlrs5^tcl>DLsaN-a(A>)E7fDx60#X`3IwSQTVY88=-Flgm* z*Inm3&KQVQ*Hy_wVxF0Bn=+Wo5dSQz>xvF<(_KbWWcY~|UKQ&jHyH5h_3o3XXA_Ei z4Owa}%Q&1b;QCj3X9dsF1j|K>XK7ve6sMUDd7Q$s_(yP0mUYuUHV#_pNS)fNv%CMf z=`6A0>UH&d$B|#;IJ9NvhH7wHbJ@A`9ZzLM&8|~TWarD|6X%{wozxjPN0WZ^>Jxc6 zI~!bC{h~G7yw6iz%%+ROL(NPCM~Y6%M};UiE785Yo=>F6h=;9!J#RK=6@jxjEu6K6 zXt0p&J4%>XbrAWpN^(7 zilsEZO=%KOX>#Z9Ow$BP(>wn#sZ8%snLeoC%sAI5^YnZj0pQDGbo2L)3rv2O75*e9UnU9{NXXT|nF35b653VKPPV&#J zbd|oSC@p_kQc+!8Sy%kBq3~sMK~>xHS1m89n<`&7RM*t~gDJT7_V$j>j?S)*uI|pR zw_V*m-EVu}_VoAk4fOU8^}QSJ8yM{yeBVFx;ob1qyW#PHk%__4$)Wd?!|$g?K1{wJ zn;M&#f+VP|=fX$uSeTie|1`TWJGX#pQY@gm6sYIJR-*zfOTkYD=&^7ZQI0uUj=WbC zWC{j3X~!9>f~il>P!aAnd3o&%dqLiD2Mgv10=$9t{gm9Q!Gfa+q-)|M<+u2#Om4=t z?a>Lv3%Ek`?{~ufn_jZ=sv1&S1_H+~aGVYWpKGxBL~LJ7;8=<0RE_IggX3I_<6QUm zq)R=HOWki0{1%kBTUm$aQitzSOL(D%Y=1l0*)!PP zJJ{1d*!OM__4PYAG(0jq@_u;q!^r!w(GL@&W7DJKGan{Cj!jHM-@E7&HZuda1>siU zk4uyAH!$=C3{DvQ#ryq)X(LvCJYi3RJQ-QDXlj|k346FkW&OtJ<+V-rF4gz*Y_$Q{ zvtpc=D9@_h^24?{u)hvH?=x{ z%Gy=W)>FsMPuo63hbR@tXeGy(y-tae&M5*eS&}XfWnGdLFC;2oNZ9XsN8{pc zZMRrm_gg2y7UQKLYfn!nFBkVK_C7w=zP>hoe&_xDF9ZZ!{=1iwA7^K8nYaJElw4d~ zSXx?GR#y1pMNvh?^UBJSmoHybRe?QyL8&A~NA8TmPYi!i}MPb`wR^-HB+CkupC&)SY&mKrM% zsk}V5Fa<^>L`%KgaGDpj--^Dda3c{M@Z6o-XEe{Loy5$*`=Ks`rLasU8^CH75yQAM zdrcGC(~qZgm5Q^Kf!0<#PT;PzkKG$1UVTj^D}}OICwApSUd^6Q?H1)79Ag~@OK*MM zm9)@RHvKk#Q2U93{EJh~_Yw-jxyWQM-uyb3VcMKjvanpX88o}kqRxpHQhqv@mxytb@^hMU9x!l^erN!2i{T$7R|LsD*DD*Qbgf5 z5wQ3lh~eRJr9XN5maS1z>e*A6t@!`q^NNg&4CsR7yLSU=kP=b{p}ROW6%{oNuwtgA zrK6*xr>6&&%wQu7@VS67^S`IJyq4|>^`oa%j+-m$os&CZCwtOSO5a7oz)jr1L->?8 zzhMC9>2UtjLBgl~#Eq^<8hJ|_d+#;z+Gl!M#nj_~nVYtS>rqQ*gEJ0h=j^Plt!->< zfakoOot?eC{durK(?W}H-1b^ELaHx(f}+6fZddb4Wx9O2gIkj)EH9 z%!fPq;1#oz4>$0CZr#Hi1<<93Tl5e)3&qX?9e6lE`yCE+6CSkOQGf;TEUT-nYp82z zs&8s(XlZY3?P_d)+tk_jrhA~dXSk*Bee1wP+wjMZ(YemCrOxrsT@x!%PVUU^$rU)? zPOXCMnOg0gUhV(5`fg@z@YC9dxwXlKwb|vhg%#*AxW2Ku@#EmvuljdJ!xWr zxBRyw%G9#R!ADOi1x*qRR7usY(b?TT^j!Qy6`QHeK;x-=TpuL)#eu932>`CuY*YDB z>=uA)8T;US^A$|DW$4TvYbs93fJVELW@f87hEtu!Pd@n2J2k+p4&YkGdbsf-q({G{ zF-tAJYrf}mdP(g?=_Q@+Tqc3$uf0;UhHi_rK4Q_J72n=&f0Qp;SvW+}s@FX&NW)b9 z7I%8G|9X?F4hfFUa0Go5g~5;?v-(CqDrI{f2o!oNim;Ljx#phE~M9_Bt^!F z`s7tI<0Jy}Ox!bh*yjqctezvRiV;>Ne_L9YBCJdPVPaXAU|ARASQq13KgYKzBC;vi zW&4!ME|wI=9%RNpd=mFC z_hwqb_4KmX%#y^6y!)9s>5m?xx7+^tCII{}`u-TIdR6(Vrn0&YbO0)9nqJhjmDYBY z*S5W?Z?0)*ZfFF&LmX_AG_SW{!wvO($&Yrfe-uCYP_P6iadj{KkhFg0_ zJNibt`i6V@hkFM``UXeejf@SxpBx&W8J?UQnO^+x>GSy9>cql2$jLwF;`-#T^ULJo zRzf9|<`x~|1>m}TqDn{JD+sb?WL0xJ2whRwh^cu+%wGp!^Skx0P;fI|NEe8ae7^fb z#_`=$CTa}FqGijD*tH{|ED2 B4+a1L diff --git a/docs/img/mcp/gemini-mcp.gif b/docs/img/mcp/gemini-mcp.gif new file mode 100644 index 0000000..5b859e2 --- /dev/null +++ b/docs/img/mcp/gemini-mcp.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d186d314f5b792a95c767cca400f252066297098653b4e1109a0e63813662d8 +size 20279546 diff --git a/docs/mcp.md b/docs/mcp.md index 837bbb7..bf72186 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -71,6 +71,31 @@ To use the Cadwork Python API documentation as an MCP server, you need to config [VS Code MCP Documentation](https://code.visualstudio.com/docs/copilot/chat/mcp-servers){target=_blank} -## Usage +??? note "Gemini CLI" + Gemini CLI supports MCP servers natively through its command-line interface. + + **Prerequisites**: Install the Gemini CLI first: + + ```bash + npm install -g @google/gemini-cli@latest + ``` + + **Add the server**: + + ```bash + gemini mcp add --transport http cadwork-pyapi https://pyapi.mcp.cadwork.dev/mcp + ``` + + **Verify the connection**: + + ```bash + gemini mcp list + ``` + + Once added, the Cadwork Python API documentation will be automatically available when you interact with Gemini CLI. + +