Skip to content

Commit

Permalink
chore: add more to output type, refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
haakonflatval-cognite committed Aug 1, 2023
1 parent 250557e commit c025a1e
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 96 deletions.
116 changes: 64 additions & 52 deletions react-components/src/components/Reveal3DResources/queryMappedData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/

import { type Cognite3DViewer, type PointerEventData, type CogniteCadModel } from '@cognite/reveal';
import { type CogniteInternalId, type CogniteClient } from '@cognite/sdk';
import { type CogniteInternalId, type CogniteClient, Node3D } from '@cognite/sdk';
import {
type EdgeItem,
type InspectResultList,
Expand All @@ -12,13 +12,72 @@ import {
type Source
} from '../../utilities/FdmSDK';
import { type FdmAssetMappingsConfig } from '../../hooks/types';
import { type NodeDataResult } from './types';
import { FdmPropertyType, type NodeDataResult } from './types';

async function getAncestorNodeIdsForTreeIndex(
export async function queryMappedData<NodeType>(
viewer: Cognite3DViewer,
cdfClient: CogniteClient,
fdmClient: FdmSDK,
fdmConfig: FdmAssetMappingsConfig,
clickEvent: PointerEventData
): Promise<NodeDataResult<NodeType> | undefined> {
const intersection = await viewer.getIntersectionFromPixel(
clickEvent.offsetX,
clickEvent.offsetY
);

if (intersection === null || intersection.type !== 'cad') {
return;
}

const cadIntersection = intersection;
const model = cadIntersection.model;

const ancestors = await getAncestorNodesForTreeIndex(cdfClient, model, cadIntersection.treeIndex);

const mappings = await getMappingEdges(
fdmClient,
fdmConfig,
model,
ancestors.map((n) => n.id)
);

if (mappings.edges.length === 0) {
return;
}

const selectedEdge = mappings.edges[0];
const selectedNodeId =
selectedEdge.properties[fdmConfig.source.space][
`${fdmConfig.source.externalId}/${fdmConfig.source.version}`
].revisionNodeId;
const selectedNode = ancestors.find((n) => n.id === selectedNodeId);
const dataNode = selectedEdge.startNode;

const inspectionResult = await inspectNode(fdmClient, dataNode);

const dataView =
inspectionResult.items[0]?.inspectionResults.involvedViewsAndContainers?.views[0];

const nodeData = await filterNodeData<NodeType>(fdmClient, dataNode, dataView);

if (nodeData === undefined) {
return undefined;
}

return {
data: nodeData as FdmPropertyType<NodeType>,
view: dataView,
cadNode: selectedNode!,
model: cadIntersection.model
};
}

async function getAncestorNodesForTreeIndex(
client: CogniteClient,
model: CogniteCadModel,
treeIndex: number
): Promise<CogniteInternalId[]> {
): Promise<Node3D[]> {
const nodeId = await model.mapTreeIndexToNodeId(treeIndex);

const ancestorNodes = await client.revisions3D.list3DNodeAncestors(
Expand All @@ -27,7 +86,7 @@ async function getAncestorNodeIdsForTreeIndex(
nodeId
);

return ancestorNodes.items.map((n) => n.id);
return ancestorNodes.items;
}

async function getMappingEdges(
Expand Down Expand Up @@ -109,50 +168,3 @@ async function filterNodeData<NodeType>(
`${dataView.externalId}/${dataView.version}`
];
}

export async function queryMappedData<NodeType>(
viewer: Cognite3DViewer,
cdfClient: CogniteClient,
fdmClient: FdmSDK,
fdmConfig: FdmAssetMappingsConfig,
clickEvent: PointerEventData
): Promise<NodeDataResult<NodeType> | undefined> {
const intersection = await viewer.getIntersectionFromPixel(
clickEvent.offsetX,
clickEvent.offsetY
);

if (intersection === null || intersection.type !== 'cad') {
return;
}

const cadIntersection = intersection;
const model = cadIntersection.model;

const ancestorIds = await getAncestorNodeIdsForTreeIndex(
cdfClient,
model,
cadIntersection.treeIndex
);

const mappings = await getMappingEdges(fdmClient, fdmConfig, model, ancestorIds);

if (mappings.edges.length === 0) {
return;
}

const dataNode = mappings.edges[0].startNode;

const inspectionResult = await inspectNode(fdmClient, dataNode);

const dataView =
inspectionResult.items[0]?.inspectionResults.involvedViewsAndContainers?.views[0];

const nodeData = await filterNodeData<NodeType>(fdmClient, dataNode, dataView);

if (nodeData === undefined) {
return undefined;
}

return { data: nodeData as NodeType, view: dataView };
}
9 changes: 7 additions & 2 deletions react-components/src/components/Reveal3DResources/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@
* Copyright 2023 Cognite AS
*/

import { type AddModelOptions, type SupportedModelTypes } from '@cognite/reveal';
import { CogniteCadModel, type AddModelOptions, type SupportedModelTypes } from '@cognite/reveal';
import { type Matrix4 } from 'three';
import { type Source } from '../../utilities/FdmSDK';
import { Node3D } from '@cognite/sdk/dist/src';

export type AddImageCollection360Options = {
siteId: string;
};

export type FdmPropertyType<NodeType> = Record<string, Record<string, NodeType>>;

export type AddResourceOptions = AddReveal3DModelOptions | AddImageCollection360Options;

export type AddReveal3DModelOptions = AddModelOptions & { transform?: Matrix4 };
export type TypedReveal3DModel = AddReveal3DModelOptions & { type: SupportedModelTypes | '' };

export type NodeDataResult<NodeType> = {
data: NodeType;
data: FdmPropertyType<NodeType>;
view: Source;
cadNode: Node3D;
model: CogniteCadModel;
};
101 changes: 59 additions & 42 deletions react-components/stories/HighlightNode.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,25 @@ import {
type FdmAssetMappingsConfig,
RevealContainer,
RevealToolbar,
useReveal
useReveal,
Reveal3DResources,
NodeDataResult,
Reveal3DResourcesProps,
AddResourceOptions
} from '../src';
import { CogniteClient } from '@cognite/sdk';
import { Color, Matrix4 } from 'three';
import { type ReactElement, useEffect, useState } from 'react';
import { type PointerEventData } from '@cognite/reveal';
import {
CogniteCadModel,
DefaultNodeAppearance,
NodeIdNodeCollection,
TreeIndexNodeCollection,
type PointerEventData
} from '@cognite/reveal';
import { queryMappedData } from '../src/components/Reveal3DResources/queryMappedData';
import { useFdmSdk, useSDK } from '../src/components/RevealContainer/SDKProvider';
import { createSdkByUrlToken } from './utilities/createSdkByUrlToken';

const DefaultFdmConfig: FdmAssetMappingsConfig = {
source: {
Expand All @@ -30,61 +41,67 @@ const DefaultFdmConfig: FdmAssetMappingsConfig = {

const meta = {
title: 'Example/HighlightNode',
component: CadModelContainer,
component: Reveal3DResources,
tags: ['autodocs']
} satisfies Meta<typeof CadModelContainer>;
} satisfies Meta<typeof Reveal3DResources>;

export default meta;
type Story = StoryObj<typeof meta>;

const token = new URLSearchParams(window.location.search).get('token') ?? '';
const sdk = new CogniteClient({
appId: 'reveal.example',
baseUrl: 'https://greenfield.cognitedata.com',
project: '3d-test',
getToken: async () => await Promise.resolve(token)
});
const sdk = createSdkByUrlToken();

export const Main: Story = {
args: {
addModelOptions: {
modelId: 2551525377383868,
revisionId: 2143672450453400
},
transform: new Matrix4().makeTranslation(0, 10, 0)
resources: [
{
modelId: 2551525377383868,
revisionId: 2143672450453400,
transform: new Matrix4().makeTranslation(-340, -480, 80)
}
],
styling: {},
fdmAssetMappingConfig: DefaultFdmConfig
},
render: ({ addModelOptions }) => (
<RevealContainer sdk={sdk} color={new Color(0x4a4a4a)}>
<CadModelContainer addModelOptions={addModelOptions} />
<RevealToolbar />
<Querier fdmConfig={DefaultFdmConfig} />
</RevealContainer>
)
render: ({ resources, fdmAssetMappingConfig }) => {
return (
<RevealContainer sdk={sdk} color={new Color(0x4a4a4a)}>
<StoryContent resources={resources} fdmAssetMappingConfig={fdmAssetMappingConfig} />
</RevealContainer>
);
}
};

const Querier = ({ fdmConfig }: { fdmConfig: FdmAssetMappingsConfig }): ReactElement => {
const StoryContent = ({
resources,
fdmAssetMappingConfig
}: {
resources: AddResourceOptions[];
fdmAssetMappingConfig: FdmAssetMappingsConfig;
}) => {
const viewer = useReveal();
const sdk = useSDK();
const fdmClient = useFdmSdk();

const [nodeData, setNodeData] = useState<any>(undefined);
const [nodeData, setNodeData] = useState<any>();

useEffect(() => {
const queryAndSetData = (e: PointerEventData): void => {
void (async (e: PointerEventData): Promise<void> => {
const nodeData = await queryMappedData(viewer, sdk, fdmClient, fdmConfig, e);
setNodeData(nodeData);
})(e);
};
const callback = (nodeData: NodeDataResult<any>) => {
setNodeData(nodeData.data);

viewer.on('click', (e: PointerEventData) => {
queryAndSetData(e);
});
if (!(viewer.models[0] instanceof CogniteCadModel)) return;

return (): void => {
viewer.off('click', queryAndSetData);
};
}, [viewer, sdk, fdmClient, fdmConfig]);
viewer.models[0].assignStyledNodeCollection(
new TreeIndexNodeCollection([nodeData.cadNode.treeIndex]),
DefaultNodeAppearance.Highlighted
);
};

return <>Clicked node content: {JSON.stringify(nodeData)}</>;
return (
<>
<Reveal3DResources
resources={resources}
fdmAssetMappingConfig={fdmAssetMappingConfig}
onNodeClick={callback}
/>
<RevealToolbar />
NodeData is: {JSON.stringify(nodeData)}
</>
);
};

0 comments on commit c025a1e

Please sign in to comment.