Conditions:
- {(['walk_to_and_sit', 'around_open_area', 'near_entrance', 'accessible', 'not_blocking_path', 'open_circulation'] as ConditionKind[]).map(
+ {(['walk_to_and_sit', 'around_open_area', 'near_entrance', 'near_object', 'accessible', 'not_blocking_path', 'open_circulation'] as ConditionKind[]).map(
(k) => (
-
+
+
+ {k === 'near_object' && selected.conditions.some((c) => c.kind === 'near_object') && (
+
+ )}
+
),
)}
diff --git a/src/layout/evaluator.ts b/src/layout/evaluator.ts
index c22f096..1a548c9 100644
--- a/src/layout/evaluator.ts
+++ b/src/layout/evaluator.ts
@@ -40,7 +40,7 @@ export function evaluateLayout(state: LayoutState, gridSize: number = 10): Layou
let score = 0;
for (const c of f.conditions) {
- const s = scoreCondition(c.kind, f, state, accessibility.find((a) => a.furnitureId === f.id) || null, path);
+ const s = scoreCondition(c.kind, c, f, state, accessibility.find((a) => a.furnitureId === f.id) || null, path);
score += (s * (c.weight || 1)) / (f.conditions.length || 1);
}
conditionScores[f.id] = score;
@@ -53,6 +53,7 @@ export function evaluateLayout(state: LayoutState, gridSize: number = 10): Layou
function scoreCondition(
kind: string,
+ c: any,
f: FurnitureConfig,
state: LayoutState,
acc: AccessibilityResult | null,
@@ -85,6 +86,18 @@ function scoreCondition(
case 'accessible': {
return acc?.reachable ? 1.0 : 0.0;
}
+ case 'near_object': {
+ const tid = (c.params as any)?.targetId;
+ if (!tid) return 0.3;
+ const t = state.furniture.find((x) => x.id === tid);
+ if (!t) return 0.3;
+ const cx = f.shape.x + f.shape.width / 2;
+ const cy = f.shape.y + f.shape.height / 2;
+ const tx = t.shape.x + t.shape.width / 2;
+ const ty = t.shape.y + t.shape.height / 2;
+ const d = Math.sqrt((cx - tx) ** 2 + (cy - ty) ** 2);
+ return Math.max(0, 1 - d / 80);
+ }
case 'open_circulation': {
return path && path.length > 2 ? 0.7 : 0.5;
}
diff --git a/src/types/index.ts b/src/types/index.ts
index 739d167..c7d600f 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -26,6 +26,7 @@ export type ConditionKind =
| 'walk_to_and_sit'
| 'around_open_area'
| 'near_entrance'
+ | 'near_object'
| 'not_blocking_path'
| 'accessible'
| 'open_circulation';
@@ -87,8 +88,18 @@ export interface LayoutEvaluation {
penalty: number;
}
+export interface FurniturePreset {
+ id: string;
+ name: string;
+ shape: Omit