rayli commited on
Commit
083aed3
·
verified ·
1 Parent(s): 084343e

Update example preview meshes

Browse files
.gitattributes CHANGED
@@ -35,3 +35,17 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  examples/000.glb filter=lfs diff=lfs merge=lfs -text
37
  examples/oven_blank.glb filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  examples/000.glb filter=lfs diff=lfs merge=lfs -text
37
  examples/oven_blank.glb filter=lfs diff=lfs merge=lfs -text
38
+ examples/001.glb filter=lfs diff=lfs merge=lfs -text
39
+ examples/002.glb filter=lfs diff=lfs merge=lfs -text
40
+ examples/003.glb filter=lfs diff=lfs merge=lfs -text
41
+ examples/004.glb filter=lfs diff=lfs merge=lfs -text
42
+ examples/005.glb filter=lfs diff=lfs merge=lfs -text
43
+ examples/006.glb filter=lfs diff=lfs merge=lfs -text
44
+ examples/render/000.png filter=lfs diff=lfs merge=lfs -text
45
+ examples/render/001.png filter=lfs diff=lfs merge=lfs -text
46
+ examples/render/002.png filter=lfs diff=lfs merge=lfs -text
47
+ examples/render/003.png filter=lfs diff=lfs merge=lfs -text
48
+ examples/render/004.png filter=lfs diff=lfs merge=lfs -text
49
+ examples/render/005.png filter=lfs diff=lfs merge=lfs -text
50
+ examples/render/006.png filter=lfs diff=lfs merge=lfs -text
51
+ instruct_particulate_1m_warning_e22a80a.png filter=lfs diff=lfs merge=lfs -text
app.py CHANGED
@@ -2,6 +2,7 @@ from __future__ import annotations
2
 
3
  import asyncio
4
  import hashlib
 
5
  import json
6
  import os
7
  import shutil
@@ -379,16 +380,49 @@ DEMO_CSS = """
379
  }
380
  .mesh-examples {
381
  flex: 0 0 auto;
382
- max-height: 180px;
383
- overflow-y: auto;
384
  border: 1px solid var(--demo-border);
385
  border-radius: 6px;
386
- padding: 6px;
387
  background: var(--demo-panel-bg);
388
  color: var(--demo-text) !important;
389
  }
390
- .mesh-examples table {
391
- margin: 0 !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  }
393
  .kin-panel {
394
  display: flex;
@@ -1467,6 +1501,34 @@ KINEMATIC_TREE_EDITOR_CSS = """
1467
  }
1468
  """
1469
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1470
  UPRIGHT_PICKER_JS = r"""
1471
  () => {
1472
  const choices = [
@@ -3033,6 +3095,14 @@ def _timestamped_mesh_output_dir(output_root: Path, mesh_hash: str, suffix: str
3033
  return output_root / "_".join(name_parts)
3034
 
3035
 
 
 
 
 
 
 
 
 
3036
  def _upright_preview_cache_dir(mesh_hash: str) -> Path:
3037
  return _mesh_cache_dir(mesh_hash) / "upright_previews"
3038
 
@@ -3934,6 +4004,17 @@ class InstructParticulateApp:
3934
  gr.update(value=None, interactive=False),
3935
  )
3936
 
 
 
 
 
 
 
 
 
 
 
 
3937
  def extract_kinematic_structure(
3938
  self,
3939
  mesh_path_value: Any,
@@ -3983,6 +4064,7 @@ class InstructParticulateApp:
3983
  auto_output_dir = output_dir / "auto_kinematics"
3984
  renders_dir = auto_output_dir / "renders"
3985
  auto_output_dir.mkdir(parents=True, exist_ok=True)
 
3986
 
3987
  mesh_geometry = self._prepare_geometry(mesh_path, canonical_up)
3988
 
@@ -4130,6 +4212,7 @@ class InstructParticulateApp:
4130
  mesh_hash = str(mesh_hash_value or _mesh_file_sha256(mesh_path))
4131
  output_dir = _timestamped_mesh_output_dir(self.output_root, mesh_hash)
4132
  output_dir.mkdir(parents=True, exist_ok=True)
 
4133
  num_query_points_value = int(num_query_points)
4134
  num_query_points_per_face_for_seg_value = (
4135
  None
@@ -4225,6 +4308,7 @@ class InstructParticulateApp:
4225
  "joint_decoding_confidence_temperature": joint_decoding_confidence_temperature_value,
4226
  },
4227
  "mesh_path": str(mesh_path),
 
4228
  "up_dir": str(canonical_up),
4229
  "output_dir": str(output_dir),
4230
  "batch": _to_cpu_payload(batch),
@@ -4364,6 +4448,7 @@ class InstructParticulateApp:
4364
  output_payload = {
4365
  "args": args_payload,
4366
  "mesh_path": str(mesh_path),
 
4367
  "up_dir": str(canonical_up),
4368
  "output_dir": str(output_dir),
4369
  "query_face_indices": np.asarray(
@@ -4401,6 +4486,7 @@ class InstructParticulateApp:
4401
 
4402
  args_payload = dict(payload["args"])
4403
  mesh_path = Path(str(payload["mesh_path"]))
 
4404
  canonical_up = str(payload["up_dir"])
4405
  output_dir = Path(str(payload["output_dir"]))
4406
  visualization_path = Path(str(payload["visualization_path"]))
@@ -4435,6 +4521,7 @@ class InstructParticulateApp:
4435
  joint_decoding_confidence_temperature=float(
4436
  args_payload["joint_decoding_confidence_temperature"]
4437
  ),
 
4438
  )
4439
  return (
4440
  str(output_dir / "animated_textured.glb"),
@@ -4608,6 +4695,7 @@ class InstructParticulateApp:
4608
  animation_frames: int,
4609
  enforce_connectivity_per_part: bool,
4610
  joint_decoding_confidence_temperature: float,
 
4611
  ) -> None:
4612
  motion_output = prediction["motion_output"]
4613
  joint_refit_sampling = prediction["joint_refit_sampling"]
@@ -4737,6 +4825,7 @@ class InstructParticulateApp:
4737
  visualization_path=visualization_path,
4738
  overparam_visualization_path=overparam_visualization_path,
4739
  optional_paths={
 
4740
  "overparam_visualization_path": overparam_visualization_path,
4741
  "urdf_export_payload_path": output_dir / "urdf_export_payload.npz",
4742
  },
@@ -4835,11 +4924,53 @@ def prepare_inference_ui():
4835
  )
4836
 
4837
 
4838
- def _example_meshes() -> list[list[str]]:
4839
  examples_dir = REPO_ROOT / "examples"
4840
- if not examples_dir.exists():
 
4841
  return []
4842
- return [[str(path)] for path in sorted(examples_dir.glob("*.glb"))]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4843
 
4844
 
4845
  def _html_attr_json(value: dict[str, Any]) -> str:
@@ -4955,15 +5086,25 @@ def create_gradio_app(app: InstructParticulateApp) -> gr.Blocks:
4955
  )
4956
  latest_output_dir = gr.State(None)
4957
  inference_payload = gr.State(None)
 
 
 
 
 
 
4958
 
4959
  with gr.Row(equal_height=True, elem_classes=["demo-row", "demo-top-row"]):
4960
  with gr.Column(scale=1, min_width=300, elem_classes=["demo-panel", "mesh-panel"]):
4961
  input_mesh = gr.Model3D(label="Input Mesh", interactive=True, height=300)
4962
  examples = _example_meshes()
4963
- examples_container = None
4964
  if examples:
4965
- with gr.Column(elem_classes=["mesh-examples"]) as examples_container:
4966
- pass
 
 
 
 
 
4967
 
4968
  with gr.Column(scale=1, min_width=300, elem_classes=["demo-panel", "kin-panel"]):
4969
  extract_button = gr.Button("Extract Kinematic Structure")
@@ -5102,29 +5243,25 @@ def create_gradio_app(app: InstructParticulateApp) -> gr.Blocks:
5102
  elem_classes=["compact-status"],
5103
  )
5104
 
5105
- if examples and examples_container is not None:
5106
- with examples_container:
5107
- gr.Examples(
5108
- examples=examples,
5109
- inputs=[input_mesh],
5110
- outputs=[
5111
- loaded_mesh_path,
5112
- loaded_mesh_hash,
5113
- mesh_face_warning,
5114
- kinematic_tree,
5115
- point_prompts,
5116
- point_prompt_mesh_data,
5117
- *upright_preview_images,
5118
- selected_up_dir,
5119
- latest_output_dir,
5120
- export_urdf_button,
5121
- urdf_zip,
5122
- ],
5123
- fn=app.register_mesh,
5124
- run_on_click=True,
5125
- cache_examples=False,
5126
- label="Examples",
5127
- )
5128
 
5129
  input_mesh.change(
5130
  fn=app.register_mesh,
@@ -5237,6 +5374,7 @@ def create_gradio_app(app: InstructParticulateApp) -> gr.Blocks:
5237
  inputs=[latest_output_dir],
5238
  outputs=[urdf_zip, urdf_status],
5239
  )
 
5240
  demo.load(fn=None, js=UPRIGHT_PICKER_JS)
5241
  demo.load(fn=None, js=KINEMATIC_TREE_EDITOR_JS)
5242
  demo.queue()
@@ -5254,5 +5392,8 @@ if __name__ == "__main__":
5254
  server_port=port,
5255
  share=share,
5256
  ssr_mode=False,
5257
- allowed_paths=[str(demo_app.output_root.resolve())],
 
 
 
5258
  )
 
2
 
3
  import asyncio
4
  import hashlib
5
+ import html
6
  import json
7
  import os
8
  import shutil
 
380
  }
381
  .mesh-examples {
382
  flex: 0 0 auto;
383
+ overflow: visible;
 
384
  border: 1px solid var(--demo-border);
385
  border-radius: 6px;
386
+ padding: 8px;
387
  background: var(--demo-panel-bg);
388
  color: var(--demo-text) !important;
389
  }
390
+ .example-preview-grid {
391
+ display: grid;
392
+ grid-template-columns: repeat(auto-fit, minmax(68px, 1fr));
393
+ gap: 8px;
394
+ }
395
+ .example-preview-button {
396
+ display: flex;
397
+ flex-direction: column;
398
+ align-items: stretch;
399
+ gap: 4px;
400
+ min-width: 0;
401
+ padding: 0;
402
+ border: 1px solid var(--demo-border);
403
+ border-radius: 6px;
404
+ background: var(--demo-panel-bg);
405
+ color: var(--demo-text);
406
+ cursor: pointer;
407
+ overflow: hidden;
408
+ }
409
+ .example-preview-button:hover,
410
+ .example-preview-button:focus-visible {
411
+ border-color: var(--demo-focus);
412
+ outline: none;
413
+ }
414
+ .example-preview-button img {
415
+ display: block;
416
+ width: 100%;
417
+ aspect-ratio: 1 / 1;
418
+ object-fit: cover;
419
+ }
420
+ .example-preview-button span {
421
+ padding: 0 6px 6px;
422
+ color: var(--demo-muted);
423
+ font-size: 12px;
424
+ line-height: 1.2;
425
+ text-align: center;
426
  }
427
  .kin-panel {
428
  display: flex;
 
1501
  }
1502
  """
1503
 
1504
+ EXAMPLE_PICKER_JS = r"""
1505
+ () => {
1506
+ function wireExamplePicker() {
1507
+ const grid = document.getElementById("example-mesh-grid");
1508
+ const indexField = document.querySelector(
1509
+ "#example_mesh_index textarea, #example_mesh_index input"
1510
+ );
1511
+ if (!grid || !indexField) {
1512
+ window.setTimeout(wireExamplePicker, 100);
1513
+ return;
1514
+ }
1515
+ grid.querySelectorAll("[data-example-index]").forEach((button) => {
1516
+ if (button.dataset.examplePickerBound === "1") {
1517
+ return;
1518
+ }
1519
+ button.dataset.examplePickerBound = "1";
1520
+ button.addEventListener("click", () => {
1521
+ indexField.value = button.dataset.exampleIndex || "";
1522
+ indexField.dispatchEvent(new Event("input", { bubbles: true }));
1523
+ indexField.dispatchEvent(new Event("change", { bubbles: true }));
1524
+ });
1525
+ });
1526
+ }
1527
+
1528
+ wireExamplePicker();
1529
+ }
1530
+ """
1531
+
1532
  UPRIGHT_PICKER_JS = r"""
1533
  () => {
1534
  const choices = [
 
3095
  return output_root / "_".join(name_parts)
3096
 
3097
 
3098
+ def _copy_original_input_mesh(mesh_path: Path, output_dir: Path) -> Path:
3099
+ suffix = mesh_path.suffix.lower() or ".mesh"
3100
+ output_path = output_dir / f"input_mesh_original{suffix}"
3101
+ output_path.parent.mkdir(parents=True, exist_ok=True)
3102
+ shutil.copy2(mesh_path, output_path)
3103
+ return output_path
3104
+
3105
+
3106
  def _upright_preview_cache_dir(mesh_hash: str) -> Path:
3107
  return _mesh_cache_dir(mesh_hash) / "upright_previews"
3108
 
 
4004
  gr.update(value=None, interactive=False),
4005
  )
4006
 
4007
+ def select_example_mesh(self, selected_index_value: Any):
4008
+ examples = _example_meshes()
4009
+ selected_index = int(str(selected_index_value).strip())
4010
+ if selected_index < 0 or selected_index >= len(examples):
4011
+ raise IndexError(
4012
+ f"Example index {selected_index} is outside the available examples."
4013
+ )
4014
+ mesh_path = examples[selected_index]["mesh_path"]
4015
+ for result in self.register_mesh(mesh_path):
4016
+ yield (mesh_path, *result)
4017
+
4018
  def extract_kinematic_structure(
4019
  self,
4020
  mesh_path_value: Any,
 
4064
  auto_output_dir = output_dir / "auto_kinematics"
4065
  renders_dir = auto_output_dir / "renders"
4066
  auto_output_dir.mkdir(parents=True, exist_ok=True)
4067
+ _copy_original_input_mesh(mesh_path, output_dir)
4068
 
4069
  mesh_geometry = self._prepare_geometry(mesh_path, canonical_up)
4070
 
 
4212
  mesh_hash = str(mesh_hash_value or _mesh_file_sha256(mesh_path))
4213
  output_dir = _timestamped_mesh_output_dir(self.output_root, mesh_hash)
4214
  output_dir.mkdir(parents=True, exist_ok=True)
4215
+ input_mesh_copy_path = _copy_original_input_mesh(mesh_path, output_dir)
4216
  num_query_points_value = int(num_query_points)
4217
  num_query_points_per_face_for_seg_value = (
4218
  None
 
4308
  "joint_decoding_confidence_temperature": joint_decoding_confidence_temperature_value,
4309
  },
4310
  "mesh_path": str(mesh_path),
4311
+ "input_mesh_copy_path": str(input_mesh_copy_path),
4312
  "up_dir": str(canonical_up),
4313
  "output_dir": str(output_dir),
4314
  "batch": _to_cpu_payload(batch),
 
4448
  output_payload = {
4449
  "args": args_payload,
4450
  "mesh_path": str(mesh_path),
4451
+ "input_mesh_copy_path": str(payload["input_mesh_copy_path"]),
4452
  "up_dir": str(canonical_up),
4453
  "output_dir": str(output_dir),
4454
  "query_face_indices": np.asarray(
 
4486
 
4487
  args_payload = dict(payload["args"])
4488
  mesh_path = Path(str(payload["mesh_path"]))
4489
+ input_mesh_copy_path = Path(str(payload["input_mesh_copy_path"]))
4490
  canonical_up = str(payload["up_dir"])
4491
  output_dir = Path(str(payload["output_dir"]))
4492
  visualization_path = Path(str(payload["visualization_path"]))
 
4521
  joint_decoding_confidence_temperature=float(
4522
  args_payload["joint_decoding_confidence_temperature"]
4523
  ),
4524
+ input_mesh_copy_path=input_mesh_copy_path,
4525
  )
4526
  return (
4527
  str(output_dir / "animated_textured.glb"),
 
4695
  animation_frames: int,
4696
  enforce_connectivity_per_part: bool,
4697
  joint_decoding_confidence_temperature: float,
4698
+ input_mesh_copy_path: Path,
4699
  ) -> None:
4700
  motion_output = prediction["motion_output"]
4701
  joint_refit_sampling = prediction["joint_refit_sampling"]
 
4825
  visualization_path=visualization_path,
4826
  overparam_visualization_path=overparam_visualization_path,
4827
  optional_paths={
4828
+ "input_mesh_original_path": input_mesh_copy_path,
4829
  "overparam_visualization_path": overparam_visualization_path,
4830
  "urdf_export_payload_path": output_dir / "urdf_export_payload.npz",
4831
  },
 
4924
  )
4925
 
4926
 
4927
+ def _example_meshes() -> list[dict[str, str]]:
4928
  examples_dir = REPO_ROOT / "examples"
4929
+ render_dir = examples_dir / "render"
4930
+ if not examples_dir.exists() or not render_dir.exists():
4931
  return []
4932
+ image_suffixes = (".png", ".jpg", ".jpeg", ".webp")
4933
+ examples: list[dict[str, str]] = []
4934
+ for mesh_path in sorted(examples_dir.glob("*.glb")):
4935
+ preview_path = next(
4936
+ (
4937
+ render_dir / f"{mesh_path.stem}{suffix}"
4938
+ for suffix in image_suffixes
4939
+ if (render_dir / f"{mesh_path.stem}{suffix}").exists()
4940
+ ),
4941
+ None,
4942
+ )
4943
+ if preview_path is None:
4944
+ continue
4945
+ examples.append(
4946
+ {
4947
+ "label": mesh_path.stem,
4948
+ "mesh_path": str(mesh_path),
4949
+ "preview_path": str(preview_path),
4950
+ }
4951
+ )
4952
+ return examples
4953
+
4954
+
4955
+ def _example_mesh_grid_html(examples: list[dict[str, str]]) -> str:
4956
+ buttons: list[str] = []
4957
+ for index, example in enumerate(examples):
4958
+ preview_path = Path(example["preview_path"]).resolve()
4959
+ label = html.escape(example["label"])
4960
+ src = html.escape(f"/file={preview_path}")
4961
+ buttons.append(
4962
+ f"""
4963
+ <button class="example-preview-button" type="button" data-example-index="{index}">
4964
+ <img src="{src}" alt="Example {label}" loading="lazy" />
4965
+ <span>{label}</span>
4966
+ </button>
4967
+ """
4968
+ )
4969
+ return f"""
4970
+ <div id="example-mesh-grid" class="example-preview-grid">
4971
+ {''.join(buttons)}
4972
+ </div>
4973
+ """
4974
 
4975
 
4976
  def _html_attr_json(value: dict[str, Any]) -> str:
 
5086
  )
5087
  latest_output_dir = gr.State(None)
5088
  inference_payload = gr.State(None)
5089
+ example_mesh_index = gr.Textbox(
5090
+ value="",
5091
+ label="Example Mesh Index",
5092
+ elem_id="example_mesh_index",
5093
+ elem_classes=["kinematic-json-sync"],
5094
+ )
5095
 
5096
  with gr.Row(equal_height=True, elem_classes=["demo-row", "demo-top-row"]):
5097
  with gr.Column(scale=1, min_width=300, elem_classes=["demo-panel", "mesh-panel"]):
5098
  input_mesh = gr.Model3D(label="Input Mesh", interactive=True, height=300)
5099
  examples = _example_meshes()
 
5100
  if examples:
5101
+ with gr.Column(elem_classes=["mesh-examples"]):
5102
+ gr.Markdown("Examples")
5103
+ gr.HTML(
5104
+ _example_mesh_grid_html(examples),
5105
+ container=False,
5106
+ padding=False,
5107
+ )
5108
 
5109
  with gr.Column(scale=1, min_width=300, elem_classes=["demo-panel", "kin-panel"]):
5110
  extract_button = gr.Button("Extract Kinematic Structure")
 
5243
  elem_classes=["compact-status"],
5244
  )
5245
 
5246
+ if examples:
5247
+ example_mesh_index.change(
5248
+ fn=app.select_example_mesh,
5249
+ inputs=[example_mesh_index],
5250
+ outputs=[
5251
+ input_mesh,
5252
+ loaded_mesh_path,
5253
+ loaded_mesh_hash,
5254
+ mesh_face_warning,
5255
+ kinematic_tree,
5256
+ point_prompts,
5257
+ point_prompt_mesh_data,
5258
+ *upright_preview_images,
5259
+ selected_up_dir,
5260
+ latest_output_dir,
5261
+ export_urdf_button,
5262
+ urdf_zip,
5263
+ ],
5264
+ )
 
 
 
 
5265
 
5266
  input_mesh.change(
5267
  fn=app.register_mesh,
 
5374
  inputs=[latest_output_dir],
5375
  outputs=[urdf_zip, urdf_status],
5376
  )
5377
+ demo.load(fn=None, js=EXAMPLE_PICKER_JS)
5378
  demo.load(fn=None, js=UPRIGHT_PICKER_JS)
5379
  demo.load(fn=None, js=KINEMATIC_TREE_EDITOR_JS)
5380
  demo.queue()
 
5392
  server_port=port,
5393
  share=share,
5394
  ssr_mode=False,
5395
+ allowed_paths=[
5396
+ str(demo_app.output_root.resolve()),
5397
+ str((REPO_ROOT / "examples").resolve()),
5398
+ ],
5399
  )
examples/000.glb CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:db84ea8faade8eacf033b18fdf5be1902f6ccef268aa3cf4ff07126e140f1b2f
3
- size 14824068
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a51d8e27b2a9d6efd4037ca9fc59928105bea0736faf3c0197a3e604fff4766c
3
+ size 27337420
examples/001.glb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1798e04c700bf8fc76473bce16ab947fa3ca9e0699d95c3d7983d3c8008ddf3d
3
+ size 20122296
examples/002.glb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3292f7f3df4e072842c6b39244f87068ed00c21af68e0f4bce2bd800f080a70f
3
+ size 27091456
examples/003.glb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fabba20d9ce4b9bc8b9169291a2acb028ddcfc7dc6d4b18cf7e5991b39682ab6
3
+ size 21317836
examples/004.glb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2f0f9aeedc00c829df3d00d3e90ab744283deb062b4a7809f7280e79c9712bc7
3
+ size 24409368
examples/005.glb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9c7229508031b80d9eb6106569938c6034030fdbaf2f0937a484aecad905d061
3
+ size 30834456
examples/006.glb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c2df757b9c5dea4cf0e6b08349754abe577075637daef745afa3a683a2ec44db
3
+ size 25199956
examples/render/000.png ADDED

Git LFS Details

  • SHA256: 144465590092ed29fe5a04791ac68fad29a9736321551ceea19aabe2d7c595d2
  • Pointer size: 131 Bytes
  • Size of remote file: 194 kB
examples/render/001.png ADDED

Git LFS Details

  • SHA256: c00a5d348cb002988382ec648b34ceffe3bf9cceba05e5a06b4656f487b9a727
  • Pointer size: 131 Bytes
  • Size of remote file: 179 kB
examples/render/002.png ADDED

Git LFS Details

  • SHA256: 95303991a60c53698e8efda28cbf03c1788a144c4e01c84e1b8803835eb19bb6
  • Pointer size: 131 Bytes
  • Size of remote file: 221 kB
examples/render/003.png ADDED

Git LFS Details

  • SHA256: 68495bdbcf8b74bd027500899afd89996e0f418645622f3496ac7d4f4962714b
  • Pointer size: 131 Bytes
  • Size of remote file: 165 kB
examples/render/004.png ADDED

Git LFS Details

  • SHA256: 1acc8323cc2583ac36f464bd59b7a0c35da7dcee4603bc5282df558ac87bf41c
  • Pointer size: 131 Bytes
  • Size of remote file: 175 kB
examples/render/005.png ADDED

Git LFS Details

  • SHA256: a76e0a61a297755b4e4071cc393714b0150ad62826f26613b9a50833b308098c
  • Pointer size: 131 Bytes
  • Size of remote file: 179 kB
examples/render/006.png ADDED

Git LFS Details

  • SHA256: 9a7602fc4c4552783983982bd47c145fa7f930b0e9377912fc5ce32847e8e563
  • Pointer size: 131 Bytes
  • Size of remote file: 167 kB
instruct_particulate_1m_warning_e22a80a.png ADDED

Git LFS Details

  • SHA256: 28b334ed64c815d437f0268ca270794ed24e0528efa4917e906c4ab832be16a7
  • Pointer size: 131 Bytes
  • Size of remote file: 170 kB