Skip to content

Commit

Permalink
Styling extracted as a hook
Browse files Browse the repository at this point in the history
  • Loading branch information
Savokr committed Jul 12, 2023
1 parent 11fde8e commit 69b0165
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 101 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
/*!
* Copyright 2023 Cognite AS
*/
import { useRef, type ReactElement, useContext, useState, useEffect, useMemo } from 'react';
import { useRef, type ReactElement, useContext, useState, useEffect } from 'react';
import {
type NodeAppearance,
type Cognite3DViewer,
type PointCloudAppearance
} from '@cognite/reveal';
import { ModelsLoadingStateContext } from './ModelsLoadingContext';
import {
CadModelContainer,
type CadModelStyling,
type NodeStylingGroup
} from '../CadModelContainer/CadModelContainer';
import { CadModelContainer, type CadModelStyling } from '../CadModelContainer/CadModelContainer';
import {
PointCloudContainer,
type PointCloudModelStyling
Expand All @@ -26,8 +22,8 @@ import {
type AddResourceOptions
} from './types';
import { type CogniteExternalId } from '@cognite/sdk';
import { useFdmAssetMappings } from '../../hooks/useFdmAssetMappings';
import { type FdmAssetMappingsConfig } from '../../hooks/types';
import { useCalculateModelsStyling } from '../../hooks/useCalculateModelsStyling';

export type FdmAssetStylingGroup = {
fdmAssetExternalIds: CogniteExternalId[];
Expand Down Expand Up @@ -59,76 +55,15 @@ export const Reveal3DResources = ({
const viewer = useReveal();
const numModelsLoaded = useRef(0);

const stylingExternalIds = useMemo(
() => styling?.groups?.flatMap((group) => group.fdmAssetExternalIds) ?? [],
[styling]
);

const { data: mappings } = useFdmAssetMappings(stylingExternalIds, fdmAssetMappingConfig);

useEffect(() => {
getTypedModels(resources, viewer).then(setReveal3DModels).catch(console.error);
}, [resources, viewer]);

useEffect(() => {
if (styling === undefined || reveal3DModels === undefined) return;

const modelsStyling = reveal3DModels.map((model) => {
let modelStyling: PointCloudModelStyling | CadModelStyling;

switch (model.type) {
case 'cad': {
const modelNodeMappings = mappings?.find(
(mapping) =>
mapping.modelId === model.modelId && mapping.revisionId === model.revisionId
);

const newStylingGroups: NodeStylingGroup[] | undefined =
styling.groups !== null ? [] : undefined;

styling.groups?.forEach((group) => {
const connectedExternalIds = group.fdmAssetExternalIds.filter((externalId) =>
modelNodeMappings?.mappings.some(
(modelNodeMapping) => modelNodeMapping.externalId === externalId
)
);

const newGroup: NodeStylingGroup = {
style: group.style.cad,
nodeIds: connectedExternalIds.map((externalId) => {
const mapping = modelNodeMappings?.mappings.find(
(mapping) => mapping.externalId === externalId
);
return mapping?.nodeId ?? -1;
})
};

if (connectedExternalIds.length > 0) newStylingGroups?.push(newGroup);
});

modelStyling = {
defaultStyle: styling.defaultStyle?.cad,
groups: newStylingGroups
};
break;
}
case 'pointcloud': {
modelStyling = {
defaultStyle: styling.defaultStyle?.pointcloud
};
break;
}
default: {
modelStyling = {};
console.warn(`Unknown model type: ${model.type}`);
break;
}
}
return modelStyling;
});
const modelsStyling = useCalculateModelsStyling(reveal3DModels, styling, fdmAssetMappingConfig);

useEffect(() => {
setReveal3DModelsStyling(modelsStyling);
}, [mappings, styling, reveal3DModels, mappings]);
}, [modelsStyling]);

const image360CollectionAddOptions = resources.filter(
(resource): resource is AddImageCollection360Options =>
Expand Down
33 changes: 18 additions & 15 deletions react-components/src/hooks/types.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
/*!
* Copyright 2023 Cognite AS
*/
import { type Source } from '../utilities/FdmSDK';

export type FdmAssetMappingsConfig = {
/**
* 3D Data model source
*/
source: Source;
/*
* FDM space where model assets are located
*/
assetFdmSpace: string;
};
export type ThreeDModelMappings = {
modelId: number;
revisionId: number;
mappings: Array<{ nodeId: number; externalId: string }>;
};
/**
* 3D Data model source
*/
source: Source;
/*
* FDM space where model assets are located
*/
assetFdmSpace: string;
};

export type ThreeDModelMappings = {
modelId: number;
revisionId: number;
mappings: Array<{ nodeId: number; externalId: string }>;
};
95 changes: 95 additions & 0 deletions react-components/src/hooks/useCalculateModelsStyling.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*!
* Copyright 2023 Cognite AS
*/
import { useMemo } from 'react';
import { type FdmAssetMappingsConfig } from './types';
import { type Reveal3DResourcesStyling } from '../components/Reveal3DResources/Reveal3DResources';
import { type TypedReveal3DModel } from '../components/Reveal3DResources/types';
import { useFdmAssetMappings } from './useFdmAssetMappings';
import { type PointCloudModelStyling } from '../components/PointCloudContainer/PointCloudContainer';
import {
type CadModelStyling,
type NodeStylingGroup
} from '../components/CadModelContainer/CadModelContainer';

/**
* Calculates the styling for the models based on the styling configuration and the mappings.
* @param models Models to calculate styling for.
* @param styling Styling configuration.
* @param fdmAssetMappingConfig Configuration for the FDM asset mappings.
* @returns
*/
export const useCalculateModelsStyling = (
models?: TypedReveal3DModel[],
styling?: Reveal3DResourcesStyling,
fdmAssetMappingConfig?: FdmAssetMappingsConfig
): Array<PointCloudModelStyling | CadModelStyling> => {
const stylingExternalIds = useMemo(
() => styling?.groups?.flatMap((group) => group.fdmAssetExternalIds) ?? [],
[styling]
);

const { data: mappings } = useFdmAssetMappings(stylingExternalIds, fdmAssetMappingConfig);

const modelsStyling = useMemo(() => {
if (styling === undefined || models === undefined) return [];

const internalModelsStyling = models.map((model) => {
let modelStyling: PointCloudModelStyling | CadModelStyling;

switch (model.type) {
case 'cad': {
const modelNodeMappings = mappings?.find(
(mapping) =>
mapping.modelId === model.modelId && mapping.revisionId === model.revisionId
);

const newStylingGroups: NodeStylingGroup[] | undefined =
styling.groups !== null ? [] : undefined;

styling.groups?.forEach((group) => {
const connectedExternalIds = group.fdmAssetExternalIds.filter((externalId) =>
modelNodeMappings?.mappings.some(
(modelNodeMapping) => modelNodeMapping.externalId === externalId
)
);

const newGroup: NodeStylingGroup = {
style: group.style.cad,
nodeIds: connectedExternalIds.map((externalId) => {
const mapping = modelNodeMappings?.mappings.find(
(mapping) => mapping.externalId === externalId
);
return mapping?.nodeId ?? -1;
})
};

if (connectedExternalIds.length > 0) newStylingGroups?.push(newGroup);
});

modelStyling = {
defaultStyle: styling.defaultStyle?.cad,
groups: newStylingGroups
};
break;
}
case 'pointcloud': {
modelStyling = {
defaultStyle: styling.defaultStyle?.pointcloud
};
break;
}
default: {
modelStyling = {};
console.warn(`Unknown model type: ${model.type}`);
break;
}
}
return modelStyling;
});

return internalModelsStyling;
}, [mappings, styling, models, mappings]);

return modelsStyling;
};
14 changes: 0 additions & 14 deletions react-components/src/utilities/FdmSDK.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,6 @@ export class FdmSDK {
this._sdk = sdk;
}

public async getInstancesByExternalIds<T = Record<string, any>>(
items: Item[],
source: Source
): Promise<T[]> {
const result = await this._sdk.post(this._byIdsEndpoint, {
data: { items, sources: [{ source }] }
});

if (result.status === 200) {
return result.data.items;
}
throw new Error(`Failed to fetch instances. Status: ${result.status}`);
}

public async filterInstances<PropertiesType = Record<string, any>>(
filter: any,
instanceType: InstanceType,
Expand Down
5 changes: 4 additions & 1 deletion react-components/src/utilities/constants.ts
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
export const DEFAULT_QUERY_STALE_TIME = 1000 * 60 * 10 ; // 10 minutes
/*!
* Copyright 2023 Cognite AS
*/
export const DEFAULT_QUERY_STALE_TIME = 1000 * 60 * 10; // 10 minutes

0 comments on commit 69b0165

Please sign in to comment.