Skip to content
This repository was archived by the owner on Apr 24, 2025. It is now read-only.

Commit 830f0c1

Browse files
Merge pull request #722 from ibra-kdbra/ibra-kdbra
Ibra kdbra
2 parents 2f05e9c + a48c735 commit 830f0c1

31 files changed

Lines changed: 4238 additions & 0 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ ipython_config.py
8686
# For a library or package, you might want to ignore these files since the code is
8787
# intended to run in multiple environments; otherwise, check them in:
8888
# .python-version
89+
path/
8990

9091
# pipenv
9192
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from nltk.corpus import wordnet
2+
import nltk
3+
import re
4+
import json
5+
6+
nltk.download('wordnet', quiet=True)
7+
8+
# Load irregular adjectives from a JSON file
9+
with open('irregular_adjectives.json', 'r') as f:
10+
IRREGULAR_ADJECTIVES = json.load(f)
11+
12+
13+
def get_comp_sup(adjs):
14+
comp_sup = []
15+
16+
for adj in adjs:
17+
synsets = wordnet.synsets(adj, pos=wordnet.ADJ)
18+
if synsets:
19+
syn = synsets[0]
20+
comp_forms = [lemma.name().replace('_', ' ')
21+
for lemma in syn.lemmas()]
22+
if len(comp_forms) >= 2:
23+
comp_form = comp_forms[1]
24+
else:
25+
comp_form = get_comparative_form(adj)
26+
if len(comp_forms) >= 3:
27+
superl_form = comp_forms[2]
28+
else:
29+
superl_form = get_superlative_form(adj)
30+
comp_sup.append((adj, comp_form, superl_form))
31+
else:
32+
comp_sup.append((adj, get_comparative_form(adj), get_superlative_form(adj)))
33+
34+
return comp_sup
35+
36+
37+
def get_comparative_form(adj):
38+
if adj in IRREGULAR_ADJECTIVES:
39+
return IRREGULAR_ADJECTIVES[adj][0]
40+
elif re.match(r"^[aeiou][a-z]*$", adj):
41+
return adj + "er"
42+
else:
43+
return "more " + adj
44+
45+
46+
def get_superlative_form(adj):
47+
if adj in IRREGULAR_ADJECTIVES:
48+
return IRREGULAR_ADJECTIVES[adj][1]
49+
elif re.match(r"^[aeiou][a-z]*$", adj):
50+
return adj + "est"
51+
else:
52+
return "most " + adj
53+
54+
55+
def main():
56+
adjs = input("Enter a list of adjectives (comma-separated): ").split(',')
57+
adjs = [adj.strip() for adj in adjs]
58+
59+
comp_sup = get_comp_sup(adjs)
60+
61+
print("\nAdjective\tComparative\tSuperlative")
62+
print("------------------------------------------")
63+
for adj, c, s in comp_sup:
64+
print(f"{adj}\t\t{c}\t\t{s}")
65+
66+
67+
if __name__ == "__main__":
68+
main()
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"good": ["better", "best"],
3+
"fat":["fatter", "fattest"],
4+
"nice":["nice", "nicest"],
5+
"bad": ["worse", "worst"],
6+
"little": ["less", "least"],
7+
"much": ["more", "most"],
8+
"many": ["more", "most"],
9+
"far": ["further", "furthest"],
10+
"old": ["older", "oldest"],
11+
"late": ["later", "latest"],
12+
"early": ["earlier", "earliest"],
13+
"well": ["better", "best"],
14+
"ill": ["worse", "worst"],
15+
"near": ["nearer", "nearest"],
16+
"low": ["lower", "lowest"],
17+
"high": ["higher", "highest"],
18+
"deep": ["deeper", "deepest"],
19+
"long": ["longer", "longest"],
20+
"short": ["shorter", "shortest"],
21+
"wide": ["wider", "widest"],
22+
"narrow": ["narrower", "narrowest"],
23+
"big": ["bigger", "biggest"],
24+
"small": ["smaller", "smallest"],
25+
"young": ["younger", "youngest"],
26+
"full": ["fuller", "fullest"],
27+
"hot": ["hotter", "hottest"],
28+
"cold": ["colder", "coldest"],
29+
"happy": ["happier", "happiest"],
30+
"sad": ["sadder", "saddest"],
31+
"easy": ["easier", "easiest"],
32+
"hard": ["harder", "hardest"],
33+
"heavy": ["heavier", "heaviest"],
34+
"light": ["lighter", "lightest"],
35+
"fast": ["faster", "fastest"],
36+
"slow": ["slower", "slowest"],
37+
"strong": ["stronger", "strongest"],
38+
"weak": ["weaker", "weakest"],
39+
"rich": ["richer", "richest"],
40+
"poor": ["poorer", "poorest"],
41+
"dirty": ["dirtier", "dirtiest"],
42+
"clean": ["cleaner", "clearest"],
43+
"new": ["newer", "newest"]
44+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nltk

projects/Advisor/advisor.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Importing libraries
2+
import requests
3+
import tkinter as tk
4+
from tkinter import messagebox
5+
6+
# Fetching advice from the advice api
7+
8+
9+
def advice():
10+
try:
11+
res = requests.get("https://api.adviceslip.com/advice").json()
12+
advice_text.set(res["slip"]["advice"])
13+
except requests.exceptions.RequestException:
14+
messagebox.showerror(
15+
"Error", "Failed to fetch advice. Please check your internet connection.")
16+
17+
18+
# Create the main window
19+
root = tk.Tk()
20+
root.title("Random Advisor Application")
21+
22+
# Create and configure widgets
23+
advice_text = tk.StringVar()
24+
advice_label = tk.Label(root, textvariable=advice_text,
25+
wraplength=400, font=("Arial", 14))
26+
get_advice_button = tk.Button(root, text="Get Advice", command=advice)
27+
28+
# Pack widgets
29+
advice_label.pack(pady=20)
30+
get_advice_button.pack(pady=10)
31+
32+
# Initial advice fetching
33+
advice()
34+
35+
# Run the main event loop
36+
root.mainloop()

projects/Blender_tools/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/venv
2+
/.vscode

projects/Blender_tools/README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Blender Tools with Unreal/Unity
2+
3+
## Description
4+
5+
A series of tools used to store vertex data in various ways. The data can then used in a game engine to animate meshes via a vertex shader.
6+
7+
### Mesh Morpher
8+
9+
Used to store vertex offsets between a meshes shape keys in it's UV layers. Optionally vertex normals from it's second shape key can be stored in it's vertex colors.
10+
11+
### Vertex Animation
12+
13+
Used to store vertex offsets and normals of selected mesh objects per frame into image textures.
14+
15+
## Getting Started
16+
17+
These tools can be installed as add-ons or ran as scripts. Each tool has a panel located in the 3D View's sidebar under the Unreal Tools tab.
18+
19+
### Installing as an Add-on
20+
21+
* First download and unzip files into desired directory.
22+
23+
* While in Blender open the user preferences window.
24+
25+
**Edit > Preferences**
26+
27+
* Navigate the the **add-ons** tab.
28+
29+
* Click the option to **install**.
30+
31+
* A file browser will open.
32+
33+
* Navigate to directory containing the tools.
34+
35+
* Select the tool you want install.
36+
37+
* Then click **install add-on**.
38+
39+
### Running as a Script
40+
41+
* First download and unzip files into desired directory.
42+
43+
* While in Blender use the text editor to open the tool you want to use.
44+
45+
* Then either click the run script operator (the **arrow** icon in header) or use **alt+p** shortcut.
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
bl_info = {
2+
"name": "Mesh Morpher",
3+
"author": "ibra-kdbra",
4+
"version": (1, 0),
5+
"blender": (4, 0, 1),
6+
"location": "View3D > Sidebar > Unreal Tools Tab",
7+
"description": "A tool for storing shape key data for use in a vertex shader.",
8+
"warning": "",
9+
"doc_url": "",
10+
"category": "Unreal Tools",
11+
}
12+
13+
14+
import bpy
15+
16+
17+
def pack_normals(me):
18+
"""Stores normals in a given mesh's vertex colors"""
19+
if not me.vertex_colors:
20+
me.vertex_colors.new()
21+
col = me.vertex_colors[0]
22+
col.name = "normals"
23+
key = me.shape_keys.key_blocks[1]
24+
normals = list(zip(*[iter(key.normals_vertex_get())]*3))
25+
for loop in me.loops:
26+
r, g, b = normals[loop.vertex_index]
27+
col.data[loop.index].color = ((r + 1) * 0.5, (-g + 1) * 0.5, (b + 1) * 0.5, 1)
28+
29+
30+
def get_shape_key_offsets(shape_keys, two_shape_keys=False):
31+
"""Return a list of vertex offsets between shape keys"""
32+
keys = shape_keys.key_blocks
33+
offsets = []
34+
original = keys[0].data
35+
target = keys[1].data
36+
offset = [v1.co - v2.co for v1, v2 in zip(target, original)]
37+
offsets.append(offset)
38+
if two_shape_keys:
39+
target = keys[2].data
40+
offset = [v1.co - v2.co for v1, v2 in zip(target, original)]
41+
offsets.append(offset)
42+
return offsets
43+
44+
45+
def pack_offsets(ob, offsets):
46+
"""Stores shape key vertex offsets in mesh's UVs"""
47+
me = ob.data
48+
while len(me.uv_layers) < 4:
49+
me.uv_layers.new()
50+
for loop in me.loops:
51+
x1, y1, z1 = offsets[0][loop.vertex_index]
52+
if len(offsets) > 1:
53+
offset = offsets[1][loop.vertex_index]
54+
else:
55+
offset = ob.location
56+
x2, y2, z2 = offset
57+
me.uv_layers[1].data[loop.index].uv = (x2, 1 - (-y2))
58+
me.uv_layers[2].data[loop.index].uv = (z2, 1 - x1)
59+
me.uv_layers[3].data[loop.index].uv = (-y1, 1 - z1)
60+
61+
62+
class MeshMorpherSettings(bpy.types.PropertyGroup):
63+
store_shape_key1_normals: bpy.props.BoolProperty(
64+
name="First Shape Key Normals",
65+
description="Store first shape key's vertex normals in vertex colors",
66+
default=True
67+
)
68+
two_shape_keys: bpy.props.BoolProperty(
69+
name="Two Shape Keys",
70+
description="Store vertex offsets for first and second shape keys",
71+
default=False
72+
)
73+
74+
75+
class OBJECT_OT_ProcessShapeKeys(bpy.types.Operator):
76+
"""Store object's shape key offsets in it's UV layers"""
77+
bl_idname = "object.process_shape_keys"
78+
bl_label = "Process Shape Keys"
79+
80+
store_shape_key1_normals: bpy.props.BoolProperty(
81+
name="First Shape Key Normals",
82+
default=True
83+
)
84+
two_shape_keys: bpy.props.BoolProperty(
85+
name="Two Shape Keys",
86+
default=False
87+
)
88+
89+
@classmethod
90+
def poll(cls, context):
91+
ob = context.active_object
92+
return ob and ob.type == 'MESH' and ob.mode == 'OBJECT'
93+
94+
95+
def execute(self, context):
96+
units = context.scene.unit_settings
97+
ob = context.object
98+
shape_keys = ob.data.shape_keys
99+
if units.system != 'METRIC' or round(units.scale_length, 2) != 0.01:
100+
self.report(
101+
{'ERROR'},
102+
"Scene Units must be Metric with a Unit Scale of 0.01!"
103+
)
104+
return {'CANCELLED'}
105+
if not shape_keys:
106+
self.report({'ERROR'}, "Object has no shape keys!")
107+
return {'CANCELLED'}
108+
if len(shape_keys.key_blocks) < 2 + self.two_shape_keys:
109+
self.report({'ERROR'}, "Object needs additional shape keys!")
110+
return {'CANCELLED'}
111+
if self.store_shape_key1_normals:
112+
pack_normals(ob.data)
113+
offsets = get_shape_key_offsets(shape_keys, self.two_shape_keys)
114+
pack_offsets(ob, offsets)
115+
return {'FINISHED'}
116+
117+
118+
class VIEW3D_PT_MeshMorpher(bpy.types.Panel):
119+
"""Creates a Panel in 3D Viewport"""
120+
bl_label = "Mesh Morpher"
121+
bl_idname = "VIEW3D_PT_mesh_morpher"
122+
bl_space_type = 'VIEW_3D'
123+
bl_region_type = 'UI'
124+
bl_category = "Unreal Tools"
125+
126+
def draw(self, context):
127+
layout = self.layout
128+
col = layout.column()
129+
props = context.scene.mesh_morpher_settings
130+
col.prop(props, "store_shape_key1_normals")
131+
col.prop(props, "two_shape_keys")
132+
op = col.operator("object.process_shape_keys")
133+
op.store_shape_key1_normals = props.store_shape_key1_normals
134+
op.two_shape_keys = props.two_shape_keys
135+
136+
137+
def register():
138+
bpy.utils.register_class(MeshMorpherSettings)
139+
bpy.utils.register_class(OBJECT_OT_ProcessShapeKeys)
140+
bpy.utils.register_class(VIEW3D_PT_MeshMorpher)
141+
bpy.types.Scene.mesh_morpher_settings = bpy.props.PointerProperty(
142+
type=MeshMorpherSettings
143+
)
144+
145+
146+
def unregister():
147+
bpy.utils.unregister_class(MeshMorpherSettings)
148+
bpy.utils.unregister_class(OBJECT_OT_ProcessShapeKeys)
149+
bpy.utils.unregister_class(VIEW3D_PT_MeshMorpher)
150+
del bpy.types.Scene.mesh_morpher_settings
151+
152+
153+
if __name__ == "__main__":
154+
register()

0 commit comments

Comments
 (0)