ae28d55f81
Source: RGB-D -> Dyn-HaMR -> L20 retargeting -> FoundationPose -> reference repair -> SPIDER, documented in docs/PIPELINE_LATEST.md and docs/SETUP_AND_WEIGHTS.md. Adds FoundationPose and nvdiffrast upstream snapshots, requirements/pipeline_venv.txt and the FoundationPose weight manifest/downloader. Assets (Git LFS): weights/ (WiLoR detector, HandFlow denoiser, UniDepth-L), FoundationPose checkpoints, HaMeR checkpoint, Dyn-HaMR HMP model and BMC constraints, L20 URDF/meshes, the 20260915_171525 D405 recording and the two box CADs. MANO models are not redistributed (third_party/hamer/_DATA/data/mano/README.txt). Environments, caches and run outputs excluded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
15 lines
1.7 KiB
Python
15 lines
1.7 KiB
Python
"""Split one collinear T-junction; preserve all original vertices and surface geometry."""
|
|
from pathlib import Path
|
|
import json,trimesh,numpy as np
|
|
root=Path(__file__).resolve().parents[1];out=root/'output/depth_ablation_red_20260916';m=trimesh.load(root/'docs/上半.stl');old=m.copy()
|
|
c=np.bincount(m.edges_unique_inverse);boundary=m.edges_unique[c==1];edge=max(boundary,key=lambda e:np.linalg.norm(m.vertices[e[0]]-m.vertices[e[1]]));a,b=edge
|
|
v=m.vertices;ab=v[b]-v[a];t=(v-v[a])@ab/(ab@ab);dist=np.linalg.norm(v-(v[a]+t[:,None]*ab),axis=1);inside=np.flatnonzero((t>1e-7)&(t<1-1e-7)&(dist<1e-9));assert len(inside)==2
|
|
faces=m.faces.tolist();hit=[i for i,f in enumerate(faces) if a in f and b in f];assert len(hit)==1
|
|
face=faces.pop(hit[0]);k=next(k for k in range(3) if face[k] in edge and face[(k+1)%3] in edge);a,b,third=face[k],face[(k+1)%3],face[(k+2)%3]
|
|
inside=sorted(inside,key=lambda q:np.linalg.norm(v[q]-v[a]));chain=[a,*inside,b];faces.extend([[int(x),int(y),int(third)] for x,y in zip(chain[:-1],chain[1:])]);m=trimesh.Trimesh(vertices=v.copy(),faces=faces,process=False)
|
|
assert m.is_watertight and m.is_winding_consistent and m.volume>0
|
|
assert np.array_equal(m.vertices,old.vertices) and abs(m.area-old.area)<1e-10 and abs(m.volume-old.volume)<1e-10
|
|
m.export(out/'red_box_closed.ply')
|
|
(out/'mesh_repair.json').write_text(json.dumps({'method':'Split original long boundary edge at two existing collinear vertices (T-junction); no added vertices or geometric hole filling','before_faces':len(old.faces),'after_faces':len(m.faces),'watertight':m.is_watertight,'winding_consistent':m.is_winding_consistent,'area_change_m2':m.area-old.area,'volume_change_m3':m.volume-old.volume},indent=2))
|
|
print('Topology repaired with unchanged geometry',m.is_watertight)
|