@@ -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 {
|
||||
|
||||
@@ -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}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user