add 3d image model

This commit is contained in:
dawoodkhan82 2022-03-02 22:01:05 -05:00
parent 842f337038
commit 07b2a4992f
11 changed files with 9435 additions and 2 deletions

7474
demo/model/files/Bunny.obj Normal file

File diff suppressed because it is too large Load Diff

BIN
demo/model/files/Duck.glb Normal file

Binary file not shown.

1777
demo/model/files/Fox.gltf Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
Stanford Bunny:
https://graphics.stanford.edu/data/3Dscanrep/
https://graphics.stanford.edu/~mdfisher/Data/Meshes/bunny.obj
Duck & Fox:
https://github.com/KhronosGroup/glTF-Sample-Models

26
demo/model/run.py Normal file
View File

@ -0,0 +1,26 @@
import os.path
import gradio as gr
def load_mesh(mesh_file_name):
file_dir = "files"
mesh_path = os.path.join(file_dir, mesh_file_name)
return mesh_path
iface = gr.Interface(
load_mesh,
inputs=[
gr.inputs.Dropdown(["Duck.glb", "Bunny.obj", "Fox.gltf"], type="value", default="Duck.glb", label="Mesh File")
],
outputs=[
"model"
# to specify options use the object initializer
# gr.outputs.Model(clear_color=[1.0, 1.0, 1.0], label="3D Model")
]
)
if __name__ == "__main__":
iface.launch()

View File

@ -853,6 +853,57 @@ class State(OutputComponent):
}
class Model(OutputComponent):
'''
Used for 3d model output.
Output type: filepath
Demos: hello_model
'''
def __init__(self, clear_color=None, label=None):
'''
Parameters:
label (str): component name in interface.
'''
super().__init__(label)
self.clear_color = clear_color
@classmethod
def get_shortcut_implementations(cls):
return {
"model": {},
}
def postprocess(self, y):
"""
Parameters:
y (str): path to the model
Returns:
(str): file name
(str): file extension
(str): base64 url data
"""
if self.clear_color is None:
self.clear_color = [0.2, 0.2, 0.2]
return {
"name": os.path.basename(y),
"extension": os.path.splitext(y)[1],
"clearColor": self.clear_color,
"data": processing_utils.encode_file_to_base64(y, type="model"),
}
def deserialize(self, x):
return processing_utils.decode_base64_to_file(x).name
def save_flagged(self, dir, label, data, encryption_key):
"""
Returns: (str) path to model file
"""
return self.save_flagged_file(dir, label, data['data'], encryption_key)
def get_output_instance(iface: Interface):
if isinstance(iface, str):
shortcut = OutputComponent.get_all_shortcut_implementations()[iface]

6
package.json Normal file
View File

@ -0,0 +1,6 @@
{
"dependencies": {
"three": "^0.138.2",
"vitest": "^0.5.9"
}
}

View File

@ -20,6 +20,7 @@
"svelte": "^3.46.3",
"svelte-check": "^2.4.1",
"svelte-i18n": "^3.3.13",
"vitest": "^0.3.2"
"vitest": "^0.3.2",
"three": "^0.138.2"
}
}

View File

@ -25,6 +25,7 @@ import OutputTextbox from "./output/Textbox/config.js";
import OutputVideo from "./output/Video/config.js";
import OutputTimeSeries from "./output/TimeSeries/config.js";
import OutputChatbot from "./output/Chatbot/config.js";
import OutputModel from "./output/Model/config.js";
import StaticButton from "./static/Button/config.js";
import StaticMarkdown from "./static/Markdown/config.js";
@ -58,7 +59,8 @@ export const output_component_map = {
textbox: OutputTextbox,
timeseries: OutputTimeSeries,
video: OutputVideo,
chatbot: OutputChatbot
chatbot: OutputChatbot,
model: OutputModel
};
export const static_component_map = {

View File

@ -0,0 +1,85 @@
<script lang="ts">
export let value: string;
export let theme: string;
componentDidMount() {
const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true);
this.scene = new BABYLON.Scene(engine);
this.scene.createDefaultCameraOrLight();
const clearColor = this.props.value["clearColor"]
this.scene.clearColor = new BABYLON.Color3(clearColor[0], clearColor[1], clearColor[2]);
this.addNewModel();
engine.runRenderLoop(() => {
this.scene.render();
});
window.addEventListener("resize", () => {
engine.resize();
});
}
componentDidUpdate(prevProps, prevState, snapshot) {
this.addNewModel();
}
addNewModel() {
// remove all existing models
for (let mesh of this.scene.meshes) {
mesh.dispose();
}
// add new model
let base64_model_content = this.props.value["data"];
let raw_content = BABYLON.Tools.DecodeBase64(base64_model_content);
let blob = new Blob([raw_content]);
let url = URL.createObjectURL(blob);
BABYLON.SceneLoader.Append("", url, this.scene, () => {
this.scene.createDefaultCamera(true, true, true);
}, undefined, undefined, this.props.value["extension"]);
}
render() {
if (this.props.value) {
return (
<div className="output_model">
<canvas id="renderCanvas"></canvas>
<a href={this.props.value["data"]} download={this.props.value["name"]} className="download_link">Download {this.props.value["name"]}</a>
</div>
)
} else {
return false;
}
}
</script>
<div
class="output-image w-full h-60 flex justify-center items-center bg-gray-200 dark:bg-gray-600 relative"
{theme}
>
<div className="output_model_example">{value}</div>;
<div className="output_model">
<canvas id="renderCanvas"></canvas>
<a href={this.props.value["data"]} download={value} className="download_link">Download {value}</a>
</div>
</div>
<style lang="postcss">
</style>
// class ModelOutputExample extends ComponentExample {
// render() {
// return <div className="output_model_example">{this.props.value}</div>;
// }
// }
// export {ModelOutput, ModelOutputExample};

View File

@ -0,0 +1,5 @@
import Component from "./Model.svelte";
export default {
component: Component
};