Skip to content

Commit

Permalink
Merge pull request #5069 from 3drepo/ISSUE_4911
Browse files Browse the repository at this point in the history
ISSUE #4911 - Milestone 3: Step 3 - Planes height calibration
  • Loading branch information
sanmont3drepo authored Aug 27, 2024
2 parents 150b3d0 + c1e68a0 commit e1fc566
Show file tree
Hide file tree
Showing 38 changed files with 288,144 additions and 5,059 deletions.
Binary file modified frontend/assets/drawings/blueprint.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43,508 changes: 38,608 additions & 4,900 deletions frontend/assets/drawings/blueprint.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/assets/drawings/rac_level_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
131,338 changes: 131,338 additions & 0 deletions frontend/assets/drawings/rac_level_1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/assets/drawings/rac_level_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72,952 changes: 72,952 additions & 0 deletions frontend/assets/drawings/rac_level_2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/assets/drawings/rac_site.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44,678 changes: 44,678 additions & 0 deletions frontend/assets/drawings/rac_site.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions frontend/assets/icons/viewer/vertical_calibration.svg.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright (C) 2024 3D Repo Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

type IProps = {
className?: any;
};

export default ({ className }: IProps) => (
<svg width="21" height="22" viewBox="0 0 21 22" fill="none" xmlns="http://www.w3.org/2000/svg" className={className}>
<path d="M21 1.23828C21 1.64602 20.6695 1.97656 20.2617 1.97656L12.2739 1.97656C11.8662 1.97656 11.5356 1.64602 11.5356 1.23828C11.5356 0.83054 11.8662 0.5 12.2739 0.5L20.2617 0.5C20.6695 0.5 21 0.83054 21 1.23828Z" fill="currentColor"/>
<path fillRule="evenodd" clipRule="evenodd" d="M0.750587 0.5C0.336049 0.5 1.1266e-06 0.83605 1.08484e-06 1.25059L0 20.7494C-2.30677e-08 21.164 0.336128 21.5 0.750586 21.5H6.11953C6.53407 21.5 6.87012 21.1639 6.87012 20.7494L6.87012 1.25059C6.87012 0.836061 6.53408 0.500001 6.11953 0.500001L0.750587 0.5ZM1.47656 20.0234L1.47656 1.97656L5.39356 1.97656V5.38086H3.594C3.18625 5.38086 2.85571 5.7114 2.85571 6.11914C2.85571 6.52688 3.18625 6.85742 3.594 6.85742H5.39356V10.2617H3.59399C3.18625 10.2617 2.85571 10.5923 2.85571 11C2.85571 11.4077 3.18625 11.7383 3.59399 11.7383H5.39356V15.1426H3.59399C3.18625 15.1426 2.85571 15.4731 2.85571 15.8809C2.85571 16.2886 3.18625 16.6191 3.59399 16.6191H5.39356L5.39355 20.0234H1.47656Z" fill="currentColor"/>
<path d="M17.4305 5.13674C17.7189 5.42506 18.1863 5.42506 18.4746 5.13674C18.7629 4.84842 18.7629 4.38097 18.4746 4.09265L16.7859 2.40389C16.6474 2.26543 16.4596 2.18765 16.2638 2.18765C16.068 2.18765 15.8802 2.26543 15.7418 2.40389L14.0553 4.09038C13.767 4.37869 13.767 4.84615 14.0553 5.13446C14.3436 5.42278 14.8111 5.42278 15.0994 5.13446L15.5136 4.7202L15.5221 17.2906L15.0949 16.8633C14.8066 16.575 14.3391 16.575 14.0508 16.8633C13.7625 17.1517 13.7625 17.6191 14.0508 17.9074L15.7396 19.5962C15.878 19.7347 16.0658 19.8124 16.2616 19.8124C16.4574 19.8124 16.6452 19.7347 16.7836 19.5962L18.4701 17.9097C18.7584 17.6214 18.7584 17.1539 18.4701 16.8656C18.1818 16.5773 17.7144 16.5773 17.426 16.8656L16.9987 17.293L16.9902 4.69638L17.4305 5.13674Z" fill="currentColor"/>
<path d="M20.2617 21.5C20.6695 21.5 21 21.1695 21 20.7617C21 20.354 20.6695 20.0234 20.2617 20.0234H12.2739C11.8662 20.0234 11.5356 20.354 11.5356 20.7617C11.5356 21.1695 11.8662 21.5 12.2739 21.5H20.2617Z" fill="currentColor"/>
</svg>
);
4 changes: 3 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"@mui/system": "5.4.1",
"@mui/x-date-pickers": "5.0.3",
"@popperjs/core": "2.6.0",
"@types/three": "0.167.1",
"@webscopeio/react-textarea-autocomplete": "4.9.0",
"axios": "1.6.5",
"bezier-easing": "2.1.0",
Expand Down Expand Up @@ -121,6 +122,7 @@
"simplebar-react": "2.4.3",
"socket.io-client": "4.6.1",
"styled-components": "5.3.9",
"three": "0.167.1",
"type-fest": "2.3.2",
"ua-parser-js": "1.0.37",
"uuidv4": "5.0.1",
Expand Down Expand Up @@ -199,4 +201,4 @@
"@mui/styled-engine": "npm:@mui/[email protected]",
"@babel/traverse": "7.23.7"
}
}
}
41 changes: 38 additions & 3 deletions frontend/src/globals/unity-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -744,8 +744,7 @@ export class UnityUtil {
/** @hidden */
public static calibrationPlanesChanged(planesJson) {
const planes = JSON.parse(planesJson);
// eslint-disable-next-line no-console
console.log(planes); //todo 4857 - remove this line when the viewer events are hooked up
UnityUtil.viewer.calibrationPlanesChanged([planes.lower, planes.upper]);
}

/*
Expand Down Expand Up @@ -2528,6 +2527,14 @@ export class UnityUtil {
UnityUtil.toUnity('SetCalibrationToolFloorToObject', UnityUtil.LoadingState.VIEWER_READY, JSON.stringify(parms));
}

/**
* Sets the default height of the floor used when calling setCalibrationToolFloorToObject, in meters.
* @category Calibration
*/
public static setCalibrationToolFloorHeight(height: number) {
UnityUtil.toUnity('SetCalibrationToolFloorHeight', UnityUtil.LoadingState.VIEWER_READY, height);
}

/**
* Sets or removes the Start and End of the Calibration Vector. If Start or End are set to null, the tool
* will immediately allow the user to place them again. Vector Mode must be explicitly enabled - calling
Expand All @@ -2538,6 +2545,34 @@ export class UnityUtil {
UnityUtil.toUnity('SetCalibrationToolVector', UnityUtil.LoadingState.VIEWER_READY, JSON.stringify({ start, end }));
}

/**
* Sets tint and border colours of the image in the image preview, for the level that is selected.
* Both properties must be provided, and as HTML colour strings.
* @category Calibration
*/
public static setCalibrationToolSelectedColors(fill: string, border: string) {
UnityUtil.toUnity('SetCalibrationToolSelectedColours', UnityUtil.LoadingState.VIEWER_READY, JSON.stringify({fill, border}));
}

/**
* Sets tint and border colours of the image in the image preview, for the level that is not selected.
* Both properties must be provided, and as HTML colour strings.
* @category Calibration
*/
public static setCalibrationToolUnselectedColors(fill: string, border: string) {
UnityUtil.toUnity('SetCalibrationToolUnselectedColours', UnityUtil.LoadingState.VIEWER_READY, JSON.stringify({fill, border}));
}

/**
* Sets the additional transparency that is applied, as a multiplier, to the image tint colour set by
* setCalibrationToolSelectedColors or setCalibrationToolUnselectedColors when part of the preview
* plane is obscured by model geometry. This should be between 0 and 1.
* @category Calibration
*/
public static setCalibrationToolOcclusionOpacity(opacity: number) {
UnityUtil.toUnity('SetCalibrationToolOcclusionOpacity', UnityUtil.LoadingState.VIEWER_READY, opacity);
}

/**
* Shows the DrawingImageSource for the Lower and Upper vertical planes at the horizontal location specified by rect.
* rect should be the size and location of the image, given as the location of three corners (bottomLeft, bottomRight,
Expand Down Expand Up @@ -2578,7 +2613,7 @@ export class UnityUtil {
ctx.texSubImage2D(ctx.TEXTURE_2D, 0, 0, 0, image.width, image.height, ctx.RGBA, ctx.UNSIGNED_BYTE, image);
delete this.domTextureReferences[index];
}

/**
* Sets the maximum number of responses WebRequestManager2 should attempt to
* handle at any one time. The higher this is the faster models will load but
Expand Down
1 change: 1 addition & 0 deletions frontend/src/v4/constants/viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export const VIEWER_EVENTS = {
UNHIGHLIGHT_OBJECTS: 'VIEWER_UNHIGHLIGHT_OBJECTS',
UNITY_ERROR: 'VIEWER_EVENT_UNITY_ERROR',
UNITY_READY: 'VIEWER_EVENT_UNITY_READY',
UPDATE_CALIBRATION_PLANES: 'VIEWER_UPDATE_CALIBRATION_PLANES',
UPDATE_CLIP: 'VIEWER_UPDATE_CLIP',
UPDATE_CLIP_EDIT: 'VIEWER_SET_CLIP_EDIT',
UPDATE_CLIP_MODE: 'VIEWER_UPDATE_CLIP_MODE',
Expand Down
43 changes: 43 additions & 0 deletions frontend/src/v4/services/viewer/viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1326,6 +1326,49 @@ export class ViewerService {
})

}

/**
* Drawings Calibration
*/
public setCalibrationToolMode(mode: string) {
UnityUtil.setCalibrationToolMode(mode);
}

public setCalibrationToolVerticalPlanes(lower, upper) {
UnityUtil.setCalibrationToolVerticalPlanes(lower, upper);
}

public selectCalibrationToolUpperPlane() {
UnityUtil.selectCalibrationToolUpperPlane();
}

public selectCalibrationToolLowerPlane() {
UnityUtil.selectCalibrationToolLowerPlane();
}

public setCalibrationToolDrawing(image: any, rect: number[]) {
UnityUtil.setCalibrationToolDrawing(image, rect);
}

public calibrationPlanesChanged(planes) {
this.emit(VIEWER_EVENTS.UPDATE_CALIBRATION_PLANES, planes);
}

public setCalibrationToolFloorToObject(teamspace, modelId, meshId) {
UnityUtil.setCalibrationToolFloorToObject(teamspace, modelId, meshId);
}

public setCalibrationToolSelectedColors(fill, border) {
UnityUtil.setCalibrationToolSelectedColors(fill, border);
}

public setCalibrationToolUnselectedColors(fill, border) {
UnityUtil.setCalibrationToolUnselectedColors(fill, border);
}

public setCalibrationToolOcclusionOpacity(opacity) {
UnityUtil.setCalibrationToolOcclusionOpacity(opacity);
}
}

export const Viewer = new ViewerService({});
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/v5/store/containers/containers.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,27 @@ export const CONTAINER_UNITS = [
{
value: 'mm',
name: formatMessage({ id: 'containers.unit.name.mm', defaultMessage: 'Millimetres' }),
abbreviation: formatMessage({ id: 'containers.unit.abbreviation.mm', defaultMessage: 'mm' }),
},
{
value: 'cm',
name: formatMessage({ id: 'containers.unit.name.cm', defaultMessage: 'Centimetres' }),
abbreviation: formatMessage({ id: 'containers.unit.abbreviation.cm', defaultMessage: 'cm' }),
},
{
value: 'dm',
name: formatMessage({ id: 'containers.unit.name.dm', defaultMessage: 'Decimetres' }),
abbreviation: formatMessage({ id: 'containers.unit.abbreviation.dm', defaultMessage: 'dm' }),
},
{
value: 'm',
name: formatMessage({ id: 'containers.unit.name.m', defaultMessage: 'Metres' }),
abbreviation: formatMessage({ id: 'containers.unit.abbreviation.m', defaultMessage: 'm' }),
},
{
value: 'ft',
name: formatMessage({ id: 'containers.unit.name.ft', defaultMessage: 'Feet and Inches' }),
abbreviation: formatMessage({ id: 'containers.unit.abbreviation.ft', defaultMessage: 'ft' }),
},
];

Expand Down
12 changes: 7 additions & 5 deletions frontend/src/v5/store/drawings/drawings.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import { Role } from '../currentUser/currentUser.types';
import { Calibration, CalibrationState } from './drawings.types';
import { selectContainerById } from '../containers/containers.selectors';
import { selectFederationById } from '../federations/federations.selectors';
import { convertVectorUnits, getUnitsConvertionFactor } from '@/v5/ui/routes/dashboard/projects/calibration/calibration.helpers';
import { convertUnits, convertVectorUnits, getUnitsConversionFactor } from '@/v5/ui/routes/dashboard/projects/calibration/calibration.helpers';
import { EMPTY_CALIBRATION } from '@/v5/ui/routes/dashboard/projects/calibration/calibration.constants';
import { Vector1D } from '@/v5/ui/routes/dashboard/projects/calibration/calibration.types';

const selectDrawingsDomain = (state): DrawingsState => state?.drawings || ({ drawingsByProjectByProject: {} });

Expand Down Expand Up @@ -102,13 +103,14 @@ export const selectCalibration = createSelector(
(state, drawingId, modelId) => selectContainerById(state, modelId) || selectFederationById(state, modelId),
(drawing, model) => {
const calibration = drawing?.calibration || EMPTY_CALIBRATION as Partial<Calibration>;
const convertionFactor = getUnitsConvertionFactor(calibration?.units, model.unit);
const conversionFactor = getUnitsConversionFactor(calibration?.units, model.unit);
const horizontalCalibration = calibration.horizontal || EMPTY_CALIBRATION.horizontal;
return {
horizontal: {
model: convertVectorUnits(horizontalCalibration.model, convertionFactor),
drawing: convertVectorUnits(horizontalCalibration.drawing, convertionFactor),
model: convertVectorUnits(horizontalCalibration.model, conversionFactor),
drawing: convertVectorUnits(horizontalCalibration.drawing, conversionFactor),
},
verticalRange: convertUnits(calibration.verticalRange || EMPTY_CALIBRATION.verticalRange, conversionFactor) as Vector1D,
};
},
);
Expand All @@ -121,4 +123,4 @@ export const selectHasCommenterAccess = createSelector(
export const selectHasViewerAccess = createSelector(
selectDrawingRole,
(role): boolean => isViewerRole(role),
);
);
2 changes: 1 addition & 1 deletion frontend/src/v5/store/drawings/drawings.temp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const drawingIds = [
'97933311-draw-4178-a241-1fe8219fffb6',
];

export const drawingFilesName = ['map.svg', 'fly.svg', 'blueprint.svg', 'carpark.svg', 'blueprint2.svg', 'blueprint.png', 'blueprint2.png', 'blueprint3.png', 'blueprint4.png'];
export const drawingFilesName = ['map.svg', 'fly.svg', 'blueprint.svg', 'carpark.svg', 'blueprint2.svg', 'blueprint.png', 'blueprint2.png', 'blueprint3.png', 'blueprint4.png', 'rac_level_1.png', 'rac_level_2.png', 'rac_site.png', 'rac_level_1.svg', 'rac_level_2.svg', 'rac_site.svg'];
export const mapDrawingIdToName = (id) => {
const index = drawingIds.findIndex((d) => d === id);
if (index !== -1) {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/v5/store/drawings/drawings.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { Coord2D, Vector2D, Vector3D } from '../../ui/routes/dashboard/projects/calibration/calibration.types';
import { Vector1D, Vector2D, Vector3D } from '../../ui/routes/dashboard/projects/calibration/calibration.types';
import { Role } from '../currentUser/currentUser.types';

export enum CalibrationState {
Expand Down Expand Up @@ -46,7 +46,7 @@ export interface MinimumDrawing {

export interface Calibration {
state: CalibrationState;
verticalRange: Coord2D;
verticalRange: Vector1D;
horizontal: {
model: Vector3D,
drawing: Vector2D,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,12 @@ export const Viewer2D = () => {
}
{showSVGImage && <SVGImage ref={imgRef} src={src} onLoad={onImageLoad} />}
{!showSVGImage && <DrawingViewerImage ref={imgRef} src={src} onLoad={onImageLoad} />}
<ViewerLayer2D
{ !isLoading && (<ViewerLayer2D
active={isCalibrating2D}
viewBox={viewBox}
value={vector2D}
onChange={setVector2D}
/>
/>)}
</ImageContainer>
<ToolbarContainer>
<MainToolbar>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { PanZoomHandler } from '../panzoom/centredPanZoom';
import { isEqual } from 'lodash';
import { SvgArrow } from './svgArrow/svgArrow.component';
import { SvgCircle } from './svgCircle/svgCircle.component';
import { useSearchParam } from '@/v5/ui/routes/useSearchParam';
import { Coord2D, Vector2D } from '@/v5/ui/routes/dashboard/projects/calibration/calibration.types';
import { CalibrationContext } from '@/v5/ui/routes/dashboard/projects/calibration/calibrationContext';
import { EMPTY_VECTOR } from '@/v5/ui/routes/dashboard/projects/calibration/calibration.constants';
Expand All @@ -39,7 +38,6 @@ export const ViewerLayer2D = ({ viewBox, active, value, onChange }: ViewerLayer2
const [offsetEnd, setOffsetEnd] = useState<Coord2D>(value?.[1] || null);
const previousViewBox = useRef<ViewBoxType>(null);
const [mousePosition, setMousePosition] = useState<Coord2D>(null);
const [drawingId] = useSearchParam('drawingId');

const containerStyle: CSSProperties = {
transformOrigin: '0 0',
Expand Down Expand Up @@ -87,8 +85,6 @@ export const ViewerLayer2D = ({ viewBox, active, value, onChange }: ViewerLayer2
}
}, [active]);

useEffect(() => { resetArrow(); }, [drawingId]);

return (
<Container style={containerStyle} id="viewerLayer2d">
{isCalibrating && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ export const EMPTY_CALIBRATION = {
model: EMPTY_VECTOR,
drawing: EMPTY_VECTOR,
},
verticalRange: null,
verticalRange: EMPTY_VECTOR,
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,50 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

const UNITS_CONVERTION_FACTORS_TO_METRES = {
import { Matrix3, Vector2 } from 'three';
import { Coord2D, Vector2D, Vector3D } from './calibration.types';
import { isNumber } from 'lodash';

export const UNITS_CONVERSION_FACTORS_TO_METRES = {
'm': 1,
'dm': 10,
'cm': 100,
'mm': 1000,
'ft': 3.28084,
} as const;

export const getUnitsConvertionFactor = (drawingUnits, modelUnits) => {
export const getUnitsConversionFactor = (drawingUnits, modelUnits) => {
if (!drawingUnits) return 1;
return UNITS_CONVERTION_FACTORS_TO_METRES[drawingUnits] / UNITS_CONVERTION_FACTORS_TO_METRES[modelUnits];
return UNITS_CONVERSION_FACTORS_TO_METRES[drawingUnits] / UNITS_CONVERSION_FACTORS_TO_METRES[modelUnits];
};

export const convertCoordUnits = (coord, convertionFactor: number) => coord?.map((point) => point * convertionFactor) || null;
export const convertVectorUnits = (vector, convertionFactor: number) => vector.map((coord) => convertCoordUnits(coord, convertionFactor));
export const convertUnits = (coords: number[], conversionFactor: number) => coords?.map((coord) => isNumber(coord) ? coord * conversionFactor : null) || null;
export const convertVectorUnits = (vector, conversionFactor: number) => vector.map((coord) => convertUnits(coord, conversionFactor));

const removeZ = (vector) => [vector[0], vector[2]] as Coord2D;

export const getTransformationMatrix = (vector2D: Vector2D, vector3D: Vector3D) => {
const drawVecStart = new Vector2(...vector2D[0]);
const drawVecEnd = new Vector2(...vector2D[1]);
const modelVecStart = new Vector2(...removeZ(vector3D[0]));
const modelVecEnd = new Vector2(...removeZ(vector3D[1]));
const diff2D = new Vector2().subVectors(drawVecEnd, drawVecStart);
const diff3D = new Vector2().subVectors(modelVecEnd, modelVecStart);

const magnitudeA = diff2D.length();
const magnitudeB = diff3D.length();
const scaleFactor = magnitudeB / magnitudeA;

// in order to know if angle is clockwise or anti-clockwise we find the cross product of both vectors and take the sign of the z-component
const crossProductZ = diff2D.cross(diff3D);
const directionFactor = crossProductZ > 0 ? 1 : -1;
const angle = diff3D.angleTo(diff2D);

const scaleMatrix = new Matrix3().makeScale(scaleFactor, scaleFactor);
const rotationMatrix = new Matrix3().makeRotation(directionFactor * angle);
drawVecStart.applyMatrix3(scaleMatrix.clone().multiply(rotationMatrix));

const translationMatrix = new Matrix3().makeTranslation(new Vector2().subVectors(modelVecStart, drawVecStart));
const transformationMatrix = translationMatrix.multiply(scaleMatrix).multiply(rotationMatrix);
return transformationMatrix;
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,11 @@ type Coord3D = [number, number, number];

export type Vector<CoordType> = [CoordType | null, CoordType | null];

export type Vector1D = Vector<number>;
export type Vector2D = Vector<Coord2D>;
export type Vector3D = Vector<Coord3D>;

export enum PlaneType {
UPPER = 'upper',
LOWER = 'lower',
}
Loading

0 comments on commit e1fc566

Please sign in to comment.