integrate ganjihong engine refactor

This commit is contained in:
2026-09-09 18:41:56 +08:00
parent cf9cd0366a
commit 21a5185926
116 changed files with 3596 additions and 12259 deletions
@@ -14,7 +14,7 @@ from OCP.BRepFilletAPI import BRepFilletAPI_MakeChamfer, BRepFilletAPI_MakeFille
from OCP.BRepOffset import BRepOffset_Skin
from OCP.BRepOffsetAPI import BRepOffsetAPI_MakePipeShell, BRepOffsetAPI_MakeThickSolid, BRepOffsetAPI_ThruSections
from OCP.BRepBuilderAPI import BRepBuilderAPI_Transform
from OCP.BRepPrimAPI import BRepPrimAPI_MakePrism, BRepPrimAPI_MakeRevol
from OCP.BRepPrimAPI import BRepPrimAPI_MakeCylinder, BRepPrimAPI_MakePrism, BRepPrimAPI_MakeRevol
from OCP.Geom import Geom_SurfaceOfRevolution
from OCP.GeomAbs import GeomAbs_Arc
from OCP.LocOpe import LocOpe_DPrism
@@ -23,7 +23,7 @@ from OCP.TopAbs import TopAbs_FACE, TopAbs_SHELL
from OCP.TopExp import TopExp_Explorer
from OCP.TopTools import TopTools_ListOfShape
from OCP.TopoDS import TopoDS
from OCP.gp import gp_Ax1, gp_Dir, gp_Pnt, gp_Trsf, gp_Vec
from OCP.gp import gp_Ax1, gp_Ax2, gp_Dir, gp_Pnt, gp_Trsf, gp_Vec
from .parametric_bend import build_bend_solid
from .parametric_gears import build_gear_solid, build_rack_solid
@@ -1136,6 +1136,37 @@ class Build123dGeometryAdapter:
)
return Solid.make_cylinder(radius_mm, height_mm, build_plane)
@staticmethod
def cylinder_with_topology_delta(
radius_mm: float,
height_mm: float,
axis: AxisSpec | None = None,
) -> tuple[Solid, TopologyDelta]:
"""Build a cylinder with exact OCC witnesses for its two cap faces."""
origin = axis.origin_mm if axis is not None else (0.0, 0.0, 0.0)
direction = axis.direction if axis is not None else (0.0, 0.0, 1.0)
placement = gp_Ax2(
gp_Pnt(float(origin[0]), float(origin[1]), float(origin[2])),
gp_Dir(float(direction[0]), float(direction[1]), float(direction[2])),
)
builder = BRepPrimAPI_MakeCylinder(placement, float(radius_mm), float(height_mm))
builder.Build()
if not builder.IsDone():
raise ValueError("OCC cylinder operation did not complete")
result = Solid(builder.Solid())
if not result.is_valid or not Build123dGeometryAdapter.body_solids(result) or result.volume <= 1e-9:
raise ValueError("OCC cylinder operation did not produce a valid solid")
primitive = builder.Cylinder()
relations = tuple(
TopologyDeltaRelation("generated", "face", result.wrapped, (face,), output_role=role)
for face, role in (
(primitive.BottomFace(), "cylinder.start"),
(primitive.TopFace(), "cylinder.end"),
)
if not face.IsNull()
)
return result, TopologyDelta(operation="cylinder", relations=relations)
@staticmethod
def intersect(left: Any, right: Any) -> Any:
# 布尔交:取两实体公共部分。结果可能为空(不相交或仅边界接触),
@@ -1242,7 +1273,21 @@ class Build123dGeometryAdapter:
relations.append(TopologyDeltaRelation("preserved", kind, source_value, (source_value,)))
if generated:
relations.append(TopologyDeltaRelation("generated", kind, source_value, generated))
return TopologyDelta(operation=operation_name, relations=tuple(relations))
section_values: tuple[Any, ...] = ()
section_edges = getattr(operation, "SectionEdges", None)
if callable(section_edges):
try:
# BRepAlgoAPI boolean builders expose the exact intersection
# edges. Builders without that API simply carry no section
# evidence; callers must not infer it from result geometry.
section_values = tuple(section_edges())
except (AttributeError, TypeError, ValueError):
section_values = ()
return TopologyDelta(
operation=operation_name,
relations=tuple(relations),
section_values=section_values,
)
@staticmethod
def _shell_topology_delta(