Refine column support selection and polygon handling

This commit is contained in:
sudhir
2026-05-10 12:51:57 +05:30
parent 0514363136
commit 4956de4910
5 changed files with 65 additions and 83 deletions
@@ -1,5 +1,4 @@
import { type SiteNode, type SlabNode, useRegistry, useScene } from '@pascal-app/core'
import polygonClipping from 'polygon-clipping'
import { useMemo, useRef } from 'react'
import { BufferGeometry, Float32BufferAttribute, type Group, Path, Shape } from 'three'
import { useNodeEvents } from '../../../hooks/use-node-events'
@@ -88,24 +87,16 @@ export const SiteRenderer = ({ node }: { node: SiteNode }) => {
for (let i = 1; i < pts.length; i++) shape.lineTo(pts[i]![0], -pts[i]![1])
shape.closePath()
if (slabPolygons.length > 0) {
const multiPolygons = slabPolygons.map((p) => [
p.map((pt) => [pt[0], -pt[1]] as [number, number]),
])
const unioned = polygonClipping.union(
multiPolygons[0] as polygonClipping.Polygon,
...(multiPolygons.slice(1) as polygonClipping.Polygon[]),
)
for (const geom of unioned) {
const ring = geom[0]
if (ring && ring.length > 0) {
const hole = new Path()
hole.moveTo(ring[0]![0], ring[0]![1])
for (let i = 1; i < ring.length; i++) hole.lineTo(ring[i]![0], ring[i]![1])
hole.closePath()
shape.holes.push(hole)
}
for (const polygon of slabPolygons) {
if (polygon.length < 3) continue
const hole = new Path()
hole.moveTo(polygon[0]![0], -polygon[0]![1])
for (let i = 1; i < polygon.length; i++) {
hole.lineTo(polygon[i]![0], -polygon[i]![1])
}
hole.closePath()
shape.holes.push(hole)
}
return shape
@@ -1,5 +1,4 @@
import { type LevelNode, useScene } from '@pascal-app/core'
import polygonClipping from 'polygon-clipping'
import { useMemo } from 'react'
import * as THREE from 'three'
import useViewer from '../../store/use-viewer'
@@ -63,33 +62,16 @@ export const GroundOccluder = () => {
polygons.push(node.polygon as [number, number][])
})
if (polygons.length > 0) {
// Format for polygon-clipping: [[[x, y], [x, y], ...]]
const multiPolygons = polygons.map((pts) => {
const ring = pts.map((p) => [p[0], -p[1]] as [number, number]) // Negate Y (which was Z)
return [ring]
})
for (const polygon of polygons) {
if (polygon.length < 3) continue
// Union all polygons together to prevent artifacts from overlapping
const unionedPolygons = polygonClipping.union(multiPolygons[0]!, ...multiPolygons.slice(1))
// Add each resulting unioned polygon as a hole
for (const geom of unionedPolygons) {
// First ring in each geometry is the exterior ring
if (geom.length > 0) {
const ring = geom[0]!
const hole = new THREE.Path()
if (ring.length > 0) {
hole.moveTo(ring[0]![0], ring[0]![1])
for (let i = 1; i < ring.length; i++) {
hole.lineTo(ring[i]![0], ring[i]![1])
}
hole.closePath()
s.holes.push(hole)
}
}
const hole = new THREE.Path()
hole.moveTo(polygon[0]![0], -polygon[0]![1])
for (let i = 1; i < polygon.length; i++) {
hole.lineTo(polygon[i]![0], -polygon[i]![1])
}
hole.closePath()
s.holes.push(hole)
}
return s