версия перед отпуском

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ваше Имя
2026-07-24 15:38:14 +03:00
co-authored by Cursor
parent a6e8ba31bd
commit 215b2108be
5 changed files with 477 additions and 56 deletions
+8
View File
@@ -301,6 +301,10 @@ export const api = {
nearlyHiddenPct = 20,
partialPct = 40,
visiblePct = 40,
mleMode = false,
auvDepthMin = 2,
auvDepthMax = 8,
reliefScalePct = 100,
modelPreset = null,
modelFile = null,
onProgress,
@@ -323,6 +327,10 @@ export const api = {
formData.append("nearlyHiddenPct", String(nearlyHiddenPct ?? 20));
formData.append("partialPct", String(partialPct ?? 40));
formData.append("visiblePct", String(visiblePct ?? 40));
formData.append("mleMode", mleMode ? "true" : "false");
formData.append("auvDepthMin", String(auvDepthMin ?? 2));
formData.append("auvDepthMax", String(auvDepthMax ?? 8));
formData.append("reliefScalePct", String(reliefScalePct ?? 100));
if (preset) {
formData.append("modelPreset", preset);
} else {
+22 -2
View File
@@ -19,6 +19,10 @@ const PERSIST_KEYS = [
"nearlyHiddenPct",
"partialPct",
"visiblePct",
"mleMode",
"auvDepthMin",
"auvDepthMax",
"reliefScalePct",
];
function loadPersistedDataset() {
@@ -52,6 +56,10 @@ export const useDatasetStore = defineStore("dataset", {
objectScaleIsMax: !!saved.objectScaleIsMax,
beamCount: saved.beamCount ?? 45,
lengthCount: saved.lengthCount ?? 45,
mleMode: !!saved.mleMode,
auvDepthMin: saved.auvDepthMin ?? 2,
auvDepthMax: saved.auvDepthMax ?? 8,
reliefScalePct: saved.reliefScalePct ?? 100,
absentPct: saved.absentPct ?? 30,
nearlyHiddenPct: saved.nearlyHiddenPct ?? 20,
partialPct: saved.partialPct ?? 40,
@@ -283,7 +291,11 @@ export const useDatasetStore = defineStore("dataset", {
this.statusText = "Генерация датасета…";
const modelLabel = this.selectedModelLabel || this.modelFileName || this.modelPreset;
this.pushLog(
`Старт: count=${this.count}, seed=${this.seed}, beams=${this.beamCount}, length=${this.lengthCount}, scale=${this.objectScale}${this.objectScaleIsMax ? " (макс.)" : ""}, без объекта=${this.absentPct}%, видимость=${this.nearlyHiddenPct}/${this.partialPct}/${this.visiblePct}%, dir=${this.outputDir}, model=${modelLabel}`,
`Старт: count=${this.count}, seed=${this.seed}, beams=${this.beamCount}, length=${this.lengthCount}, неровности=${this.reliefScalePct}%${
this.mleMode
? `, МЛЭ высоты=${this.auvDepthMin}${this.auvDepthMax} м`
: ""
}, scale=${this.objectScale}${this.objectScaleIsMax ? " (макс.)" : ""}, без объекта=${this.absentPct}%, видимость=${this.nearlyHiddenPct}/${this.partialPct}/${this.visiblePct}%, dir=${this.outputDir}, model=${modelLabel}`,
);
try {
const result = await api.datasetGenerate({
@@ -298,6 +310,10 @@ export const useDatasetStore = defineStore("dataset", {
nearlyHiddenPct: Number(this.nearlyHiddenPct) || 0,
partialPct: Number(this.partialPct) || 0,
visiblePct: Number(this.visiblePct) || 0,
mleMode: !!this.mleMode,
auvDepthMin: Number(this.auvDepthMin) || 2,
auvDepthMax: Number(this.auvDepthMax) || 8,
reliefScalePct: Number(this.reliefScalePct) || 100,
modelPreset: this.modelSource === "preset" ? this.modelPreset : null,
modelFile: this.modelSource === "file" ? this.modelFile : null,
onProgress: (event) => {
@@ -321,8 +337,12 @@ export const useDatasetStore = defineStore("dataset", {
entry.objectScale != null
? `, scale=${Number(entry.objectScale).toFixed(3)}`
: "";
const depthPart =
entry.auvDepth != null
? `, h=${Number(entry.auvDepth).toFixed(2)} м`
: "";
this.pushLog(
`${entry.stem}: pts=${entry.pointCount}, object=${entry.objectPointCount}, ${entry.visibility}${scalePart}`,
`${entry.stem}: pts=${entry.pointCount}, object=${entry.objectPointCount}, ${entry.visibility}${scalePart}${depthPart}`,
);
}
}
+82 -2
View File
@@ -79,6 +79,10 @@ watch(
store.objectScaleIsMax,
store.beamCount,
store.lengthCount,
store.mleMode,
store.auvDepthMin,
store.auvDepthMax,
store.reliefScalePct,
store.absentPct,
store.nearlyHiddenPct,
store.partialPct,
@@ -276,7 +280,12 @@ function runOptionLabel(run) {
:disabled="store.busy"
/>
<span class="ref-caption">
Поперечные лучи эхолота (X): N лучей = N возвратов по ширине галса.
<template v-if="store.mleMode">
Число лучей веера МЛЭ в одном пинге (поперек курса).
</template>
<template v-else>
Поперечные лучи эхолота (X): N лучей = N возвратов по ширине галса.
</template>
</span>
</label>
@@ -291,7 +300,72 @@ function runOptionLabel(run) {
:disabled="store.busy"
/>
<span class="ref-caption">
Пинги вдоль курса (Y): L возвратов по длине. Итого точек сцены: N×L (первый отклик луча).
<template v-if="store.mleMode">
Число пингов вдоль курса. Итого точек сцены: лучи × пинги.
</template>
<template v-else>
Пинги вдоль курса (Y): L возвратов по длине. Итого точек сцены: N×L (первый отклик луча).
</template>
</span>
</label>
<label class="field check-block">
<span class="field-label-row">
<label class="check-inline">
<input
v-model="store.mleMode"
type="checkbox"
:disabled="store.busy"
/>
Съёмка как многолучевой эхолот
</label>
</span>
<span class="ref-caption">
Рельеф и объекты как первый отклик веера МЛЭ (наклонными лучами), а не ортогональной сеткой.
</span>
</label>
<div v-if="store.mleMode" class="grid-2">
<label class="field">
<span>Диапазон высот, м (от)</span>
<input
v-model.number="store.auvDepthMin"
type="number"
min="0.3"
max="200"
step="0.1"
:disabled="store.busy"
/>
</label>
<label class="field">
<span>Диапазон высот, м (до)</span>
<input
v-model.number="store.auvDepthMax"
type="number"
min="0.3"
max="200"
step="0.1"
:disabled="store.busy"
/>
</label>
<span class="ref-caption" style="grid-column: 1 / -1">
Для каждой сцены высота АНПА над ровным дном выбирается случайно из этого диапазона.
</span>
</div>
<label class="field">
<span>Размер неровностей, %</span>
<input
v-model.number="store.reliefScalePct"
type="number"
min="5"
max="500"
step="5"
:disabled="store.busy"
/>
<span class="ref-caption">
Масштаб случайного рельефа дна относительно размера сцены.
100% заметные холмы/впадины; 200% примерно вдвое крупнее.
</span>
</label>
@@ -638,6 +712,12 @@ function runOptionLabel(run) {
gap: 4px;
font-size: 13px;
}
.grid-2 {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px 12px;
align-items: start;
}
.field-label-row {
display: flex;
align-items: center;