Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(react-components): support node coloring in Reveal3D resources, rename types and bump version 0.53.0 #4665

Merged
2 changes: 1 addition & 1 deletion react-components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cognite/reveal-react-components",
"version": "0.52.2",
"version": "0.53.0",
"exports": {
".": {
"import": "./dist/index.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useSDK } from '../RevealCanvas/SDKProvider';
import { useRevealKeepAlive } from '../RevealKeepAlive/RevealKeepAliveContext';
import { PointCloudAnnotationCache } from './PointCloudAnnotationCache';
import { type PointCloudModelOptions, type TypedReveal3DModel } from '../Reveal3DResources/types';
import { type AnnotationModelDataResult } from '../../hooks/useCalculatePointCloudModelsStyling';
import { type AnnotationModelDataResult } from '../Reveal3DResources/useCalculatePointCloudStyling';
import { type PointCloudAnnotationMappedAssetData } from '../../hooks/types';
import { EMPTY_ARRAY } from '../../utilities/constants';
import { isDefined } from '../../utilities/isDefined';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import { type AddModelOptions, type CogniteCadModel } from '@cognite/reveal';
import { useReveal } from '../RevealCanvas/ViewerContext';
import { Matrix4 } from 'three';
import { useRevealKeepAlive } from '../RevealKeepAlive/RevealKeepAliveContext';
import { type CadModelStyling, useApplyCadModelStyling } from './useApplyCadModelStyling';
import { useReveal3DResourcesCount } from '../Reveal3DResources/Reveal3DResourcesInfoContext';
import { isEqual } from 'lodash';
import { modelExists } from '../../utilities/modelExists';
import { getViewerResourceCount } from '../../utilities/getViewerResourceCount';
import { type CadModelStyling } from './types';
import { useApplyCadModelStyling } from './useApplyCadModelStyling';

export type CogniteCadModelProps = {
addModelOptions: AddModelOptions;
Expand Down
33 changes: 33 additions & 0 deletions react-components/src/components/CadModelContainer/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*!
* Copyright 2024 Cognite AS
*/
import { type IndexSet, type NodeAppearance } from '@cognite/reveal';

export type NodeStylingGroup = {
nodeIds: number[];
style?: NodeAppearance;
};

export type TreeIndexStylingGroup = {
treeIndexSet: IndexSet;
style?: NodeAppearance;
};

export type CadStylingGroup = NodeStylingGroup | TreeIndexStylingGroup;

export type CadModelStyling = {
defaultStyle?: NodeAppearance;
groups?: CadStylingGroup[];
};

export function isNodeStylingGroup(
stylingGroup: CadStylingGroup
): stylingGroup is NodeStylingGroup {
return 'nodeIds' in stylingGroup;
}

export function isTreeIndexStylingGroup(
stylingGroup: CadStylingGroup
): stylingGroup is TreeIndexStylingGroup {
return 'treeIndexSet' in stylingGroup;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,22 @@ import {
type NodeAppearance,
type NodeCollection,
NodeIdNodeCollection,
TreeIndexNodeCollection,
type IndexSet
TreeIndexNodeCollection
} from '@cognite/reveal';
import { useEffect } from 'react';
import { useSDK } from '../RevealCanvas/SDKProvider';
import { type CogniteClient } from '@cognite/sdk';
import { isEqual } from 'lodash';
import { useReveal } from '../RevealCanvas/ViewerContext';
import { modelExists } from '../../utilities/modelExists';

export type NodeStylingGroup = {
nodeIds: number[];
style?: NodeAppearance;
};

export type TreeIndexStylingGroup = {
treeIndexSet: IndexSet;
style?: NodeAppearance;
};

export type CadModelStyling = {
defaultStyle?: NodeAppearance;
groups?: Array<NodeStylingGroup | TreeIndexStylingGroup>;
};
import {
isNodeStylingGroup,
isTreeIndexStylingGroup,
type CadModelStyling,
type NodeStylingGroup,
type TreeIndexStylingGroup
} from './types';
import { assertNever } from '../../utilities/assertNever';

export const useApplyCadModelStyling = (
model?: CogniteCadModel,
Expand Down Expand Up @@ -72,15 +64,15 @@ async function applyStyling(

if (stylingGroup.style === undefined) continue;

if ('treeIndexSet' in stylingGroup) {
if (isTreeIndexStylingGroup(stylingGroup)) {
const nodes = new TreeIndexNodeCollection(stylingGroup.treeIndexSet);
model.assignStyledNodeCollection(nodes, stylingGroup.style);
}

if ('nodeIds' in stylingGroup) {
} else if (isNodeStylingGroup(stylingGroup)) {
const nodes = new NodeIdNodeCollection(sdk, model);
await nodes.executeFilter(stylingGroup.nodeIds);
model.assignStyledNodeCollection(nodes, stylingGroup.style);
} else {
assertNever(stylingGroup);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,17 @@
import { useRef, type ReactElement, useState, useEffect, useMemo } from 'react';
import { type Cognite3DViewer } from '@cognite/reveal';
import { CadModelContainer } from '../CadModelContainer/CadModelContainer';
import { type CadModelStyling } from '../CadModelContainer/useApplyCadModelStyling';
import { PointCloudContainer } from '../PointCloudContainer/PointCloudContainer';
import { Image360CollectionContainer } from '../Image360CollectionContainer/Image360CollectionContainer';
import { useReveal } from '../RevealCanvas/ViewerContext';
import {
type AddReveal3DModelOptions,
type TypedReveal3DModel,
type AddResourceOptions,
type Reveal3DResourcesProps,
type CadModelOptions,
type PointCloudModelOptions
} from './types';
import { useCalculateCadStyling } from '../../hooks/useCalculateModelsStyling';
import { useCalculatePointCloudStyling } from '../../hooks/useCalculatePointCloudModelsStyling';
import { useCalculatePointCloudStyling } from './useCalculatePointCloudStyling';
import {
type AnnotationIdStylingGroup,
type PointCloudModelStyling
Expand All @@ -29,14 +26,16 @@ import {
isImage360AssetStylingGroup
} from '../../utilities/StylingGroupUtils';
import { type ImageCollectionModelStyling } from '../Image360CollectionContainer/useApply360AnnotationStyling';
import { is360ImageAddOptions } from './typeGuards';
import { is360ImageAddOptions, is3dResourceOptions } from './typeGuards';
import { useRemoveNonReferencedModels } from './useRemoveNonReferencedModels';
import {
useAssetMappedNodesForRevisions,
useGenerateAssetMappingCachePerItemFromModelCache,
useGenerateNode3DCache
} from '../CacheProvider/AssetMappingAndNode3DCacheProvider';
import { useCalculateCadStyling } from './useCalculateCadStyling';
import { useReveal3DResourcesStylingLoadingSetter } from './Reveal3DResourcesInfoContext';
import { type CadModelStyling } from '../CadModelContainer/types';

export const Reveal3DResources = ({
resources,
Expand Down Expand Up @@ -93,7 +92,6 @@ export const Reveal3DResources = ({
);

const setModel3DStylingLoading = useReveal3DResourcesStylingLoadingSetter();
setModel3DStylingLoading(!(isModelMappingsFetched || !isModelMappingsLoading));

useEffect(() => {
setModel3DStylingLoading(!(isModelMappingsFetched || !isModelMappingsLoading));
Expand Down Expand Up @@ -210,22 +208,16 @@ async function getTypedModels(
): Promise<TypedReveal3DModel[]> {
const errorFunction = onLoadFail ?? defaultLoadFailHandler;

const modelTypePromises = resources
.filter(
(resource): resource is AddReveal3DModelOptions =>
(resource as AddReveal3DModelOptions).modelId !== undefined &&
(resource as AddReveal3DModelOptions).revisionId !== undefined
)
.map(async (addModelOptions) => {
const type = await viewer
.determineModelType(addModelOptions.modelId, addModelOptions.revisionId)
.catch((error) => {
errorFunction(addModelOptions, error);
return '';
});
const typedModel = { ...addModelOptions, type };
return typedModel;
});
const modelTypePromises = resources.filter(is3dResourceOptions).map(async (addModelOptions) => {
const type = await viewer
.determineModelType(addModelOptions.modelId, addModelOptions.revisionId)
.catch((error) => {
errorFunction(addModelOptions, error);
return '';
});
const typedModel = { ...addModelOptions, type };
return typedModel;
});

const resourceLoadResults = await Promise.all(modelTypePromises);
const successfullyLoadedResources = resourceLoadResults.filter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ import {
type AddImage360CollectionDatamodelsOptions,
type AddImage360CollectionOptions,
type AddResourceOptions,
type AddReveal3DModelOptions
type Add3dResourceOptions
} from './types';

export function is360ImageAddOptions(
addOptions: AddResourceOptions
): addOptions is AddImage360CollectionOptions {
return !is3dModelOptions(addOptions);
return !is3dResourceOptions(addOptions);
}

export function is3dModelOptions(
export function is3dResourceOptions(
addOptions: AddResourceOptions
): addOptions is AddReveal3DModelOptions {
const modelOptions = addOptions as AddReveal3DModelOptions;
): addOptions is Add3dResourceOptions {
const modelOptions = addOptions as Add3dResourceOptions;
return modelOptions.modelId !== undefined && modelOptions.revisionId !== undefined;
}

Expand Down
45 changes: 31 additions & 14 deletions react-components/src/components/Reveal3DResources/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { type Matrix4 } from 'three';
import { type DmsUniqueIdentifier, type Source } from '../../utilities/FdmSDK';
import { type CogniteInternalId, type Node3D } from '@cognite/sdk';
import { type TreeIndexStylingGroup } from '../CadModelContainer/types';

export type AddImage360CollectionOptions =
| AddImage360CollectionEventsOptions
Expand Down Expand Up @@ -40,29 +41,45 @@ export type TaggedAddImage360CollectionOptions = {
type: 'image360';
addOptions: AddImage360CollectionOptions;
};
export type TaggedAdd3DModelOptions = {
type: 'cad' | 'pointcloud';
addOptions: AddReveal3DModelOptions;
export type TaggedAddCadResourceOptions = {
type: 'cad';
addOptions: AddCadResourceOptions;
};

export type TaggedAddResourceOptions = TaggedAdd3DModelOptions | TaggedAddImage360CollectionOptions;
export type TaggedAddPointCloudResourceOptions = {
type: 'pointcloud';
addOptions: AddPointCloudResourceOptions;
};

export type TaggedAddResourceOptions =
| TaggedAddCadResourceOptions
| TaggedAddPointCloudResourceOptions
| TaggedAddImage360CollectionOptions;

export type AddResourceOptions =
| AddCadResourceOptions
| AddPointCloudResourceOptions
| AddImage360CollectionOptions;

export type AddResourceOptions = AddReveal3DModelOptions | AddImage360CollectionOptions;
export type Add3dResourceOptions = AddModelOptions & { transform?: Matrix4 };

export type AddReveal3DModelOptions = AddModelOptions & { transform?: Matrix4 } & {
export type AddPointCloudResourceOptions = Add3dResourceOptions & {
styling?: { default?: NodeAppearance; mapped?: NodeAppearance };
};
export type TypedReveal3DModel = CadModelOptions | PointCloudModelOptions;

export type CadModelOptions = { type: 'cad' } & AddModelOptions & { transform?: Matrix4 } & {
styling?: { default?: NodeAppearance; mapped?: NodeAppearance };
export type AddCadResourceOptions = AddModelOptions & { transform?: Matrix4 } & {
styling?: {
default?: NodeAppearance;
mapped?: NodeAppearance;
nodeGroups?: TreeIndexStylingGroup[];
};
};

export type PointCloudModelOptions = { type: 'pointcloud' } & AddModelOptions & {
transform?: Matrix4;
} & {
styling?: { default?: NodeAppearance; mapped?: NodeAppearance };
};
export type TypedReveal3DModel = CadModelOptions | PointCloudModelOptions;

export type CadModelOptions = { type: 'cad' } & AddCadResourceOptions;

export type PointCloudModelOptions = { type: 'pointcloud' } & AddPointCloudResourceOptions;

export type NodeDataResult = {
fdmNode: DmsUniqueIdentifier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,35 @@ import {
type CadModelOptions,
type DefaultResourceStyling,
type FdmAssetStylingGroup
} from '../components/Reveal3DResources/types';
} from './types';
import { NumericRange, type NodeAppearance, IndexSet } from '@cognite/reveal';
import { type ThreeDModelFdmMappings } from './types';
import { type Node3D, type CogniteExternalId, type AssetMapping3D } from '@cognite/sdk';
import {
useFdmAssetMappings,
useMappedEdgesForRevisions
} from '../components/CacheProvider/NodeCacheProvider';
} from '../CacheProvider/NodeCacheProvider';
import { useMemo } from 'react';
import {
type NodeId,
type FdmEdgeWithNode,
type AssetId,
type ModelRevisionAssetNodesResult
} from '../components/CacheProvider/types';
} from '../CacheProvider/types';
import {
type CadStylingGroup,
type NodeStylingGroup,
type TreeIndexStylingGroup
} from '../components/CadModelContainer/useApplyCadModelStyling';
} from '../CadModelContainer/types';
import {
useAssetMappedNodesForRevisions,
useNodesForAssets
} from '../components/CacheProvider/AssetMappingAndNode3DCacheProvider';
import { isSameModel } from '../utilities/isSameModel';
import { isAssetMappingStylingGroup, isFdmAssetStylingGroup } from '../utilities/StylingGroupUtils';
} from '../CacheProvider/AssetMappingAndNode3DCacheProvider';
import {
isAssetMappingStylingGroup,
isFdmAssetStylingGroup
} from '../../utilities/StylingGroupUtils';
import { type ThreeDModelFdmMappings } from '../../hooks/types';
import { isSameModel } from '../../utilities/isSameModel';

type ModelStyleGroup = {
model: CadModelOptions;
Expand All @@ -49,11 +53,9 @@ type StyledModelWithMappingsFetched = {
isModelMappingsLoading: boolean;
};

export type CadStyleGroup = NodeStylingGroup | TreeIndexStylingGroup;

export type StyledModel = {
model: CadModelOptions;
styleGroups: CadStyleGroup[];
styleGroups: CadStylingGroup[];
};

export const useCalculateCadStyling = (
Expand Down Expand Up @@ -285,6 +287,11 @@ function useJoinStylingGroups(
const instanceStyleGroups = modelInstanceStyleGroups
.filter((typedModel) => isSameModel(typedModel.model, model))
.flatMap((typedModel) => typedModel.styleGroup);

if (model.styling?.nodeGroups !== undefined) {
instanceStyleGroups.push(...model.styling.nodeGroups);
}

return {
model,
styleGroups: [...mappedStyleGroup, ...instanceStyleGroups]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ import {
type DefaultResourceStyling,
type PointCloudModelOptions,
type AssetStylingGroup
} from '../components/Reveal3DResources/types';
} from './types';
import { useMemo } from 'react';
import { type AnnotationIdStylingGroup } from '../components/PointCloudContainer/useApplyPointCloudStyling';
import { type AnnotationIdStylingGroup } from '../PointCloudContainer/useApplyPointCloudStyling';
import { useQuery } from '@tanstack/react-query';
import { isSame3dModel } from '../utilities/isSameModel';
import { isSame3dModel } from '../../utilities/isSameModel';
import {
usePointCloudAnnotationMappingsForModels,
usePointCloudAnnotationIdsForModels
} from '../components/CacheProvider/PointCloudAnnotationCacheProvider';
import { EMPTY_ARRAY } from '../utilities/constants';
import { type PointCloudAnnotationModel } from '../components/CacheProvider/types';
} from '../CacheProvider/PointCloudAnnotationCacheProvider';
import { EMPTY_ARRAY } from '../../utilities/constants';
import { type PointCloudAnnotationModel } from '../CacheProvider/types';

export type StyledPointCloudModel = {
model: PointCloudModelOptions;
Expand Down
Loading
Loading