dylanebert commited on
Commit
a1b46a8
·
1 Parent(s): 0ba09c4

prettier, formatting

Browse files
src/app.html CHANGED
@@ -14,4 +14,4 @@
14
  <div style="display: contents">%sveltekit.body%</div>
15
  </body>
16
 
17
- </html>
 
14
  <div style="display: contents">%sveltekit.body%</div>
15
  </body>
16
 
17
+ </html>
src/routes/+page.svelte CHANGED
@@ -7,8 +7,8 @@
7
  import { Filter } from "carbon-icons-svelte";
8
  import { onMount } from "svelte";
9
  import { CaretDown, Code, Development } from "carbon-icons-svelte";
10
- import { dev } from '$app/environment';
11
- import { getApiConfig } from '$lib/config';
12
 
13
  interface Scene {
14
  name: string;
@@ -22,8 +22,8 @@
22
  let showOnlyOpenSource = false;
23
  let showFilter = false;
24
  let filterContainer: HTMLDivElement;
25
- let voteType: 'render' | 'topology' = 'render';
26
-
27
  $: apiConfig = getApiConfig();
28
  $: isDevelopment = dev || apiConfig.isLocal;
29
 
@@ -62,7 +62,7 @@
62
  <span>Development Mode - Backend: {apiConfig.baseUrl}</span>
63
  </div>
64
  {/if}
65
-
66
  <div on:pointerdown={goHome} class="banner">
67
  <h1>3D Arena</h1>
68
  <p>Generative 3D Leaderboard</p>
@@ -70,12 +70,17 @@
70
 
71
  {#if currentView === "Leaderboard" || currentView === "Vote" || currentView === "About"}
72
  <div class="tabs">
73
- <button on:click={() => (currentView = "Vote")} class={currentView === "Vote" ? "active" : ""}>Vote</button>
74
- <button on:click={() => (currentView = "Leaderboard")} class={currentView === "Leaderboard" ? "active" : ""}
75
- >Leaderboard</button
 
 
 
 
76
  >
77
- <button on:click={() => (currentView = "About")} class={currentView === "About" ? "active" : ""}
78
- >About</button
 
79
  >
80
  {#if currentView === "Leaderboard"}
81
  <div class="filter-container" bind:this={filterContainer}>
@@ -94,28 +99,24 @@
94
  <div class="filter-section-title">Vote Type</div>
95
  <div
96
  class="filter-option {voteType === 'render' ? 'active' : ''}"
97
- on:click={() => (voteType = 'render')}
98
- on:keydown={(e) => e.key === "Enter" && (voteType = 'render')}
99
  role="menuitemradio"
100
- aria-checked={voteType === 'render'}
101
  tabindex="0"
102
  >
103
- <div class="filter-label">
104
- Render Quality
105
- </div>
106
  <span class="filter-checkbox">✓</span>
107
  </div>
108
  <div
109
  class="filter-option {voteType === 'topology' ? 'active' : ''}"
110
- on:click={() => (voteType = 'topology')}
111
- on:keydown={(e) => e.key === "Enter" && (voteType = 'topology')}
112
  role="menuitemradio"
113
- aria-checked={voteType === 'topology'}
114
  tabindex="0"
115
  >
116
- <div class="filter-label">
117
- Topology
118
- </div>
119
  <span class="filter-checkbox">✓</span>
120
  </div>
121
  </div>
@@ -124,7 +125,9 @@
124
  <div
125
  class="filter-option {showOnlyOpenSource ? 'active' : ''}"
126
  on:click={() => (showOnlyOpenSource = !showOnlyOpenSource)}
127
- on:keydown={(e) => e.key === "Enter" && (showOnlyOpenSource = !showOnlyOpenSource)}
 
 
128
  role="menuitemcheckbox"
129
  aria-checked={showOnlyOpenSource}
130
  tabindex="0"
@@ -154,7 +157,11 @@
154
  onSceneClick={showScene}
155
  />
156
  {:else if currentView === "Viewer" && selectedScene && selectedEntry}
157
- <Viewer modelName={selectedEntry.name} scene={selectedScene} onBack={() => (currentView = "ModelDetails")} />
 
 
 
 
158
  {:else if currentView === "About"}
159
  <About />
160
  {/if}
 
7
  import { Filter } from "carbon-icons-svelte";
8
  import { onMount } from "svelte";
9
  import { CaretDown, Code, Development } from "carbon-icons-svelte";
10
+ import { dev } from "$app/environment";
11
+ import { getApiConfig } from "$lib/config";
12
 
13
  interface Scene {
14
  name: string;
 
22
  let showOnlyOpenSource = false;
23
  let showFilter = false;
24
  let filterContainer: HTMLDivElement;
25
+ let voteType: "render" | "topology" = "render";
26
+
27
  $: apiConfig = getApiConfig();
28
  $: isDevelopment = dev || apiConfig.isLocal;
29
 
 
62
  <span>Development Mode - Backend: {apiConfig.baseUrl}</span>
63
  </div>
64
  {/if}
65
+
66
  <div on:pointerdown={goHome} class="banner">
67
  <h1>3D Arena</h1>
68
  <p>Generative 3D Leaderboard</p>
 
70
 
71
  {#if currentView === "Leaderboard" || currentView === "Vote" || currentView === "About"}
72
  <div class="tabs">
73
+ <button
74
+ on:click={() => (currentView = "Vote")}
75
+ class={currentView === "Vote" ? "active" : ""}>Vote</button
76
+ >
77
+ <button
78
+ on:click={() => (currentView = "Leaderboard")}
79
+ class={currentView === "Leaderboard" ? "active" : ""}>Leaderboard</button
80
  >
81
+ <button
82
+ on:click={() => (currentView = "About")}
83
+ class={currentView === "About" ? "active" : ""}>About</button
84
  >
85
  {#if currentView === "Leaderboard"}
86
  <div class="filter-container" bind:this={filterContainer}>
 
99
  <div class="filter-section-title">Vote Type</div>
100
  <div
101
  class="filter-option {voteType === 'render' ? 'active' : ''}"
102
+ on:click={() => (voteType = "render")}
103
+ on:keydown={(e) => e.key === "Enter" && (voteType = "render")}
104
  role="menuitemradio"
105
+ aria-checked={voteType === "render"}
106
  tabindex="0"
107
  >
108
+ <div class="filter-label">Render</div>
 
 
109
  <span class="filter-checkbox">✓</span>
110
  </div>
111
  <div
112
  class="filter-option {voteType === 'topology' ? 'active' : ''}"
113
+ on:click={() => (voteType = "topology")}
114
+ on:keydown={(e) => e.key === "Enter" && (voteType = "topology")}
115
  role="menuitemradio"
116
+ aria-checked={voteType === "topology"}
117
  tabindex="0"
118
  >
119
+ <div class="filter-label">Topology</div>
 
 
120
  <span class="filter-checkbox">✓</span>
121
  </div>
122
  </div>
 
125
  <div
126
  class="filter-option {showOnlyOpenSource ? 'active' : ''}"
127
  on:click={() => (showOnlyOpenSource = !showOnlyOpenSource)}
128
+ on:keydown={(e) =>
129
+ e.key === "Enter" &&
130
+ (showOnlyOpenSource = !showOnlyOpenSource)}
131
  role="menuitemcheckbox"
132
  aria-checked={showOnlyOpenSource}
133
  tabindex="0"
 
157
  onSceneClick={showScene}
158
  />
159
  {:else if currentView === "Viewer" && selectedScene && selectedEntry}
160
+ <Viewer
161
+ modelName={selectedEntry.name}
162
+ scene={selectedScene}
163
+ onBack={() => (currentView = "ModelDetails")}
164
+ />
165
  {:else if currentView === "About"}
166
  <About />
167
  {/if}
src/routes/About.svelte CHANGED
@@ -1,7 +1,10 @@
1
  <div class="section" style="padding: 10px 0;">
2
  <p class="muted">
3
- The <span class="emphasis">3D Arena</span> leaderboard evaluates leading generative 3D models. It is inspired by
4
- <a class="emphasis" target="_blank" href="https://huggingface.co/spaces/TTS-AGI/TTS-Arena">TTS-Arena</a>
 
 
 
5
  and
6
  <a class="emphasis" target="_blank" href="https://chat.lmsys.org/">Chatbot Arena</a>.
7
  </p>
@@ -15,18 +18,20 @@
15
  <div class="section">
16
  <h3 class="emphasis">Motivation</h3>
17
  <p class="muted">
18
- Evaluating generated 3D quality quantitatively is challenging, and there is no standard practice for reporting
19
- critical factors like mesh topology in real-world applications.
 
 
 
20
  </p>
21
- <p class="muted">This leaderboard displays usable, final results side-by-side for the community to rank.</p>
22
  </div>
23
  <div class="section">
24
  <h3 class="emphasis">Criteria</h3>
25
  <p class="muted">
26
  Models must handle <span class="emphasis">image</span> (.png, .jpg) inputs and produce
27
  <span class="emphasis">mesh</span>
28
- (.obj, .glb) or <span class="emphasis">splat</span> (.splat, .ply) outputs. They should run end-to-end without human
29
- intervention, including UV unwrapping, texture mapping, and other post-processing.
30
  </p>
31
  <p class="muted">
32
  To preview how your results will look in the leaderboard, upload them to any <a
@@ -43,13 +48,17 @@
43
  class="emphasis"
44
  target="_blank"
45
  href="https://huggingface.co/datasets/dylanebert/3d-arena">here</a
 
 
 
 
 
46
  >.
47
- Input image URLs are provided
48
- <a class="emphasis" target="_blank" href="https://huggingface.co/datasets/dylanebert/3d-arena/raw/main/inputs.txt">here</a>.
49
  </p>
50
  <p class="muted">
51
- To contribute a model, run your model on all input images and create a pull request with your model's output.
52
- Refer to other examples in the dataset to understand the expected format.
 
53
  </p>
54
  </div>
55
  <div class="section">
 
1
  <div class="section" style="padding: 10px 0;">
2
  <p class="muted">
3
+ The <span class="emphasis">3D Arena</span> leaderboard evaluates leading generative 3D
4
+ models. It is inspired by
5
+ <a class="emphasis" target="_blank" href="https://huggingface.co/spaces/TTS-AGI/TTS-Arena"
6
+ >TTS-Arena</a
7
+ >
8
  and
9
  <a class="emphasis" target="_blank" href="https://chat.lmsys.org/">Chatbot Arena</a>.
10
  </p>
 
18
  <div class="section">
19
  <h3 class="emphasis">Motivation</h3>
20
  <p class="muted">
21
+ Evaluating generated 3D quality quantitatively is challenging, and there is no standard
22
+ practice for reporting critical factors like mesh topology in real-world applications.
23
+ </p>
24
+ <p class="muted">
25
+ This leaderboard displays usable, final results side-by-side for the community to rank.
26
  </p>
 
27
  </div>
28
  <div class="section">
29
  <h3 class="emphasis">Criteria</h3>
30
  <p class="muted">
31
  Models must handle <span class="emphasis">image</span> (.png, .jpg) inputs and produce
32
  <span class="emphasis">mesh</span>
33
+ (.obj, .glb) or <span class="emphasis">splat</span> (.splat, .ply) outputs. They should run end-to-end
34
+ without human intervention, including UV unwrapping, texture mapping, and other post-processing.
35
  </p>
36
  <p class="muted">
37
  To preview how your results will look in the leaderboard, upload them to any <a
 
48
  class="emphasis"
49
  target="_blank"
50
  href="https://huggingface.co/datasets/dylanebert/3d-arena">here</a
51
+ >. Input image URLs are provided
52
+ <a
53
+ class="emphasis"
54
+ target="_blank"
55
+ href="https://huggingface.co/datasets/dylanebert/3d-arena/raw/main/inputs.txt">here</a
56
  >.
 
 
57
  </p>
58
  <p class="muted">
59
+ To contribute a model, run your model on all input images and create a pull request with
60
+ your model's output. Refer to other examples in the dataset to understand the expected
61
+ format.
62
  </p>
63
  </div>
64
  <div class="section">
src/routes/Leaderboard.svelte CHANGED
@@ -14,7 +14,7 @@
14
 
15
  export let onEntryClick: (entry: Entry) => void;
16
  export let showOnlyOpenSource: boolean;
17
- export let voteType: string = 'render';
18
 
19
  const baseUrl = "https://huggingface.co/datasets/dylanebert/3d-arena/resolve/main/outputs";
20
  let leaderboard: Entry[] = [];
@@ -42,7 +42,9 @@
42
  };
43
 
44
  const updateFilteredLeaderboard = () => {
45
- filteredLeaderboard = showOnlyOpenSource ? leaderboard.filter((entry) => entry.open_source) : leaderboard;
 
 
46
  };
47
 
48
  $: {
@@ -64,7 +66,11 @@
64
  <div class="grid">
65
  {#each filteredLeaderboard as entry, index}
66
  <button class="grid-item" on:click={() => onEntryClick(entry)}>
67
- <img src={`${baseUrl}/${entry.name}/thumbnail.png`} alt={entry.name} class="thumbnail" />
 
 
 
 
68
  <div class="ranking">{index + 1}</div>
69
  <div class="title">{entry.displayName}</div>
70
  <div class="score-container">
 
14
 
15
  export let onEntryClick: (entry: Entry) => void;
16
  export let showOnlyOpenSource: boolean;
17
+ export let voteType: string = "render";
18
 
19
  const baseUrl = "https://huggingface.co/datasets/dylanebert/3d-arena/resolve/main/outputs";
20
  let leaderboard: Entry[] = [];
 
42
  };
43
 
44
  const updateFilteredLeaderboard = () => {
45
+ filteredLeaderboard = showOnlyOpenSource
46
+ ? leaderboard.filter((entry) => entry.open_source)
47
+ : leaderboard;
48
  };
49
 
50
  $: {
 
66
  <div class="grid">
67
  {#each filteredLeaderboard as entry, index}
68
  <button class="grid-item" on:click={() => onEntryClick(entry)}>
69
+ <img
70
+ src={`${baseUrl}/${entry.name}/thumbnail.png`}
71
+ alt={entry.name}
72
+ class="thumbnail"
73
+ />
74
  <div class="ranking">{index + 1}</div>
75
  <div class="title">{entry.displayName}</div>
76
  <div class="score-container">
src/routes/ModelDetails.svelte CHANGED
@@ -116,7 +116,9 @@
116
  {#each scenes as scene}
117
  <button class="grid-item" on:click={() => onSceneClick(scene)}>
118
  <img loading="lazy" src={scene.thumbnail} alt={scene.name} class="thumbnail" />
119
- <div class="title">{scene.name.length > 16 ? `${scene.name.slice(0, 16)}...` : scene.name}</div>
 
 
120
  </button>
121
  {/each}
122
  </div>
 
116
  {#each scenes as scene}
117
  <button class="grid-item" on:click={() => onSceneClick(scene)}>
118
  <img loading="lazy" src={scene.thumbnail} alt={scene.name} class="thumbnail" />
119
+ <div class="title">
120
+ {scene.name.length > 16 ? `${scene.name.slice(0, 16)}...` : scene.name}
121
+ </div>
122
  </button>
123
  {/each}
124
  </div>
src/routes/Vote.svelte CHANGED
@@ -91,12 +91,22 @@
91
  try {
92
  const isTopology = data.vote_type === "topology";
93
  [viewerA, viewerB] = await Promise.all([
94
- createViewer(model1_path, canvasA, (progress) => {
95
- loadingBarFillA.style.width = `${progress * 100}%`;
96
- }, isTopology),
97
- createViewer(model2_path, canvasB, (progress) => {
98
- loadingBarFillB.style.width = `${progress * 100}%`;
99
- }, isTopology),
 
 
 
 
 
 
 
 
 
 
100
  ]);
101
 
102
  if (isTopology) {
@@ -209,7 +219,6 @@
209
  window.removeEventListener("resize", handleResize);
210
  }
211
  });
212
-
213
  </script>
214
 
215
  {#if errorMessage}
 
91
  try {
92
  const isTopology = data.vote_type === "topology";
93
  [viewerA, viewerB] = await Promise.all([
94
+ createViewer(
95
+ model1_path,
96
+ canvasA,
97
+ (progress) => {
98
+ loadingBarFillA.style.width = `${progress * 100}%`;
99
+ },
100
+ isTopology,
101
+ ),
102
+ createViewer(
103
+ model2_path,
104
+ canvasB,
105
+ (progress) => {
106
+ loadingBarFillB.style.width = `${progress * 100}%`;
107
+ },
108
+ isTopology,
109
+ ),
110
  ]);
111
 
112
  if (isTopology) {
 
219
  window.removeEventListener("resize", handleResize);
220
  }
221
  });
 
222
  </script>
223
 
224
  {#if errorMessage}