feat: 完善一级关系编辑 UI 与视图体验
This commit is contained in:
+70
-3
@@ -80,14 +80,27 @@ class PolydataMixin:
|
||||
|
||||
face_key = _polydata_id_key(face_ids)
|
||||
part_key = _polydata_id_key(part_ids)
|
||||
cache_key = ("faces", face_key, part_key, float(deflection))
|
||||
requested_deflection = max(float(deflection), 1e-9)
|
||||
local_mesh_face_ids = self._local_fine_mesh_face_ids(face_key, part_key, requested_deflection)
|
||||
mesh_deflection = self._effective_face_mesh_deflection(
|
||||
requested_deflection,
|
||||
local_mesh_face_ids=local_mesh_face_ids,
|
||||
)
|
||||
cache_key = (
|
||||
"faces",
|
||||
face_key,
|
||||
part_key,
|
||||
float(requested_deflection),
|
||||
float(mesh_deflection),
|
||||
local_mesh_face_ids,
|
||||
)
|
||||
cached = self._polydata_cache_get("_face_polydata_cache", cache_key)
|
||||
if cached is not None:
|
||||
return cached
|
||||
|
||||
selected_faces = set(face_key) if face_key is not None else None
|
||||
selected_parts = set(part_key) if part_key is not None else None
|
||||
self._ensure_mesh(deflection)
|
||||
self._ensure_mesh(mesh_deflection, face_ids=local_mesh_face_ids)
|
||||
|
||||
points = vtk.vtkPoints()
|
||||
polys = vtk.vtkCellArray()
|
||||
@@ -137,8 +150,47 @@ class PolydataMixin:
|
||||
poly.GetCellData().AddArray(solid_arr)
|
||||
return self._polydata_cache_remember("_face_polydata_cache", cache_key, poly)
|
||||
|
||||
def _ensure_mesh(self, deflection: float) -> None:
|
||||
def _local_fine_mesh_face_ids(
|
||||
self,
|
||||
face_key: tuple[int, ...] | None,
|
||||
part_key: tuple[int, ...] | None,
|
||||
requested: float,
|
||||
) -> tuple[int, ...] | None:
|
||||
if requested > 0.04 or part_key is not None or face_key is None:
|
||||
return None
|
||||
valid_face_ids = tuple(face_id for face_id in face_key if 0 <= face_id < len(self.faces))
|
||||
if 0 < len(valid_face_ids) <= 64:
|
||||
return valid_face_ids
|
||||
return None
|
||||
|
||||
def _effective_face_mesh_deflection(
|
||||
self,
|
||||
requested: float,
|
||||
*,
|
||||
local_mesh_face_ids: tuple[int, ...] | None = None,
|
||||
) -> float:
|
||||
requested = max(float(requested), 1e-9)
|
||||
if local_mesh_face_ids:
|
||||
return requested
|
||||
face_count = len(getattr(self, "faces", ()) or ())
|
||||
if requested <= 0.04 and face_count > 600:
|
||||
# Ultra-fine analytic remeshing can create million-cell VTK meshes
|
||||
# on large STEP assemblies. Keep the B-Rep edit precision separate
|
||||
# from the display mesh budget so selection and rotation stay usable.
|
||||
return 0.1 if face_count > 1500 else 0.06
|
||||
return requested
|
||||
|
||||
def _ensure_mesh(self, deflection: float, face_ids: tuple[int, ...] | None = None) -> None:
|
||||
requested = max(float(deflection), 1e-9)
|
||||
if face_ids:
|
||||
local_deflections = getattr(self, "_face_mesh_deflections", {})
|
||||
for face_id in face_ids:
|
||||
if local_deflections.get(face_id) is not None and requested >= float(local_deflections[face_id]) * 0.999:
|
||||
continue
|
||||
self._mesh_single_face(face_id, requested)
|
||||
local_deflections[face_id] = requested
|
||||
self._face_mesh_deflections = local_deflections
|
||||
return
|
||||
if self._mesh_deflection is None or requested < self._mesh_deflection * 0.999:
|
||||
if requested <= 0.04:
|
||||
BRepMesh_IncrementalMesh(
|
||||
@@ -162,6 +214,21 @@ class PolydataMixin:
|
||||
BRepMesh_IncrementalMesh(self.shape, requested, False, math.radians(angular_degrees), True)
|
||||
self._mesh_deflection = requested
|
||||
|
||||
def _mesh_single_face(self, face_id: int, requested: float) -> None:
|
||||
if face_id < 0 or face_id >= len(self.faces):
|
||||
return
|
||||
try:
|
||||
face = self.faces[face_id]
|
||||
surface_type = BRepAdaptor_Surface(face).GetType()
|
||||
if surface_type in {GeomAbs_Cylinder, GeomAbs_Cone}:
|
||||
BRepMesh_IncrementalMesh(face, requested, False, math.radians(1.2), True)
|
||||
elif surface_type in {GeomAbs_Sphere, GeomAbs_Torus}:
|
||||
BRepMesh_IncrementalMesh(face, max(requested, 0.1), False, math.radians(4.0), True)
|
||||
else:
|
||||
BRepMesh_IncrementalMesh(face, requested, False, math.radians(12.0), True)
|
||||
except Exception:
|
||||
return
|
||||
|
||||
def build_snapshot_polydata(self, snapshot: dict[object, object], deflection: float = 0.8):
|
||||
shape = _compound_from_shapes(value for value in snapshot.values() if isinstance(value, TopoDS_Shape))
|
||||
BRepMesh_IncrementalMesh(shape, deflection)
|
||||
|
||||
Reference in New Issue
Block a user