Skip to content

Commit

Permalink
Button to Center view on visible objects (#452)
Browse files Browse the repository at this point in the history
* Can't access camera

* Use CustomEvent to emit and trigger correct method

* Use CustomEvent to emit and trigger correct method

* Use MainViewModel ID to only trigger correct model

* Rename custom event to `jupytercadObjectSelection`

* Return full `MainViewModel` with `get mainViewModel()`
  • Loading branch information
arjxn-py authored Oct 10, 2024
1 parent 2a39e90 commit a5442ea
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 3 deletions.
32 changes: 32 additions & 0 deletions packages/base/src/3dview/mainview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ export class MainView extends React.Component<IProps, IStates> {
this.addContextMenu();
this._mainViewModel.initWorker();
this._mainViewModel.initSignal();
window.addEventListener('jupytercadObjectSelection', (e: Event) => {
const customEvent = e as CustomEvent;

if (customEvent.detail.mainViewModelId === this._mainViewModel.id) {
this.lookAtPosition(customEvent.detail.objPosition);
}
});
}

componentDidUpdate(oldProps: IProps, oldState: IStates): void {
Expand Down Expand Up @@ -435,6 +442,31 @@ export class MainView extends React.Component<IProps, IStates> {
this.resizeCanvasToDisplaySize();
};

private lookAtPosition(position: { x: number; y: number; z: number }) {
const objPosition = new THREE.Vector3(
position[0],
position[1],
position[2]
);
if (this._camera) {
this._camera.lookAt(objPosition);
const cameraToTargetDistance =
this._camera.position.distanceTo(objPosition);

if (cameraToTargetDistance < 1) {
// Move the camera back slightly to ensure visibility
this._camera.position.add(
this._camera.getWorldDirection(new THREE.Vector3()).multiplyScalar(-2)
);
}
this._camera.updateProjectionMatrix();
}
if (this._controls) {
this._controls.target.copy(objPosition);
this._controls.update();
}
}

private _updateAnnotation() {
Object.keys(this.state.annotations).forEach(key => {
const el = document.getElementById(key);
Expand Down
7 changes: 7 additions & 0 deletions packages/base/src/panelview/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { ISignal } from '@lumino/signaling';

import { IJupyterCadTracker, IJupyterCadWidget } from '@jupytercad/schema';
import { IControlPanelModel } from '../types';
import { JupyterCadWidget } from '../widget';
import { MainViewModel } from '../3dview/mainviewmodel';

export class ControlPanelModel implements IControlPanelModel {
constructor(options: ControlPanelModel.IOptions) {
Expand All @@ -26,6 +28,11 @@ export class ControlPanelModel implements IControlPanelModel {
return this._tracker.currentWidget?.context.model.sharedModel;
}

get mainViewModel(): MainViewModel | undefined {
return (this._tracker.currentWidget as JupyterCadWidget | null)?.content
.currentViewModel;
}

disconnect(f: any): void {
this._tracker.forEach(w => {
w.context.model.sharedObjectsChanged.disconnect(f);
Expand Down
26 changes: 23 additions & 3 deletions packages/base/src/panelview/objecttree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,27 @@ class ObjectTreeReact extends React.Component<IProps, IStates> {
this.setState(old => ({ ...old, lightTheme }));
};

handleNodeClick = (objectId: string) => {
const object = this.getObjectFromName(objectId);

if (object && object.visible === true) {
const objPosition = object?.parameters?.Placement?.Position || {
x: 0,
y: 0,
z: 0
};

const event = new CustomEvent('jupytercadObjectSelection', {
detail: {
objectId,
objPosition,
mainViewModelId: this.props.cpModel.mainViewModel?.id
}
});
window.dispatchEvent(event);
}
};

private _sharedJcadModelChanged = (
sender: IJupyterCadDoc,
change: IJcadObjectDocChange
Expand Down Expand Up @@ -378,9 +399,8 @@ class ObjectTreeReact extends React.Component<IProps, IStates> {

return (
<div
className={`jpcad-control-panel-tree ${
opts.selected ? 'selected' : ''
}`}
className={`jpcad-control-panel-tree ${opts.selected ? 'selected' : ''}`}
onClick={() => this.handleNodeClick(opts.node.id as string)}
>
<div
style={{
Expand Down
2 changes: 2 additions & 0 deletions packages/base/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ISignal } from '@lumino/signaling';
import { IJupyterCadModel, IJupyterCadDoc, IDict } from '@jupytercad/schema';
import { IJupyterCadTracker, IJupyterCadWidget } from '@jupytercad/schema';
import { MainViewModel } from './3dview/mainviewmodel';

export { IDict };
export type ValueOf<T> = T[keyof T];
Expand Down Expand Up @@ -42,4 +43,5 @@ export interface IControlPanelModel {
filePath: string | undefined;
jcadModel: IJupyterCadModel | undefined;
sharedModel: IJupyterCadDoc | undefined;
mainViewModel: MainViewModel | undefined;
}

0 comments on commit a5442ea

Please sign in to comment.