kompas-kernel 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. kompas_kernel/__init__.py +3 -0
  2. kompas_kernel/features/__init__.py +9 -0
  3. kompas_kernel/features/assembly_navigator/__init__.py +8 -0
  4. kompas_kernel/features/assembly_navigator/commands.py +37 -0
  5. kompas_kernel/features/assembly_navigator/ksapi/__init__.py +5 -0
  6. kompas_kernel/features/assembly_navigator/ksapi/mapping.py +122 -0
  7. kompas_kernel/features/assembly_navigator/ksapi/presentation.py +107 -0
  8. kompas_kernel/features/assembly_navigator/ksapi/raw.py +74 -0
  9. kompas_kernel/features/assembly_navigator/ksapi/reader.py +287 -0
  10. kompas_kernel/features/assembly_navigator/ksapi/resolver.py +35 -0
  11. kompas_kernel/features/assembly_navigator/models.py +218 -0
  12. kompas_kernel/features/assembly_navigator/queries.py +42 -0
  13. kompas_kernel/features/assembly_navigator/service.py +31 -0
  14. kompas_kernel/features/assembly_navigator/summary.py +90 -0
  15. kompas_kernel/features/document_session/__init__.py +5 -0
  16. kompas_kernel/features/document_session/checkpointed.py +165 -0
  17. kompas_kernel/features/document_session/commands.py +94 -0
  18. kompas_kernel/features/document_session/digest.py +126 -0
  19. kompas_kernel/features/document_session/ksapi/__init__.py +5 -0
  20. kompas_kernel/features/document_session/ksapi/context_reader.py +174 -0
  21. kompas_kernel/features/document_session/ksapi/screenshot.py +365 -0
  22. kompas_kernel/features/document_session/ksapi/snapshot.py +181 -0
  23. kompas_kernel/features/document_session/models.py +311 -0
  24. kompas_kernel/features/document_session/queries.py +62 -0
  25. kompas_kernel/features/document_session/registry.py +101 -0
  26. kompas_kernel/features/document_session/service.py +128 -0
  27. kompas_kernel/features/geometry_3d/__init__.py +9 -0
  28. kompas_kernel/features/geometry_3d/axis_math.py +50 -0
  29. kompas_kernel/features/geometry_3d/commands.py +68 -0
  30. kompas_kernel/features/geometry_3d/hex_detect.py +113 -0
  31. kompas_kernel/features/geometry_3d/ksapi/__init__.py +5 -0
  32. kompas_kernel/features/geometry_3d/ksapi/component_geometry.py +559 -0
  33. kompas_kernel/features/geometry_3d/ksapi/measurements.py +368 -0
  34. kompas_kernel/features/geometry_3d/ksapi/presentation.py +204 -0
  35. kompas_kernel/features/geometry_3d/models.py +216 -0
  36. kompas_kernel/features/geometry_3d/queries.py +96 -0
  37. kompas_kernel/features/geometry_3d/service.py +69 -0
  38. kompas_kernel/features/geometry_3d/wrench_zone.py +161 -0
  39. kompas_kernel/features/ksapi_automation/__init__.py +9 -0
  40. kompas_kernel/features/ksapi_automation/gate.py +282 -0
  41. kompas_kernel/features/ksapi_automation/models.py +75 -0
  42. kompas_kernel/features/ksapi_automation/namespace.py +12 -0
  43. kompas_kernel/features/ksapi_automation/run_python.py +133 -0
  44. kompas_kernel/features/ksapi_automation/runner.py +126 -0
  45. kompas_kernel/features/ksapi_automation/service.py +85 -0
  46. kompas_kernel/features/part_authoring/__init__.py +5 -0
  47. kompas_kernel/features/part_authoring/build_geometry.py +122 -0
  48. kompas_kernel/features/part_authoring/models.py +99 -0
  49. kompas_kernel/features/wrench_clearance/__init__.py +7 -0
  50. kompas_kernel/features/wrench_clearance/models.py +87 -0
  51. kompas_kernel/features/wrench_clearance/service.py +154 -0
  52. kompas_kernel/kompas/__init__.py +14 -0
  53. kompas_kernel/kompas/errors.py +11 -0
  54. kompas_kernel/kompas/models.py +68 -0
  55. kompas_kernel/kompas/objects.py +93 -0
  56. kompas_kernel/kompas/platform.py +40 -0
  57. kompas_kernel/kompas/runtime.py +186 -0
  58. kompas_kernel/kompas/session.py +195 -0
  59. kompas_kernel/kompas/units.py +48 -0
  60. kompas_kernel/ksapi_static/__init__.py +8 -0
  61. kompas_kernel/ksapi_static/facts.py +132 -0
  62. kompas_kernel/ksapi_static/inventory.py +185 -0
  63. kompas_kernel/ksapi_static/recipes.py +114 -0
  64. kompas_kernel/ksapi_static/wrapper_grep.py +83 -0
  65. kompas_kernel/observability/__init__.py +1 -0
  66. kompas_kernel/observability/logger.py +24 -0
  67. kompas_kernel/observability/setup.py +115 -0
  68. kompas_kernel/observability/taxonomy.py +27 -0
  69. kompas_kernel/py.typed +1 -0
  70. kompas_kernel/standards/__init__.py +1 -0
  71. kompas_kernel/standards/wrench_clearance.py +234 -0
  72. kompas_kernel/utils/__init__.py +1 -0
  73. kompas_kernel/utils/filesystem.py +82 -0
  74. kompas_kernel/utils/validation.py +21 -0
  75. kompas_kernel-0.0.1.dist-info/METADATA +56 -0
  76. kompas_kernel-0.0.1.dist-info/RECORD +77 -0
  77. kompas_kernel-0.0.1.dist-info/WHEEL +4 -0
@@ -0,0 +1,68 @@
1
+ """Framework-free public dimension-line commands for geometry 3D, over `KompasSession`.
2
+
3
+ No Pydantic AI, no `kompas_copilot.bridge` import — raw KsAPI presentation lives in
4
+ `ksapi/presentation.py`; this module wires it through session callbacks receiving
5
+ `KompasContext` directly and owns the explicit `ShownDimensionsState` holder that
6
+ `show_distance_dimension`/`clear_dimensions` share.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from dataclasses import dataclass, field
12
+
13
+ from kompas_kernel.features.geometry_3d.ksapi import presentation
14
+ from kompas_kernel.features.geometry_3d.models import ShowDistanceResult
15
+ from kompas_kernel.kompas.session import KompasContext, KompasSession
16
+
17
+
18
+ @dataclass
19
+ class ShownDimensionsState:
20
+ """Mutable holder for `IDistanceAngleMeasurement3D` references created by
21
+ `show_distance_dimension` in this session — owned by `GeometryService`, one per
22
+ `KompasSession` (mirrors the field that used to live directly on
23
+ `KompasKsApiAdapter`, `_shown_distance_measurement_references`).
24
+
25
+ `clear_dimensions` below reads and rewrites `.references` INSIDE the same worker
26
+ queue item (`KompasSession.run` callback) as the KsAPI delete calls, not after the
27
+ `await` returns — so two concurrent `clear_dimensions()`/`show_distance_dimension()`
28
+ calls on the same service can never interleave a stale read with a write (the
29
+ property the legacy adapter's `_clear_dimensions` docstring called "update stable
30
+ state in the same queue item").
31
+ """
32
+
33
+ references: list[int] = field(default_factory=list)
34
+
35
+
36
+ async def show_distance_dimension(
37
+ session: KompasSession,
38
+ component_identifier_1: str,
39
+ component_identifier_2: str,
40
+ state: ShownDimensionsState,
41
+ ) -> ShowDistanceResult:
42
+ """Показать место зазора: создать ПОСТОЯННУЮ размерную линию между компонентами."""
43
+
44
+ def _operation(context: KompasContext) -> ShowDistanceResult:
45
+ return presentation.show_distance_dimension(
46
+ context.modules,
47
+ context.app,
48
+ component_identifier_1,
49
+ component_identifier_2,
50
+ state.references,
51
+ )
52
+
53
+ return await session.run(operation_name="geometry_3d.show_distance_dimension", operation=_operation)
54
+
55
+
56
+ async def clear_dimensions(session: KompasSession, state: ShownDimensionsState) -> int:
57
+ """Убрать все размерные линии, созданные `show_distance_dimension` в этой сессии.
58
+
59
+ `state.references` перезаписывается ВНУТРИ того же callback, что и сам вызов
60
+ `IFeature.Delete()` (см. `ShownDimensionsState` докстринг) — не после `await`.
61
+ """
62
+
63
+ def _operation(context: KompasContext) -> int:
64
+ deleted, remaining = presentation.clear_dimensions(context.modules, context.app, state.references)
65
+ state.references = remaining
66
+ return deleted
67
+
68
+ return await session.run(operation_name="geometry_3d.clear_dimensions", operation=_operation)
@@ -0,0 +1,113 @@
1
+ """Pure hexagonal-prism detection from exact planar-face facts — no KsAPI, no mesh.
2
+
3
+ `PlanarFaces` (from `features.geometry_3d.ksapi.component_geometry.component_planar_faces`)
4
+ already did the only KsAPI-touching work: found every planar face of a component whose
5
+ plane is parallel to the component's own axis, with an exact radial distance and exact
6
+ corner points (see that function's docstring — no tessellation anywhere in that path).
7
+ This module only clusters those already-computed facts — pure math, consumes DTOs, same
8
+ shape as `wrench_zone.py` (no pydantic-ai, no bridge port calls).
9
+
10
+ A hexagonal prism (a bolt head or a nut) presents as a GROUP of side-wall faces sharing
11
+ one radial distance from the axis (K = S/2, ГОСТ 13682-80) — a live check (2026-07-07)
12
+ found 6 for a plain nut and 12 for a bolt head (KOMPAS split each flat in two at the
13
+ under-head bearing chamfer, both halves at the identical radius) — hence "count is a
14
+ multiple of 6", not "count is exactly 6".
15
+
16
+ The z-zone this produces plugs directly into `measure_radial_distance`'s
17
+ `z_min_mm`/`z_max_mm` (same axis-projection convention, `axis_math.py`) — replacing
18
+ the LLM's hand-guessed zone that caused the false "Покемон mешает гайке" verdict this
19
+ task originates from (see AGENTS.md §«KsAPI: точный B-rep вместо меша/тесселляции»).
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ from pydantic import Field
25
+
26
+ from kompas_kernel.features.geometry_3d.axis_math import axial_and_radial_mm, unit_axis_direction
27
+ from kompas_kernel.features.geometry_3d.models import AxisLine, PlanarFaces
28
+ from kompas_kernel.utils.validation import CustomModel
29
+
30
+ _HEX_FACE_COUNT_DIVISOR = 6
31
+ _DEFAULT_RADIUS_TOLERANCE_MM = 1e-2
32
+
33
+
34
+ class HexPrismRegion(CustomModel):
35
+ """One hexagonal-prism region found on a component's own axis, mm.
36
+
37
+ `z_min_mm`/`z_max_mm` — axial extent along the `AxisLine` passed to `find_hex_prisms`
38
+ (same convention `measure_radial_distance` expects for its own `z_min_mm`/`z_max_mm` —
39
+ a region's bounds plug straight in, no conversion). `across_flats_mm` — 2 × the
40
+ group's shared radial distance (= S per ГОСТ, measured from geometry, not looked up —
41
+ useful as a cross-check against `search_fastener`'s S). `face_indices` — which
42
+ `PlanarFaceFact.face_index` values formed this region (diagnostics/highlighting).
43
+ """
44
+
45
+ z_min_mm: float
46
+ z_max_mm: float
47
+ across_flats_mm: float = Field(gt=0)
48
+ face_indices: list[int]
49
+
50
+
51
+ def find_hex_prisms(
52
+ axis: AxisLine,
53
+ faces: PlanarFaces,
54
+ *,
55
+ radius_tolerance_mm: float = _DEFAULT_RADIUS_TOLERANCE_MM,
56
+ ) -> list[HexPrismRegion]:
57
+ """Group axis-parallel planar faces into hexagonal-prism regions, sorted by `z_min_mm`.
58
+
59
+ Grouping: two faces belong to the same region if their `radial_mm` (already computed
60
+ exactly by `component_planar_faces` — see its docstring) match within
61
+ `radius_tolerance_mm`. This is exact B-rep geometry, not a tessellation fit, so the
62
+ default tolerance (0.01 mm) only absorbs float noise, not modeling error — a real
63
+ hex flat's radius does not drift between faces.
64
+
65
+ A group is kept only if its face count is a positive multiple of 6 (a hexagon has 6
66
+ side walls; KOMPAS may split each flat into more than one topological face at a
67
+ chamfer/fillet transition, always in multiples of 6 for a regular hex — see module
68
+ docstring). Groups that don't fit (stray coplanar faces from unrelated features
69
+ landing at the same radius by coincidence) are silently dropped — a false NEGATIVE
70
+ (missing a real hex) is safer here than a false POSITIVE feeding a wrong z-zone into
71
+ `measure_radial_distance`.
72
+
73
+ Each kept group's `z_min_mm`/`z_max_mm` is the union of its member faces' corner
74
+ points projected onto `axis` (`axis_math.axial_and_radial_mm`) — the group's full
75
+ axial reach, not a single face's.
76
+ """
77
+ unit = unit_axis_direction(axis)
78
+ axial_ranges: list[tuple[float, float]] = []
79
+ for fact in faces.faces:
80
+ axial_values = [axial_and_radial_mm(corner, axis, unit)[0] for corner in fact.corners]
81
+ if not axial_values:
82
+ axial_ranges.append((0.0, 0.0))
83
+ continue
84
+ axial_ranges.append((min(axial_values), max(axial_values)))
85
+
86
+ groups: list[list[int]] = [] # indices into faces.faces
87
+ for index, fact in enumerate(faces.faces):
88
+ placed = False
89
+ for group in groups:
90
+ if abs(faces.faces[group[0]].radial_mm - fact.radial_mm) <= radius_tolerance_mm:
91
+ group.append(index)
92
+ placed = True
93
+ break
94
+ if not placed:
95
+ groups.append([index])
96
+
97
+ regions: list[HexPrismRegion] = []
98
+ for group in groups:
99
+ if len(group) == 0 or len(group) % _HEX_FACE_COUNT_DIVISOR != 0:
100
+ continue
101
+ z_min_mm = min(axial_ranges[i][0] for i in group)
102
+ z_max_mm = max(axial_ranges[i][1] for i in group)
103
+ radial_mm = sum(faces.faces[i].radial_mm for i in group) / len(group)
104
+ regions.append(
105
+ HexPrismRegion(
106
+ z_min_mm=z_min_mm,
107
+ z_max_mm=z_max_mm,
108
+ across_flats_mm=2 * radial_mm,
109
+ face_indices=[faces.faces[i].face_index for i in group],
110
+ )
111
+ )
112
+ regions.sort(key=lambda region: region.z_min_mm)
113
+ return regions
@@ -0,0 +1,5 @@
1
+ """Raw KsAPI reads for geometry 3D: component geometry, measurements, presentation.
2
+
3
+ Everything that touches raw `IPart`/`IFace`/`ksapi.py` objects lives here, inside a
4
+ `KompasSession.run(...)` callback — no raw handle leaves this package.
5
+ """