Skip to content

Commit

Permalink
👌Merge pull request #5 from gdagil/develop
Browse files Browse the repository at this point in the history
lab-6
  • Loading branch information
gdagil authored Dec 10, 2022
2 parents 7a1d899 + 30305b0 commit dababca
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 55 deletions.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ $$ ρ = {a\overϕ}, \qquad 0 < A \leq ϕ \leq B$$
![lab_2](docs/imgs/wireframe_vis.png)

---
## Лабораторная работа № 3
## Лабораторная работа № 3-5
Тема: Каркасная визуализация выпуклого многогранника. Удаление невидимых линий

Задание: Разработать формат представления многогранника и процедуру его каркасной
Expand All @@ -82,10 +82,19 @@ $$ ρ = {a\overϕ}, \qquad 0 < A \leq ϕ \leq B$$
Обеспечить автоматическое центрирование и изменение размеров изображения при изменении
размеров окна

![lab_3](docs/imgs/wireframe_cone.png)
![lab_3-5](docs/imgs/wireframe_cone.png)

---

## Лабораторная работа № 6
Тема: Создание анимационных эффектов

Задание: Для поверхности, созданной в прощлой ЛР, обеспечить выполнение эффекта изменения
интенсивности источника рассеянного света

![lab_6](docs/imgs/animation.png)
---

## Лабораторная работа № 7
Тема: Построение плоских полиномиальных кривых

Expand Down
1 change: 1 addition & 0 deletions app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ RUN apt-get update && apt-get install -y \
software-properties-common \
&& rm -rf /var/lib/apt/lists/*

RUN pip install --upgrade pip setuptools wheel

WORKDIR /app

Expand Down
163 changes: 121 additions & 42 deletions app/labs/wireframe_vis.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
from typing import Literal

import numpy as np
# from numpy.typing import NDArray
from pydantic import BaseModel


class LEffect(BaseModel):
ambient: float|list[float]
diffuse: float|list[float]
fresnel: float|list[float]
roughness: float|list[float]
specular: float|list[float]


class LEffectRCSteps(LEffect):
r_c_steps: int|None = None # Range controle steps


class Wframe_3d:
ambient_range = (0.0, 1.0)
diffuse_range = (0.0, 1.0)
fresnel_range = (0.0, 5.0)
roughness_range = (0.0, 1.0)
specular_range = (0.0, 1.0)


@staticmethod
def st_text_menu_prizm(st):
st.header('Каркасная визуализация выпуклого многогранника. Удаление невидимых линий')
Expand All @@ -12,7 +38,7 @@ def st_text_menu_prizm(st):
размеров окна
\n
Гранная прямая правильная призма
''')
''')
radius = st.slider('Радиус призмы', 0.1, 10.0, step=0.1, value=5.0)
delta_z = st.slider('Высота призмы', 0.1, 30.0, step=0.1, value=5.0)
num_of_slices = st.slider('Количество граней', 3, 30, step=1, value=5)
Expand All @@ -22,17 +48,23 @@ def st_text_menu_prizm(st):


@staticmethod
def st_text_menu_cone(st):
st.header('Основы построения фотореалистичных изображений')

st.subheader('Задание:')
st.write('''
def st_text_menu_cone(st, lab:Literal["3", "6"]="3"):
if lab == "3":
st.header('Основы построения фотореалистичных изображений')
st.subheader('Задание:')
st.write('''
Используя результаты Л.Р.№2, аппроксимировать заданное тело выпуклым многогранником. Точность
аппроксимации задается пользователем. Обеспечить возможность вращения и масштабирования многогранника и
удаление невидимых линий и поверхностей. Реализовать простую модель закраски для случая одного источника света.
\n
Прямой усеченный круговой конус
''')
elif lab == "6":
st.header('Создание анимационных эффектов')
st.subheader('Задание:')
st.write('''Для поверхности, созданной в прощлой ЛР, обеспечить выполнение эффекта изменения
интенсивности источника рассеянного света
''')
radius_1 = st.slider('Нижний радиус конуса', 0.1, 10.0, step=0.1, value=8.1)
radius_2 = st.slider('Верхний радиус конуса', 0.1, 10.0, step=0.1, value=2.8)
delta_z = st.slider('Высота конуса', 0.1, 30.0, step=0.1, value=11.4)
Expand All @@ -43,48 +75,95 @@ def st_text_menu_cone(st):


@staticmethod
def st_lighting_effects(st) -> dict[str, float]:
def st_lighting_effects(st, range_control:bool=False) -> LEffectRCSteps:
st.subheader('Освещение объекта')
ambient = st.slider('''ambient - рассеянный свет увеличивает общую видимость
цвета, но может размыть изображение''',
0.0,
1.0,
step=0.01,
value=0.8
)
diffuse = st.slider('''diffuse - степень отражения падающих лучей
в различных ракурсах''',
0.0,
1.0,
step=0.01,
value=0.8
)
fresnel = st.slider('''fresnel - коэффициент отражения в зависимости от

if range_control:
r_c_steps = st.slider(
"Определите количество кадров анимации",
1,
100,
step=1,
value=30
)
else:
r_c_steps=None

st.write('''ambient - рассеянный свет увеличивает общую видимость
цвета, но может размыть изображение
''')
if range_control:
a_r = st.slider("Определите интервал ambient", value=Wframe_3d.ambient_range)
ambient = np.linspace(a_r[0], a_r[1], r_c_steps).tolist()
else:
ambient = st.slider("Выберите ambient", Wframe_3d.ambient_range[0], Wframe_3d.ambient_range[1], step=0.01, value=0.8)


st.write('''diffuse - степень отражения падающих лучей
в различных ракурсах
''')
if range_control:
d_r = st.slider("Определите интервал diffuse", value=Wframe_3d.diffuse_range)
diffuse = np.linspace(d_r[0], d_r[1], r_c_steps).tolist()
else:
diffuse = st.slider("Выберите diffuse", Wframe_3d.diffuse_range[0], Wframe_3d.diffuse_range[1], step=0.01, value=0.8)


st.write('''fresnel - коэффициент отражения в зависимости от
угла обзора; например, бумага отражает при просмотре ее
от края бумаги (почти на 90 градусов), возникает сияние''',
0.0,
5.0,
step=0.01,
value=0.2
)
roughness = st.slider('''roughness - изменяет зеркальное отражение;
чем грубее поверхность, чем шире и менее контрастен блеск''',
0.0,
1.0,
step=0.01,
value=0.5
)
specular = st.slider('''specular - уровень отражения падающих лучей
в одном направлении, вызывающий блеск''',
0.0,
2.0,
step=0.01,
value=0.05
от края бумаги (почти на 90 градусов), возникает сияние
''')
if range_control:
f_r = st.slider("Определите интервал fresnel", value=Wframe_3d.fresnel_range)
fresnel = np.linspace(f_r[0], f_r[1], r_c_steps).tolist()
else:
fresnel = st.slider("Выберите fresnel", Wframe_3d.fresnel_range[0], Wframe_3d.fresnel_range[1], step=0.01, value=0.2)


st.write('''roughness - изменяет зеркальное отражение;
чем грубее поверхность, чем шире и менее контрастен блеск
''')
if range_control:
r_r = st.slider("Определите интервал roughness", value=Wframe_3d.roughness_range)
roughness = np.linspace(r_r[0], r_r[1], r_c_steps).tolist()
else:
roughness = st.slider("Выберите roughness", Wframe_3d.roughness_range[0], Wframe_3d.roughness_range[1],
step=0.01, value=0.5
)


st.write('''specular - уровень отражения падающих лучей
в одном направлении, вызывающий блеск
''')
if range_control:
s_r = st.slider("Определите интервал specular", value=Wframe_3d.specular_range)
specular = np.linspace(s_r[0], s_r[1], r_c_steps).tolist()
else:
specular = st.slider("Выберите specular", Wframe_3d.specular_range[0], Wframe_3d.specular_range[1], step=0.01, value=0.05)


return LEffectRCSteps(
ambient=ambient,
diffuse=diffuse,
fresnel=fresnel,
roughness=roughness,
specular=specular,
r_c_steps=r_c_steps if r_c_steps else 1
)

@staticmethod
def st_lighting_effects_checkboxes(st) -> dict[str,bool]:
st.write("Выбор эффектов анимации")
ambient = st.checkbox('ambient', value=True)
diffuse = st.checkbox('diffuse')
fresnel = st.checkbox('fresnel')
roughness = st.checkbox('roughness')
specular = st.checkbox('specular')
return dict(
ambient=ambient,
diffuse=diffuse,
fresnel=fresnel,
roughness=roughness,
specular=specular
)
)

97 changes: 90 additions & 7 deletions app/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os

import streamlit as st
from stqdm import stqdm
import numpy as np

from utils import Plotter, Figure, PickerFunc
Expand All @@ -20,7 +21,8 @@
[
'ЛР1 - функция в полярных координатах',
'ЛР2 - гранная прямая правильная призма',
'ЛР3 - Основы построения фотореалистичных изображений',
'ЛР3-5 - Основы построения фотореалистичных изображений',
'ЛР6 - Создание анимационных эффектов',
'ЛР7 - Построение плоских полиномиальных кривых',
],
label_visibility='hidden')
Expand Down Expand Up @@ -56,18 +58,99 @@
st.plotly_chart(prism, use_container_width=True)


if activation_function == 'ЛР3 - Основы построения фотореалистичных изображений':
if activation_function == 'ЛР3-5 - Основы построения фотореалистичных изображений':
with st.sidebar:
radius_1, radius_2, delta_z, num_of_slices, cyl_op, bord_op = Wframe_3d.st_text_menu_cone(st)
lighting_effects = Wframe_3d.st_lighting_effects(st)
radius_1, radius_2, delta_z, num_of_slices, cyl_op, bord_op = Wframe_3d.st_text_menu_cone(st, lab="3")
lighting_effects = Wframe_3d.st_lighting_effects(st).dict(exclude={'r_c_steps'})
st.header(lighting_effects)
base = Figure(num_of_slices, height=delta_z, lighting_effects=lighting_effects)
cone = base.cone(delta_z, radius_1, radius_2, opacity=cyl_op)
circle_1 = base.circle(0, radius_1, opacity=bord_op)
circle_2 = base.circle(delta_z, radius_2, opacity=bord_op)
fig = Plotter.wireframe_plot_1_scene(cone, [circle_1, circle_2])
circles = [
base.circle(0, radius_1, opacity=bord_op),
base.circle(delta_z, radius_2, opacity=bord_op)
]
fig = Plotter.wireframe_plot_1_scene(cone, circles)
st.plotly_chart(fig, use_container_width=True)


if activation_function == 'ЛР6 - Создание анимационных эффектов':
with st.sidebar:
radius_1, radius_2, delta_z, num_of_slices, cyl_op, bord_op = Wframe_3d.st_text_menu_cone(st, lab="6")
lighting_effects_lists = Wframe_3d.st_lighting_effects(st, range_control=True) # .dict(exclude={'r_c_steps'})
lighting_effects_checkboxes = Wframe_3d.st_lighting_effects_checkboxes(st)

lel_dict = lighting_effects_lists.dict(exclude={'r_c_steps'})
frames = list()

for i in stqdm(range(lighting_effects_lists.r_c_steps)):
lighting_effects_frame = dict()
for key, check in lighting_effects_checkboxes.items():
if check:
lighting_effects_frame.setdefault(key, lel_dict[key][i])

base = Figure(num_of_slices, height=delta_z, lighting_effects=lighting_effects_frame)
frames.append(
dict(
data=[
base.cone(delta_z, radius_1, radius_2, opacity=cyl_op),
base.circle(0, radius_1, opacity=bord_op),
base.circle(delta_z, radius_2, opacity=bord_op)
],
name=f'frame-{i}'
)
)
fig = Plotter.wireframe_plot_1_scene(frames[0]["data"])
if lighting_effects_lists.r_c_steps > 1:
fig.update(frames=Plotter.go_frames(frames))
fig.update_layout(
updatemenus = [
{
"buttons": [
{
"args": [None, Plotter.frame_args(50)],
"label": "Play",
"method": "animate",
},
{
"args": [[None], Plotter.frame_args(0)],
"label": "Pause",
"method": "animate",
}
],
"direction": "left",
"pad": {"r": 10, "t": 87},
"showactive": False,
"type": "buttons",
"x": 0.1,
"xanchor": "right",
"y": 0,
"yanchor": "top"
}
],
sliders = [
{
"pad": {"b": 10, "t": 60},
"len": 0.9,
"x": 0.1,
"y": 0,
"steps": [
{
"args": [[f.name], Plotter.frame_args(0)],
"label": str(k),
"method": "animate",
}
for k, f in enumerate(fig.frames)
]
}
]
)

st.plotly_chart(fig, use_container_width=True)






if activation_function == 'ЛР7 - Построение плоских полиномиальных кривых':
with st.sidebar:
Expand Down
3 changes: 2 additions & 1 deletion app/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ scipy==1.9.3
semver==2.13.0
six==1.16.0
smmap==5.0.0
streamlit==1.14.0
streamlit==1.14.1
tenacity==8.1.0
toml==0.10.2
toolz==0.12.0
Expand All @@ -54,3 +54,4 @@ validators==0.20.0
watchdog==2.1.9
xyzservices==2022.9.0
zipp==3.10.0
stqdm==0.0.4
Loading

0 comments on commit dababca

Please sign in to comment.