Skip to content

Commit d0f3525

Browse files
authored
Merge pull request #96 from Exabyte-io/feature/SOF-4599
Added possibility to check distances and angles between atoms
2 parents f160ca6 + e8ca075 commit d0f3525

File tree

8 files changed

+1206
-4
lines changed

8 files changed

+1206
-4
lines changed

src/components/ThreeDEditor.jsx

Lines changed: 147 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import Replay from "@material-ui/icons/Replay";
1717
import Spellcheck from "@material-ui/icons/Spellcheck";
1818
import SwitchCamera from "@material-ui/icons/SwitchCamera";
1919
import ThreeDRotation from "@material-ui/icons/ThreeDRotation";
20+
import SquareFootIcon from "@material-ui/icons/SquareFoot";
21+
import HeightIcon from "@material-ui/icons/Height";
22+
import LooksIcon from "@material-ui/icons/Looks";
23+
import DeleteIcon from "@material-ui/icons/Delete";
2024
import setClass from "classnames";
2125
import $ from "jquery";
2226
import PropTypes from "prop-types";
@@ -52,6 +56,14 @@ export class ThreeDEditor extends React.Component {
5256
// on/off switch for the component
5357
isInteractive: false,
5458
isThreejsEditorModalShown: false,
59+
// isDistanceAndAnglesShown: false,
60+
measuresSettings: {
61+
isDistanceShown: false,
62+
isAnglesShown: false,
63+
measureLabelsShown: false,
64+
distance: 0,
65+
angle: 0,
66+
},
5567
// TODO: remove the need for `viewerTriggerResize`
5668
// whether to trigger resize
5769
viewerTriggerResize: false,
@@ -88,6 +100,13 @@ export class ThreeDEditor extends React.Component {
88100
this.onThreejsEditorModalHide = this.onThreejsEditorModalHide.bind(this);
89101
this.handleChemicalConnectivityFactorChange =
90102
this.handleChemicalConnectivityFactorChange.bind(this);
103+
this.handleToggleDistanceShown = this.handleToggleDistanceShown.bind(this);
104+
this.handleToggleAnglesShown = this.handleToggleAnglesShown.bind(this);
105+
this.handleSetState = this.handleSetState.bind(this);
106+
this.handleDeleteConnection = this.handleDeleteConnection.bind(this);
107+
this.handleResetMeasures = this.handleResetMeasures.bind(this);
108+
this.offMeasureParam = this.offMeasureParam.bind(this);
109+
this.onMeasureParam = this.onMeasureParam.bind(this);
91110
}
92111

93112
// TODO: update component to fully controlled or fully uncontrolled with a key?
@@ -121,7 +140,6 @@ export class ThreeDEditor extends React.Component {
121140
});
122141
};
123142

124-
// eslint-disable-next-line class-methods-use-this
125143
handleCellRepetitionsChange(e) {
126144
this.handleSetSetting({ [e.target.id]: parseFloat($(e.target).val()) });
127145
}
@@ -153,6 +171,7 @@ export class ThreeDEditor extends React.Component {
153171

154172
handleToggleConventionalCell() {
155173
const { isConventionalCellShown, originalMaterial } = this.state;
174+
this.handleResetMeasures();
156175
this.setState({
157176
isConventionalCellShown: !isConventionalCellShown,
158177
originalMaterial: this.getPrimitiveOrConventionalMaterial(
@@ -185,6 +204,10 @@ export class ThreeDEditor extends React.Component {
185204

186205
// TODO: reset the colors for other buttons in the panel on call to the function below
187206
handleResetViewer() {
207+
const { measuresSettings } = this.state;
208+
this.setState({
209+
measuresSettings: { ...measuresSettings, isDistanceShown: false, isAnglesShown: false },
210+
});
188211
this.WaveComponent.initViewer();
189212
this._resetStateWaveComponent();
190213
}
@@ -212,6 +235,67 @@ export class ThreeDEditor extends React.Component {
212235
return this.WaveComponent && this.WaveComponent.wave[name];
213236
}
214237

238+
handleSetState(newState) {
239+
this.setState(newState);
240+
}
241+
242+
handleDeleteConnection() {
243+
this.WaveComponent.wave.deleteConnection();
244+
}
245+
246+
handleToggleDistanceShown() {
247+
const { measuresSettings } = this.state;
248+
const { isDistanceShown, isAnglesShown } = measuresSettings;
249+
if (isAnglesShown) {
250+
this.offMeasureParam("isAnglesShown");
251+
}
252+
253+
if (!isDistanceShown) {
254+
this.onMeasureParam("isDistanceShown", "isAnglesShown");
255+
} else {
256+
this.offMeasureParam("isDistanceShown");
257+
}
258+
}
259+
260+
handleResetMeasures() {
261+
this.WaveComponent.wave.resetMeasures();
262+
}
263+
264+
offMeasureParam(param) {
265+
this.WaveComponent.wave.destroyListeners();
266+
this.handleResetMeasures();
267+
this.setState((prevState) => {
268+
const { measuresSettings } = prevState;
269+
return { ...prevState, measuresSettings: { ...measuresSettings, [param]: false } };
270+
});
271+
}
272+
273+
onMeasureParam(param, offParam) {
274+
this.setState((prevState) => {
275+
const { measuresSettings } = prevState;
276+
return { ...prevState, measuresSettings: { ...measuresSettings, [param]: true } };
277+
});
278+
const { measuresSettings } = this.state;
279+
this.WaveComponent.wave.initListeners(this.handleSetState, {
280+
...measuresSettings,
281+
[param]: true,
282+
[offParam]: false,
283+
});
284+
}
285+
286+
handleToggleAnglesShown() {
287+
const { measuresSettings } = this.state;
288+
const { isAnglesShown, isDistanceShown } = measuresSettings;
289+
if (isDistanceShown) {
290+
this.offMeasureParam("isDistanceShown");
291+
}
292+
if (!isAnglesShown) {
293+
this.onMeasureParam("isAnglesShown", "isDistanceShown");
294+
} else {
295+
this.offMeasureParam("isAnglesShown");
296+
}
297+
}
298+
215299
/**
216300
* Returns a cover div to cover the area and prevent user interaction with component
217301
*/
@@ -398,6 +482,66 @@ export class ThreeDEditor extends React.Component {
398482
);
399483
}
400484

485+
getMeasuresToolbarItems() {
486+
const { measuresSettings } = this.state;
487+
const { isDistanceShown, isAnglesShown } = measuresSettings;
488+
489+
return [
490+
<RoundIconButton
491+
key="Distance"
492+
tooltipPlacement="top"
493+
title="Distance"
494+
isToggled={isDistanceShown}
495+
onClick={this.handleToggleDistanceShown}
496+
>
497+
<HeightIcon />
498+
</RoundIconButton>,
499+
<RoundIconButton
500+
key="Angles"
501+
tooltipPlacement="top"
502+
title="Angles"
503+
isToggled={isAnglesShown}
504+
onClick={this.handleToggleAnglesShown}
505+
>
506+
<LooksIcon />
507+
</RoundIconButton>,
508+
<RoundIconButton
509+
key="Reset Measures"
510+
tooltipPlacement="top"
511+
title="Reset Measures"
512+
isToggleable={false}
513+
onClick={this.handleResetMeasures}
514+
>
515+
<Replay />
516+
</RoundIconButton>,
517+
518+
<RoundIconButton
519+
key="Delete"
520+
tooltipPlacement="top"
521+
title="Delete connection"
522+
isToggleable={false}
523+
onClick={this.handleDeleteConnection}
524+
>
525+
<DeleteIcon />
526+
</RoundIconButton>,
527+
];
528+
}
529+
530+
renderMeasuresToolbar(className) {
531+
const { isInteractive } = this.state;
532+
533+
return (
534+
<IconToolbar
535+
className={className}
536+
title="Measurements"
537+
iconComponent={SquareFootIcon}
538+
isHidden={!isInteractive}
539+
>
540+
{this.getMeasuresToolbarItems()}
541+
</IconToolbar>
542+
);
543+
}
544+
401545
getParametersToolbarItems() {
402546
const { viewerSettings } = this.state;
403547
return [
@@ -581,6 +725,7 @@ export class ThreeDEditor extends React.Component {
581725

582726
renderWaveOrThreejsEditorModal() {
583727
const { originalMaterial, isThreejsEditorModalShown } = this.state;
728+
584729
const { editable } = this.props;
585730
if (isThreejsEditorModalShown) {
586731
return (
@@ -600,6 +745,7 @@ export class ThreeDEditor extends React.Component {
600745
{this.renderViewToolbar(this.classNamesForTopToolbar + " second-row")}
601746
{this.renderParametersToolbar(this.classNamesForTopToolbar + " third-row")}
602747
{editable && this.render3DEditToggle(this.classNamesForTopToolbar + " fourth-row")}
748+
{this.renderMeasuresToolbar(this.classNamesForTopToolbar + " fifth-row")}
603749
{this.renderExportToolbar(this.classNamesForBottomToolbar)}
604750
</div>
605751
);

src/enums.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,13 @@ export const BOUNDARY_CONDITIONS = [
2222
];
2323

2424
export const ATOM_GROUP_NAME = "Atoms";
25+
export const ATOM_CONNECTIONS_GROUP_NAME = "Atom_Connections";
26+
export const ATOM_CONNECTION_LINE_NAME = "Atom_Connection";
27+
export const MIN_ANGLE_POINTS_DISTANCE = 0.7;
28+
export const MEASURE_LABELS_GROUP_NAME = "Measure_Labels";
29+
export const ANGLE = "ANGLE";
30+
31+
export const COLORS = {
32+
RED: 0xff0000,
33+
GREEN: 0x00ff00,
34+
};

src/mixins/atoms.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,7 @@ export const AtomsMixin = (superclass) =>
109109
const basis = this.areNonPeriodicBoundariesPresent
110110
? this.basisWithElementsInsideNonPeriodicBoundaries
111111
: this.basis;
112-
this.repeatObject3DAtRepetitionCoordinates(
113-
this.createAtomsGroup(basis, atomRadiiScale),
114-
);
112+
this.repeatAtomsAtRepetitionCoordinates(this.createAtomsGroup(basis, atomRadiiScale));
115113
}
116114

117115
getAtomColorByElement(element, pallette = this.settings.elementColors) {

0 commit comments

Comments
 (0)