From 6a7e9d2fa3f94d3fa7704af0f373b3a2dcd5ce3e Mon Sep 17 00:00:00 2001 From: Pzaff Date: Mon, 9 Oct 2017 18:29:49 -0400 Subject: [PATCH 1/3] Added a work in progress version of the command line parser. Doesn't fully work at this point. --- curve_data_objects/__init__.py | 0 curve_data_objects/straight_curve.py | 10 + curves/TJP-4_1_stick-unknot-halved-1.curve | 33 ++ curves/TJP-4_1_stick-unknot-halved-2.curve | 65 +++ curves/TJP-4_1_stick-unknot-halved-3.curve | 130 ++++++ curves/TJP-4_1_stick-unknot.curve | 16 + curves/TJP-4_1_stick-unknot_TEST.curve | 28 ++ curves/TJP-4th-C1-high-precision.curve | 194 +++++++++ curves/test.curve | 17 + data_objects/stick_knot.py | 3 +- generator/__init__.py | 0 generator/parser.py | 33 ++ run.sh | 5 + subdivision_generator_orig_pyth_3_6.py | 462 +++++++++++++++++++++ user_interface/cli.py | 32 -- user_interface/cli_application.py | 50 +++ user_interface/gui.py | 2 +- 17 files changed, 1045 insertions(+), 35 deletions(-) create mode 100644 curve_data_objects/__init__.py create mode 100644 curve_data_objects/straight_curve.py create mode 100644 curves/TJP-4_1_stick-unknot-halved-1.curve create mode 100644 curves/TJP-4_1_stick-unknot-halved-2.curve create mode 100644 curves/TJP-4_1_stick-unknot-halved-3.curve create mode 100644 curves/TJP-4_1_stick-unknot.curve create mode 100644 curves/TJP-4_1_stick-unknot_TEST.curve create mode 100644 curves/TJP-4th-C1-high-precision.curve create mode 100644 curves/test.curve create mode 100644 generator/__init__.py create mode 100644 generator/parser.py create mode 100755 run.sh create mode 100644 subdivision_generator_orig_pyth_3_6.py delete mode 100644 user_interface/cli.py create mode 100755 user_interface/cli_application.py diff --git a/curve_data_objects/__init__.py b/curve_data_objects/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/curve_data_objects/straight_curve.py b/curve_data_objects/straight_curve.py new file mode 100644 index 0000000..c3d2892 --- /dev/null +++ b/curve_data_objects/straight_curve.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +""" +@author Peter Zaffetti 2017 +""" + +class StraightCurve: + + def __init__(self, curve_points): + pass + diff --git a/curves/TJP-4_1_stick-unknot-halved-1.curve b/curves/TJP-4_1_stick-unknot-halved-1.curve new file mode 100644 index 0000000..16f6d44 --- /dev/null +++ b/curves/TJP-4_1_stick-unknot-halved-1.curve @@ -0,0 +1,33 @@ + 1.307600000000000, -3.332000000000000, -2.507200000000000 + +-0.0765185, 0.67527525, -0.7968295 + + -1.384118500000000, 4.682550500000000, 0.913541000000000 +-1.44393425, 4.40945025, 0.9689405 + + +-1.50375, 4.13635, 1.02434 +-2.40102875, 0.03983375, 1.8552645 + + +-3.2983075,-4.0566825,2.686189 +-1.7108035, -0.64421425, 0.1113025 + + +-0.1232995,2.768254,-2.463584 +1.892346, -0.8825515, -0.61860675 + + +3.9079915,-4.533357,1.2263705 +-0.01399575, -2.4858145, 0.12150275 + + +-3.935983,-0.438272,-0.983365 +-0.3589045, 1.9289255, 0.56454725 + + +3.218174000000000, 4.296123000000000, 2.112459500000000 +2.262887, 0.4820615, -0.19737025 + + +1.307600000000000, -3.332000000000000, -2.507200000000000 diff --git a/curves/TJP-4_1_stick-unknot-halved-2.curve b/curves/TJP-4_1_stick-unknot-halved-2.curve new file mode 100644 index 0000000..083c2bd --- /dev/null +++ b/curves/TJP-4_1_stick-unknot-halved-2.curve @@ -0,0 +1,65 @@ + 1.307600000000000, -3.332000000000000, -2.507200000000000 + +0.634670375,-1.328362375,-1.65201475 + +-0.03825925,0.67527525,-0.7968295 +-0.711188875,2.678912875,0.05835575 + + + -1.384118500000000, 4.682550500000000, 0.913541000000000 +-1.414026375,4.546000375,0.94124075 + + +-1.44393425,4.40945025,0.9689405 +-1.473842125,4.272900125,0.99664025 + + +-1.50375,4.13635,1.02434 +-1.952389375,2.088091875,1.43980225 + + +-2.40102875,0.03983375,1.8552645 +-2.849668125,-2.008424375,2.27072675 + + +-3.2983075,-4.0566825,2.686189 +-2.5045555,-2.350448375,1.39874575 + + +-1.7108035,-0.64421425,0.1113025 +-0.9170515,1.062019875,-1.17614075 + + +-0.1232995,2.768254,-2.463584 +0.88452325,0.94285125,-1.541095375 + + +1.892346,-0.8825515,-0.61860675 +2.90016875,-2.70795425,0.303881875 + + +3.9079915,-4.533357,1.2263705 +1.946997875,-3.50958575,0.673936625 + + +-0.01399575,-2.4858145,0.12150275 +-1.974989375,-1.46204325,-0.430931125 + + +-3.935983,-0.438272,-0.983365 +-2.14744375,0.74532675,-0.209408875 + + +-0.3589045,1.9289255,0.56454725 +1.42963475,3.11252425,1.338503375 + + +3.218174000000000, 4.296123000000000, 2.112459500000000 +2.7405305,2.38909225,0.957544625 + + +2.262887,0.4820615,-0.19737025 +1.7852435,-1.42496925,-1.352285125 + + +1.307600000000000, -3.332000000000000, -2.507200000000000 diff --git a/curves/TJP-4_1_stick-unknot-halved-3.curve b/curves/TJP-4_1_stick-unknot-halved-3.curve new file mode 100644 index 0000000..92bb3e9 --- /dev/null +++ b/curves/TJP-4_1_stick-unknot-halved-3.curve @@ -0,0 +1,130 @@ + 1.307600000000000, -3.332000000000000, -2.507200000000000 + +0.9711351875,-2.3301811875,-2.079607375 + +0.634670375,-1.328362375,-1.65201475 +0.2982055625,-0.3265435625,-1.224422125 + + +-0.03825925,0.67527525,-0.7968295 +-0.3747240625,1.6770940625,-0.369236875 + + +-0.711188875,2.678912875,0.05835575 +-1.0476536875,3.6807316875,0.485948375 + + + -1.384118500000000, 4.682550500000000, 0.913541000000000 +-1.3990724375,4.6142754375,0.927390875 + + +-1.414026375,4.546000375,0.94124075 +-1.4289803125,4.4777253125,0.955090625 + + +-1.44393425,4.40945025,0.9689405 +-1.4588881875,4.3411751875,0.982790375 + + +-1.473842125,4.272900125,0.99664025 +-1.4887960625,4.2046250625,1.010490125 + + +-1.50375,4.13635,1.02434 +-1.7280696875,3.1122209375,1.232071125 + + +-1.952389375,2.088091875,1.43980225 +-2.1767090625,1.0639628125,1.647533375 + + +-2.40102875,0.03983375,1.8552645 +-2.6253484375,-0.9842953125,2.062995625 + + +-2.849668125,-2.008424375,2.27072675 +-3.0739878125,-3.0325534375,2.478457875 + + +-3.2983075,-4.0566825,2.686189 +-2.9014315,-3.2035654375,2.042467375 + + +-2.5045555,-2.350448375,1.39874575 +-2.1076795,-1.4973313125,0.755024125 + + +-1.7108035,-0.64421425,0.1113025 +-1.3139275,0.2089028125,-0.532419125 + + +-0.9170515,1.062019875,-1.17614075 +-0.5201755,1.9151369375,-1.819862375 + + +-0.1232995,2.768254,-2.463584 +0.380611875,1.855552625,-2.0023396875 + + +0.88452325,0.94285125,-1.541095375 +1.388434625,0.030149875,-1.0798510625 + + +1.892346,-0.8825515,-0.61860675 +2.396257375,-1.795252875,-0.1573624375 + + +2.90016875,-2.70795425,0.303881875 +3.404080125,-3.620655625,0.7651261875 + + +3.9079915,-4.533357,1.2263705 +2.9274946875,-4.021471375,0.9501535625 + + +1.946997875,-3.50958575,0.673936625 +0.9665010625,-2.997700125,0.3977196875 + + +-0.01399575,-2.4858145,0.12150275 +-0.9944925625,-1.973928875,-0.1547141875 + + +-1.974989375,-1.46204325,-0.430931125 +-2.9554861875,-0.950157625,-0.7071480625 + + +-3.935983,-0.438272,-0.983365 +-3.041713375,0.153527375,-0.5963869375 + + +-2.14744375,0.74532675,-0.209408875 +-1.253174125,1.337126125,0.1775691875 + + +-0.3589045,1.9289255,0.56454725 +0.535365125,2.520724875,0.9515253125 + + +1.42963475,3.11252425,1.338503375 +2.323904375,3.704323625,1.7254814375 + + +3.218174000000000, 4.296123000000000, 2.112459500000000 +2.97935225,3.342607625,1.5350020625 + + +2.7405305,2.38909225,0.957544625 +2.50170875,1.435576875,0.3800871875 + + +2.262887,0.4820615,-0.19737025 +2.02406525,-0.471453875,-0.7748276875 + + +1.7852435,-1.42496925,-1.352285125 +1.54642175,-2.378484625,-1.9297425625 + + +1.307600000000000, -3.332000000000000, -2.507200000000000 + diff --git a/curves/TJP-4_1_stick-unknot.curve b/curves/TJP-4_1_stick-unknot.curve new file mode 100644 index 0000000..e1d9f92 --- /dev/null +++ b/curves/TJP-4_1_stick-unknot.curve @@ -0,0 +1,16 @@ + %ignore me + 1.307600000000000, -3.332000000000000, -2.507200000000000 + -1.384118500000000, 4.682550500000000, 0.913541000000000 + + + +-3.2983075,-4.0566825,2.686189 + +-0.1232995,2.768254,-2.463584 + +3.9079915,-4.533357,1.2263705 + +-3.935983,-0.438272,-0.983365 + +3.218174000000000, 4.296123000000000, 2.112459500000000 + diff --git a/curves/TJP-4_1_stick-unknot_TEST.curve b/curves/TJP-4_1_stick-unknot_TEST.curve new file mode 100644 index 0000000..c7f3fb2 --- /dev/null +++ b/curves/TJP-4_1_stick-unknot_TEST.curve @@ -0,0 +1,28 @@ +1.3076, -3.332, -2.5072 + +-0.038259268, 0.6752752, -0.79682946 + +-1.3841186, 4.6825504, 0.913541 + +-2.341213, 0.31293392, 1.799865 + +-3.2983074, -4.0566826, 2.686189 + +-1.7108035, -0.6442143, 0.111302495 + +-0.1232995, 2.768254, -2.463584 + +1.8923459, -0.88255155, -0.61860675 + +3.9079914, -4.533357, 1.2263705 + +-0.013995767, -2.4858146, 0.12150273 + +-3.935983, -0.438272, -0.983365 + +-0.35890448, 1.9289255, 0.5645472 + +3.218174, 4.296123, 2.1124594 + +2.262887, 0.4820615, -0.19737029 + diff --git a/curves/TJP-4th-C1-high-precision.curve b/curves/TJP-4th-C1-high-precision.curve new file mode 100644 index 0000000..1ac6bbb --- /dev/null +++ b/curves/TJP-4th-C1-high-precision.curve @@ -0,0 +1,194 @@ + 1.28318923, -2.84316645, -2.25593748 + 1.139367593750000, -2.831090593750000, -2.293403687500000 + 0.971135187500000, -2.330181187500000, -2.079607375000000 + 0.802902781250000, -1.829271781250000, -1.865811062500000 + 0.634670375000000, -1.328362375000000, -1.652014750000000 + 0.466437968750000, -0.827452968750000, -1.438218437500000 + 0.298205562500000, -0.326543562500000, -1.224422125000000 + 0.129973156250000, 0.174365843750000, -1.010625812500000 + -0.038259250000000, 0.675275250000000, -0.796829500000000 + -0.206491656250000, 1.176184656250000, -0.583033187500000 + -0.374724062500000, 1.677094062500000, -0.369236875000000 + -0.542956468750000, 2.178003468750000, -0.155440562500000 + -0.711188875000000, 2.678912875000000, 0.058355750000000 + -0.879421281250000, 3.179822281250000, 0.272152062500000 + -1.047653687500000, 3.680731687500000, 0.485948375000000 + -1.215886093750000, 4.181641093750000, 0.699744687500000 + -1.384118500000000, 4.682550500000000, 0.913541000000000 + +-1.50375, 4.13635, 1.02434 + +-1.62339, 3.59015, 1.13513 + +-1.74303, 3.04394, 1.24592 + +-1.86266, 2.49774, 1.35671 + +-1.9823, 1.95154, 1.4675 + +-2.10194, 1.40534, 1.57829 + +-2.22157, 0.859137, 1.68908 + +-2.34121, 0.312934, 1.79987 + +-2.46084, -0.233267, 1.91066 + +-2.58048, -0.779468, 2.02145 + +-2.70012, -1.32567, 2.13224 + +-2.81976, -1.87187, 2.24303 + +-2.9394, -2.41807, 2.35382 + +-3.05903, -2.96428, 2.46461 + +-3.17867, -3.51048, 2.5754 + +-3.2983075,-4.0566825,2.686189 + +-3.09987, -3.63013, 2.36433 + +-2.90143, -3.20357, 2.04247 + +-2.70299, -2.77701, 1.72061 + +-2.50455, -2.35045, 1.39875 + +-2.30611, -1.92389, 1.07689 + +-2.10767, -1.49733, 0.755026 + +-1.90924, -1.07077, 0.433165 + +-1.7108, -0.644214, 0.111303 + +-1.51236, -0.217655, -0.210558 + +-1.31393, 0.208903, -0.532419 + +-1.11549, 0.635462, -0.854279 + +-0.91705, 1.06202, -1.17614 + +-0.718613, 1.48858, -1.498 + +-0.520175, 1.91514, -1.81986 + +-0.321737, 2.3417, -2.14172 + +-0.1232995,2.768254,-2.463584 + +0.128657, 2.3119, -2.23296 + +0.380613, 1.85555, -2.00234 + +0.632569, 1.3992, -1.77172 + +0.884525, 0.942852, -1.5411 + +1.13648, 0.486501, -1.31047 + +1.38844, 0.0301505, -1.07985 + +1.64039, -0.4262, -0.849228 + +1.89235, -0.882551, -0.618607 + +2.14431, -1.3389, -0.387985 + +2.39626, -1.79525, -0.157363 + +2.64821, -2.2516, 0.0732595 + +2.90017, -2.70795, 0.303882 + +3.15212, -3.1643, 0.534504 + +3.40408, -3.62065, 0.765126 + +3.65604, -4.077, 0.995748 + +3.9079915,-4.533357,1.2263705 + +3.41775, -4.27741, 1.08826 + +2.9275, -4.02147, 0.950154 + +2.43725, -3.76553, 0.812045 + +1.947, -3.50958, 0.673937 + +1.45675, -3.25364, 0.535829 + +0.966502, -2.9977, 0.39772 + +0.476253, -2.74175, 0.259611 + +-0.0139957, -2.48581, 0.121503 + +-0.504244, -2.22986, -0.0166055 + +-0.994493, -1.97392, -0.154714 + +-1.48474, -1.71798, -0.292822 + +-1.97499, -1.46204, -0.430931 + +-2.46524, -1.2061, -0.56904 + +-2.95549, -0.950156, -0.707148 + +-3.44574, -0.694214, -0.845257 + +-3.935983,-0.438272,-0.983365 + +-3.48885, -0.142371, -0.789876 + +-3.04171, 0.153529, -0.596387 + +-2.59457, 0.449429, -0.402898 + +-2.14744, 0.745329, -0.209409 + +-1.7003, 1.04123, -0.01592 + +-1.25317, 1.33713, 0.177569 + +-0.806037, 1.63303, 0.371058 + +-0.358904, 1.92893, 0.564547 + +0.0882295, 2.22483, 0.758035 + +0.535363, 2.52073, 0.951523 + +0.982496, 2.81663, 1.14501 + +1.42963, 3.11253, 1.3385 + +1.87677, 3.40843, 1.53199 + +2.3239, 3.70433, 1.72548 + +2.77104, 4.00023, 1.91897 + + + 3.218174000000000, 4.296123000000000, 2.112459500000000 + 3.098763125000000, 3.819365312500000, 1.823730781250000 + 2.979352250000000, 3.342607625000000, 1.535002062500000 + 2.859941375000000, 2.865849937500000, 1.246273343750000 + 2.740530500000000, 2.389092250000000, 0.957544625000000 + 2.621119625000000, 1.912334562500000, 0.668815906250000 + 2.501708750000000, 1.435576875000000, 0.380087187500000 + 2.382297875000000, 0.958819187500000, 0.091358468750000 + 2.262887000000000, 0.482061500000000, -0.197370250000000 + 2.143476125000000, 0.005303812500000, -0.486098968750000 + 2.024065250000000, -0.471453875000000, -0.774827687500000 + 1.904654375000000, -0.948211562500000, -1.063556406250000 + 1.785243500000000, -1.424969250000000, -1.352285125000000 + 1.665832625000000, -1.901726937500000, -1.641013843750000 + 1.546421750000000, -2.378484625000000, -1.929742562500000 + 1.427010875000000, -2.855242312500000, -2.218471281250000 + 1.28318923, -2.84316645, -2.25593748 diff --git a/curves/test.curve b/curves/test.curve new file mode 100644 index 0000000..27f824e --- /dev/null +++ b/curves/test.curve @@ -0,0 +1,17 @@ + %ignore me + 1.307600000000000, -3.332000000000000, -2.507200000000000 + -1.384118500000000, 4.682550500000000, 0.913541000000000 + + + +-3.2983075,-4.0566825,2.686189 + +-0.1232995,2.768254,-2.463584 + +3.9079915,-4.533357,1.2263705 + +-3.935983,-0.438272,-0.983365 + +3.218174000000000, 4.296123000000000, 2.112459500000000 + 1.307600000000000, -3.332000000000000, -2.507200000000000 + diff --git a/data_objects/stick_knot.py b/data_objects/stick_knot.py index e735457..fac6ae0 100644 --- a/data_objects/stick_knot.py +++ b/data_objects/stick_knot.py @@ -5,7 +5,6 @@ from point import Point - class StickKnot: def __init__(self, knot_points_arr=None): @@ -13,4 +12,4 @@ def __init__(self, knot_points_arr=None): pass def get_points(self): - return self.knot_points \ No newline at end of file + return self.knot_points diff --git a/generator/__init__.py b/generator/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/generator/parser.py b/generator/parser.py new file mode 100644 index 0000000..0a63575 --- /dev/null +++ b/generator/parser.py @@ -0,0 +1,33 @@ +# #!/usr/bin/env python +# """ +# @author Peter Zaffetti 2017 +# """ +# class Parser: +# +# def __init__(self): +# pass +# +# def parse_curve(curve_filename=None): +# +# if curve_filename is None: +# return None +# +# curve_file = open(curve_filename, "r") +# +# +# for line in curve_file: +# comment_parts = "" +# curve_points = list() +# +# if line.startswith("%"): +# continue +# elif "%" in line: +# comment_parts = line.split("%") +# +# if comment_parts is not None: +# curve_string = comment_parts[0] +# curve_points = curve_string.split(",") +# else: +# curve_points = line.split(",") +# +# if len(curve_points) == 3: \ No newline at end of file diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..b6b0735 --- /dev/null +++ b/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)" + +$SCRIPT_DIR/user_interface/cli_application.py $* diff --git a/subdivision_generator_orig_pyth_3_6.py b/subdivision_generator_orig_pyth_3_6.py new file mode 100644 index 0000000..25ee45d --- /dev/null +++ b/subdivision_generator_orig_pyth_3_6.py @@ -0,0 +1,462 @@ +import numpy as np +import math + +def closestDistanceBetweenLines(a0,a1,b0,b1,clampAll=False,clampA0=False,clampA1=False,clampB0=False,clampB1=False): + ''' Given two lines defined by numpy.array pairs (a0,a1,b0,b1) + Return distance, the two closest points, and their average + ''' + + # If clampAll=True, set all clamps to True + if clampAll: + clampA0=True + clampA1=True + clampB0=True + clampB1=True + + # Calculate denomitator + A = a1 - a0 + B = b1 - b0 + + normA = np.linalg.norm(B) + if normA == 0: + print ("HERE", b0, b1) + _A = A / np.linalg.norm(A) + _B = B / np.linalg.norm(B) + cross = np.cross(_A, _B); + + denom = np.linalg.norm(cross)**2 + + # If denominator is 0, lines are parallel: Calculate distance with a projection + # and evaluate clamp edge cases + if (denom == 0): + d0 = np.dot(_A,(b0-a0)) + d = np.linalg.norm(((d0*_A)+a0)-b0) + + # If clamping: the only time we'll get closest points will be when lines don't overlap at all. + # Find if segments overlap using dot products. + if clampA0 or clampA1 or clampB0 or clampB1: + d1 = np.dot(_A,(b1-a0)) + + # Is segment B before A? + if d0 <= 0 >= d1: + if clampA0 == True and clampB1 == True: + if np.absolute(d0) < np.absolute(d1): + return b0,a0,np.linalg.norm(b0-a0) + return b1,a0,np.linalg.norm(b1-a0) + + # Is segment B after A? + elif d0 >= np.linalg.norm(A) <= d1: + if clampA1 == True and clampB0 == True: + if np.absolute(d0) < np.absolute(d1): + return b0,a1,np.linalg.norm(b0-a1) + return b1,a1,np.linalg.norm(b1,a1) + + # If clamping is off, or segments overlapped, we have infinite results, just return position. + return None,None,d + + + + # Lines criss-cross: Calculate the dereminent and return points + t = (b0 - a0); + det0 = np.linalg.det([t, _B, cross]) + det1 = np.linalg.det([t, _A, cross]) + + t0 = det0/denom; + t1 = det1/denom; + + pA = a0 + (_A * t0); + pB = b0 + (_B * t1); + + # Clamp results to line segments if needed + if clampA0 or clampA1 or clampB0 or clampB1: + + if t0 < 0 and clampA0: + pA = a0 + elif t0 > np.linalg.norm(A) and clampA1: + pA = a1 + + if t1 < 0 and clampB0: + pB = b0 + elif t1 > np.linalg.norm(B) and clampB1: + pB = b1 + + d = np.linalg.norm(pA-pB) + + return pA,pB,d + +''' +Calculate the distance of the line segment between the start and end points +''' +def distanceBetweenTwoPoints(startPoint, endPoint): + x = endPoint[0] - startPoint[0] + y = endPoint[1] - startPoint[1] + z = endPoint[2] - startPoint[2] + return math.sqrt( x*x + y*y + z*z) +''' +A function used to reduce a line segment between the startPoint and the endPoint +by the recduce amount. So if you have a line that is 1 distance long and you want to +move both of its end points in by .25 this function will return the two new end points +and the length of the new line will be .5. +''' +def reduceLineSegment(startPoint, endPoint, reduceAmount): + vector = [] + ''' + Parametrize the line segment so that you can subtract the distace. Since the line + is parametrized its distance will be from 0 to 1. To reduce it by the desired amount + we need to figure out the proportion of the line compared to the parameter and then + subtract that amount. + ''' + vector.append(startPoint[0] - endPoint[0]) #Calculate Vector X + vector.append(startPoint[1] - endPoint[1]) #Calculate Vector Y + vector.append(startPoint[2] - endPoint[2]) #Calculate Vector Z + dist = distanceBetweenTwoPoints(startPoint, endPoint) + proportion = reduceAmount / dist + newX = endPoint[0] + proportion * vector[0] + newY = endPoint[1] + proportion * vector[1] + newZ = endPoint[2] + proportion * vector[2] + newEndPoint = np.array([newX, newY, newZ]) + + output = [] + newX = endPoint[0] + (1 - proportion) * vector[0] + newY = endPoint[1] + (1 - proportion) * vector[1] + newZ = endPoint[2] + (1 - proportion) * vector[2] + newStartPoint = np.array([newX, newY, newZ]) + output.append(newStartPoint) + output.append(newEndPoint) + return output +''' +Generates the set of second iterated forward difference operator. This comes from Professor Peters' and +Ji Li's paper. In the paper it is define. It shows up as a triangle with a subscript 2 and and set P next to it +''' +def secondIteratedForwardDifferenceOperator(listOfControlPoints, index): + deltaSub2Set = [] + numCtrlPts = len(listOfControlPoints) + #Need to wrap around and connect back to the first point + for i in range(0, numCtrlPts): #Add -1 to numCtrlPts to make it an open curve again + deltaSub2Ofi = listOfControlPoints[(i+2) % numCtrlPts][index] - (2 * listOfControlPoints[(i + 1) % numCtrlPts][index]) + listOfControlPoints[i][index] + deltaSub2Set.append(deltaSub2Ofi) + return deltaSub2Set +''' +This is the l1 - Norm for a set. The l1 norm is just the summation of the absolute value of all the +elements in the set. +''' +def l1Norm(setForNorming): + norm = 0 + i = 0 + for element in setForNorming: + norm += abs(element) + i+= 1 + print ('Terms in L1 Norm: ', i) + return norm +''' +This generates the Omega one value from Professor Peters' and Ji Li's paper. Omega one is used in combination with the delta from the Denne-Sullivan paper to figure out m1 +''' +def omegaOne(listOfControlPoints): + deltaSetX = secondIteratedForwardDifferenceOperator(listOfControlPoints, 0) + deltaSetY = secondIteratedForwardDifferenceOperator(listOfControlPoints, 1) + deltaSetZ = secondIteratedForwardDifferenceOperator(listOfControlPoints, 2) + + l1NormX = l1Norm(deltaSetX) + l1NormY = l1Norm(deltaSetY) + l1NormZ = l1Norm(deltaSetZ) + + return max(l1NormX, l1NormY, l1NormZ) +''' +This function generates the m1 value from Professor Peters' and Ji Li's paper. M1 is compared against +m2 and m3 to determine the number of iterations, j, that need to be done in order for the stick knot +to properly associate with its correct bezier curve +''' +def generateM1(omegaOne, delta): + omegaOneSquared = omegaOne * omegaOne + deltaSquared = delta * delta + intermediate = ((float(7)/float(16) * omegaOneSquared * (1 / deltaSquared)) - (float(1)/ float(7)) ) + logResult = math.log(intermediate, 2) + return math.ceil(logResult) + +''' +Generates the hodograph delta sub 2 set from Professor Peters' and Ji Li's paper. It is defined in the paper +''' +def generateHodographDeltaTwoSet(listOfControlPoints, index): + hodographDelta2Set = [] + numControlPoints = len(listOfControlPoints) + #Need to wrap around and connect back to the first point + for i in range(1, numControlPoints): #Add -1 to numControlPoints to make it an open curve again + hodographDeltaSub2Ofi = numControlPoints * (listOfControlPoints[(i + 2) % numControlPoints][index] - (3 * listOfControlPoints[(i+1)% numControlPoints][index]) + (3 * listOfControlPoints[i][index]) - listOfControlPoints[i - 1][index]) + hodographDelta2Set.append(hodographDeltaSub2Ofi) + return hodographDelta2Set + +''' +Found the same way as Omega One but uses the hodograph sets instead +''' +def omegaTwo(listOfControlPoints): + hodographX = generateHodographDeltaTwoSet(listOfControlPoints, 0) + hodographY = generateHodographDeltaTwoSet(listOfControlPoints, 1) + hodographZ = generateHodographDeltaTwoSet(listOfControlPoints, 2) + + l1NormX = l1Norm(hodographX) + l1NormY = l1Norm(hodographY) + l1NormZ = l1Norm(hodographZ) + + return max(l1NormX, l1NormY, l1NormZ) + +''' +The M2 value from Professor Peters' and Ji Li's paper. It is found using the hodograph set +''' +def generateM2(omegaTwo, lambdaVal, numCtrlPts): + j = 0 + #This gets the next int higher to what would be an unreducible logarithm + while( (numCtrlPts * math.pow(2, 3 * j) + math.pow(2, 2 * j)) < math.pow( omegaTwo/lambdaVal , 2)): + j += 1 + return j + +''' +The M3 value from Professor Peters' and Ji Li's paper. It is very similar to M2 except for the additional sin(pi/ 8) value +''' +def generateM3(omegaTwo, lambdaVal, numCtrlPts): + j = 0 + #This gets the next int higher to what would be an unreducible logarithm + while( ( numCtrlPts * math.pow(2, 3 * j) + math.pow(2, 2 * j)) < math.pow( (omegaTwo / (math.sin(math.pi / 8) * lambdaVal)), 2 ) ): + j+=1 + return j + +if __name__ == '__main__': + [testa, testb, testdist] = closestDistanceBetweenLines(np.array([0.0, 0.0, 0.0]), np.array([5.0, 0.0, 0.0]), np.array([6.0, 0.0, 1.0]), np.array([10.0, 0.0, 1.0]), clampAll=True) + print ("Done: ",testdist) + ''' + Add the line segments of the control polygon to a list + ''' + + segmentArray = [] + segmentArray.append(np.array([1.3076, -3.3320, -2.5072])) + segmentArray.append(np.array([-1.3841, 4.6826, 0.9135])) + segmentArray.append(np.array([-3.2983, -4.0567, 2.6862])) + segmentArray.append(np.array([-0.1233, 2.7683, -2.4636])) + segmentArray.append(np.array([3.9080, -4.5334, 1.2264])) + segmentArray.append(np.array([-3.9360, -0.4383, -0.9834])) + segmentArray.append(np.array([3.2182, 4.2961, 2.1125])) + [a, b, dist] = closestDistanceBetweenLines(segmentArray[0], segmentArray[1], segmentArray[2], segmentArray[3], clampAll = True) + print ('TEST: a is: ', a, ' b is: ', b, ' dist is: ', dist) + ''' + segmentArray = [] + segmentArray.append(np.array([1.28318923, -2.84316645, -2.25593748])) + segmentArray.append(np.array([1.139367593750000, -2.831090593750000, -2.293403687500000])) + segmentArray.append(np.array([0.971135187500000, -2.330181187500000, -2.079607375000000])) + segmentArray.append(np.array([0.802902781250000, -1.829271781250000, -1.865811062500000])) + segmentArray.append(np.array([0.634670375000000, -1.328362375000000, -1.652014750000000])) + segmentArray.append(np.array([0.466437968750000, -0.827452968750000, -1.438218437500000])) + segmentArray.append(np.array([0.298205562500000, -0.326543562500000, -1.224422125000000])) + segmentArray.append(np.array([0.129973156250000, 0.174365843750000, -1.010625812500000])) + segmentArray.append(np.array([-0.038259250000000, 0.675275250000000, -0.796829500000000])) + segmentArray.append(np.array([-0.206491656250000, 1.176184656250000, -0.583033187500000])) + segmentArray.append(np.array([-0.374724062500000, 1.677094062500000, -0.369236875000000])) + segmentArray.append(np.array([-0.542956468750000, 2.178003468750000, -0.155440562500000])) + segmentArray.append(np.array([-0.711188875000000, 2.678912875000000, 0.058355750000000])) + segmentArray.append(np.array([-0.879421281250000, 3.179822281250000, 0.272152062500000])) + segmentArray.append(np.array([-1.047653687500000, 3.680731687500000, 0.485948375000000])) + segmentArray.append(np.array([-1.215886093750000, 4.181641093750000, 0.699744687500000])) + segmentArray.append(np.array([-1.384118500000000, 4.682550500000000, 0.913541000000000])) + segmentArray.append(np.array([-1.50375, 4.13635, 1.02434])) + segmentArray.append(np.array([-1.62339, 3.59015, 1.13513])) + segmentArray.append(np.array([-1.74303, 3.04394, 1.24592])) + segmentArray.append(np.array([-1.86266, 2.49774, 1.35671])) + segmentArray.append(np.array([-1.9823, 1.95154, 1.4675])) + segmentArray.append(np.array([-2.10194, 1.40534, 1.57829])) + segmentArray.append(np.array([-2.22157, 0.859137, 1.68908])) + segmentArray.append(np.array([-2.34121, 0.312934, 1.79987])) + segmentArray.append(np.array([-2.46084, -0.233267, 1.91066])) + segmentArray.append(np.array([-2.58048, -0.779468, 2.02145])) + segmentArray.append(np.array([-2.70012, -1.32567, 2.13224])) + segmentArray.append(np.array([-2.81976, -1.87187, 2.24303])) + segmentArray.append(np.array([-2.9394, -2.41807, 2.35382])) + segmentArray.append(np.array([-3.05903, -2.96428, 2.46461])) + segmentArray.append(np.array([-3.17867, -3.51048, 2.5754])) + segmentArray.append(np.array([-3.2983075,-4.0566825,2.686189])) + segmentArray.append(np.array([-3.09987, -3.63013, 2.36433])) + segmentArray.append(np.array([-2.90143, -3.20357, 2.04247])) + segmentArray.append(np.array([-2.70299, -2.77701, 1.72061])) + segmentArray.append(np.array([-2.50455, -2.35045, 1.39875])) + segmentArray.append(np.array([-2.30611, -1.92389, 1.07689])) + segmentArray.append(np.array([-2.10767, -1.49733, 0.755026])) + segmentArray.append(np.array([-1.90924, -1.07077, 0.433165])) + segmentArray.append(np.array([-1.7108, -0.644214, 0.111303])) + segmentArray.append(np.array([-1.51236, -0.217655, -0.210558])) + segmentArray.append(np.array([-1.31393, 0.208903, -0.532419])) + segmentArray.append(np.array([-1.11549, 0.635462, -0.854279])) + segmentArray.append(np.array([-0.91705, 1.06202, -1.17614])) + segmentArray.append(np.array([-0.718613, 1.48858, -1.498])) + segmentArray.append(np.array([-0.520175, 1.91514, -1.81986])) + segmentArray.append(np.array([-0.321737, 2.3417, -2.14172])) + segmentArray.append(np.array([-0.1232995,2.768254,-2.463584])) + segmentArray.append(np.array([0.128657, 2.3119, -2.23296])) + segmentArray.append(np.array([0.380613, 1.85555, -2.00234])) + segmentArray.append(np.array([0.632569, 1.3992, -1.77172])) + segmentArray.append(np.array([0.884525, 0.942852, -1.5411])) + segmentArray.append(np.array([1.13648, 0.486501, -1.31047])) + segmentArray.append(np.array([1.38844, 0.0301505, -1.07985])) + segmentArray.append(np.array([1.64039, -0.4262, -0.849228])) + segmentArray.append(np.array([1.89235, -0.882551, -0.618607])) + segmentArray.append(np.array([2.14431, -1.3389, -0.387985])) + segmentArray.append(np.array([2.39626, -1.79525, -0.157363])) + segmentArray.append(np.array([2.64821, -2.2516, 0.0732595])) + segmentArray.append(np.array([2.90017, -2.70795, 0.303882])) + segmentArray.append(np.array([3.15212, -3.1643, 0.534504])) + segmentArray.append(np.array([3.40408, -3.62065, 0.765126])) + segmentArray.append(np.array([3.65604, -4.077, 0.995748])) + segmentArray.append(np.array([3.9079915,-4.533357,1.2263705])) + segmentArray.append(np.array([3.41775, -4.27741, 1.08826])) + segmentArray.append(np.array([2.9275, -4.02147, 0.950154])) + segmentArray.append(np.array([2.43725, -3.76553, 0.812045])) + segmentArray.append(np.array([1.947, -3.50958, 0.673937])) + segmentArray.append(np.array([1.45675, -3.25364, 0.535829])) + segmentArray.append(np.array([0.966502, -2.9977, 0.39772])) + segmentArray.append(np.array([0.476253, -2.74175, 0.259611])) + segmentArray.append(np.array([-0.0139957, -2.48581, 0.121503])) + segmentArray.append(np.array([-0.504244, -2.22986, -0.0166055])) + segmentArray.append(np.array([-0.994493, -1.97392, -0.154714])) + segmentArray.append(np.array([-1.48474, -1.71798, -0.292822])) + segmentArray.append(np.array([-1.97499, -1.46204, -0.430931])) + segmentArray.append(np.array([-2.46524, -1.2061, -0.56904])) + segmentArray.append(np.array([-2.95549, -0.950156, -0.707148])) + segmentArray.append(np.array([-3.44574, -0.694214, -0.845257])) + segmentArray.append(np.array([-3.935983,-0.438272,-0.983365])) + segmentArray.append(np.array([-3.48885, -0.142371, -0.789876])) + segmentArray.append(np.array([-3.04171, 0.153529, -0.596387])) + segmentArray.append(np.array([-2.59457, 0.449429, -0.402898])) + segmentArray.append(np.array([-2.14744, 0.745329, -0.209409])) + segmentArray.append(np.array([-1.7003, 1.04123, -0.01592])) + segmentArray.append(np.array([-1.25317, 1.33713, 0.177569])) + segmentArray.append(np.array([-0.806037, 1.63303, 0.371058])) + segmentArray.append(np.array([-0.358904, 1.92893, 0.564547])) + segmentArray.append(np.array([0.0882295, 2.22483, 0.758035])) + segmentArray.append(np.array([0.535363, 2.52073, 0.951523])) + segmentArray.append(np.array([0.982496, 2.81663, 1.14501])) + segmentArray.append(np.array([1.42963, 3.11253, 1.3385])) + segmentArray.append(np.array([1.87677, 3.40843, 1.53199])) + segmentArray.append(np.array([2.3239, 3.70433, 1.72548])) + segmentArray.append(np.array([2.77104, 4.00023, 1.91897])) + segmentArray.append(np.array([3.218174000000000, 4.296123000000000, 2.112459500000000])) + segmentArray.append(np.array([3.098763125000000, 3.819365312500000, 1.823730781250000])) + segmentArray.append(np.array([2.979352250000000, 3.342607625000000, 1.535002062500000])) + segmentArray.append(np.array([2.859941375000000, 2.865849937500000, 1.246273343750000])) + segmentArray.append(np.array([2.740530500000000, 2.389092250000000, 0.957544625000000])) + segmentArray.append(np.array([2.621119625000000, 1.912334562500000, 0.668815906250000])) + segmentArray.append(np.array([2.501708750000000, 1.435576875000000, 0.380087187500000])) + segmentArray.append(np.array([2.382297875000000, 0.958819187500000, 0.091358468750000])) + segmentArray.append(np.array([2.262887000000000, 0.482061500000000, -0.197370250000000])) + segmentArray.append(np.array([2.143476125000000, 0.005303812500000, -0.486098968750000])) + segmentArray.append(np.array([2.024065250000000, -0.471453875000000, -0.774827687500000])) + segmentArray.append(np.array([1.904654375000000, -0.948211562500000, -1.063556406250000])) + segmentArray.append(np.array([1.785243500000000, -1.424969250000000, -1.352285125000000])) + segmentArray.append(np.array([1.665832625000000, -1.901726937500000, -1.641013843750000])) + segmentArray.append(np.array([1.546421750000000, -2.378484625000000, -1.929742562500000])) + segmentArray.append(np.array([1.427010875000000, -2.855242312500000, -2.218471281250000])) + ''' + + minimums = [] + ''' + For each line segment, compare it to all non-incident (non-adjacent) line segments. Add the distances + to the minimums list. + ''' + numCtrlPointSegments = len(segmentArray) + for i in range(0, numCtrlPointSegments): + #print'i is: ' ,i + j = i + 2 + while j < numCtrlPointSegments: + if(i == 0 and (j+1)% numCtrlPointSegments == 0): + j+=1 + continue + #print 'j is: ', j, ' and j + 1 mod 7 is', (j+1)% numCtrlPointSegments + [a, b, dist] = closestDistanceBetweenLines(segmentArray[i],segmentArray[i+1],segmentArray[j],segmentArray[(j+1) % numCtrlPointSegments],clampAll=True) + print ('a is: ', a, ' b is: ', b, ' dist is: ', dist) + #print(dist) + minimums.append(dist) + j+= 1 + + ''' + Of all the distances, take the minimum. This is the r1 value from the Denne-Sullivan paper + ''' + r1 = min(minimums) + print ('r1 is: ', r1) + ''' + Epsilon is a constant that we have pre selected and can change + ''' + epsilon = 1.0 + ''' + r2 is also from the Denne-Sullivan paper + ''' + r2 = min(r1/2, epsilon/2) + print ('r2 is: ', r2) + + ''' + For each line segment of the control polygon, remove r2 from each end. + ''' + adjustedSegments = [] + for i in range(0, numCtrlPointSegments): + #print 'i is: ', i, 'and the Line Segment is ', segmentArray[i], segmentArray[(i+1)%numCtrlPointSegments] + [segment1, segment2] = reduceLineSegment(segmentArray[i], segmentArray[(i+1)%numCtrlPointSegments], r2) + adjustedSegments.append(segment1) + adjustedSegments.append(segment2) + #print 'The new segment is: ', segment1, segment2 + i+=1 + #At this point the segments have been reduced along the vertex. This means that the number of points is 2 times the number of control points. This is because the segments no longer share any common points between themselves + + numAdjustedPoints = len(adjustedSegments) + newMinimums = [] + + ''' + Then, for each reduced segment find the distance from that segment to all other reduced segments + ''' + i = 0 + while i + 3 < numAdjustedPoints: + j = i + 2 + while j+1 < numAdjustedPoints: + #print 'Comparing: ', adjustedSegments[i], adjustedSegments[i+1], 'to: ', adjustedSegments[j],adjustedSegments[j+1] + [a, b, dist] = closestDistanceBetweenLines(adjustedSegments[i],adjustedSegments[i+1],adjustedSegments[j],adjustedSegments[j+1],clampAll=True) + newMinimums.append(dist) + #print dist + j+=2 + i+=2 + + ''' + Take r3 (also from Denne-Sullivan) to be the minimum distance of all distances between line segments + ''' + r3 = min(newMinimums) + print ('r3 is: ', r3) + + ''' + r4 is also from Denne-Sullivan paper + ''' + r4 = r3 / 6 + print ('r4 is: ', r4) + + ''' + Finally, calculate delta (from Denne-Sullivan) + ''' + delta = r4 / 3 + print ('delta is: ', delta) + + omega1 = omegaOne(segmentArray) + print ('Omega One is: ', omega1) + m1 = generateM1(omega1, delta) + print ('M1 is: ', m1) + + segmentLengths = [] + for i in range(0, numCtrlPointSegments): + segmentLengths.append(distanceBetweenTwoPoints(segmentArray[i], segmentArray[(i +1) % numCtrlPointSegments])) + + lambdaVal = min(segmentLengths) + print ('Lambda is: ', lambdaVal) + omega2 = omegaTwo(segmentArray) + print ('Omega Two is: ', omega2) + m2 = generateM2(omega2, lambdaVal, numCtrlPointSegments) + print ('M2 is: ', m2) + + m3 = generateM3(omega2, lambdaVal, numCtrlPointSegments) + print ('M3 is: ', m3) + + + + + + + diff --git a/user_interface/cli.py b/user_interface/cli.py deleted file mode 100644 index 3104f00..0000000 --- a/user_interface/cli.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python -""" -@author Peter Zaffetti 2017 -""" -import logging -import argparse - - -class Cli: - - def __init__(self): - self.parser = argparse.ArgumentParser(description='Generates the required number of subdivisions for a Bezier curve to match the stick knot it was created from') - self.parser.add_argument() - pass - - def generate_m_value(self, curve_file=None): - pass - -class GenerateMValue(app.CommandLineApp): - - def setup(self): - self.add_param("-g", "--generateM", help="generates the minimum number of iterations needed for the supplied \ - stick knot's Bezier cure to match the stick knot", default=None, action="store") - - -def main(): - logging.info("Pretend to do something here...") - return True - - -if __name__ == "__main__": - GenerateMValue.run() \ No newline at end of file diff --git a/user_interface/cli_application.py b/user_interface/cli_application.py new file mode 100755 index 0000000..b0e3ec2 --- /dev/null +++ b/user_interface/cli_application.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +""" +@author Peter Zaffetti 2017 +""" +import argparse +import cmd +import logging.config +import os +import sys +from parser import parse_curve_file + +class CliApplication(cmd.Cmd): + + def __init__(self, *args): + self.logger = logging.getLogger(__name__) + self.arguments = args + self.parse_cmd_args(self.arguments) + sys.exit(1) + + def parse_cmd_args(*args): + if args.generate_m_value: + self.generate_m_value(args.generate_m_value) + + def generate_m_value(self, curve_file="test.curve"): + knot_curve = parse_curve_file(curve_file) + + pass + + +def main(): + """The main function that runs the Subdivision Generator application""" + + application_path = os.path.dirname(os.path.abspath(__file__)) + application_name = os.path.splitext(os.path.basename(__file__))[0] + + argument_parser = argparse.ArgumentParser( + description='Generates the required number of subdivisions for a Bezier curve to match the stick knot it was created from') + argument_parser.add_argument("-g", "--generate_m_value", help="generates the minimum number of iterations needed for the supplied \ + stick knot's Bezier cure to match the stick knot", default=None, action="store") + arguments = argument_parser.parse_args() + + logging.basicConfig(filename="generator_log.txt", level="DEBUG") + logger = logging.getLogger(application_name) + logger.info("Parsing arguments") + + application = CliApplication(arguments) + + +if __name__ == "__main__": + main() diff --git a/user_interface/gui.py b/user_interface/gui.py index ae3331f..d98475e 100644 --- a/user_interface/gui.py +++ b/user_interface/gui.py @@ -2,4 +2,4 @@ TODO: This is stubbed out for now. Eventually, the GUI will sit on top of the CLI functionality in the cli.py file @author Peter Zaffetti 2017 """ -from cli import GenerateMValue +from cli_application import GenerateMValue From 9a6453156c4512120d03fd4229e68044d3e0b44e Mon Sep 17 00:00:00 2001 From: Pzaff Date: Wed, 11 Oct 2017 22:41:00 -0400 Subject: [PATCH 2/3] Fixed the cli so that curves are properly parsed. --- .gitignore | 3 +++ __init__.py | 0 .../cli_application.py => cli_application.py | 25 +++++++++++-------- data_objects/point.py | 17 +++++++++++++ generator/{parser.py => old_parser.py} | 0 logger.py | 21 ++++++++++++++++ run.sh | 4 +-- unit_tests/parser_test.py | 2 +- unit_tests/point_test.py | 25 +++++++++++++++++++ user_interface/{parser.py => curve_parser.py} | 8 +++++- user_interface/gui.py | 1 - 11 files changed, 90 insertions(+), 16 deletions(-) create mode 100644 __init__.py rename user_interface/cli_application.py => cli_application.py (60%) mode change 100755 => 100644 rename generator/{parser.py => old_parser.py} (100%) create mode 100644 logger.py create mode 100644 unit_tests/point_test.py rename user_interface/{parser.py => curve_parser.py} (77%) diff --git a/.gitignore b/.gitignore index dd158e4..6c25327 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,6 @@ target/ #IntelliJ Files *.idea + +#Subdivision Log Generator log file +logs/ diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/user_interface/cli_application.py b/cli_application.py old mode 100755 new mode 100644 similarity index 60% rename from user_interface/cli_application.py rename to cli_application.py index b0e3ec2..d71a642 --- a/user_interface/cli_application.py +++ b/cli_application.py @@ -7,19 +7,28 @@ import logging.config import os import sys -from parser import parse_curve_file +from user_interface.curve_parser import parse_curve_file + class CliApplication(cmd.Cmd): - def __init__(self, *args): + def __init__(self, application_path=None, application_name="generator", args=None): self.logger = logging.getLogger(__name__) + self.curve_paths = os.path.join(application_path, "curves") self.arguments = args self.parse_cmd_args(self.arguments) sys.exit(1) - def parse_cmd_args(*args): - if args.generate_m_value: - self.generate_m_value(args.generate_m_value) + def parse_cmd_args(self, args): + if args is not None: + if args.generate_m_value: + if os.path.exists(args.generate_m_value): + self.generate_m_value(args.generate_m_value) + else: + self.generate_m_value(os.path.join(self.curve_paths, args.generate_m_value)) + + else: + raise Exception("There were no arguments when running the application") def generate_m_value(self, curve_file="test.curve"): knot_curve = parse_curve_file(curve_file) @@ -39,11 +48,7 @@ def main(): stick knot's Bezier cure to match the stick knot", default=None, action="store") arguments = argument_parser.parse_args() - logging.basicConfig(filename="generator_log.txt", level="DEBUG") - logger = logging.getLogger(application_name) - logger.info("Parsing arguments") - - application = CliApplication(arguments) + application = CliApplication(application_path, application_name, arguments) if __name__ == "__main__": diff --git a/data_objects/point.py b/data_objects/point.py index cb1f020..214292b 100644 --- a/data_objects/point.py +++ b/data_objects/point.py @@ -4,6 +4,14 @@ """ +def distance_between_points(start_point, end_point): + x = end_point.get_x() - start_point.get_x() + y = end_point.get_y() - start_point.get_y() + z = end_point.get_z() - start_point.get_z() + + return float((x * x + y * y + z * z) ** (1 / 2)) + + class Point: def __init__(self, x_val, y_val, z_val): @@ -17,3 +25,12 @@ def __eq__(self, other): return self.x_val == other.x_val and self.y_val == other.y_val and self.z_val == other.z_val return False + def get_x(self): + return self.x_val + + def get_y(self): + return self.y_val + + def get_z(self): + return self.z_val + diff --git a/generator/parser.py b/generator/old_parser.py similarity index 100% rename from generator/parser.py rename to generator/old_parser.py diff --git a/logger.py b/logger.py new file mode 100644 index 0000000..cc3c6a3 --- /dev/null +++ b/logger.py @@ -0,0 +1,21 @@ +""" +A simplistic Logger class which wraps the Python logging class + +@author Peter Zaffetti +@date 10/10/2017 +""" +import logging +import os + + +def get_logger(classname=None): + log_dir = "logs" + if not os.path.exists(log_dir): + os.makedirs(log_dir) + + logging.basicConfig(filename="logs/generator_log.txt", level="DEBUG") + + if classname is None: + classname = "Subdivision Generator" + + return logging.getLogger(classname) diff --git a/run.sh b/run.sh index b6b0735..2089cea 100755 --- a/run.sh +++ b/run.sh @@ -1,5 +1,3 @@ #!/bin/bash - SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)" - -$SCRIPT_DIR/user_interface/cli_application.py $* +"$SCRIPT_DIR/user_interface/cli_application.py" $* diff --git a/unit_tests/parser_test.py b/unit_tests/parser_test.py index 7ae371d..774df6e 100644 --- a/unit_tests/parser_test.py +++ b/unit_tests/parser_test.py @@ -3,7 +3,7 @@ @author Peter Zaffetti 2017 """ import unittest -from user_interface.parser import parse_curve_file +from user_interface.curve_parser import parse_curve_file from data_objects.point import Point diff --git a/unit_tests/point_test.py b/unit_tests/point_test.py new file mode 100644 index 0000000..7745e0c --- /dev/null +++ b/unit_tests/point_test.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +""" +@author Peter Zaffetti 2017 +""" +import unittest +from data_objects.point import Point, distance_between_points + + +class PointTest(unittest.TestCase): + origin_test_point = Point(0, 0, 0) + test_point = Point(12, 8, 4) + + def test_getters(self): + self.assertTrue(self.test_point.get_x() == 12) + self.assertTrue(self.test_point.get_y() == 8) + self.assertTrue(self.test_point.get_z() == 4) + + def test_distance_between_points(self): + """Test the distance from the origin to 12, 8 , 4 -> it should be about 14.96662954""" + distance = distance_between_points(self.origin_test_point, self.test_point) + self.assertTrue( distance == 14.96662954) + + +if __name__ == "__main__": + unittest.main() diff --git a/user_interface/parser.py b/user_interface/curve_parser.py similarity index 77% rename from user_interface/parser.py rename to user_interface/curve_parser.py index dd573d0..4c0be08 100644 --- a/user_interface/parser.py +++ b/user_interface/curve_parser.py @@ -4,18 +4,24 @@ """ from data_objects.point import Point from data_objects.stick_knot import StickKnot +from logger import get_logger def parse_curve_file(filename="test.curve"): + logger = get_logger(parse_curve_file.__name__) + curve_file = open(filename, "r") stick_knot_points = list() for line in curve_file: - if line.startswith("%"): + line = ''.join(line.split()) # PDZ- Remove all whitespace in the row + + if line.startswith("%") or line == "": continue comment_split_line = line.split("%") point_values = comment_split_line[0] comma_split_point_values = point_values.split(",") + logger.debug(comma_split_point_values) if len(comma_split_point_values) != 3: raise Exception("The curve file is not formatted properly") diff --git a/user_interface/gui.py b/user_interface/gui.py index d98475e..3aac5fb 100644 --- a/user_interface/gui.py +++ b/user_interface/gui.py @@ -2,4 +2,3 @@ TODO: This is stubbed out for now. Eventually, the GUI will sit on top of the CLI functionality in the cli.py file @author Peter Zaffetti 2017 """ -from cli_application import GenerateMValue From 9ac0bd0710336e4aa23da61eec22630ebbd84573 Mon Sep 17 00:00:00 2001 From: Pzaff Date: Mon, 16 Oct 2017 17:40:07 -0400 Subject: [PATCH 3/3] Fixed logging so that it prints to the file as well as the console. Added log formatting. Added log files to be ignorned in git. Updated the run script to call the application correctly. --- .gitignore | 2 +- cli_application.py | 13 +++++++++---- logger.py | 11 ++++++++++- run.sh | 2 +- 4 files changed, 21 insertions(+), 7 deletions(-) mode change 100644 => 100755 cli_application.py diff --git a/.gitignore b/.gitignore index 6c25327..b3e3458 100644 --- a/.gitignore +++ b/.gitignore @@ -60,4 +60,4 @@ target/ *.idea #Subdivision Log Generator log file -logs/ +logs/* diff --git a/cli_application.py b/cli_application.py old mode 100644 new mode 100755 index d71a642..237f1d4 --- a/cli_application.py +++ b/cli_application.py @@ -4,16 +4,17 @@ """ import argparse import cmd -import logging.config import os import sys + from user_interface.curve_parser import parse_curve_file +from logger import get_logger class CliApplication(cmd.Cmd): def __init__(self, application_path=None, application_name="generator", args=None): - self.logger = logging.getLogger(__name__) + self.logger = get_logger(__name__) self.curve_paths = os.path.join(application_path, "curves") self.arguments = args self.parse_cmd_args(self.arguments) @@ -25,8 +26,11 @@ def parse_cmd_args(self, args): if os.path.exists(args.generate_m_value): self.generate_m_value(args.generate_m_value) else: - self.generate_m_value(os.path.join(self.curve_paths, args.generate_m_value)) - + curve_path = os.path.join(self.curve_paths, args.generate_m_value) + if os.path.exists(curve_path): + self.generate_m_value(curve_path) + else: + self.logger.info("The curve file doesn't exist. Please choose an appropriate file.") else: raise Exception("There were no arguments when running the application") @@ -48,6 +52,7 @@ def main(): stick knot's Bezier cure to match the stick knot", default=None, action="store") arguments = argument_parser.parse_args() + get_logger().debug("Subdivision-Generator Starting Up") application = CliApplication(application_path, application_name, arguments) diff --git a/logger.py b/logger.py index cc3c6a3..3d3bfaf 100644 --- a/logger.py +++ b/logger.py @@ -13,9 +13,18 @@ def get_logger(classname=None): if not os.path.exists(log_dir): os.makedirs(log_dir) - logging.basicConfig(filename="logs/generator_log.txt", level="DEBUG") + root = logging.getLogger() + if root.handlers: + for handler in root.handlers: + root.removeHandler(handler) + + logging.basicConfig(format='%(asctime)s: %(filename)s: %(funcName)s: %(levelname)s:\t %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', filename="logs/generator_log.txt") if classname is None: classname = "Subdivision Generator" + logger = logging.getLogger(classname) + logger.setLevel(logging.INFO) + logger.addHandler(logging.StreamHandler()) + return logging.getLogger(classname) diff --git a/run.sh b/run.sh index 2089cea..48fffd9 100755 --- a/run.sh +++ b/run.sh @@ -1,3 +1,3 @@ #!/bin/bash SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)" -"$SCRIPT_DIR/user_interface/cli_application.py" $* +"$SCRIPT_DIR/cli_application.py" $*