bx-1480-constructor #68

Merged
ksenia_mikhailova merged 3 commits from bx-1480-constructor into dev 2024-09-23 14:19:31 +03:00
6 changed files with 86 additions and 93 deletions
Showing only changes of commit 1461e178ca - Show all commits

View File

@ -178,10 +178,17 @@ a[href^="#"] {
} }
&_calc { &_calc {
@apply py-0; @apply py-0 relative;
> .container:first-child {
@apply relative h-[50vh] min-h-[600px] justify-between;
> * {
@apply z-10
}
}
&-canvas { &-canvas {
@apply relative h-[50vh] min-h-[600px]; @apply absolute top-0 bottom-0;
} }
} }
@ -301,10 +308,10 @@ button {
} }
&-item { &-item {
@apply flex flex-row gap-4 items-center justify-start xl:justify-center flex-wrap xl:flex-nowrap; @apply flex flex-row items-center justify-start flex-wrap;
label { label {
@apply w-full xl:w-auto; @apply w-full;
} }
.icon { .icon {
@ -316,7 +323,7 @@ button {
} }
&_checkbox { &_checkbox {
@apply w-full xl:w-auto flex-row xl:flex-initial flex-nowrap @apply w-full xl:w-auto flex-row xl:flex-initial flex-nowrap gap-4
} }
input[type=range] { input[type=range] {

View File

@ -2,10 +2,9 @@
import { TresCanvas } from '@tresjs/core' import { TresCanvas } from '@tresjs/core'
import { OrbitControls } from '@tresjs/cientos' import { OrbitControls } from '@tresjs/cientos'
//@ts-ignore //@ts-ignore
import { useGLTF } from '@tresjs/cientos' import { useGLTF, Stats } from '@tresjs/cientos'
import { degToRad, radToDeg } from 'three/src/math/MathUtils.js'; import { degToRad } from 'three/src/math/MathUtils.js';
const fence_section = use_fence_section()
const section_count = use_section_count() const section_count = use_section_count()
const extra_section = use_extra_section() const extra_section = use_extra_section()
const max_size = use_max_size() const max_size = use_max_size()
@ -13,14 +12,15 @@ const max_size = use_max_size()
const controlsState = reactive({ const controlsState = reactive({
distance: section_count.value, distance: section_count.value,
minDistance: 10, minDistance: 10,
maxDistance: 20, maxDistance: 10,
position: { x: 0, y: 0, z: 0 }, position: { x: 0, y: 0, z: 0 },
// enablePan: false, enablePan: false,
minPolarAngle: degToRad(30), enableZoom: false,
maxPolarAngle: degToRad(80), minPolarAngle: degToRad(45),
maxPolarAngle: degToRad(45),
}) })
const cameraStat = reactive({ const cameraStat = reactive({
position: [-4, 2, 8], position: [-5, 7, 5],
aspect: 1920 / 600, aspect: 1920 / 600,
// fov: 40, // fov: 40,
}) })
@ -50,10 +50,11 @@ onMounted(() => {
loadAll() loadAll()
}) })
watch([section_count, extra_section], () => { watch([section_count, extra_section], () => {
let v = (section_count.value + ~~(!!extra_section.value)) * 2 let v = (section_count.value + ~~(!!extra_section.value));
if (v < controlsState.minDistance) v = controlsState.minDistance; if (v <= 10) v = 10
if (v > controlsState.maxDistance) v = controlsState.maxDistance; controlsState.minDistance = v;
// (camera.value as any).position.normalize().multiplyScalar(v) controlsState.maxDistance = v;
(camera.value as any).position.normalize().multiplyScalar(v)
}) })
</script> </script>
<template> <template>
@ -65,6 +66,7 @@ watch([section_count, extra_section], () => {
</div> </div>
</template> </template>
<Loader /> <Loader />
<Stats />
<TresCanvas clear-color="#ccc"> <TresCanvas clear-color="#ccc">
<TresPerspectiveCamera v-bind="cameraStat" ref="camera" /> <TresPerspectiveCamera v-bind="cameraStat" ref="camera" />
<OrbitControls v-bind="controlsState" make-default /> <OrbitControls v-bind="controlsState" make-default />

View File

@ -151,69 +151,62 @@ const goal = (target: string, params: object) => {
</script> </script>
<template> <template>
<div class="container relative py-4"> <div class="container relative py-4">
<form class="form"> <div class="col-span-4">
<div class="col-span-12 sm:col-span-6"> <div class="form-row">
<div class="form-row"> <div class="form-item w-full">
<div class="form-item w-full"> <label for="length">Длина ламельного блока, мм</label>
<label for="length">Длина ламельного блока, мм</label> <input disabled :value.input="`${form_state.length.toFixed(0)} мм`" class="w-28" />
<input disabled :value.input="`${form_state.length.toFixed(0)} мм`" class="w-28" /> <input id="length" type="range" class="xl:w-full" v-bind="parametric.length"
<input id="length" type="range" class="xl:w-full" v-bind="parametric.length" v-model="form_state.length" :disabled="form_state.auto_length" :ref="form_refs.length" />
v-model="form_state.length" :disabled="form_state.auto_length" :ref="form_refs.length" /> </div>
</div> <div class="form-item w-full">
<div class="form-item w-full"> <label for="height">Высота забора, мм</label>
<label for="height">Высота забора, мм</label> <input disabled :value="`${form_state.height} мм`" class="w-28" />
<input disabled :value="`${form_state.height} мм`" class="w-28" /> <input id="height" type="range" class="xl:w-full" v-bind="parametric.height"
<input id="height" type="range" class="xl:w-full" v-bind="parametric.height" v-model="form_state.height" :ref="form_refs.height" />
v-model="form_state.height" :ref="form_refs.height" /> </div>
</div>
<div class="form-item">
<label for="lamelle_color">Цвет ламелей</label>
<input id="lamelle_color" type="text" :value="getColorNameFromRal(lamelle_color)" class="w-60"
disabled />
<ColorPicker :cb="setLamelleColor" />
</div>
<div class="form-item">
<label for="pillar_color">Цвет столба</label>
<input id="pillar_color" type="text" :value="getColorNameFromRal(pillar_color)" class="w-60"
disabled />
<ColorPicker :cb="setPillarColor" />
</div>
<div class="form-item">
<label for="total_length">Общая длина забора, м</label>
<input type="number" id="total_length" v-bind="parametric.total_length" min=0
v-model="form_state.total_length" :ref="form_refs.total_length" />
</div>
<div class="form-item xl:w-2/4 text-sm xl:text-base">
<p v-if="form_state.total_length_mm < parametric.length.min" class="text-ioprim">
Выбранный размер забора слишком мал для расчета стоимости. Пожалуйста, выберите больший
размер, чтобы продолжить.
</p>
<p v-if="form_state.extra_section" class="text-ioprim">
Внимание! Дополнительная секция приводит к увеличению стоимости.
Рекомендуем вам изменить длину забора или длину секции!
</p>
</div>
<div class="form-item form-item_checkbox">
<input id="auto_length" type="checkbox" v-model="form_state.auto_length" />
<label for="auto_length">Автоматический подбор секции</label>
</div>
<div class="form-item form-item_checkbox">
<input id="remove_pillar" type="checkbox" v-model="form_state.remove_pillar" />
<label for="remove_pillar">Без столбов</label>
</div> </div>
</div> </div>
<div class="col-span-12 sm:col-span-6"> </div>
<div class="form-row"> <template v-if="(form_state.total_length * 1000) >= parametric.length.min">
<div class="form-item"> <div class="col-span-4 col-start-9">
<label for="lamelle_color">Цвет ламелей</label>
<input id="lamelle_color" type="text" :value="getColorNameFromRal(lamelle_color)" class="w-60"
disabled />
<ColorPicker :cb="setLamelleColor" />
</div>
<div class="form-item">
<label for="pillar_color">Цвет столба</label>
<input id="pillar_color" type="text" :value="getColorNameFromRal(pillar_color)" class="w-60"
disabled />
<ColorPicker :cb="setPillarColor" />
</div>
</div>
</div>
<div class="col-span-12">
<div class="form-row">
<div class="form-item">
<label for="total_length">Общая длина забора, м</label>
<input type="number" id="total_length" v-bind="parametric.total_length" min=0
v-model="form_state.total_length" :ref="form_refs.total_length" />
</div>
<div class="form-item xl:w-2/4 text-sm xl:text-base">
<p v-if="form_state.total_length_mm < parametric.length.min" class="text-ioprim">
Выбранный размер забора слишком мал для расчета стоимости. Пожалуйста, выберите больший
размер, чтобы продолжить.
</p>
<p v-if="form_state.extra_section" class="text-ioprim">
Внимание! Дополнительная секция приводит к увеличению стоимости.
Рекомендуем вам изменить длину забора или длину секции!
</p>
</div>
</div>
<div class="form-row min-h-12 mt-2 xl:mt-0">
<div class="form-item form-item_checkbox">
<input id="auto_length" type="checkbox" v-model="form_state.auto_length" />
<label for="auto_length">Автоматический подбор секции</label>
</div>
<div class="form-item form-item_checkbox">
<input id="remove_pillar" type="checkbox" v-model="form_state.remove_pillar" />
<label for="remove_pillar">Без столбов</label>
</div>
</div>
</div>
<template v-if="(form_state.total_length * 1000) >= parametric.length.min">
<div class="col-span-12 xl:col-span-8 xl:col-start-3 grid calc_table"> <div class="col-span-12 xl:col-span-8 xl:col-start-3 grid calc_table">
<div class="grid grid-cols-6"> <div class="grid grid-cols-6">
<div class="col-span-4 calc_table-maincell">Секции</div> <div class="col-span-4 calc_table-maincell">Секции</div>
@ -250,7 +243,7 @@ const goal = (target: string, params: object) => {
<div class="col-span-12 text-center mb-4"> <div class="col-span-12 text-center mb-4">
<button @click.prevent="toggleModal">Рассчитать</button> <button @click.prevent="toggleModal">Рассчитать</button>
</div> </div>
</template> </div>
</form> </template>
</div> </div>
</template> </template>

View File

@ -9,7 +9,6 @@ const fence_section = use_fence_section()
const section_count = use_section_count() const section_count = use_section_count()
const extra_section = use_extra_section() const extra_section = use_extra_section()
const remove_pillar = use_remove_pillar() const remove_pillar = use_remove_pillar()
const max_size = use_max_size()
const lSize = lamelle_height.value const lSize = lamelle_height.value
const bSize = 0.0235 const bSize = 0.0235

View File

@ -20,6 +20,8 @@ const { scene } = useTresContext()
const section_count = use_section_count() const section_count = use_section_count()
const extra_section = use_extra_section() const extra_section = use_extra_section()
const fence_section = use_fence_section()
const max_size = use_max_size()
const total = ref((section_count.value + ~~(!!extra_section.value))) const total = ref((section_count.value + ~~(!!extra_section.value)))
const position = ref(new Vector3()) const position = ref(new Vector3())
@ -29,12 +31,11 @@ const count_pos = () => {
const line = seekByName(scene.value, `line_${props.number}`) const line = seekByName(scene.value, `line_${props.number}`)
const line_size = new Vector3() const line_size = new Vector3()
const line_pos = new Vector3() const line_pos = new Vector3()
const line_lpos = new Vector3()
if (line && line.children.length) { if (line && line.children.length) {
line.updateMatrixWorld() line.updateMatrixWorld()
new Box3().expandByObject(line).getSize(line_size) new Box3().expandByObject(line).getSize(line_size)
line.getWorldPosition(line_pos) line.getWorldPosition(line_pos)
console.log(`line_${props.number}`, line, line_size, line_pos)
} }
const line1 = seekByName(scene.value, `line_1`); const line1 = seekByName(scene.value, `line_1`);
const line1_size = new Vector3() const line1_size = new Vector3()
@ -42,7 +43,6 @@ const count_pos = () => {
if (line1) { if (line1) {
new Box3().expandByObject(line1).getSize(line1_size) new Box3().expandByObject(line1).getSize(line1_size)
line1.getWorldPosition(line1_pos) line1.getWorldPosition(line1_pos)
console.log('first', line1, line1_size, line1_pos)
} }
const k = ((line1_size.x / props.count) - line1_size.z) * 0.5 const k = ((line1_size.x / props.count) - line1_size.z) * 0.5
switch (props.number) { switch (props.number) {
@ -64,7 +64,7 @@ const count_pos = () => {
onMounted(() => { onMounted(() => {
count_pos() count_pos()
}) })
watch(() => [props.count, section_count.value, extra_section.value], count_pos) watch(() => [props.count, fence_section.value, section_count.value, extra_section.value], count_pos)
</script> </script>
<template> <template>
<TresGroup :name="`line_${props.number}`" :rotate-y="rotate()" :position-x="position.x" :position-y="position.y" <TresGroup :name="`line_${props.number}`" :rotate-y="rotate()" :position-x="position.x" :position-y="position.y"

View File

@ -1,25 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import { import {
PCFSoftShadowMap, PCFSoftShadowMap,
EquirectangularReflectionMapping,
CineonToneMapping, CineonToneMapping,
Euler,
Mesh, Mesh,
Group,
Object3D, Object3D,
} from 'three'; } from 'three';
import { GainMapLoader, } from '@monogrid/gainmap-js'
//@ts-ignore //@ts-ignore
import { useGLTF, } from '@tresjs/cientos' import { useGLTF, } from '@tresjs/cientos'
import { getColorHexFromRal, type ralTypes } from '../ral'; import { getColorHexFromRal, type ralTypes } from '../ral';
import { degToRad, radToDeg } from 'three/src/math/MathUtils.js';
const pillar_color = use_pillar_color() const pillar_color = use_pillar_color()
const lamelle_color = use_lamelle_color() const lamelle_color = use_lamelle_color()
const section_count = use_section_count() const section_count = use_section_count()
const lamelle_count = use_lamelles_count() const lamelle_count = use_lamelles_count()
const extra_section = use_extra_section() const extra_section = use_extra_section()
const max_size = use_max_size()
const { scene, renderer, camera } = useTresContext() const { scene, renderer, camera } = useTresContext()
renderer.value.toneMapping = CineonToneMapping renderer.value.toneMapping = CineonToneMapping
@ -29,7 +23,6 @@ renderer.value.shadowMap.enabled = true
renderer.value.shadowMap.type = PCFSoftShadowMap renderer.value.shadowMap.type = PCFSoftShadowMap
const { scene: top_model } = await useGLTF('/models_one/verh_100.glb', { draco: true }) const { scene: top_model } = await useGLTF('/models_one/verh_100.glb', { draco: true })
// const { scene: fence_model } = await useGLTF('/models_one/fence.glb', { draco: true })
const { scene: model_fence_top } = await useGLTF('/fence_one/top.glb') const { scene: model_fence_top } = await useGLTF('/fence_one/top.glb')
const { scene: model_fence_center } = await useGLTF('/fence_one/center.glb') const { scene: model_fence_center } = await useGLTF('/fence_one/center.glb')
const { scene: model_fence_bottom } = await useGLTF('/fence_one/bottom.glb') const { scene: model_fence_bottom } = await useGLTF('/fence_one/bottom.glb')
@ -98,7 +91,6 @@ const size = ref(Math.ceil(total.value / 4))
const count = ref((total.value >= 4) ? size.value : total.value) const count = ref((total.value >= 4) ? size.value : total.value)
watch(() => [section_count.value, extra_section.value], () => { watch(() => [section_count.value, extra_section.value], () => {
console.log('parametric line clear')
total.value = (section_count.value + ~~(!!extra_section.value)) total.value = (section_count.value + ~~(!!extra_section.value))
size.value = Math.ceil(total.value / 4); size.value = Math.ceil(total.value / 4);
count.value = (total.value >= 4) ? size.value : total.value; count.value = (total.value >= 4) ? size.value : total.value;