@ifc-lite/viewer 1.17.6 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +20 -15
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +949 -0
- package/dist/assets/{basketViewActivator-86rgogji.js → basketViewActivator-RZy5c3Td.js} +1 -1
- package/dist/assets/decode-worker-Collf_X_.js +1320 -0
- package/dist/assets/{exporters-CcPS9MK5.js → exporters-BraHBeoi.js} +4194 -3025
- package/dist/assets/{geometry.worker-BFUYA08u.js → geometry.worker-DQEZB2rB.js} +1 -1
- package/dist/assets/ifc-lite_bg-4yUkDRD8.wasm +0 -0
- package/dist/assets/index-0XpVr_S5.css +1 -0
- package/dist/assets/{index-Bfms9I4A.js → index-BOi3BuUI.js} +46423 -31181
- package/dist/assets/index-XwKzDuw6.js +22 -0
- package/dist/assets/{native-bridge-DUyLCMZS.js → native-bridge-CpBeOPQa.js} +1 -1
- package/dist/assets/sandbox-Baez7n-t.js +9682 -0
- package/dist/assets/{server-client-BuZK7OST.js → server-client-BB6cMAXE.js} +1 -1
- package/dist/assets/{wasm-bridge-JsqEGDV8.js → wasm-bridge-CAYCUHbE.js} +1 -1
- package/dist/index.html +6 -6
- package/package.json +11 -10
- package/src/apache-arrow.d.ts +30 -0
- package/src/components/viewer/AddElementPanel.tsx +758 -0
- package/src/components/viewer/BulkPropertyEditor.tsx +7 -0
- package/src/components/viewer/ChatPanel.tsx +64 -2
- package/src/components/viewer/CommandPalette.tsx +56 -7
- package/src/components/viewer/EntityContextMenu.tsx +168 -4
- package/src/components/viewer/ExportChangesButton.tsx +25 -5
- package/src/components/viewer/ExportDialog.tsx +19 -1
- package/src/components/viewer/MainToolbar.tsx +73 -12
- package/src/components/viewer/PointCloudPanel.tsx +174 -0
- package/src/components/viewer/PropertiesPanel.tsx +222 -22
- package/src/components/viewer/SearchInline.tsx +669 -0
- package/src/components/viewer/SearchModal.filter.builder.tsx +766 -0
- package/src/components/viewer/SearchModal.filter.tsx +514 -0
- package/src/components/viewer/SearchModal.text.tsx +388 -0
- package/src/components/viewer/SearchModal.tsx +235 -0
- package/src/components/viewer/ToolOverlays.tsx +5 -0
- package/src/components/viewer/ViewerLayout.tsx +24 -4
- package/src/components/viewer/Viewport.tsx +29 -2
- package/src/components/viewer/ViewportContainer.tsx +45 -5
- package/src/components/viewer/ViewportOverlays.tsx +13 -2
- package/src/components/viewer/annotations/AnnotationDropInput.tsx +203 -0
- package/src/components/viewer/annotations/AnnotationLayer.tsx +287 -0
- package/src/components/viewer/annotations/AnnotationPin.tsx +90 -0
- package/src/components/viewer/annotations/AnnotationPopover.tsx +296 -0
- package/src/components/viewer/bcf/BCFTopicDetail.tsx +1 -1
- package/src/components/viewer/lists/ListPanel.tsx +14 -21
- package/src/components/viewer/properties/RawStepCard.tsx +332 -0
- package/src/components/viewer/properties/RawStepRow.tsx +261 -0
- package/src/components/viewer/properties/ScheduleCard.tsx +224 -0
- package/src/components/viewer/properties/TaskEditCard.tsx +510 -0
- package/src/components/viewer/properties/raw-step-format.ts +193 -0
- package/src/components/viewer/schedule/AnimationSettingsPopover.tsx +542 -0
- package/src/components/viewer/schedule/GanttDependencyArrows.tsx +89 -0
- package/src/components/viewer/schedule/GanttDragTooltip.tsx +48 -0
- package/src/components/viewer/schedule/GanttEmptyState.tsx +97 -0
- package/src/components/viewer/schedule/GanttPanel.tsx +295 -0
- package/src/components/viewer/schedule/GanttTaskBar.tsx +199 -0
- package/src/components/viewer/schedule/GanttTaskTree.tsx +250 -0
- package/src/components/viewer/schedule/GanttTimeline.tsx +305 -0
- package/src/components/viewer/schedule/GanttToolbar.tsx +406 -0
- package/src/components/viewer/schedule/GenerateAdvancedPanel.tsx +147 -0
- package/src/components/viewer/schedule/GenerateScheduleDialog.tsx +392 -0
- package/src/components/viewer/schedule/HeightStrategyPanel.tsx +120 -0
- package/src/components/viewer/schedule/generate-schedule.test.ts +439 -0
- package/src/components/viewer/schedule/generate-schedule.ts +648 -0
- package/src/components/viewer/schedule/schedule-animator.test.ts +452 -0
- package/src/components/viewer/schedule/schedule-animator.ts +488 -0
- package/src/components/viewer/schedule/schedule-selection.test.ts +148 -0
- package/src/components/viewer/schedule/schedule-selection.ts +163 -0
- package/src/components/viewer/schedule/schedule-utils.ts +223 -0
- package/src/components/viewer/schedule/useConstructionSequence.ts +156 -0
- package/src/components/viewer/schedule/useGanttBarDrag.test.ts +90 -0
- package/src/components/viewer/schedule/useGanttBarDrag.ts +305 -0
- package/src/components/viewer/schedule/useGanttSelection3DHighlight.ts +152 -0
- package/src/components/viewer/schedule/useOverlayCompositor.ts +108 -0
- package/src/components/viewer/selectionHandlers.ts +446 -0
- package/src/components/viewer/tools/AddElementOverlay.tsx +581 -0
- package/src/components/viewer/useDuplicateShortcut.ts +77 -0
- package/src/components/viewer/useMouseControls.ts +9 -1
- package/src/components/viewer/usePointCloudLifecycle.ts +64 -0
- package/src/components/viewer/usePointCloudSync.ts +98 -0
- package/src/hooks/ingest/pointCloudIngest.ts +391 -0
- package/src/hooks/ingest/viewerModelIngest.ts +32 -3
- package/src/hooks/useIfcFederation.ts +72 -3
- package/src/hooks/useIfcLoader.ts +89 -13
- package/src/hooks/useKeyboardShortcuts.ts +25 -0
- package/src/hooks/useSandbox.ts +1 -1
- package/src/hooks/useSearchIndex.ts +125 -0
- package/src/index.css +66 -0
- package/src/lib/llm/system-prompt.test.ts +14 -0
- package/src/lib/llm/system-prompt.ts +102 -1
- package/src/lib/llm/types.ts +6 -0
- package/src/lib/recent-files.ts +38 -4
- package/src/lib/scripts/templates/bim-globals.d.ts +136 -114
- package/src/lib/scripts/templates/construction-schedule.ts +223 -0
- package/src/lib/scripts/templates.ts +7 -0
- package/src/lib/search/common-ifc-types.ts +36 -0
- package/src/lib/search/filter-evaluate.test.ts +537 -0
- package/src/lib/search/filter-evaluate.ts +610 -0
- package/src/lib/search/filter-rules.test.ts +119 -0
- package/src/lib/search/filter-rules.ts +198 -0
- package/src/lib/search/filter-schema.test.ts +233 -0
- package/src/lib/search/filter-schema.ts +146 -0
- package/src/lib/search/recent-searches.test.ts +116 -0
- package/src/lib/search/recent-searches.ts +93 -0
- package/src/lib/search/result-export.test.ts +101 -0
- package/src/lib/search/result-export.ts +104 -0
- package/src/lib/search/saved-filters.test.ts +118 -0
- package/src/lib/search/saved-filters.ts +154 -0
- package/src/lib/search/tier0-scan.test.ts +196 -0
- package/src/lib/search/tier0-scan.ts +237 -0
- package/src/lib/search/tier1-index.test.ts +242 -0
- package/src/lib/search/tier1-index.ts +448 -0
- package/src/sdk/adapters/export-adapter.test.ts +434 -1
- package/src/sdk/adapters/export-adapter.ts +404 -1
- package/src/sdk/adapters/export-schedule-splice.test.ts +127 -0
- package/src/sdk/adapters/export-schedule-splice.ts +87 -0
- package/src/sdk/adapters/model-compat.ts +8 -2
- package/src/sdk/adapters/schedule-adapter.ts +73 -0
- package/src/sdk/adapters/store-adapter.ts +201 -0
- package/src/sdk/adapters/visibility-adapter.ts +3 -0
- package/src/sdk/local-backend.ts +16 -8
- package/src/services/desktop-export.ts +3 -1
- package/src/services/desktop-native-metadata.ts +41 -18
- package/src/services/file-dialog.ts +8 -3
- package/src/services/tauri-modules.d.ts +25 -0
- package/src/store/basketVisibleSet.ts +3 -0
- package/src/store/globalId.ts +4 -1
- package/src/store/index.ts +79 -1
- package/src/store/slices/addElementMeshes.ts +365 -0
- package/src/store/slices/addElementSlice.ts +275 -0
- package/src/store/slices/annotationsSlice.test.ts +133 -0
- package/src/store/slices/annotationsSlice.ts +251 -0
- package/src/store/slices/dataSlice.test.ts +23 -4
- package/src/store/slices/dataSlice.ts +1 -1
- package/src/store/slices/modelSlice.test.ts +67 -9
- package/src/store/slices/modelSlice.ts +39 -7
- package/src/store/slices/mutationSlice.ts +964 -3
- package/src/store/slices/overlayCompositor.test.ts +164 -0
- package/src/store/slices/overlaySlice.test.ts +93 -0
- package/src/store/slices/overlaySlice.ts +151 -0
- package/src/store/slices/pinboardSlice.test.ts +6 -1
- package/src/store/slices/playbackSlice.ts +128 -0
- package/src/store/slices/pointCloudSlice.ts +102 -0
- package/src/store/slices/schedule-edit-helpers.test.ts +97 -0
- package/src/store/slices/schedule-edit-helpers.ts +179 -0
- package/src/store/slices/scheduleSlice.test.ts +694 -0
- package/src/store/slices/scheduleSlice.ts +1330 -0
- package/src/store/slices/searchSlice.test.ts +342 -0
- package/src/store/slices/searchSlice.ts +341 -0
- package/src/store/slices/selectionSlice.test.ts +46 -0
- package/src/store/slices/selectionSlice.ts +20 -0
- package/src/store/types.ts +7 -0
- package/src/store.ts +14 -0
- package/vite.config.ts +1 -0
- package/dist/assets/ifc-lite_bg-BINvzoCP.wasm +0 -0
- package/dist/assets/index-_bfZsDCC.css +0 -1
- package/dist/assets/sandbox-C8575tul.js +0 -5951
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
|
|
5
|
+
export {} // module boundary (stripped by transpiler)
|
|
6
|
+
|
|
7
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
8
|
+
// Construction schedule — build an IfcWorkSchedule + IfcTasks + sequences
|
|
9
|
+
//
|
|
10
|
+
// Two modes:
|
|
11
|
+
// 1) Attach a construction sequence to the CURRENTLY LOADED model.
|
|
12
|
+
// The script reads CSV task rows (attached via the chat paperclip)
|
|
13
|
+
// and creates IfcTasks whose products are resolved by name/type.
|
|
14
|
+
//
|
|
15
|
+
// 2) No model loaded — generate a standalone demo IFC file with a few
|
|
16
|
+
// walls and a matching 4-task construction schedule.
|
|
17
|
+
//
|
|
18
|
+
// CSV expected columns (case-insensitive, any subset works):
|
|
19
|
+
// id, name, start, finish, duration, predecessor, products, predefinedType,
|
|
20
|
+
// isMilestone, isCritical, completion
|
|
21
|
+
//
|
|
22
|
+
// Dates are ISO 8601 (e.g. 2024-05-01T08:00:00).
|
|
23
|
+
// Durations are ISO 8601 (e.g. P5D, PT8H).
|
|
24
|
+
// `products` is a comma-separated list of IFC types (e.g. "IfcWall,IfcSlab")
|
|
25
|
+
// OR entity globalIds; elements matching each row are assigned to that task.
|
|
26
|
+
// `predecessor` is the `id` of the row that must finish before this one.
|
|
27
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
function toIso(v: string | undefined): string | undefined {
|
|
30
|
+
if (!v) return undefined
|
|
31
|
+
const s = String(v).trim()
|
|
32
|
+
if (!s) return undefined
|
|
33
|
+
// Accept "YYYY-MM-DD" → append midnight
|
|
34
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return `${s}T00:00:00`
|
|
35
|
+
return s
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function toBool(v: unknown): boolean | undefined {
|
|
39
|
+
if (v === undefined || v === null || v === '') return undefined
|
|
40
|
+
const s = String(v).trim().toLowerCase()
|
|
41
|
+
if (s === 'true' || s === '1' || s === 'yes' || s === 'y') return true
|
|
42
|
+
if (s === 'false' || s === '0' || s === 'no' || s === 'n') return false
|
|
43
|
+
return undefined
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function toNumber(v: unknown): number | undefined {
|
|
47
|
+
if (v === undefined || v === null || v === '') return undefined
|
|
48
|
+
const n = Number(v)
|
|
49
|
+
return Number.isFinite(n) ? n : undefined
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Canonicalize a column name so "Start Date", "start_date" and "start" all match.
|
|
53
|
+
function findCol(cols: string[], ...aliases: string[]): string | null {
|
|
54
|
+
const norm = (s: string) => s.toLowerCase().replace(/[\s_-]+/g, '')
|
|
55
|
+
const wanted = aliases.map(norm)
|
|
56
|
+
for (const c of cols) if (wanted.includes(norm(c))) return c
|
|
57
|
+
return null
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const files = bim.files.list()
|
|
61
|
+
const csvFile = files.find((f) => f.name.toLowerCase().endsWith('.csv'))
|
|
62
|
+
|
|
63
|
+
if (csvFile) {
|
|
64
|
+
// ─── Mode 1: attach schedule to currently loaded model ────────────────
|
|
65
|
+
const rows = bim.files.csv(csvFile.name) ?? []
|
|
66
|
+
const cols = bim.files.csvColumns(csvFile.name)
|
|
67
|
+
if (rows.length === 0) {
|
|
68
|
+
console.warn(`[schedule] ${csvFile.name} has no rows`)
|
|
69
|
+
} else {
|
|
70
|
+
console.log(`[schedule] loading ${rows.length} tasks from ${csvFile.name}`)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const idCol = findCol(cols, 'id', 'taskid')
|
|
74
|
+
const nameCol = findCol(cols, 'name', 'task', 'activity')
|
|
75
|
+
const startCol = findCol(cols, 'start', 'startdate', 'schedulestart')
|
|
76
|
+
const finishCol = findCol(cols, 'finish', 'end', 'enddate', 'schedulefinish')
|
|
77
|
+
const durCol = findCol(cols, 'duration', 'scheduleduration')
|
|
78
|
+
const predCol = findCol(cols, 'predecessor', 'depends', 'dependson')
|
|
79
|
+
const productsCol = findCol(cols, 'products', 'type', 'entities', 'targets')
|
|
80
|
+
const typeCol = findCol(cols, 'predefinedtype', 'kind')
|
|
81
|
+
const mileCol = findCol(cols, 'ismilestone', 'milestone')
|
|
82
|
+
const critCol = findCol(cols, 'iscritical', 'critical')
|
|
83
|
+
const compCol = findCol(cols, 'completion', 'percentcomplete', 'progress')
|
|
84
|
+
|
|
85
|
+
// Discover every loaded product once so we can resolve `products` values
|
|
86
|
+
// (IFC type OR globalId substring) into a list of expressIds.
|
|
87
|
+
const allProducts = bim.query.byType(
|
|
88
|
+
'IfcWall', 'IfcSlab', 'IfcColumn', 'IfcBeam', 'IfcRoof', 'IfcStair',
|
|
89
|
+
'IfcDoor', 'IfcWindow', 'IfcRailing', 'IfcFooting', 'IfcCurtainWall',
|
|
90
|
+
'IfcMember', 'IfcPlate', 'IfcFurnishingElement', 'IfcBuildingElementProxy',
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
// Minimum character count before we fall back to a globalId prefix match;
|
|
94
|
+
// avoids accidental wildcarding when the CSV column holds short tokens.
|
|
95
|
+
const MIN_GID_PREFIX_LEN = 4
|
|
96
|
+
|
|
97
|
+
function resolveProducts(spec: string | undefined): number[] {
|
|
98
|
+
if (!spec) return []
|
|
99
|
+
const parts = spec.split(/[,;]/).map((s) => s.trim()).filter(Boolean)
|
|
100
|
+
const ids = new Set<number>()
|
|
101
|
+
for (const part of parts) {
|
|
102
|
+
const upper = part.toUpperCase()
|
|
103
|
+
if (upper.startsWith('IFC')) {
|
|
104
|
+
// IFC type — match all loaded entities of that class
|
|
105
|
+
for (const e of allProducts) {
|
|
106
|
+
if (e.type.toUpperCase() === upper) ids.add(e.ref.expressId)
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
// Exact globalId match, OR prefix match when the token is long enough
|
|
110
|
+
// to uniquely identify an element (≥ 4 chars).
|
|
111
|
+
for (const e of allProducts) {
|
|
112
|
+
if (e.globalId === part) {
|
|
113
|
+
ids.add(e.ref.expressId)
|
|
114
|
+
} else if (part.length >= MIN_GID_PREFIX_LEN && e.globalId.startsWith(part)) {
|
|
115
|
+
ids.add(e.ref.expressId)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return Array.from(ids)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// We can't use bim.create on an existing model in this iteration — the
|
|
124
|
+
// creator produces a fresh IFC file. So we log what *would* be created
|
|
125
|
+
// and print a plan. The plan is directly feedable to a follow-up
|
|
126
|
+
// save/export workflow.
|
|
127
|
+
console.log('[schedule] plan:')
|
|
128
|
+
for (const row of rows) {
|
|
129
|
+
const id = idCol ? row[idCol] : '-'
|
|
130
|
+
const name = nameCol ? row[nameCol] : '(unnamed)'
|
|
131
|
+
const start = startCol ? toIso(row[startCol]) : undefined
|
|
132
|
+
const finish = finishCol ? toIso(row[finishCol]) : undefined
|
|
133
|
+
const dur = durCol ? row[durCol] : undefined
|
|
134
|
+
const pred = predCol ? row[predCol] : undefined
|
|
135
|
+
const prodSpec = productsCol ? row[productsCol] : undefined
|
|
136
|
+
const prodIds = resolveProducts(prodSpec)
|
|
137
|
+
const predefinedType = typeCol ? row[typeCol] : undefined
|
|
138
|
+
const isMilestone = mileCol ? toBool(row[mileCol]) : undefined
|
|
139
|
+
const isCritical = critCol ? toBool(row[critCol]) : undefined
|
|
140
|
+
const completion = compCol ? toNumber(row[compCol]) : undefined
|
|
141
|
+
console.log(
|
|
142
|
+
` • [${id}] ${name} ${start ?? '?'} → ${finish ?? dur ?? '?'} ` +
|
|
143
|
+
`prod=${prodIds.length} pred=${pred ?? '-'} ` +
|
|
144
|
+
`type=${predefinedType ?? '-'} mile=${isMilestone ?? '-'} ` +
|
|
145
|
+
`crit=${isCritical ?? '-'} comp=${completion ?? '-'}`,
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
console.log(
|
|
149
|
+
'[schedule] Attaching tasks to an existing IFC requires a separate ' +
|
|
150
|
+
'mutation workflow — ask the assistant to wire the plan into a fresh ' +
|
|
151
|
+
'IFC export using bim.create.* so the 4D Gantt panel can play it.',
|
|
152
|
+
)
|
|
153
|
+
} else {
|
|
154
|
+
// ─── Mode 2: generate a demo IFC with walls + a matching schedule ─────
|
|
155
|
+
console.log('[schedule] No CSV attached — building demo model + schedule')
|
|
156
|
+
|
|
157
|
+
const h = bim.create.project({ Name: 'Demo with schedule', Schema: 'IFC4' })
|
|
158
|
+
const storey = bim.create.addIfcBuildingStorey(h, { Name: 'Ground', Elevation: 0 })
|
|
159
|
+
|
|
160
|
+
const wallA = bim.create.addIfcWall(h, storey, {
|
|
161
|
+
Name: 'Wall A', Start: [0, 0, 0], End: [5, 0, 0], Thickness: 0.2, Height: 3,
|
|
162
|
+
})
|
|
163
|
+
const wallB = bim.create.addIfcWall(h, storey, {
|
|
164
|
+
Name: 'Wall B', Start: [5, 0, 0], End: [5, 5, 0], Thickness: 0.2, Height: 3,
|
|
165
|
+
})
|
|
166
|
+
const wallC = bim.create.addIfcWall(h, storey, {
|
|
167
|
+
Name: 'Wall C', Start: [5, 5, 0], End: [0, 5, 0], Thickness: 0.2, Height: 3,
|
|
168
|
+
})
|
|
169
|
+
const wallD = bim.create.addIfcWall(h, storey, {
|
|
170
|
+
Name: 'Wall D', Start: [0, 5, 0], End: [0, 0, 0], Thickness: 0.2, Height: 3,
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
const schedule = bim.create.addIfcWorkSchedule(h, {
|
|
174
|
+
Name: 'Construction schedule',
|
|
175
|
+
StartTime: '2024-05-01T08:00:00',
|
|
176
|
+
FinishTime: '2024-05-20T17:00:00',
|
|
177
|
+
PredefinedType: 'PLANNED',
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
const tFoundation = bim.create.addIfcTask(h, {
|
|
181
|
+
Name: 'Site preparation',
|
|
182
|
+
PredefinedType: 'CONSTRUCTION',
|
|
183
|
+
ScheduleStart: '2024-05-01T08:00:00',
|
|
184
|
+
ScheduleFinish: '2024-05-03T17:00:00',
|
|
185
|
+
ScheduleDuration: 'P3D',
|
|
186
|
+
IsMilestone: false,
|
|
187
|
+
})
|
|
188
|
+
const tWallAB = bim.create.addIfcTask(h, {
|
|
189
|
+
Name: 'Install walls A+B',
|
|
190
|
+
PredefinedType: 'INSTALLATION',
|
|
191
|
+
ScheduleStart: '2024-05-06T08:00:00',
|
|
192
|
+
ScheduleFinish: '2024-05-10T17:00:00',
|
|
193
|
+
ScheduleDuration: 'P5D',
|
|
194
|
+
})
|
|
195
|
+
const tWallCD = bim.create.addIfcTask(h, {
|
|
196
|
+
Name: 'Install walls C+D',
|
|
197
|
+
PredefinedType: 'INSTALLATION',
|
|
198
|
+
ScheduleStart: '2024-05-13T08:00:00',
|
|
199
|
+
ScheduleFinish: '2024-05-17T17:00:00',
|
|
200
|
+
ScheduleDuration: 'P5D',
|
|
201
|
+
IsCritical: true,
|
|
202
|
+
})
|
|
203
|
+
const tHandover = bim.create.addIfcTask(h, {
|
|
204
|
+
Name: 'Handover',
|
|
205
|
+
PredefinedType: 'CONSTRUCTION',
|
|
206
|
+
ScheduleStart: '2024-05-20T08:00:00',
|
|
207
|
+
ScheduleFinish: '2024-05-20T17:00:00',
|
|
208
|
+
IsMilestone: true,
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
bim.create.assignTasksToWorkSchedule(h, schedule, [tFoundation, tWallAB, tWallCD, tHandover])
|
|
212
|
+
bim.create.assignProductsToTask(h, tWallAB, [wallA, wallB])
|
|
213
|
+
bim.create.assignProductsToTask(h, tWallCD, [wallC, wallD])
|
|
214
|
+
|
|
215
|
+
bim.create.addIfcRelSequence(h, tFoundation, tWallAB, { SequenceType: 'FINISH_START', TimeLag: 'P2D' })
|
|
216
|
+
bim.create.addIfcRelSequence(h, tWallAB, tWallCD, { SequenceType: 'FINISH_START' })
|
|
217
|
+
bim.create.addIfcRelSequence(h, tWallCD, tHandover, { SequenceType: 'FINISH_START' })
|
|
218
|
+
|
|
219
|
+
const result = bim.create.toIfc(h)
|
|
220
|
+
console.log(`[schedule] generated ${result.stats.entityCount} entities (${result.stats.fileSize} bytes)`)
|
|
221
|
+
bim.export.download(result.content, 'demo-with-schedule.ifc', 'model/ifc')
|
|
222
|
+
console.log('[schedule] downloaded demo-with-schedule.ifc — open it in this viewer to see the 4D Gantt panel animate the construction.')
|
|
223
|
+
}
|
|
@@ -24,6 +24,7 @@ import spaceValidation from './templates/space-validation.ts?raw';
|
|
|
24
24
|
import federationCompare from './templates/federation-compare.ts?raw';
|
|
25
25
|
import resetView from './templates/reset-view.ts?raw';
|
|
26
26
|
import createBuilding from './templates/create-building.ts?raw';
|
|
27
|
+
import constructionSchedule from './templates/construction-schedule.ts?raw';
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
export interface ScriptTemplate {
|
|
@@ -86,6 +87,12 @@ export const SCRIPT_TEMPLATES: ScriptTemplate[] = [
|
|
|
86
87
|
'Developer — generate a complete IFC file with walls, slab, columns, beams, stair, and parametric timber gridshell roof with diamond lattice',
|
|
87
88
|
code: stripModuleLine(createBuilding),
|
|
88
89
|
},
|
|
90
|
+
{
|
|
91
|
+
name: 'Construction schedule (4D)',
|
|
92
|
+
description:
|
|
93
|
+
'Scheduler — build an IfcWorkSchedule with IfcTasks, IfcRelSequence dependencies, and product assignments that drive the 4D Gantt animation. Accepts a CSV attachment for real task data.',
|
|
94
|
+
code: stripModuleLine(constructionSchedule),
|
|
95
|
+
},
|
|
89
96
|
{
|
|
90
97
|
name: 'Reset view',
|
|
91
98
|
description: 'Utility — remove all color overrides and show all entities',
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Starter IFC type catalog used as a dropdown fallback when the active
|
|
7
|
+
* model's `entityIndex.byType` isn't yet populated (e.g. server-loaded
|
|
8
|
+
* stores without the on-demand maps). Once a model is loaded, the
|
|
9
|
+
* filter-schema layer surfaces only the types actually present so users
|
|
10
|
+
* don't waste time picking IfcBeam from a house model that doesn't have
|
|
11
|
+
* one.
|
|
12
|
+
*/
|
|
13
|
+
export const COMMON_IFC_TYPES: readonly string[] = [
|
|
14
|
+
'IfcWall',
|
|
15
|
+
'IfcWallStandardCase',
|
|
16
|
+
'IfcSlab',
|
|
17
|
+
'IfcBeam',
|
|
18
|
+
'IfcColumn',
|
|
19
|
+
'IfcDoor',
|
|
20
|
+
'IfcWindow',
|
|
21
|
+
'IfcRoof',
|
|
22
|
+
'IfcStair',
|
|
23
|
+
'IfcStairFlight',
|
|
24
|
+
'IfcRailing',
|
|
25
|
+
'IfcRamp',
|
|
26
|
+
'IfcSpace',
|
|
27
|
+
'IfcCovering',
|
|
28
|
+
'IfcCurtainWall',
|
|
29
|
+
'IfcFooting',
|
|
30
|
+
'IfcPlate',
|
|
31
|
+
'IfcMember',
|
|
32
|
+
'IfcOpeningElement',
|
|
33
|
+
'IfcBuildingElementProxy',
|
|
34
|
+
'IfcFurnishingElement',
|
|
35
|
+
'IfcDistributionElement',
|
|
36
|
+
];
|