Skip to content

Commit

Permalink
Merge pull request #19 from SebLeich/features/fixVisualization
Browse files Browse the repository at this point in the history
Fix visualization
  • Loading branch information
SebLeich authored May 12, 2024
2 parents 1331cba + 8e17326 commit 1819c2c
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 167 deletions.
43 changes: 23 additions & 20 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
version: "2.4"
version: "3.5"
services:

nginx:
build: ./projects/rpx
container_name: reverseproxy
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
ports:
- "80:80"
- "81:81"
- "443:443"
networks:
- docker-service
depends_on:
- frontend
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot

certbot:
image: certbot/certbot
container_name: certbot
Expand All @@ -30,19 +14,38 @@ services:
container_name: storage-manager
hostname: storage-manager
labels:
- "com.centurylinklabs.watchtower.enable=true"
com.centurylinklabs.watchtower.enable: true
networks:
- docker-service
healthcheck:
test: "exit 0"

watchtower:
image: containrrr/watchtower
container_name: watchtower
container_name: storage-manager-watchtower
environment:
WATCHTOWER_POLL_INTERVAL: 30
WATCHTOWER_LABEL_ENABLE: true
volumes:
- /var/run/docker.sock:/var/run/docker.sock

nginx:
image: nginx:latest
container_name: reverseproxy
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
ports:
- "80:80"
- "443:443"
restart: always
networks:
- docker-service
depends_on:
frontend:
condition: service_healthy
volumes:
- ./rpx/nginx.conf:/etc/nginx/nginx.conf
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot

networks:
docker-service:
driver: bridge
Expand Down
3 changes: 0 additions & 3 deletions projects/rpx/Dockerfile

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,53 +1,53 @@
import { TestBed } from '@angular/core/testing';
import defaultImportsConstant from '../../../app/default-imports.constant';
import { VisualizationService } from './visualization.service';
import { ArrowHelper, GridHelper } from 'three';
import { IPosition, IPositionedElement, ISpace } from '@/lib/storage-manager/interfaces';
import { IPositionedElement, ISpace } from '@/lib/storage-manager/interfaces';
import { infinityReplacement } from '@/app/globals';
import { SpectatorService, createServiceFactory } from '@ngneat/spectator';

describe('SolutionVisualizationService', () => {
const containerLength = 500;
const containerWidth = 1000;
let service: VisualizationService;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [VisualizationService],
imports: [
...defaultImportsConstant
]
const containerLength = 500;
const containerWidth = 1000;

let spectator: SpectatorService<VisualizationService>;

const createService = createServiceFactory({
imports: [
...defaultImportsConstant
],
service: VisualizationService,
});

beforeEach(() => spectator = createService());

it('should be created', () => {
expect(spectator.service).toBeTruthy();
});

it('should create correct grid helper', () => {
const gridHelper = VisualizationService.getContainerBaseGrid(containerWidth, containerLength);

expect(gridHelper instanceof GridHelper).toBeTruthy();
expect(gridHelper.position.x).toBe(0);
expect(gridHelper.position.y).toBe(containerWidth / -2);
expect(gridHelper.position.z).toBe(0);
});

it('should create unloading arrow', () => {
const unloadingArrow = VisualizationService.getContainerUnloadingArrow(containerLength);

expect(unloadingArrow instanceof ArrowHelper).toBeTruthy();
});
service = TestBed.inject(VisualizationService);
});

it('should be created', () => {
expect(service).toBeTruthy();
});

it('should create correct grid helper', () => {
const gridHelper = VisualizationService.getContainerBaseGrid(containerWidth, containerLength);

expect(gridHelper instanceof GridHelper).toBeTruthy();
expect(gridHelper.position.x).toBe(0);
expect(gridHelper.position.y).toBe(containerWidth / -2);
expect(gridHelper.position.z).toBe(0);
});

it('should create unloading arrow', () => {
const unloadingArrow = VisualizationService.getContainerUnloadingArrow(containerWidth, containerLength);

expect(unloadingArrow instanceof ArrowHelper).toBeTruthy();
});

const testSet = [
{ position: { height: 100, length: 100, width: 100, xCoord: 1, yCoord: 0, zCoord: 1 } as IPositionedElement & ISpace, parent: undefined as undefined | (IPositionedElement & ISpace), expected: { xCoord: 1, yCoord: 0, zCoord: 1 } as IPositionedElement },
{ position: { height: 100, length: 200, width: 100, xCoord: 1, yCoord: 0, zCoord: 1 } as IPositionedElement & ISpace, parent: { height: 1000, length: 1000, width: 1000, xCoord: 0, yCoord: 0, zCoord: 0 } as undefined | (IPositionedElement & ISpace), expected: { xCoord: -449, yCoord: -450, zCoord: -399 } as IPositionedElement },
{ position: { height: 100, length: Infinity, width: 100, xCoord: 1, yCoord: 0, zCoord: 1 } as IPositionedElement & ISpace, parent: { height: 1000, length: 1000, width: 1000, xCoord: 0, yCoord: 0, zCoord: 0 } as undefined | (IPositionedElement & ISpace), expected: { xCoord: -449, yCoord: -500 + (infinityReplacement/2), zCoord: -449 } as IPositionedElement }
];
testSet.forEach(({ position, parent, expected }) => {
it(`expect relative position for pos(x: ${position.xCoord}, y: ${position.yCoord}, z: ${position.zCoord} | h: ${position.height}, w: ${position.width}, l: ${position.length}) and par(x: ${parent?.xCoord}, y: ${parent?.yCoord}, z: ${parent?.zCoord} | h: ${parent?.height}, w: ${parent?.width}, l: ${parent?.length}) to be rpos(x: ${expected.xCoord}, y: ${expected.yCoord}, z: ${expected.zCoord})`, () => {
const relativePosition = VisualizationService.calculateRelativePosition(position, parent);
expect(relativePosition).toEqual(expected);

const testSet = [
{ position: { height: 100, length: 100, width: 100, xCoord: 1, yCoord: 0, zCoord: 1 } as IPositionedElement & ISpace, parent: undefined as undefined | (IPositionedElement & ISpace), expected: { xCoord: 1, yCoord: 0, zCoord: 1 } as IPositionedElement },
{ position: { height: 100, length: 200, width: 100, xCoord: 1, yCoord: 0, zCoord: 1 } as IPositionedElement & ISpace, parent: { height: 1000, length: 1000, width: 1000, xCoord: 0, yCoord: 0, zCoord: 0 } as undefined | (IPositionedElement & ISpace), expected: { xCoord: -449, yCoord: -450, zCoord: -399 } as IPositionedElement },
{ position: { height: 100, length: Infinity, width: 100, xCoord: 1, yCoord: 0, zCoord: 1 } as IPositionedElement & ISpace, parent: { height: 1000, length: 1000, width: 1000, xCoord: 0, yCoord: 0, zCoord: 0 } as undefined | (IPositionedElement & ISpace), expected: { xCoord: -449, yCoord: -500 + (infinityReplacement / 2), zCoord: -449 } as IPositionedElement }
];
testSet.forEach(({ position, parent, expected }) => {
it(`expect relative position for pos(x: ${position.xCoord}, y: ${position.yCoord}, z: ${position.zCoord} | h: ${position.height}, w: ${position.width}, l: ${position.length}) and par(x: ${parent?.xCoord}, y: ${parent?.yCoord}, z: ${parent?.zCoord} | h: ${parent?.height}, w: ${parent?.width}, l: ${parent?.length}) to be rpos(x: ${expected.xCoord}, y: ${expected.yCoord}, z: ${expected.zCoord})`, () => {
const relativePosition = VisualizationService.calculateRelativePosition(position, parent);
expect(relativePosition).toEqual(expected);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,88 +10,92 @@ import { ArrowHelper, BoxGeometry, Color, EdgesGeometry, GridHelper, LineBasicMa
@Injectable()
export class VisualizationService {

constructor(private _store: Store) { }
static _helperArrowLength = 500;

public static calculateRelativePosition(position: IPositionedElement & ISpace, parent?: IPositionedElement & ISpace): IPositionedElement {
return {
xCoord: parent ? position.xCoord - (parent.width / 2) + (position.width / 2) : position.xCoord,
yCoord: parent ? position.yCoord - (parent.height / 2) + (position.height / 2) : position.yCoord,
zCoord: parent ? position.zCoord - (parent.length / 2) + ((position.length === Infinity ? infinityReplacement : position.length) / 2) : position.zCoord
constructor(private _store: Store) { }

public static calculateRelativePosition(position: IPositionedElement & ISpace, parent?: IPositionedElement & ISpace): IPositionedElement {
return {
xCoord: parent ? position.xCoord - (parent.width / 2) + (position.width / 2) : position.xCoord,
yCoord: parent ? position.yCoord - (parent.height / 2) + (position.height / 2) : position.yCoord,
zCoord: parent ? position.zCoord - (parent.length / 2) + ((position.length === Infinity ? infinityReplacement : position.length) / 2) : position.zCoord
}
}

public async configureSolutionScene(solution: ISolution, scene: Scene = new Scene(), fillColor: boolean | string = false, addBaseGrid = true, addUnloadingArrow = true) {
scene.clear();
const goodMeshes: { goodId: string, mesh: Mesh }[] = [];
if (solution?.container) {
if (fillColor) {
scene.background = new Color(typeof fillColor === 'string' ? fillColor : 'rgb(255,255,255)');
}
const containerPosition = getContainerPositionSharedMethods(solution.container);
const containerResult = VisualizationService.generateOutlinedBoxMesh(containerPosition, 'container');
scene.add(containerResult.edges);
const groups = await selectSnapshot(this._store.select(selectGroups));
for (const good of solution.container.goods) {
const group = groups.find((group) => group.id === good.group);
const goodResult = VisualizationService.generateFilledBoxMesh(getContainerPositionSharedMethods(good), group?.color ?? '#ffffff', 'good', containerPosition);
goodResult.mesh.userData['goodId'] = good.id;
goodResult.mesh.userData['groupId'] = good.group;
goodMeshes.push({ goodId: good.id, mesh: goodResult.mesh });
scene.add(goodResult.edges, goodResult.mesh);
}

if (addBaseGrid) {
scene.add(VisualizationService.getContainerBaseGrid(solution.container.height, solution.container.length));
}

if (addUnloadingArrow) {
scene.add(VisualizationService.getContainerUnloadingArrow(solution.container.length));
}

}

return { scene, goodMeshes };
}

public static getContainerUnloadingArrow(containerLength: number, arrowColor = "#e33268") {
const from = new Vector3(0, 0, (containerLength / 2)),
to = new Vector3(0, 0, (containerLength / 2) + this._helperArrowLength);

const direction = to.clone().sub(from);
const length = direction.length();
const arrowHelper = new ArrowHelper(direction.normalize(), from, length, arrowColor, (.2 * length), ((.2 * length) * .5));

return arrowHelper;
}
}

public async configureSolutionScene(solution: ISolution, scene: Scene = new Scene(), fillColor: boolean | string = false, addBaseGrid = true, addUnloadingArrow = true) {
scene.clear();
const goodMeshes: { goodId: string, mesh: Mesh }[] = [];
if (solution?.container) {
if (fillColor) {
scene.background = new Color(typeof fillColor === 'string' ? fillColor : 'rgb(255,255,255)');
}
const containerPosition = getContainerPositionSharedMethods(solution.container);
const containerResult = VisualizationService.generateOutlinedBoxMesh(containerPosition, 'container');
scene.add(containerResult.edges);
const groups = await selectSnapshot(this._store.select(selectGroups));
for (const good of solution.container.goods) {
const group = groups.find((group) => group.id === good.group);
const goodResult = VisualizationService.generateFilledBoxMesh(getContainerPositionSharedMethods(good), group?.color ?? '#ffffff', 'good', containerPosition);
goodResult.mesh.userData['goodId'] = good.id;
goodResult.mesh.userData['groupId'] = good.group;
goodMeshes.push({ goodId: good.id, mesh: goodResult.mesh });
scene.add(goodResult.edges, goodResult.mesh);
}

if (addBaseGrid) {
scene.add(VisualizationService.getContainerBaseGrid(solution.container.width, solution.container.length));
}

if (addUnloadingArrow) {
scene.add(VisualizationService.getContainerUnloadingArrow(solution.container.width, solution.container.length));
}

public static getContainerBaseGrid(containerHeight: number, containerLength: number): GridHelper {
const gridHelper = new GridHelper(1.5 * containerLength, 15);
gridHelper.position.set(0, (containerHeight / -2), 0);

return gridHelper;
}

return { scene, goodMeshes };
}

public static getContainerUnloadingArrow(containerWidth: number, containerLength: number, arrowColor = "#e33268") {
const from = new Vector3(0, (containerWidth / -2), (containerLength / 2));
const to = new Vector3(0, (containerWidth / -2), (containerLength / 2) + 1000);
const direction = to.clone().sub(from);
const length = direction.length();
const arrowHelper = new ArrowHelper(direction.normalize(), from, length, arrowColor, (.2 * length), ((.2 * length) * .5));

return arrowHelper;
}

public static getContainerBaseGrid(containerWidth: number, containerLength: number): GridHelper {
const gridHelper = new GridHelper(1.5 * containerLength, 15);
gridHelper.position.set(0, (containerWidth / -2), 0);
return gridHelper;
}

public static generateFilledBoxMesh(position: IPosition, surfaceColor: string, type: string, relativeToParent?: IPosition, borderColor: string = defaultGoodEdgeColor, borderWidth = 1) {
const geometry = new BoxGeometry(position.width, position.height, position.length === Infinity ? infinityReplacement : position.length, 4, 4, 4);
const material = new MeshBasicMaterial({ color: surfaceColor });
const mesh = new Mesh(geometry, material);
const relativePosition = this.calculateRelativePosition(position, relativeToParent);
mesh.position.set(relativePosition.xCoord, relativePosition.yCoord, relativePosition.zCoord);
mesh.userData = { type: type };

const edges = new LineSegments(new EdgesGeometry(mesh.geometry), new LineBasicMaterial({ color: borderColor, linewidth: borderWidth }));
edges.position.set(relativePosition.xCoord, relativePosition.yCoord, relativePosition.zCoord);
edges.userData = { type: type, positionId: position.id };

return { mesh, edges };
}

public static generateOutlinedBoxMesh(position: IPosition, type: string, relativeToParent?: IPosition, borderColor: string = defaultGoodEdgeColor, borderWidth = 1) {
const geometry = new BoxGeometry(position.width, position.height, position.length === Infinity ? infinityReplacement : position.length);
const edges = new LineSegments(new EdgesGeometry(geometry), new LineBasicMaterial({ color: borderColor, linewidth: borderWidth }));
const relativePosition = this.calculateRelativePosition(position, relativeToParent);
edges.position.set(relativePosition.xCoord, relativePosition.yCoord, relativePosition.zCoord);
edges.userData = { type: type, positionId: position.id };

return { edges };
}
public static generateFilledBoxMesh(position: IPosition, surfaceColor: string, type: string, relativeToParent?: IPosition, borderColor: string = defaultGoodEdgeColor, borderWidth = 1) {
const geometry = new BoxGeometry(position.width, position.height, position.length === Infinity ? infinityReplacement : position.length, 4, 4, 4);
const material = new MeshBasicMaterial({ color: surfaceColor });
const mesh = new Mesh(geometry, material);
const relativePosition = this.calculateRelativePosition(position, relativeToParent);
mesh.position.set(relativePosition.xCoord, relativePosition.yCoord, relativePosition.zCoord);
mesh.userData = { type: type };

const edges = new LineSegments(new EdgesGeometry(mesh.geometry), new LineBasicMaterial({ color: borderColor, linewidth: borderWidth }));
edges.position.set(relativePosition.xCoord, relativePosition.yCoord, relativePosition.zCoord);
edges.userData = { type: type, positionId: position.id };

return { mesh, edges };
}

public static generateOutlinedBoxMesh(position: IPosition, type: string, relativeToParent?: IPosition, borderColor: string = defaultGoodEdgeColor, borderWidth = 1) {
const geometry = new BoxGeometry(position.width, position.height, position.length === Infinity ? infinityReplacement : position.length);
const edges = new LineSegments(new EdgesGeometry(geometry), new LineBasicMaterial({ color: borderColor, linewidth: borderWidth }));
const relativePosition = this.calculateRelativePosition(position, relativeToParent);
edges.position.set(relativePosition.xCoord, relativePosition.yCoord, relativePosition.zCoord);
edges.userData = { type: type, positionId: position.id };

return { edges };
}

}
22 changes: 0 additions & 22 deletions projects/rpx/nginx.conf → rpx/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,6 @@ http {
}
}

server {
listen 81;
listen [::]:81;

location / {
proxy_pass http://storage-manager:4000;
proxy_redirect off;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $server_name;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
}

server {
listen 443 ssl;
server_name _;
Expand Down

0 comments on commit 1819c2c

Please sign in to comment.