This commit is contained in:
IDONTSUDO 2024-07-23 15:57:22 +03:00
parent 318d0a7893
commit 9120729d41
20 changed files with 119 additions and 79 deletions

View file

@ -1,6 +1,6 @@
import * as fs from "fs";
import { promisify } from "node:util";
import { rimraf } from 'rimraf'
import { rimraf } from "rimraf";
export class FileSystemRepository {
public createDir = promisify(fs.mkdir);
@ -8,6 +8,7 @@ export class FileSystemRepository {
public writeFileAsync = promisify(fs.writeFile);
public dirIsExists = promisify(fs.exists);
public stat = promisify(fs.stat);
public deleteDir = promisify(fs.unlink);
public readFileAsync = promisify(fs.readFile);
public readdir = promisify(fs.readdir);
public deleteDirRecursive = rimraf;
@ -21,7 +22,9 @@ export class FileSystemRepository {
}
return await this.readFileAsync(path);
}
deleteFile = async (path: string) => {
return await this.deleteDir(path);
};
readDirRecursive(path: string, filesToDir: string[] = []): string[] {
const files = fs.readdirSync(path);
files.forEach((file) => {
@ -41,5 +44,4 @@ export class FileSystemRepository {
});
return filesToDir;
}
}

View file

@ -0,0 +1,14 @@
import { Result } from "../helpers/result";
import { FileSystemRepository } from "../repository/file_system_repository";
export class DeleteFileUseCase {
fileSystemRepository = new FileSystemRepository();
call = (path: string) => {
try {
this.fileSystemRepository.deleteFile(path);
return Result.ok("file delete");
} catch {
return Result.error("Unknown error");
}
};
}

View file

@ -0,0 +1,16 @@
import { CallbackStrategyWithIdQuery, ResponseBase } from "../../core/controllers/http_controller";
import { Result } from "../../core/helpers/result";
import { DeleteDataBaseModelUseCase } from "../../core/usecases/delete_database_model_usecase";
import { ReadByIdDataBaseModelUseCase } from "../../core/usecases/read_by_id_database_model_usecase";
import { CoreValidation } from "../../core/validations/core_validation";
import { MongoIdValidation } from "../../core/validations/mongo_id_validation";
import { SceneModel } from "./create_new_scene_scenario";
export class DeleteSceneScenario extends CallbackStrategyWithIdQuery {
idValidationExpression: CoreValidation = new MongoIdValidation();
call = async (id: string): ResponseBase =>
(await new ReadByIdDataBaseModelUseCase<SceneModel>(SceneModel).call(id)).map((sceneModel) => Result.ok()
// (await new DeleteDataBaseModelUseCase(SceneModel).call(id)).map(() => DeleteF )
);
}

View file

@ -11,8 +11,8 @@ export class CameraModel implements Instance {
type = SceneModelsTypes.CAMERA;
jointType = 'fixed';
constructor(
public quaternion: number[],
public vector3: Vector3,
public orientation: number[],
public position: Vector3,
public name: string,
public cameraType: CameraTypes,
public width: number,
@ -37,8 +37,8 @@ export class CameraModel implements Instance {
}
const perspectiveCamera = new PerspectiveCamera(this.fov, this.aspect, this.near, this.far);
perspectiveCamera.name = this.name;
perspectiveCamera.position.copy(this.vector3);
perspectiveCamera.quaternion.copy(new Quaternion().fromArray(this.quaternion));
perspectiveCamera.position.copy(this.position);
perspectiveCamera.quaternion.copy(new Quaternion().fromArray(this.orientation));
const cameraHelper = new CameraHelper(perspectiveCamera);
cameraHelper.name = this.name + "camera_helper";
perspectiveCamera.userData[UserData.selectedObject] = true;

View file

@ -21,8 +21,8 @@ export class LightModel implements Instance {
penumbra: number;
decay: number;
@Type(() => Vector3)
vector3: Vector3;
quaternion: number[];
position: Vector3;
orientation: number[];
constructor() {}
update = (coreThreeRepository: CoreThreeRepository) => this.toWebGl(coreThreeRepository);
icon: string = "Light";
@ -48,8 +48,8 @@ export class LightModel implements Instance {
);
light!.castShadow = true;
light!.position.copy(this.vector3);
light!.quaternion.copy(new Quaternion().fromArray(this.quaternion));
light!.position.copy(this.position);
light!.quaternion.copy(new Quaternion().fromArray(this.orientation));
coreThreeRepository.scene.add(light!);
};

View file

@ -11,10 +11,10 @@ export class PointModel implements Instance {
type = SceneModelsTypes.POINT;
name: string;
@Type(() => Vector3)
vector3: Vector3;
position: Vector3;
color: string = "#E91E63";
size: number = 0.01;
quaternion: number[];
orientation: number[];
icon: string = "Point";
constructor() {}
@ -22,8 +22,8 @@ export class PointModel implements Instance {
toWebGl = (coreThreeRepository: CoreThreeRepository) =>
coreThreeRepository.makePoint(
this.name,
this.vector3,
new Quaternion().fromArray(this.quaternion),
this.position,
new Quaternion().fromArray(this.orientation),
this.color,
this.size
);
@ -38,12 +38,12 @@ export class PointModel implements Instance {
toDependency = (): Pose => {
return {
name: this.name,
position: this.vector3,
position: this.position,
orientation: {
x: this.quaternion[0],
y: this.quaternion[1],
z: this.quaternion[2],
w: this.quaternion[3],
x: this.orientation[0],
y: this.orientation[1],
z: this.orientation[2],
w: this.orientation[3],
},
};
};

View file

@ -23,24 +23,24 @@ interface RobotJoint {
export class RobotModel implements Instance {
type = SceneModelsTypes.ROBOT;
@Type(() => Vector3)
vector3: Vector3;
position: Vector3;
jointPosition: RobotJoint[];
quaternion: number[];
orientation: number[];
name: string;
httpUrl: string;
nDof: number;
toolType: string;
constructor(
vector3: Vector3,
quaternion: number[],
position: Vector3,
orientation: number[],
name: string,
httpUrl: string,
nDof: number,
toolType: string,
jointPosition: RobotJoint[]
) {
this.quaternion = quaternion;
this.vector3 = vector3;
this.orientation = orientation;
this.position = position;
this.name = name;
this.httpUrl = httpUrl;
this.nDof = nDof;
@ -61,8 +61,8 @@ export class RobotModel implements Instance {
};
update = (coreThreeRepository: CoreThreeRepository) => {
const robot = coreThreeRepository.scene.getObjectByName(this.name) as URDFRobot;
robot.position.copy(this.vector3);
robot.quaternion.copy(new Quaternion().fromArray(this.quaternion));
robot.position.copy(this.position);
robot.quaternion.copy(new Quaternion().fromArray(this.orientation));
this.jointPosition.forEach((el) => {
robot.setJointValue(el.name, el.angle);
});

View file

@ -1,4 +1,4 @@
import { IsArray, IsEnum, IsNumber, IsOptional, IsString, ValidateNested } from "class-validator";
import { IsArray } from "class-validator";
import { Type } from "class-transformer";
import { CameraModel } from "./camera_model";
import { SceneModelsTypes } from "./scene_models_type";
@ -15,11 +15,11 @@ export abstract class Instance {
type: string;
abstract icon: string;
@Type(() => Vector3)
vector3: Vector3;
quaternion: number[];
position: Vector3;
orientation: number[];
name: string;
toWebGl = (coreThreeRepository: CoreThreeRepository) => {};
update = (coreThreeRepository: CoreThreeRepository) => {};
toWebGl = (_coreThreeRepository: CoreThreeRepository) => {};
update = (_coreThreeRepository: CoreThreeRepository) => {};
}
export class SceneAsset {

View file

@ -10,17 +10,17 @@ export class SolidModel implements Instance {
icon: string = "Solid";
type = SceneModelsTypes.SOLID;
@Type(() => Vector3)
public vector3: Vector3;
public position: Vector3;
constructor(
vector3: Vector3,
public quaternion: number[],
public orientation: number[],
public name: string,
public solidType: string,
public mesh: string,
public collisionMesh: string,
public spawnType: string
) {
this.vector3 = vector3;
this.position = vector3;
}
toSceneItems = (): SceneItems => {
return {
@ -33,8 +33,8 @@ export class SolidModel implements Instance {
update = (coreThreeRepository: CoreThreeRepository) => {
const object = coreThreeRepository.getObjectsAtName(this.name) as Object3D<Object3DEventMap>;
object.position.copy(this.vector3)
object.quaternion.copy(new Quaternion().fromArray(this.quaternion))
object.position.copy(this.position)
object.quaternion.copy(new Quaternion().fromArray(this.orientation))
};
@ -45,12 +45,12 @@ export class SolidModel implements Instance {
this.mesh,
() => (
coreThreeRepository.raiseAnObjectAboveZeroVector(this.name),
(this.quaternion = coreThreeRepository.scene.getObjectByName(this.name)!.quaternion.toArray()),
(this.vector3 = coreThreeRepository.scene.getObjectByName(this.name)!.position)
(this.orientation = coreThreeRepository.scene.getObjectByName(this.name)!.quaternion.toArray()),
(this.position = coreThreeRepository.scene.getObjectByName(this.name)!.position)
),
this.name,
this.vector3
this.position
),
() => console.log("UNKNOWN SPAWN TYPE SOLID MODEL")
);

View file

@ -9,17 +9,17 @@ export class ZoneModel implements Instance {
type = SceneModelsTypes.ZONE;
color: string = "#E91E63";
@Type(() => Vector3)
vector3: Vector3;
position: Vector3;
constructor(
vector3: Vector3,
public quaternion: number[],
public orientation: number[],
public name: string,
public width: number,
public height: number,
public length: number
) {
this.vector3 = vector3;
this.position = vector3;
}
update = (coreThreeRepository: CoreThreeRepository) => this.toWebGl(coreThreeRepository)
icon: string = "Zone";

View file

@ -140,8 +140,8 @@ export class CoreThreeRepository extends TypedEvent<any> {
);
mesh.name = zoneModel.name;
mesh.userData[UserData.selectedObject] = "";
mesh.position.copy(zoneModel.vector3);
mesh.quaternion.copy(new Quaternion().fromArray(zoneModel.quaternion));
mesh.position.copy(zoneModel.position);
mesh.quaternion.copy(new Quaternion().fromArray(zoneModel.orientation));
this.scene.add(mesh);
};
makeCube(inc: number, vector?: Vector3, color?: string, size?: number) {
@ -188,8 +188,8 @@ export class CoreThreeRepository extends TypedEvent<any> {
this.urdfLoader.load(robotModel.httpUrl, (robot) => {
robot.userData[UserData.selectedObject] = true;
robot.name = robotModel.name;
if (robotModel.vector3) robot.position.copy(robotModel.vector3);
if (robotModel.quaternion) robot.quaternion.copy(new Quaternion().fromArray(robotModel.quaternion));
if (robotModel.position) robot.position.copy(robotModel.position);
if (robotModel.orientation) robot.quaternion.copy(new Quaternion().fromArray(robotModel.orientation));
if (robotModel.jointPosition.isNotEmpty()) {
robotModel.jointPosition.forEach((el) => {
robot.setJointValue(el.name, el.angle);
@ -258,8 +258,8 @@ export class CoreThreeRepository extends TypedEvent<any> {
updateSolidBody = (solidBodyModel: SolidModel) => {
const mesh = this.scene.getObjectByName(solidBodyModel.name);
mesh?.position.copy(solidBodyModel.vector3);
mesh?.quaternion.copy(new Quaternion().fromArray(solidBodyModel.quaternion));
mesh?.position.copy(solidBodyModel.position);
mesh?.quaternion.copy(new Quaternion().fromArray(solidBodyModel.orientation));
};
disposeTransformControlsMode = () => this.transformControls.detach();

View file

@ -7,11 +7,12 @@ export interface IIconsProps extends IStyle {
onClick?: Function;
height?: number;
width?: number;
color?: string;
isNeedStopPropagation?: boolean;
}
export function Icon(props: IIconsProps) {
return getIconSvg(props.type, props.height, props.width).fold(
return getIconSvg(props.type, props.height, props.width, props.color).fold(
(node) => {
return (
<div
@ -47,7 +48,8 @@ export function Icon(props: IIconsProps) {
const getIconSvg = (
type: string,
height: number | undefined,
width: number | undefined
width: number | undefined,
color: string | undefined
): Result<undefined, React.JSX.Element> => {
switch (type) {
case "":
@ -385,7 +387,7 @@ const getIconSvg = (
fillRule="evenodd"
clipRule="evenodd"
d="M10 0C4.47 0 0 4.47 0 10C0 15.53 4.47 20 10 20C15.53 20 20 15.53 20 10C20 4.47 15.53 0 10 0ZM10 18C5.59 18 2 14.41 2 10C2 5.59 5.59 2 10 2C14.41 2 18 5.59 18 10C18 14.41 14.41 18 10 18ZM10 8.59L13.59 5L15 6.41L11.41 10L15 13.59L13.59 15L10 11.41L6.41 15L5 13.59L8.59 10L5 6.41L6.41 5L10 8.59Z"
fill="#49454F"
fill={color ?? "#49454F"}
/>
</svg>
);

View file

@ -2,14 +2,15 @@ import { Type } from "class-transformer";
import { Result } from "../../../core/helper/result";
import { Skills } from "../../../core/model/skill_model";
import { NodeBehaviorTree } from "./node_behavior_tree";
import { IsOptional } from "class-validator";
import { IsOptional, IsString } from "class-validator";
import { BehaviorTreeBuilderHttpRepository } from "../data/behavior_tree_builder_repository";
import { message } from "antd";
export class BehaviorTreeModel {
@IsString()
public sceneId: string;
@IsOptional()
@Type(() => Skills)
public sceneId: string;
public skills?: Skills;
public scene: NodeBehaviorTree[] = [];
public xml: string;

View file

@ -326,7 +326,6 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
);
}
isFilledInput = (type: string, sid: string): boolean => {
console.log(this.filledOutTemplates?.dependencyIsFilled)
return this.filledOutTemplates?.dependencyIsFilled(type, sid) ?? false;
};
getInputs(name: string) {

View file

@ -7,10 +7,7 @@ import { SceneAsset } from "../../../core/model/scene_asset";
export class SceneHttpRepository extends CoreHttpRepository {
editScene = (scene: SceneAsset) => this._jsonRequest(HttpMethod.PUT, "/scenes", scene);
deleteScene = (sceneId:string) => this._jsonRequest(HttpMethod.DELETE, '/scenes', )
newScene = (sceneViewModel: SceneViewModel) =>
this._jsonRequest(HttpMethod.POST, "/scenes", sceneViewModel) as unknown as Promise<Result<CoreError, void>>;
}

View file

@ -29,8 +29,8 @@ export class PointStore extends FormState<PointModel, CoreError> {
clickLister = (event: MouseEvent) =>
this.storeType.isEqualR(PointStoreType.awaitClick).map(() =>
this.sceneMangerStore!.clickScene(event, this.sceneMangerStore!.canvasOffsetX).map((vector3) => {
this.viewModel.vector3 = vector3;
this.viewModel.quaternion = [0, 0, 0, 1];
this.viewModel.position = vector3;
this.viewModel.orientation = [0, 0, 0, 1];
this.viewModel.toWebGl(this.sceneMangerStore.coreThreeRepository!);
this.sceneMangerStore.activeFormType = undefined;
this.sceneMangerStore.sceneItems.push(this.viewModel.toSceneItems(this.sceneMangerStore));

View file

@ -23,7 +23,7 @@ export class RobotFormStore extends FormState<RobotModel, CoreError> {
clickLister = (event: MouseEvent) =>
this.storeType.isEqualR(RobotStoreType.awaitMouseClick).map(() =>
this.sceneMangerStore!.clickScene(event, this.sceneMangerStore!.canvasOffsetX).map((vector3) => {
this.viewModel.vector3 = vector3;
this.viewModel.position = vector3;
this.viewModel.toWebGl(this.sceneMangerStore.coreThreeRepository!);
this.sceneMangerStore.activeFormType = undefined;
this.sceneMangerStore.sceneItems.push(this.viewModel.toSceneItems(this.sceneMangerStore));

View file

@ -63,7 +63,7 @@ export class SolidBodyStore extends FormState<SolidModel, CoreError> {
clickLister = (event: MouseEvent) =>
this.solidBodyStoreType.isEqualR(SolidBodyStoreType.spawn2DVector).map(() =>
this.sceneMangerStore!.clickScene(event, this.sceneMangerStore!.canvasOffsetX).map((vector3) => {
this.viewModel.vector3 = vector3;
this.viewModel.position = vector3;
this.viewModel.spawnType = "BoundBox";
this.viewModel.toWebGl(this.sceneMangerStore.coreThreeRepository!);
this.sceneMangerStore.sceneItems.push(this.viewModel.toSceneItems());

View file

@ -209,14 +209,17 @@ export const SceneManger = observer(() => {
}}
>
<CoreText text={el.name} type={CoreTextType.large} color="white" />
<CoreButton
text="Перейти"
onClick={() => {
navigate(`${SceneManagerPath}${el._id}`);
}}
textStyle={{ color: "black", textAlign: "center" }}
style={{ marginRight: 10, backgroundColor: "white", width: 126 }}
/>
<div style={{ display: "flex", alignItems: "center", marginLeft: 10, marginRight: 10 }}>
<CoreButton
text="Перейти"
onClick={() => {
navigate(`${SceneManagerPath}${el._id}`);
}}
textStyle={{ color: "black", textAlign: "center" }}
style={{ marginRight: 10, backgroundColor: "white", width: 126 }}
/>
<Icon style={{ height: 20 }} type={"DeleteCircle"} color="red" />
</div>
</div>
))}
</div>

View file

@ -44,10 +44,9 @@ export interface SceneItems {
icon: string;
}
export class SceneMangerStore extends UiDrawerFormState<SceneViewModel, HttpError> {
activeFormType?: string;
activeSceneId?: string;
activeSceneId: string = "";
selectedItemName?: string;
activeFormDependency: Object = {};
viewModel: SceneViewModel = SceneViewModel.empty();
@ -183,8 +182,8 @@ export class SceneMangerStore extends UiDrawerFormState<SceneViewModel, HttpErro
};
addNewCamera = (model: CameraModel) => {
model.vector3 = this.coreThreeRepository!.camera.position;
model.quaternion = this.coreThreeRepository!.camera.quaternion.toArray();
model.position = this.coreThreeRepository!.camera.position;
model.orientation = this.coreThreeRepository!.camera.quaternion.toArray();
model.aspect = this.coreThreeRepository!.camera.aspect;
this.sceneItems.push({ name: model.name, icon: "Camera", fn: () => {}, isSelected: false });
this.scene.push(model);
@ -207,6 +206,13 @@ export class SceneMangerStore extends UiDrawerFormState<SceneViewModel, HttpErro
errorHandingStrategy = (error: HttpError) =>
error.status.isEqualR(404).map(() => this.errors.push(new UiBaseError(`not found to project`)));
clickDeleteScene = async () => {
await this.messageHttp(this.sceneHttpRepository.deleteScene(this.activeSceneId), {
successMessage: "сцена удалена",
});
this.mapOk("scenes", this.sceneHttpRepository.getAllScenes());
};
loadScene = (canvasRef: HTMLCanvasElement) => {
this.canvasRef = canvasRef;
this.storeMode.isEqualR(StoreMode.sceneInstance).map(() => this.loadWebGl(canvasRef));
@ -258,8 +264,8 @@ export class SceneMangerStore extends UiDrawerFormState<SceneViewModel, HttpErro
(this.scene = this.scene.map((el) =>
el.name.isEqualR(mesh.name).fold(
() => {
el.vector3 = mesh.position;
el.quaternion = mesh.quaternion.toArray();
el.position = mesh.position;
el.orientation = mesh.quaternion.toArray();
return el;
},
() => el