From 872d8e5e0338dd565536f05e9d7268621cf5781b Mon Sep 17 00:00:00 2001 From: Yeicor <4929005+Yeicor@users.noreply.github.com> Date: Sat, 24 Feb 2024 11:00:34 +0100 Subject: [PATCH] share hashcode implementation --- yacv_server/server.py | 4 ++-- yacv_server/tessellate.py | 24 +++++++++++++++--------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/yacv_server/server.py b/yacv_server/server.py index 75e6fa8..98667a3 100644 --- a/yacv_server/server.py +++ b/yacv_server/server.py @@ -162,7 +162,7 @@ class Server: """Publishes any single-file GLTF object to the server (GLB format recommended).""" start = time.time() # Precompute the info and send it to the client as if it was a CAD object - precomputed_info = self._show_common(name, hashlib.md5(gltf).hexdigest(), start) + precomputed_info = self._show_common(name, _hashcode(gltf, **kwargs), start) # Also pre-populate the GLTF data for the object API publish_to = BufferedPubSub[bytes]() publish_to.publish_nowait(gltf) @@ -191,7 +191,7 @@ class Server: # Convert Z-up (OCCT convention) to Y-up (GLTF convention) obj = Shape(obj).rotate(Axis.X, -90).wrapped - self._show_common(name, _hashcode(obj), start, obj) + self._show_common(name, _hashcode(obj, **kwargs), start, obj) async def _api_object(self, request: web.Request) -> web.Response: """Returns the object file with the matching name, building it if necessary.""" diff --git a/yacv_server/tessellate.py b/yacv_server/tessellate.py index 2a34633..565a534 100644 --- a/yacv_server/tessellate.py +++ b/yacv_server/tessellate.py @@ -1,7 +1,7 @@ import hashlib import io import re -from typing import List, Dict, Tuple +from typing import List, Dict, Tuple, Union from OCP.BRep import BRep_Tool from OCP.BRepAdaptor import BRepAdaptor_Curve @@ -123,18 +123,24 @@ def _tessellate_vertex(mgr: GLTFMgr, ocp_vertex: TopoDS_Vertex, faces: List[Topo mgr.add_vertex(_push_point((c.X, c.Y, c.Z), faces)) -def _hashcode(obj: TopoDS_Shape) -> str: +def _hashcode(obj: Union[bytes, TopoDS_Shape], **extras) -> str: """Utility to compute the hash code of a shape recursively without the need to tessellate it""" # NOTE: obj.HashCode(MAX_HASH_CODE) is not stable across different runs of the same program # This is best-effort and not guaranteed to be unique map_of_shapes = TopTools_IndexedMapOfShape() TopExp.MapShapes_s(obj, map_of_shapes) hasher = hashlib.md5(usedforsecurity=False) - for i in range(1, map_of_shapes.Extent() + 1): - sub_shape = map_of_shapes.FindKey(i) - sub_data = io.BytesIO() - TopoDS_Shape.DumpJson(sub_shape, sub_data) - val = sub_data.getvalue() - val = re.sub(b'"this": "[^"]*"', b'', val) # Remove memory address - hasher.update(val) + for k, v in extras.items(): + hasher.update(str(k).encode()) + hasher.update(str(v).encode()) + if isinstance(obj, bytes): + hasher.update(obj) + else: + for i in range(1, map_of_shapes.Extent() + 1): + sub_shape = map_of_shapes.FindKey(i) + sub_data = io.BytesIO() + TopoDS_Shape.DumpJson(sub_shape, sub_data) + val = sub_data.getvalue() + val = re.sub(b'"this": "[^"]*"', b'', val) # Remove memory address + hasher.update(val) return hasher.hexdigest()