Merge branch 'main' into feat/elevator-system
# Conflicts: # packages/editor/src/components/tools/item/move-tool.tsx # packages/editor/src/components/tools/tool-manager.tsx # packages/editor/src/components/ui/panels/panel-manager.tsx # packages/editor/src/store/use-editor.tsx # packages/viewer/src/components/renderers/site/site-renderer.tsx # packages/viewer/src/components/viewer/ground-occluder.tsx # packages/viewer/src/components/viewer/index.tsx # packages/viewer/src/components/viewer/post-processing.tsx
This commit is contained in:
@@ -1,7 +1,3 @@
|
||||
// @ts-expect-error — bun:test is provided by the Bun runtime; core does not
|
||||
// depend on @types/bun so the import type is unresolved at compile time.
|
||||
// The tsconfig in packages/core still emits this file; the @ts-expect-error
|
||||
// keeps the build green while letting `bun test` pick it up normally.
|
||||
import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
|
||||
import { ALLOWED_ORIGINS_ENV, AssetUrl } from './asset-url'
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ export const FenceNode = BaseNode.extend({
|
||||
materialPreset: z.string().optional(),
|
||||
start: z.tuple([z.number(), z.number()]),
|
||||
end: z.tuple([z.number(), z.number()]),
|
||||
curveOffset: z.number().optional(),
|
||||
height: z.number().default(1.8),
|
||||
thickness: z.number().default(0.08),
|
||||
curveOffset: z.number().optional(),
|
||||
baseHeight: z.number().default(0.22),
|
||||
postSpacing: z.number().default(2),
|
||||
postSize: z.number().default(0.1),
|
||||
@@ -30,8 +30,8 @@ export const FenceNode = BaseNode.extend({
|
||||
dedent`
|
||||
Fence node - used to represent a fence segment in the building/site level coordinate system
|
||||
- start/end: fence endpoints in level coordinate system
|
||||
- curveOffset: midpoint sagitta offset used to bend the fence into an arc
|
||||
- height/thickness: overall fence dimensions in meters
|
||||
- curveOffset: midpoint sagitta offset used to bend the fence into an arc
|
||||
- baseHeight/postSpacing/postSize/topRailHeight: exact geometric controls from the plan3D fence model
|
||||
- groundClearance/edgeInset/baseStyle: fence support and inset configuration
|
||||
- showInfill: whether to draw intermediate posts/slats between end posts
|
||||
|
||||
@@ -83,6 +83,18 @@ const assetSchema = z.object({
|
||||
// Optional top-down 2D image shown inside the item's footprint on the
|
||||
// floor plan. When present, replaces the default diagonal-cross marker.
|
||||
floorPlanUrl: z.string().optional(),
|
||||
// Where the item came from in the catalog. Used by the editor's items
|
||||
// panel to filter Library / Community / Mine. The server populates it
|
||||
// from `items.userId`: null → 'library', current user → 'mine',
|
||||
// other user → 'community'. Defaults to 'library' when absent (e.g.
|
||||
// the seeded built-in catalog).
|
||||
source: z.enum(['library', 'community', 'mine']).default('library'),
|
||||
// True when the item belongs to the caller and is still in draft status.
|
||||
// The catalog only loads my drafts (other users' drafts are never
|
||||
// published to the catalog). Used so the Community filter can include
|
||||
// *my* published items alongside other users', while leaving drafts
|
||||
// visible only under Mine.
|
||||
isDraft: z.boolean().optional(),
|
||||
src: AssetUrl,
|
||||
dimensions: z.tuple([z.number(), z.number(), z.number()]).default([1, 1, 1]), // [w, h, d]
|
||||
attachTo: z.enum(['wall', 'wall-side', 'ceiling']).optional(),
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
import dedent from 'dedent'
|
||||
import { z } from 'zod'
|
||||
import { BaseNode, nodeType, objectId } from '../base'
|
||||
import { type MaterialSchema, MaterialSchema as MaterialSchemaSchema } from '../material'
|
||||
import type { MaterialSchema as MaterialSchemaType } from '../material'
|
||||
import { MaterialSchema } from '../material'
|
||||
import { RoofSegmentNode } from './roof-segment'
|
||||
|
||||
export type RoofSurfaceMaterialRole = 'top' | 'edge' | 'wall'
|
||||
export type RoofSurfaceMaterialSpec = {
|
||||
material?: MaterialSchema
|
||||
material?: MaterialSchemaType
|
||||
materialPreset?: string
|
||||
}
|
||||
|
||||
export const RoofNode = BaseNode.extend({
|
||||
id: objectId('roof'),
|
||||
type: nodeType('roof'),
|
||||
material: MaterialSchemaSchema.optional(),
|
||||
material: MaterialSchema.optional(),
|
||||
materialPreset: z.string().optional(),
|
||||
topMaterial: MaterialSchemaSchema.optional(),
|
||||
topMaterial: MaterialSchema.optional(),
|
||||
topMaterialPreset: z.string().optional(),
|
||||
edgeMaterial: MaterialSchemaSchema.optional(),
|
||||
edgeMaterial: MaterialSchema.optional(),
|
||||
edgeMaterialPreset: z.string().optional(),
|
||||
wallMaterial: MaterialSchemaSchema.optional(),
|
||||
wallMaterial: MaterialSchema.optional(),
|
||||
wallMaterialPreset: z.string().optional(),
|
||||
position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
|
||||
// Rotation around Y axis in radians
|
||||
@@ -54,7 +55,8 @@ export function getEffectiveRoofSurfaceMaterial(
|
||||
if (node.topMaterial !== undefined || typeof node.topMaterialPreset === 'string') {
|
||||
return {
|
||||
material: node.topMaterial,
|
||||
materialPreset: typeof node.topMaterialPreset === 'string' ? node.topMaterialPreset : undefined,
|
||||
materialPreset:
|
||||
typeof node.topMaterialPreset === 'string' ? node.topMaterialPreset : undefined,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import dedent from 'dedent'
|
||||
import { z } from 'zod'
|
||||
import { BaseNode, nodeType, objectId } from '../base'
|
||||
import { type MaterialSchema, MaterialSchema as MaterialSchemaSchema } from '../material'
|
||||
import type { MaterialSchema as MaterialSchemaType } from '../material'
|
||||
import { MaterialSchema } from '../material'
|
||||
import { StairSegmentNode } from './stair-segment'
|
||||
|
||||
export const StairRailingMode = z.enum(['none', 'left', 'right', 'both'])
|
||||
@@ -15,20 +16,20 @@ export type StairTopLandingMode = z.infer<typeof StairTopLandingMode>
|
||||
export type StairSlabOpeningMode = z.infer<typeof StairSlabOpeningMode>
|
||||
export type StairSurfaceMaterialRole = 'railing' | 'tread' | 'side'
|
||||
export type StairSurfaceMaterialSpec = {
|
||||
material?: MaterialSchema
|
||||
material?: MaterialSchemaType
|
||||
materialPreset?: string
|
||||
}
|
||||
|
||||
export const StairNode = BaseNode.extend({
|
||||
id: objectId('stair'),
|
||||
type: nodeType('stair'),
|
||||
material: MaterialSchemaSchema.optional(),
|
||||
material: MaterialSchema.optional(),
|
||||
materialPreset: z.string().optional(),
|
||||
railingMaterial: MaterialSchemaSchema.optional(),
|
||||
railingMaterial: MaterialSchema.optional(),
|
||||
railingMaterialPreset: z.string().optional(),
|
||||
treadMaterial: MaterialSchemaSchema.optional(),
|
||||
treadMaterial: MaterialSchema.optional(),
|
||||
treadMaterialPreset: z.string().optional(),
|
||||
sideMaterial: MaterialSchemaSchema.optional(),
|
||||
sideMaterial: MaterialSchema.optional(),
|
||||
sideMaterialPreset: z.string().optional(),
|
||||
position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
|
||||
// Rotation around Y axis in radians
|
||||
@@ -126,18 +127,26 @@ export function getEffectiveStairSurfaceMaterial(
|
||||
|
||||
const treadFallback = {
|
||||
material: node.treadMaterial,
|
||||
materialPreset: typeof node.treadMaterialPreset === 'string' ? node.treadMaterialPreset : undefined,
|
||||
materialPreset:
|
||||
typeof node.treadMaterialPreset === 'string' ? node.treadMaterialPreset : undefined,
|
||||
}
|
||||
const sideFallback = {
|
||||
material: node.sideMaterial,
|
||||
materialPreset: typeof node.sideMaterialPreset === 'string' ? node.sideMaterialPreset : undefined,
|
||||
materialPreset:
|
||||
typeof node.sideMaterialPreset === 'string' ? node.sideMaterialPreset : undefined,
|
||||
}
|
||||
|
||||
if (role === 'tread' && (sideFallback.material !== undefined || sideFallback.materialPreset !== undefined)) {
|
||||
if (
|
||||
role === 'tread' &&
|
||||
(sideFallback.material !== undefined || sideFallback.materialPreset !== undefined)
|
||||
) {
|
||||
return sideFallback
|
||||
}
|
||||
|
||||
if (role === 'side' && (treadFallback.material !== undefined || treadFallback.materialPreset !== undefined)) {
|
||||
if (
|
||||
role === 'side' &&
|
||||
(treadFallback.material !== undefined || treadFallback.materialPreset !== undefined)
|
||||
) {
|
||||
return treadFallback
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user