From 82dd01f0db1948f647744d7ca5e2b5fdc69821b0 Mon Sep 17 00:00:00 2001 From: Hykilpikonna Date: Wed, 15 Mar 2023 20:14:20 -0400 Subject: [PATCH] [+] Macro to fill notes --- models/make.FCMacro | 68 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 models/make.FCMacro diff --git a/models/make.FCMacro b/models/make.FCMacro new file mode 100644 index 0000000..054a7aa --- /dev/null +++ b/models/make.FCMacro @@ -0,0 +1,68 @@ +doc = App.activeDocument() + +# Get the base object (C2) +# Naming format: - +c2 = doc.getObjectsByLabel('C2-Base')[0] + +# Create a list of notes from C2 to C7 +notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"] +notes = [f"{k}{str(oct)}" for oct in range(2, 8) for k in notes] +notes = notes[notes.index("C2"):notes.index("C7") + 1] +non_sharp = [note for note in notes if "#" not in note] + +MIN_WIDTH = 78 +MAX_WIDTH = 194 + + +# Calculate position offset for a note +def calc_pos_offset(note: str): + is_sharp = "#" in note + + # Find the index of the note in the list of non-sharp notes + note_index = non_sharp.index(note.replace("#", "")) + + # If it's a sharp note, place it in between the note and the previous note + if is_sharp: + note_index += 0.5 + + # Calculate the offset + return 37 * note_index + + +# Loop through C#2 to C7 +for i, note in enumerate(notes): + if i == 0: + continue + + is_sharp = "#" in note + + # Create a copy of the base object + copy: list[fc.Part] = list(doc.copyObject(c2, True, True)) + + # Since freecad will automatically name the copy ORIGINAL001, we need to rename it + for obj in copy: + obj.Label = obj.Label.replace('C2', note).replace("001", "") + + def find_ends_with(label: str) -> fc.Part: + return [obj for obj in copy if obj.Label.endswith(label)][0] + + # Find the objects by label + base, cube, hole = [find_ends_with(label) for label in ["Base", "Cube", "Hole"]] + + # Make the cube wider + # width = MIN_WIDTH + (MAX_WIDTH - MIN_WIDTH) * ((len(notes) - i) / len(notes)) + x = len(notes) - i - 1 + # Calculate width with a quadratic function 0.022172619047619x^2 + 0.60297619047619x + 78 + width = 0.016592261904762 * x ** 2 + 0.93779761904762 * x + 78 + cube.Width = fc.Units.Quantity(f"{width} mm") + + # The hole's y placement should be width - width / 4.2 + plac: list[float] = list(hole.Placement.Base) + plac[1] = width - width / 4.2 + hole.Placement.Base = App.Vector(*plac) + + # Move the base object. For sharp notes, move it to the top + y = MAX_WIDTH - 6 if is_sharp else MAX_WIDTH - width + base.Placement.move(App.Vector(calc_pos_offset(note), y, 0)) + + doc.recompute() \ No newline at end of file