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.







""" ) def get_Chinese_note(self): return gr.Markdown( """ **无条件生成介绍:** + 我们从高斯分布的采样噪声中生成 4 个 BRep 模型。 + 模型在 ABC 数据集上进行训练,复杂度范围为 10~100 个表面基元。 + 与最先进的 BRep 生成方法相比,HoLa-BRep 在 DeepCAD 数据集和 ABC 数据集上生成模型的有效率提高了 20%-40%。 + 请随意调整采样种子,以获得不同的结果。







""" ) 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.

""" ) def get_Chinese_note(self): return gr.Markdown( """ **文本条件生成介绍:** + HoLa-BRep支持简单抽象的文本和复杂的描述性文本。 + 我们使用冻结的gte-large-en-v1.5从文本描述中提取特征。 + 虽然我们使用的是包含更多复杂描述性文本的Text2CAD 数据集,但HoLa-BRep同样适用于简单抽象的文本输入。 + **当前文本输入仅支持英文,敬请谅解。**
""" ) 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.

""" ) def get_Chinese_note(self): return gr.Markdown( """ **线框图条件生成介绍:** + 输入线框图的长宽比应为1:1,背景为白色,系统处理时会降采样到224*224分辨率。 + 输入的线框图应该是透视投影,而不是正交投影。 + 我们使用冻结的 DINOv2 从线框图图像中提取特征。 + 我们使用 OpenCascade 中的线框渲染来获取训练线框图。

""" ) 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.

""" ) def get_Chinese_note(self): return gr.Markdown( """ **单视角图片条件生成介绍:** + 输入图片的长宽比应为1:1,背景为白色,系统处理时会降采样到224*224分辨率。 + 为了获得更好的生成效果,请将对象保持为灰色。 + 我们使用冻结的 DINOv2 从草图图像中提取特征。 + 我们使用 OpenCascade 中的实体渲染来获取训练图像。

""" ) 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"] ), ]