HoLa-BRep / app /AppLayout.py
YuXingyao's picture
fresh start
7b127f4
import time
import gradio as gr
from typing import List, Callable
from abc import ABC, abstractmethod
# Tab Interface
class AppLayout(ABC):
@abstractmethod
def get_English_note(self) -> gr.Markdown:
pass
@abstractmethod
def get_Chinese_note(self):
pass
@abstractmethod
def get_input_components(self) -> List[gr.Component]:
pass
# Concrete Implementation
class UncondLayout(AppLayout):
def get_English_note(self):
return gr.Markdown(
"""
**Note:**
+ We generate 4 BRep models from sampled noise in Gaussian distribution.
+ The model is trained on ABC dataset with a complexity range of 10~100 surface primitives.
+ Compared with the state-of-the-art BRep generation methods, HoLa-BRep has a 20%-40% improvement in the validity ratio of the generated models on both the DeepCAD dataset and the ABC dataset.
+ Try to adjust the seed for various results.
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
"""
)
def get_Chinese_note(self):
return gr.Markdown(
"""
**无条件生成介绍:**
+ 我们从高斯分布的采样噪声中生成 4 个 BRep 模型。
+ 模型在 ABC 数据集上进行训练,复杂度范围为 10~100 个表面基元。
+ 与最先进的 BRep 生成方法相比,HoLa-BRep 在 DeepCAD 数据集和 ABC 数据集上生成模型的有效率提高了 20%-40%。
+ 请随意调整采样种子,以获得不同的结果。
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
"""
)
def get_input_components(self) -> List[gr.Component]:
return [
gr.Number(
label="Seed",
value=int(time.time()),
minimum=0,
maximum=2**31-1,
step=1
),
]
class TextLayout(AppLayout):
def get_English_note(self):
return gr.Markdown(
"""
**Note:**
+ Text can be either abstract or descriptive.
+ We use a frozen gte-large-en-v1.5 to extract the feature from the text description.
+ While we use the existing Text2CAD dataset which contains more descriptive text, the out of distribution abstract text prompt also works.
<br>
<br>
"""
)
def get_Chinese_note(self):
return gr.Markdown(
"""
**文本条件生成介绍:**
+ HoLa-BRep支持简单抽象的文本和复杂的描述性文本。
+ 我们使用冻结的gte-large-en-v1.5从文本描述中提取特征。
+ 虽然我们使用的是包含更多复杂描述性文本的Text2CAD 数据集,但HoLa-BRep同样适用于简单抽象的文本输入。
+ **当前文本输入仅支持英文,敬请谅解。**
<br>
"""
)
def get_input_components(self) -> List[gr.Component]:
return [
gr.Textbox(lines = 8,max_length=1024, label="Text"),
]
class PCLayout(AppLayout):
def get_English_note(self):
return gr.Markdown(
"""
**Note:**
+ The input point cloud should be in .ply format with the position in -1~+1 and normal vectors.
+ The input point cloud can be either sparse or dense. We will downsample the point cloud into 2048 points.
+ After test-time augmentation the validity of the generated B-Rep model can reach ~98%.
+ We use a small and trainable PointNet++ to extract the feature from the point cloud.
+ This checkpoint is only for a clean point cloud without any noise.
+ Point cloud contains less ambiguity and usually yields the best conditional generation results compared to other modalities.
"""
)
def get_Chinese_note(self):
return gr.Markdown(
"""
**点云条件生成介绍:**
+ HoLa-BRep接受.ply 格式的点云输入,且坐标值应该归一化到-1~+1并带有法向信息。
+ HoLa-BRep接受稀疏或密集点云,网络处理点云时会将其降采样到2048 个点。
+ 经过测试时增强后点云条件生成的有效性可达98%以上。
+ 我们使用一个小型可训练的 PointNet++ 从点云中提取特征。
+ 目前开放权重仅支持没有任何噪声的点云。
+ 三维点云作为条件输入具有更少的歧义性,与其他条件相比通常能产生最佳的生成结果。
"""
)
def get_input_components(self):
return [
gr.File(
label='PC',
file_count='single',
),
]
class SketchLayout(AppLayout):
def get_English_note(self):
return gr.Markdown(
"""
**Note:**
+ The input sketch is in 1:1 ratio and on a white background, it will be further downsampled to 224*224 before feeding into the network.
+ The input sketch should be a perspective projection rather than an orthogonal projection.
+ We use a frozen DINOv2 to extract the feature from the sketch image.
+ We obtained the training sketches using wireframe rendering in OpenCascade.
<br>
<br>
"""
)
def get_Chinese_note(self):
return gr.Markdown(
"""
**线框图条件生成介绍:**
+ 输入线框图的长宽比应为1:1,背景为白色,系统处理时会降采样到224*224分辨率。
+ 输入的线框图应该是透视投影,而不是正交投影。
+ 我们使用冻结的 DINOv2 从线框图图像中提取特征。
+ 我们使用 OpenCascade 中的线框渲染来获取训练线框图。
<br>
<br>
"""
)
def get_input_components(self) -> List[gr.Component]:
return [
gr.Image(
label='Sketch',
type='filepath',
sources=["upload"],
interactive=True,
)
]
class SVRLayout(AppLayout):
def get_English_note(self):
return gr.Markdown(
"""
**Note:**
+ The input image is in 1:1 ratio and on a white background, it will be further downsampled to 224*224 before feeding into the network.
+ Keep the object in grey for better generation results.
+ We use a frozen DINOv2 to extract the feature from the sketch image.
+ We obtained the training images using solid rendering in OpenCascade.
<br>
<br>
"""
)
def get_Chinese_note(self):
return gr.Markdown(
"""
**单视角图片条件生成介绍:**
+ 输入图片的长宽比应为1:1,背景为白色,系统处理时会降采样到224*224分辨率。
+ 为了获得更好的生成效果,请将对象保持为灰色。
+ 我们使用冻结的 DINOv2 从草图图像中提取特征。
+ 我们使用 OpenCascade 中的实体渲染来获取训练图像。
<br>
<br>
"""
)
def get_input_components(self) -> List[gr.Component]:
return [
gr.Image(
label='Image',
type='filepath',
sources=["upload"],
interactive=True,
),
]
class MVRLayout(AppLayout):
def get_English_note(self):
return gr.Markdown(
"""
**Note:**
+ Similar to the single-view condition, the input image should be in 1:1 ratio and 4 fixed angles, **see the camera pose schematic**.
+ Image features are extracted by a frozen DINOv2 and averaged after adding the positional encoding on the camera **pose** embedding.
"""
)
def get_Chinese_note(self):
return gr.Markdown(
"""
**多视角图片条件生成介绍:**
+ 与单视角条件类似,输入图像应为 1:1长宽比和4 个固定角度,**见相机位姿示意图**。
+ 图像特征由冻结的 DINOv2 提取,并在对相机**位姿**特征进行位置编码后取平均值。
"""
)
def get_input_components(self) -> List[gr.Component]:
return [
gr.Image(
label='View1',
type='filepath',
interactive=True,
sources=["upload"]
),
gr.Image(
label='View2',
type='filepath',
interactive=True,
sources=["upload"]
),
gr.Image(
label='View3',
type='filepath',
interactive=True,
sources=["upload"]
),
gr.Image(
label='View4',
type='filepath',
interactive=True,
sources=["upload"]
),
]