Skip to content

Commit

Permalink
Merge pull request #257 from Yanis42/addpath_improvements
Browse files Browse the repository at this point in the history
[OoT] Improved "Add Path" button
  • Loading branch information
sauraen authored Dec 25, 2023
2 parents beb5531 + 0c7ccba commit 0e25276
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 7 deletions.
74 changes: 73 additions & 1 deletion fast64_internal/oot/oot_utility.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import bpy, math, os, re
import bpy
import math
import os
import re

from ast import parse, Expression, Num, UnaryOp, USub, Invert, BinOp
from mathutils import Vector
from bpy.types import Object
from bpy.utils import register_class, unregister_class
from typing import Callable
Expand Down Expand Up @@ -869,3 +874,70 @@ def _eval(node):
raise ValueError(f"Unsupported AST node {node}")

return f"0x{_eval(node.body):X}"


def getNewPath(type: str, isClosedShape: bool):
"""
Returns a new Curve Object with the selected spline shape
Parameters:
- ``type``: the path's type (square, line, etc)
- ``isClosedShape``: choose if the spline should have an extra point to make a closed shape
"""

# create a new curve
newCurve = bpy.data.curves.new("New Path", "CURVE")
newCurve.dimensions = "3D"

# add a new spline to the curve
newSpline = newCurve.splines.new("NURBS") # comes with 1 point

# generate shape based on 'type' parameter
scaleDivBy2 = bpy.context.scene.ootBlenderScale / 2
match type:
case "Line":
newSpline.points.add(1)
for i, point in enumerate(newSpline.points):
point.co.x = i * bpy.context.scene.ootBlenderScale
point.co.w = 1
case "Triangle":
newSpline.points.add(2)
for i, point in enumerate(newSpline.points):
point.co.x = i * scaleDivBy2
if i == 1:
point.co.y = (len(newSpline.points) * scaleDivBy2) / 2
point.co.w = 1
case "Square" | "Trapezium":
newSpline.points.add(3)
for i, point in enumerate(newSpline.points):
point.co.x = i * scaleDivBy2
if i in [1, 2]:
if type == "Square":
point.co.y = (len(newSpline.points) - 1) * scaleDivBy2
if i == 1:
point.co.x = newSpline.points[0].co.x
else:
point.co.x = point.co.y
else:
point.co.y = 1 * scaleDivBy2
point.co.w = 1
case _:
raise PluginError("ERROR: Invalid Path Type!")

if isClosedShape and type != "Line":
newSpline.points.add(1)
newSpline.points[-1].co = newSpline.points[0].co

# make the curve's display accurate to the point's shape
newSpline.use_cyclic_u = True
newSpline.use_endpoint_u = False
newSpline.resolution_u = 64
newSpline.order_u = 2

# create a new object and add the curve as data
newPath = bpy.data.objects.new("New Path", newCurve)
newPath.show_name = True
newPath.location = Vector(bpy.context.scene.cursor.location)
bpy.context.view_layer.active_layer_collection.collection.objects.link(newPath)

return newPath
38 changes: 32 additions & 6 deletions fast64_internal/oot/tools/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
from mathutils import Vector
from bpy.ops import mesh, object, curve
from bpy.types import Operator, Object, Context
from bpy.props import FloatProperty, StringProperty
from bpy.props import FloatProperty, StringProperty, EnumProperty, BoolProperty
from ...operators import AddWaterBox, addMaterialByName
from ...utility import parentObject, setOrigin
from ..cutscene.motion.utility import setupCutscene, createNewCameraShot
from ..oot_utility import getNewPath


class OOT_AddWaterBox(AddWaterBox):
Expand Down Expand Up @@ -181,23 +182,48 @@ def draw(self, context):
class OOT_AddPath(Operator):
bl_idname = "object.oot_add_path"
bl_label = "Add Path"
bl_options = {"REGISTER", "UNDO", "PRESET"}
bl_options = {"REGISTER", "UNDO"}

isClosedShape: BoolProperty(name="", default=True)
pathType: EnumProperty(
name="",
items=[
("Line", "Line", "Line"),
("Square", "Square", "Square"),
("Triangle", "Triangle", "Triangle"),
("Trapezium", "Trapezium", "Trapezium"),
],
default="Line",
)

def execute(self, context):
if context.mode != "OBJECT":
object.mode_set(mode="OBJECT")
object.select_all(action="DESELECT")

location = Vector(context.scene.cursor.location)
curve.primitive_nurbs_path_add(radius=1, align="WORLD", location=location[:])
pathObj = context.view_layer.objects.active
pathObj.name = "New Path"
pathObj = getNewPath(self.pathType, self.isClosedShape)
activeObj = context.view_layer.objects.active
if activeObj.type == "EMPTY" and activeObj.ootEmptyType == "Scene":
pathObj.parent = activeObj

object.select_all(action="DESELECT")
pathObj.select_set(True)
context.view_layer.objects.active = pathObj
return {"FINISHED"}

def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self, width=320)

def draw(self, context):
layout = self.layout
layout.label(text="Path Settings")
props = [("Path Type", "pathType"), ("Closed Shape", "isClosedShape")]

for desc, propName in props:
split = layout.split(factor=0.30)
split.label(text=desc)
split.prop(self, propName)


class OOTClearTransformAndLock(Operator):
bl_idname = "object.oot_clear_transform"
Expand Down

0 comments on commit 0e25276

Please sign in to comment.