ceiling holes

This commit is contained in:
wass08
2026-02-16 08:59:28 +09:00
parent 6f4ba92862
commit 13070a5630
9 changed files with 410 additions and 33 deletions
@@ -566,7 +566,7 @@ export class SpatialGridManager {
/**
* Check if an item can be placed on a ceiling.
* Validates that the footprint is within the ceiling polygon and doesn't overlap other ceiling items.
* Validates that the footprint is within the ceiling polygon (but not in any holes) and doesn't overlap other ceiling items.
*/
canPlaceOnCeiling(
ceilingId: string,
@@ -588,6 +588,15 @@ export class SpatialGridManager {
}
}
// Check if item center is in any hole (if so, it cannot be placed)
const [centerX, , centerZ] = position
const holes = ceiling.holes || []
for (const hole of holes) {
if (hole.length >= 3 && pointInPolygon(centerX, centerZ, hole)) {
return { valid: false, conflictIds: [] }
}
}
// Check for overlaps with other ceiling items
return this.getCeilingGrid(ceilingId).canPlace(position, dimensions, rotation, ignoreIds)
}
@@ -10,11 +10,13 @@ export const CeilingNode = BaseNode.extend({
// Specific props
// Polygon boundary - array of [x, z] coordinates defining the ceiling
polygon: z.array(z.tuple([z.number(), z.number()])),
holes: z.array(z.array(z.tuple([z.number(), z.number()]))).default([]),
height: z.number().default(2.5), // Height in meters
}).describe(
dedent`
Ceiling node - used to represent a ceiling in the building
- polygon: array of [x, z] points defining the ceiling boundary
- holes: array of polygons representing holes in the ceiling
`,
)
@@ -70,6 +70,24 @@ export function generateCeilingGeometry(ceilingNode: CeilingNode): THREE.BufferG
}
shape.closePath()
// Add holes to the shape
const holes = ceilingNode.holes || []
for (const holePolygon of holes) {
if (holePolygon.length < 3) continue
const holePath = new THREE.Path()
const holeFirstPt = holePolygon[0]!
holePath.moveTo(holeFirstPt[0], -holeFirstPt[1])
for (let i = 1; i < holePolygon.length; i++) {
const pt = holePolygon[i]!
holePath.lineTo(pt[0], -pt[1])
}
holePath.closePath()
shape.holes.push(holePath)
}
// Create flat shape geometry (no extrusion)
const geometry = new THREE.ShapeGeometry(shape)