Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-05-24 22:53:23 +00:00
parent 7efac5448b
commit 7208e2bc56
+66
View File
@@ -1115,6 +1115,72 @@ function GridCalibrationHandler() {
return null;
}
/** Applies axis-aligned clipping planes (X / Y / Z) to every mesh inside the
* registered model groups. Listens to the section state in the store; when
* all axes are off, restores empty clipping arrays so meshes render whole. */
function SectionClippingApplier() {
const enabled = useModelStore((s) => s.sectionEnabled);
const invert = useModelStore((s) => s.sectionInvert);
const level = useModelStore((s) => s.sectionLevel);
const planes = useMemo(() => ({
x: new THREE.Plane(new THREE.Vector3(1, 0, 0), 0),
y: new THREE.Plane(new THREE.Vector3(0, 1, 0), 0),
z: new THREE.Plane(new THREE.Vector3(0, 0, 1), 0),
}), []);
useEffect(() => {
// Configure each plane: keep the half-space on the positive side of the
// normal. Inverting flips the normal direction.
(['x', 'y', 'z'] as const).forEach((axis) => {
const plane = planes[axis];
const sign = invert[axis] ? -1 : 1;
plane.normal.set(
axis === 'x' ? sign : 0,
axis === 'y' ? sign : 0,
axis === 'z' ? sign : 0,
);
// For plane equation n·p + d = 0, keeping `n·p >= level*sign_axis` means
// d = -level when normal is +axis, d = +level when normal is -axis.
plane.constant = -sign * level[axis];
});
const active: THREE.Plane[] = [];
if (enabled.x) active.push(planes.x);
if (enabled.y) active.push(planes.y);
if (enabled.z) active.push(planes.z);
const groups = getAllModelLocalGroups();
const touched: THREE.Material[] = [];
const apply = (clipping: THREE.Plane[]) => {
for (const g of groups) {
g.traverse((obj) => {
if (!(obj instanceof THREE.Mesh)) return;
const mats = Array.isArray(obj.material) ? obj.material : [obj.material];
for (const mat of mats) {
if (!mat) continue;
mat.clippingPlanes = clipping;
mat.clipShadows = true;
mat.needsUpdate = true;
touched.push(mat);
}
});
}
};
apply(active);
return () => {
// Cleanup: clear clipping from any material we touched.
for (const mat of touched) {
mat.clippingPlanes = [];
mat.needsUpdate = true;
}
};
}, [enabled.x, enabled.y, enabled.z, invert.x, invert.y, invert.z, level.x, level.y, level.z, planes]);
return null;
}
/** Mouse drag handler for desktop "Posicionar" mode: translates/rotates the active model. */
function PositionDragHandler() {
const { camera, gl, scene } = useThree();