-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- add sop/InstancedMeshToMesh
- Loading branch information
Showing
20 changed files
with
819 additions
and
426 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// | ||
import * as WEBIFC from 'web-ifc'; | ||
import {FragmentsGroup} from 'bim-fragment'; | ||
import { | ||
IfcPropertiesManager, | ||
FragmentIfcLoader, | ||
IfcPropertiesFinder, | ||
IfcCategories, | ||
Components, | ||
SimpleScene, | ||
PostproductionRenderer, | ||
SimpleCamera, | ||
SimpleRaycaster, | ||
} from 'openbim-components'; | ||
|
||
export { | ||
IfcPropertiesManager, | ||
FragmentIfcLoader, | ||
IfcPropertiesFinder, | ||
IfcCategories, | ||
Components, | ||
WEBIFC, | ||
SimpleScene, | ||
PostproductionRenderer, | ||
SimpleCamera, | ||
SimpleRaycaster, | ||
FragmentsGroup, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,139 @@ | ||
import * as WEB_IFC from 'web-ifc'; | ||
import type {IFCModel} from 'web-ifc-three/IFC/components/IFCModel'; | ||
import type {IFCManager} from 'web-ifc-three/IFC/components/IFCManager'; | ||
import {Object3D, InstancedMesh, Group} from 'three'; | ||
import {setToArray} from '../../SetUtils'; | ||
import {IFCLoaderHandler} from '../../loader/geometry/IFC'; | ||
import {Object3D} from 'three'; | ||
import {isArray} from '../../Type'; | ||
import * as WEB_IFC from 'web-ifc'; | ||
import { | ||
Components, | ||
SimpleScene, | ||
PostproductionRenderer, | ||
SimpleCamera, | ||
SimpleRaycaster, | ||
FragmentIfcLoader, | ||
IfcCategories, | ||
FragmentsGroup, | ||
} from './IFCCommon'; | ||
import {isNumber} from '../../Type'; | ||
import {ThreejsCoreObject} from '../modules/three/ThreejsCoreObject'; | ||
import {copyObjectAllProperties} from '../modules/three/ThreejsObjectUtils'; | ||
|
||
export enum IFCAttribute { | ||
MODEL_ID = 'modelId', | ||
function _buildCategoryNameById() { | ||
const dict: Record<number, string> = {}; | ||
const keys = Object.keys(WEB_IFC); | ||
for (const key of keys) { | ||
const value = (WEB_IFC as any)[key]; | ||
if (isNumber(value)) { | ||
dict[value] = key; | ||
} | ||
} | ||
return dict; | ||
} | ||
export const IFC_CATEGORY_NAME_BY_ID = _buildCategoryNameById(); | ||
|
||
interface StructureItem { | ||
expressID: number; | ||
type: string; | ||
children?: StructureItem[]; | ||
export enum IFCAttribute { | ||
ALL_CATEGORY_NAMES = 'IFCAllCategoryNames', | ||
} | ||
type StructureCallback = (structure: StructureItem) => void; | ||
const _numberSet: Set<number> = new Set(); | ||
const _stringSet: Set<string> = new Set(); | ||
|
||
export async function getIFCModelCategories(object: Object3D) { | ||
const modelId = (object as IFCModel).modelID; | ||
if (modelId == null) { | ||
return; | ||
} | ||
const ifcManager = IFCLoaderHandler.ifcManager(); | ||
return await ifcCategoriesNames(ifcManager, modelId); | ||
const CATEGORY_SEPARATOR = ' '; | ||
export function setObjectAttributeAllCategoryNames(object: Object3D, categoryNames: string[]) { | ||
ThreejsCoreObject.addAttribute(object, IFCAttribute.ALL_CATEGORY_NAMES, categoryNames.join(CATEGORY_SEPARATOR)); | ||
} | ||
export function getObjectAttributeAllCategoryNames(object: Object3D): string | undefined { | ||
const categoriesJoined = ThreejsCoreObject.attribValue(object, IFCAttribute.ALL_CATEGORY_NAMES) as | ||
| string | ||
| undefined; | ||
return categoriesJoined; | ||
} | ||
// interface CagegoryResult { | ||
// categoryNames: string[]; | ||
// cagegoryIds: number[]; | ||
// } | ||
export function ifcCategoryIds(categoryNames: string[]): number[] { | ||
const cagegoryIds: number[] = []; | ||
for (const categoryName of categoryNames) { | ||
const id = (WEB_IFC as any as Record<string, number>)[categoryName]; | ||
if (id != null) { | ||
cagegoryIds.push(id); | ||
export function categoryNamesFromString(categoriesJoined: string): string[] { | ||
return categoriesJoined.split(CATEGORY_SEPARATOR); | ||
} | ||
|
||
export function ifcFragmentsGroupToGroup(fragmentsGroup: FragmentsGroup): Object3D { | ||
function buildThreeObject(ifcObject: Object3D): Object3D | Object3D[] | undefined { | ||
if ((ifcObject as InstancedMesh).isInstancedMesh) { | ||
const count = (ifcObject as InstancedMesh).count; | ||
const geometry = (ifcObject as InstancedMesh).geometry; | ||
const material = (ifcObject as InstancedMesh).material; | ||
return copyObjectAllProperties(ifcObject, new InstancedMesh(geometry, material, count)); | ||
} | ||
if ((ifcObject as Group).isGroup) { | ||
return copyObjectAllProperties(ifcObject, new Group()); | ||
} | ||
console.warn('no conversion found for IFC object', ifcObject); | ||
} | ||
return cagegoryIds; | ||
} | ||
|
||
export async function ifcElementIds(ifcManager: IFCManager, modelId: number, categoryIds: number[]): Promise<number[]> { | ||
const promises = categoryIds.map( | ||
(categoryId) => ifcManager.getAllItemsOfType(modelId, categoryId, false) as Promise<number[]> | ||
); | ||
const results = await Promise.all(promises); | ||
const group = new Group(); | ||
const threeObjectByIFCObject: Map<Object3D, Object3D> = new Map(); | ||
threeObjectByIFCObject.set(fragmentsGroup, group); | ||
|
||
_numberSet.clear(); | ||
for (const result of results) { | ||
for (const id of result) { | ||
_numberSet.add(id); | ||
function _addObject(ifcObject: Object3D, threeObject: Object3D) { | ||
threeObjectByIFCObject.set(ifcObject, threeObject); | ||
const ifcParent = ifcObject.parent; | ||
if (ifcParent) { | ||
const threeParent = threeObjectByIFCObject.get(ifcParent); | ||
if (threeParent) { | ||
threeParent.add(threeObject); | ||
} | ||
} | ||
} | ||
return setToArray(_numberSet, []); | ||
} | ||
|
||
export async function ifcCategoriesNames(ifcManager: IFCManager, modelID: number): Promise<string[]> { | ||
const root: StructureItem = await ifcManager.getSpatialStructure(modelID, false); | ||
_stringSet.clear(); | ||
traverseStructure(root, (item) => { | ||
_stringSet.add(item.type); | ||
fragmentsGroup.traverse((ifcObject) => { | ||
if (ifcObject == fragmentsGroup) { | ||
return; | ||
} | ||
|
||
const threeObject = buildThreeObject(ifcObject); | ||
if (!threeObject) { | ||
return; | ||
} | ||
if (isArray(threeObject)) { | ||
for (const obj of threeObject) { | ||
_addObject(ifcObject, obj); | ||
} | ||
} else { | ||
_addObject(ifcObject, threeObject); | ||
} | ||
}); | ||
const categoryNames = setToArray(_stringSet, []); | ||
|
||
return categoryNames; | ||
return group; | ||
} | ||
function traverseStructure(item: StructureItem, callback: StructureCallback, level = 0) { | ||
// console.log(level, item); | ||
callback(item); | ||
if (!item.children) { | ||
return; | ||
} | ||
const children = item.children; | ||
for (const child of children) { | ||
traverseStructure(child, callback, level + 1); | ||
|
||
const _stringSet: Set<string> = new Set(); | ||
|
||
export function createFragmentIfcLoader() { | ||
const components = new Components(); | ||
components.scene = new SimpleScene(components); | ||
const container = document.createElement('div'); | ||
components.renderer = new PostproductionRenderer(components, container); | ||
components.camera = new SimpleCamera(components); | ||
components.raycaster = new SimpleRaycaster(components); | ||
const fragmentIfcLoader = new FragmentIfcLoader(components); | ||
|
||
fragmentIfcLoader.settings.wasm = { | ||
path: 'https://unpkg.com/web-ifc@0.0.44/', | ||
absolute: true, | ||
}; | ||
|
||
return fragmentIfcLoader; | ||
} | ||
|
||
async function _getCategoryIds(fragmentIfcLoader: FragmentIfcLoader, byteArray: Uint8Array) { | ||
const api = fragmentIfcLoader.get(); | ||
const {path, absolute} = fragmentIfcLoader.settings.wasm; | ||
api.SetWasmPath(path, absolute); | ||
await api.Init(); | ||
api.OpenModel(byteArray, fragmentIfcLoader.settings.webIfc); | ||
const ifcCategories = new IfcCategories(); | ||
const categories = ifcCategories.getAll(api, 0); | ||
return categories; | ||
} | ||
export async function getCategoryNames(fragmentIfcLoader: FragmentIfcLoader, byteArray: Uint8Array): Promise<string[]> { | ||
const categoryIdByObjectId = await _getCategoryIds(fragmentIfcLoader, byteArray); | ||
const categoryIds = Object.values(categoryIdByObjectId); | ||
_stringSet.clear(); | ||
for (const categoryId of categoryIds) { | ||
const categoryName = IFC_CATEGORY_NAME_BY_ID[categoryId]; | ||
_stringSet.add(categoryName); | ||
} | ||
const categoryNames: string[] = []; | ||
setToArray(_stringSet, categoryNames); | ||
return categoryNames; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.