Skip to content

Commit

Permalink
ADD: animation first draft + illustration material
Browse files Browse the repository at this point in the history
  • Loading branch information
9and3 committed Dec 22, 2024
1 parent 58fc391 commit f880035
Show file tree
Hide file tree
Showing 18 changed files with 252 additions and 15 deletions.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
andre
LAPTOP-RR341PAC
Saturday, December 21, 2024
Sunday, December 22, 2024
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
andre
LAPTOP-RR341PAC
Sunday, December 22, 2024
Binary file not shown.
203 changes: 203 additions & 0 deletions assets/illustration/meshbit_illustration/moveit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
#! python3
#r: pillow
#r: Wand

import System
import System.Drawing

import math
import sys
import os

from wand.image import Image
from wand.api import library

import Rhino
import Rhino.Geometry as rg
import rhinoscriptsyntax as rs


def gaussian(x, mu, sigma):
return (1.0 / (sigma * math.sqrt(2 * math.pi))) * math.exp(-0.5 * ((x - mu) / sigma) ** 2)

def print_progress_bar(
iteration, total,
prefix='', suffix='',
decimals=1, length=10,
fill='▒', empty='■'):
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filled_length = int(length * iteration // total)
bar = fill * filled_length + empty * (length - filled_length)
Rhino.RhinoApp.SetCommandPrompt(f'{prefix} |{bar}| {percent}% {suffix}')
if iteration == total:
Rhino.RhinoApp.SetCommandPrompt(f'{prefix} |{bar}| {percent}% {suffix}\n')

def main() -> None:
#------------------------------------------------------------
# Rhin commandline options
#------------------------------------------------------------
start_log = \
">" * 60 + \
r"""
__ __ __
>-->--> .--------..-----..--.--..-----. |__|| |_ | | >-->-->
>-->--> | || _ || | || -__| | || _| |__| >-->-->
>-->--> |__|__|__||_____| \___/ |_____| |__||____| |__| >-->-->
""" + "\n" + \
"Author: @AndreaSettimi: [email protected] (IBOIS,EPFL)" + "\n" + \
"Description: Animate a mesh object in Rhino and save the animation as a gif." + "\n" + \
"Usage: Select an object to animate and set the options." + "\n" + \
">" * 60
print(start_log)

go = Rhino.Input.Custom.GetObject()
go.SetCommandPrompt("Select object to animate")
go.AcceptNothing(True)
go.ClearCommandOptions()
go.EnableHighlight(False)
__OPT_is_saving_gif = Rhino.Input.Custom.OptionToggle(False, "Off", "On")
__OPT_transparent_background = Rhino.Input.Custom.OptionToggle(True, "Off", "On")
__OPT_fps = Rhino.Input.Custom.OptionInteger(60, 0, 120)
__OPT_duration = Rhino.Input.Custom.OptionInteger(3500, 1, 10000)
_build_folder = os.path.dirname(Rhino.RhinoDoc.ActiveDoc.Path)
__OPT_width = Rhino.Input.Custom.OptionInteger(1500, 1, 5000)
__OPT_height = Rhino.Input.Custom.OptionInteger(1500, 1, 5000)
go.AddOptionToggle("isSavingGif", __OPT_is_saving_gif)
go.AddOptionToggle("TransparentBackground", __OPT_transparent_background)
go.AddOptionInteger("Fps", __OPT_fps)
go.AddOptionInteger("Duration_ms", __OPT_duration)
go.AddOption("BuildDirectory")
go.AddOptionInteger("Width", __OPT_width)
go.AddOptionInteger("Height", __OPT_height)
while True:
get_rc: Rhino.Input.GetResult = go.Get()
if go.CommandResult() == Rhino.Commands.Result.Cancel:
return go.CommandResult()
if get_rc == Rhino.Input.GetResult.Object:
break
elif get_rc == Rhino.Input.GetResult.Cancel:
return Rhino.Commands.Result.Cancel
elif get_rc == Rhino.Input.GetResult.Option:
option = go.Option().EnglishName
if option == "BuildDirectory":
folder = rs.BrowseForFolder("Select folder to save the animation")
if folder:
_build_folder = folder
continue
break

go.Get()
obj_ref = go.Object(0)
mesh = obj_ref.Mesh()

_is_saving_gif = __OPT_is_saving_gif.CurrentValue
_transparent_background = __OPT_transparent_background.CurrentValue
_fps = __OPT_fps.CurrentValue
_duration = __OPT_duration.CurrentValue # FIXME: to integrate
_width = __OPT_width.CurrentValue
_height = __OPT_height.CurrentValue
num_frames = int(_fps * (_duration / 1000))
frame_duration = int(1000 / _fps)
print("\nOptions values:")
print(f"\tSaving gif: {_is_saving_gif}")
print(f"\tTransparent background: {_transparent_background}")
print(f"\tFPS: {_fps}")
print(f"\tNumber of frames: {num_frames}")
print(f"\tFrame duration: {frame_duration}")
print(f"\tDuration: {_duration}")
print(f"\tWidth: {_width}")
print(f"\tHeight: {_height}\n")

build_folder = os.path.join(_build_folder, "build")
if os.path.exists(build_folder):
for file in os.listdir(build_folder):
os.remove(os.path.join(build_folder, file))
else:
os.makedirs(build_folder)

if _is_saving_gif:
view = Rhino.RhinoDoc.ActiveDoc.Views.ActiveView
if view is None:
raise Exception("No active view found")
view_capture = Rhino.Display.ViewCapture()
view_capture.Width = _width
view_capture.Height = _height
view_capture.ScaleScreenItems = False
view_capture.DrawAxes = False
view_capture.DrawGrid = False
view_capture.DrawGridAxes = False
view_capture.TransparentBackground = _transparent_background

#------------------------------------------------------------
# Animation + save bitmpas on memory
#------------------------------------------------------------

# FIXME: there is a small final lag/jump in the animation

# FIXME: this needs to be set as a ratio not as input (frame per sec 30fps etc)
# num_steps = 30 # << input (default: 800)
total_rotation = 360 # << input (default: 360)

mu = num_frames // 2
sigma = num_frames // 6
gaussian_values = [gaussian(x, mu, sigma) for x in range(num_frames)]
max_gaussian = max(gaussian_values)

total_angle = 0
mesh_ctr = mesh.GetBoundingBox(True).Center
for i in range(num_frames):
angle = gaussian_values[i] * total_rotation # scale the angle by the Gaussian value
total_angle += angle
xform = rg.Transform.Rotation(math.radians(angle), rg.Vector3d.ZAxis, mesh_ctr)
mesh.Transform(xform)
Rhino.RhinoDoc.ActiveDoc.Objects.Replace(obj_ref, mesh)
Rhino.RhinoDoc.ActiveDoc.Views.Redraw()
print_progress_bar(i + 1, num_frames, prefix='Animate:', suffix='Complete')

if _is_saving_gif:
bitmap = view_capture.CaptureToBitmap(view)
if bitmap is None:
raise Exception("Failed to capture view to bitmap")
bitmap.Save(os.path.join(build_folder, f"frame_{i}.png"), System.Drawing.Imaging.ImageFormat.Png)

if _fps != 1:
rs.Sleep(frame_duration)

rs.UnselectAllObjects()

#------------------------------------------------------------
# Bake gif
#------------------------------------------------------------
if _is_saving_gif:
gif_path = os.path.join(build_folder, "animation.gif")
frames = [os.path.join(build_folder, f"frame_{i}.png") for i in range(num_frames)]

with Image() as new_gif:
arg2 = library.NewPixelWand()
library.MagickSetOption(
new_gif.wand,
b"dispose",
b"2"
)
for img_path in frames:
library.MagickReadImage(
new_gif.wand,
img_path.encode('utf-8')
)
new_gif.delay = frame_duration # TODO: check if ok
print_progress_bar(frames.index(img_path) + 1, len(frames), prefix='Saving:', suffix='Complete')
rs.Sleep(1)
Rhino.RhinoApp.SetCommandPrompt("Saving gif, please wait..")
new_gif.save(filename=gif_path)

for frame in frames:
os.remove(frame)

os.system(f"start {gif_path}")
print(f"Animation saved to: {gif_path}")

print("Closing moveit.")


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<acit version="0.1.0">
<toolhead name="twist_drill_bit_32_165" type="drillbit">
<toolbase> 0 0 0 </toolbase>
<tooltip> 0 0 0.162 </tooltip>
<eattip> 0 0 0.149602 </eattip>
<chucktip> 0 0 0.0399 </chucktip>
<radius> 0.025 </radius>
</toolhead>
</acit>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- [ 9.50834990e-01, 2.37247661e-01, -1.99040413e-01, 2.44926587e-02,
-6.98316872e-01, -7.15365469e-01, -3.08712870e-01, 6.75321281e-01,
-6.69801235e-01, -2.26506889e-02, 2.32661795e-02, 1.76990986e-01 ]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Blender 3.6.0 MTL File: 'reformatter_dataset.blend'
# www.blender.org

newmtl model.004
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Ks 0.000000 0.000000 0.000000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 1
map_Kd C:/Users/localuser/TTool/assets/toolheads_rework/ck30/model.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file added docs/assets/images/getting_started/drill_anim.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/images/test/test_cat.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/changelog/index.md
Binary file not shown.
33 changes: 20 additions & 13 deletions docs/hardware/woodworking-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,35 @@ If you want to add your own 3d-printable mount or tool head model and share it w
/// html | div[style='clear: both;']
///

<!-- TODO: add drawing axo of the system of the mount on the tool with locline and camera and screen -->

## Available Toolheads

<!-- TODO: add rotating svg of the toolhead -->

The following is a list of the available toolheads that are already integrated into the AC system. You will need to use or acquire the corresponding physical toolhead to use the AC system.
## Available Toolheads

The Zenodo repository containing the dataset is [here](https://zenodo.org/records/12578820).
/// html | div[style='float: left; width: 52%;']

<!-- TODO: add icons for the type of tool -->
The following is a list of the available toolheads that are already integrated into the AC system. You will need to use or acquire the corresponding physical toolhead to use the AC system. Each toolhead is digitize and integrated to the dataset, the digital model is necessary to allow AC to detect the 3D position of the toolhead from the sensor stream. The Zenodo repository containing the dataset is [here](https://zenodo.org/records/12578820).

{{ run_python_script('docs/scripts/get_zenodo_toolheads.py') }}
!!! note "Toolhead integration"
If you want to know more about the details of the integration and how toolhead are managed in the AC system, you can read the [developer guide](../developer-guide/toolheads.md).

!!! tip "Want to add a new toolhead?"
If you want to add your own toolhead to the AC system, follow the instructions in the section [contributing](../contributing/index.md).

!!! note "Toolhead integration"
If you want to know more about the details of the integration and how toolhead are managed in the AC system, you can read the [developer guide](../developer-guide/toolheads.md).
///

/// html | div[style='float: right;width: 45%;']

![rotating model drill bit](../assets/images/getting_started/drill_anim.gif){width="500" class="rounded-corners"}

///

/// html | div[style='clear: both;']
///


{{ run_python_script('docs/scripts/get_zenodo_toolheads.py') }}

## Available 3D mounts

Expand All @@ -60,15 +70,12 @@ Each mount is designed with a flexible integration mechanism, allowing for the a

The Zenodo repository containing the dataset is [here](https://zenodo.org/records/14531724).

For convinience, here is a list of the available mounts regrouped by brands:

{{ run_python_script('docs/scripts/get_zenodo_mounts.py') }}

!!! tip "Want to add a new mount?"
If you want to add your own toolhead to the AC system, follow the instructions in the section [contributing](../contributing/index.md).

<!-- TODO: add example and images on how to integrate our prototype with the loc line and the magnet -->
{{ run_python_script('docs/scripts/get_zenodo_mounts.py') }}

<!-- TODO: add example and images on how to integrate our prototype with the loc line and the magnet -->

<!-- TODO: update -->
## Components list
Expand Down
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -272,5 +272,5 @@ nav:

- Publications: publications/index.md

- Team:
- Research team:
- team/index.md

0 comments on commit f880035

Please sign in to comment.