Skip to content

Commit

Permalink
chore: simplify quality component (#3583)
Browse files Browse the repository at this point in the history
* basic high quality setting button

* Updated component to switch & restructured code

* separated high fidelity & original cad coloring as two containers

* Setting button component which contains High Fidelity setting as default option and supports addingcustom setting elements

* moved custom settings button story example into Toolbar story

* Added custom High fidelity config option

* chore: simplify quality component

* chore: rename internal type

---------

Co-authored-by: Pramod S <[email protected]>
Co-authored-by: cognite-bulldozer[bot] <51074376+cognite-bulldozer[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Aug 16, 2023
1 parent 64aa284 commit dc41c81
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { useRevealContainerElement } from '../RevealContainer/RevealContainerEle
export const LayersButton = (): ReactElement => {
const viewer = useReveal();
const revealContainerElement = useRevealContainerElement();
const [layersEnabled, setLayersEnabled] = useState<boolean>(false);
const [visible, setVisible] = useState<boolean>(false);

const [cadModelIds, setCadModelIds] = useState<number[]>([]);
Expand All @@ -38,7 +37,6 @@ export const LayersButton = (): ReactElement => {
const pointCloudModelName = use3DModelName(pointCloudModelIds);

const showLayers = (): void => {
setLayersEnabled(!layersEnabled);
setVisible((prevState) => !prevState);
};

Expand Down
47 changes: 32 additions & 15 deletions react-components/src/components/RevealToolbar/RevealToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import { Button, ToolBar, type ToolBarProps } from '@cognite/cogs.js';
import { FitModelsButton } from './FitModelsButton';
import { LayersButton } from './LayersButton';
import { SlicerButton } from './SlicerButton';
import { SettingsButton } from './SettingsButton';
import { withSuppressRevealEvents } from '../../higher-order-components/withSuppressRevealEvents';
import { MeasurementButton } from './MeasurementButton';
import { HelpButton } from './HelpButton';
import { type QualitySettings } from './SettingsContainer/types';

const defaultStyle: ToolBarProps = {
style: {
Expand All @@ -19,32 +21,45 @@ const defaultStyle: ToolBarProps = {
}
};

const defaultContent = (
<>
<LayersButton />
type RevealToolbarProps = ToolBarProps & {
customSettingsContent?: JSX.Element;
lowFidelitySettings?: Partial<QualitySettings>;
highFidelitySettings?: Partial<QualitySettings>;
};

<FitModelsButton />
<Button type="ghost" icon="Collapse" aria-label="Focus asset" />
const DefaultContentWrapper = (props: RevealToolbarProps): ReactElement => {
return (
<>
<LayersButton />
<FitModelsButton />
<Button type="ghost" icon="Collapse" aria-label="Focus asset" />

<div className="cogs-toolbar-divider" />
<div className="cogs-toolbar-divider" />

<SlicerButton />
<MeasurementButton />
<SlicerButton />
<MeasurementButton />

<div className="cogs-toolbar-divider" />
<div className="cogs-toolbar-divider" />

<Button type="ghost" icon="Settings" aria-label="Show settings" />
<HelpButton />
</>
);
<SettingsButton
customSettingsContent={props.customSettingsContent}
lowQualitySettings={props.lowFidelitySettings}
highQualitySettings={props.highFidelitySettings}
/>
<HelpButton />
</>
);
};

const RevealToolbarContainer = (
props: ToolBarProps & { toolBarContent?: JSX.Element }
props: RevealToolbarProps & { toolBarContent?: JSX.Element }
): ReactElement => {
if (props.className === undefined && props.style === undefined) {
props = { ...props, ...defaultStyle };
}
return <ToolBar {...props}>{props.toolBarContent ?? defaultContent}</ToolBar>;
return (
<ToolBar {...props}>{props.toolBarContent ?? <DefaultContentWrapper {...props} />}</ToolBar>
);
};

export const RevealToolbar = withSuppressRevealEvents(
Expand All @@ -54,11 +69,13 @@ export const RevealToolbar = withSuppressRevealEvents(
SlicerButton: typeof SlicerButton;
LayersButton: typeof LayersButton;
MeasurementButton: typeof MeasurementButton;
SettingsButton: typeof SettingsButton;
HelpButton: typeof HelpButton;
};

RevealToolbar.FitModelsButton = FitModelsButton;
RevealToolbar.SlicerButton = SlicerButton;
RevealToolbar.LayersButton = LayersButton;
RevealToolbar.MeasurementButton = MeasurementButton;
RevealToolbar.SettingsButton = SettingsButton;
RevealToolbar.HelpButton = HelpButton;
37 changes: 37 additions & 0 deletions react-components/src/components/RevealToolbar/SettingsButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*!
* Copyright 2023 Cognite AS
*/

import { type ReactElement } from 'react';
import { Button, Dropdown, Menu } from '@cognite/cogs.js';
import { type QualitySettings } from './SettingsContainer/types';
import { HighFidelityContainer } from './SettingsContainer/HighFidelityContainer';

type CustomSettingsProps = {
customSettingsContent?: ReactElement;
lowQualitySettings?: Partial<QualitySettings>;
highQualitySettings?: Partial<QualitySettings>;
};

export const SettingsButton = ({
customSettingsContent,
lowQualitySettings,
highQualitySettings
}: CustomSettingsProps): ReactElement => {
return (
<Dropdown
appendTo={document.body}
content={
<Menu>
<HighFidelityContainer
lowQualitySettings={lowQualitySettings}
highQualitySettings={highQualitySettings}
/>
{customSettingsContent ?? <></>}
</Menu>
}
placement="auto">
<Button icon="Settings" type="ghost" aria-label="Show settings" />
</Dropdown>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*!
* Copyright 2023 Cognite AS
*/

import { type ReactElement, useState } from 'react';
import { Menu } from '@cognite/cogs.js';
import { useReveal } from '../../RevealContainer/RevealContext';
import { type QualitySettings, type QualityProps } from './types';
import { type Cognite3DViewer } from '@cognite/reveal';

const defaultLowFidelitySettings: QualitySettings = {
cadBudget: {
maximumRenderCost: 15_000_000,
highDetailProximityThreshold: 10
},
pointCloudBudget: {
numberOfPoints: 3_000_000
},
resolutionOptions: {
maxRenderResolution: 1.4e6,
movingCameraResolutionFactor: 1
}
};

const defaultHighFidelitySettings: QualitySettings = {
cadBudget: {
maximumRenderCost: 45_000_000,
highDetailProximityThreshold: 30
},
pointCloudBudget: {
numberOfPoints: 12_000_000
},
resolutionOptions: {
maxRenderResolution: Infinity,
movingCameraResolutionFactor: 1
}
};

export const HighFidelityContainer = ({
lowQualitySettings,
highQualitySettings
}: QualityProps): ReactElement => {
const viewer = useReveal();
const [active, setActive] = useState(!isLowFidelity(viewer));

const lowFidelityOptions: QualitySettings = {
...defaultLowFidelitySettings,
...lowQualitySettings
};
const highFidelityOptions: QualitySettings = {
...defaultHighFidelitySettings,
...highQualitySettings
};

const onClick = (): void => {
const config = active ? lowFidelityOptions : highFidelityOptions;
viewer.cadBudget = config.cadBudget;
viewer.pointCloudBudget = config.pointCloudBudget;
viewer.setResolutionOptions(config.resolutionOptions);
setActive((prevState) => !prevState);
};

return (
<Menu.Item hasSwitch toggled={active} onChange={onClick}>
High fidelity
</Menu.Item>
);
};

function isLowFidelity(viewer: Cognite3DViewer): boolean {
return (
viewer.cadBudget.maximumRenderCost <= defaultLowFidelitySettings.cadBudget.maximumRenderCost &&
viewer.pointCloudBudget.numberOfPoints <=
defaultLowFidelitySettings.pointCloudBudget.numberOfPoints
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*!
* Copyright 2023 Cognite AS
*/

import {
type CadModelBudget,
type PointCloudBudget,
type ResolutionOptions
} from '@cognite/reveal';
import { type ReactElement } from 'react';

export type QualityProps = {
lowQualitySettings?: Partial<QualitySettings>;
highQualitySettings?: Partial<QualitySettings>;
};

export type SettingsContainerProps = QualityProps & {
customSettingsContent?: ReactElement;
};

export type QualitySettings = {
cadBudget: CadModelBudget;
pointCloudBudget: PointCloudBudget;
resolutionOptions: ResolutionOptions;
};
1 change: 1 addition & 0 deletions react-components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ export type {
} from './components/Reveal3DResources/types';
export type { CameraNavigationActions } from './hooks/useCameraNavigation';
export type { Source } from './utilities/FdmSDK';
export type { QualitySettings } from './components/RevealToolbar/SettingsContainer/types';
1 change: 1 addition & 0 deletions react-components/src/utilities/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
export const DEFAULT_QUERY_STALE_TIME = 1000 * 60 * 10; // 10 minutes
export const METERS_TO_FEET = 3.28084;
export const FEET_TO_INCHES = 12;
export const FIDELITY_MULTIPLIER = 3;
56 changes: 54 additions & 2 deletions react-components/stories/Toolbar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
import type { Meta, StoryObj } from '@storybook/react';
import {
CadModelContainer,
type QualitySettings,
RevealContainer,
RevealToolbar,
withSuppressRevealEvents
} from '../src';
import { CogniteClient } from '@cognite/sdk';
import { Color } from 'three';
import styled from 'styled-components';
import { ToolBar, type ToolBarButton } from '@cognite/cogs.js';
import { Button, Menu, ToolBar, type ToolBarButton } from '@cognite/cogs.js';
import { type ReactElement, useState } from 'react';

const meta = {
title: 'Example/Toolbar',
Expand Down Expand Up @@ -46,6 +48,52 @@ const exampleToolBarButtons: ToolBarButton[] = [
}
];

const exampleCustomSettingElements = (): ReactElement => {
const [originalCadColor, setOriginalCadColor] = useState(false);

return (
<>
<Menu.Item
hasSwitch
toggled={originalCadColor}
onChange={() => {
setOriginalCadColor((prevMode) => !prevMode);
}}>
Original CAD coloring
</Menu.Item>
<Button>Custom Button</Button>
</>
);
};

const exampleHighQualitySettings: QualitySettings = {
cadBudget: {
maximumRenderCost: 95000000,
highDetailProximityThreshold: 100
},
pointCloudBudget: {
numberOfPoints: 12000000
},
resolutionOptions: {
maxRenderResolution: Infinity,
movingCameraResolutionFactor: 1
}
};

const exampleLowQualitySettings: QualitySettings = {
cadBudget: {
maximumRenderCost: 95000000,
highDetailProximityThreshold: 100
},
pointCloudBudget: {
numberOfPoints: 12000000
},
resolutionOptions: {
maxRenderResolution: 1e5,
movingCameraResolutionFactor: 1
}
};

export const Main: Story = {
args: {
addModelOptions: {
Expand All @@ -56,7 +104,11 @@ export const Main: Story = {
render: ({ addModelOptions }) => (
<RevealContainer sdk={sdk} color={new Color(0x4a4a4a)}>
<CadModelContainer addModelOptions={addModelOptions} />
<RevealToolbar />
<RevealToolbar
customSettingsContent={exampleCustomSettingElements()}
lowFidelitySettings={exampleLowQualitySettings}
highFidelitySettings={exampleHighQualitySettings}
/>
<MyCustomToolbar>
<RevealToolbar.FitModelsButton />
<ToolBar.ButtonGroup buttonGroup={exampleToolBarButtons} />
Expand Down

0 comments on commit dc41c81

Please sign in to comment.