-
Notifications
You must be signed in to change notification settings - Fork 21
fix some bug, remove temp file and add metric measures #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -221,14 +221,15 @@ def empty(): | |
| fgdmodel = np.zeros((1,65),np.float64) | ||
| cv2.grabCut(img2,mask,rect,bgdmodel,fgdmodel,5,cv2.GC_INIT_WITH_MASK) | ||
| elif k == ord('m'): | ||
| cv2.imwrite('tmp.pbm',bwimg) | ||
| # Write 1 channel | ||
| cv2.imwrite('tmp.pbm',bwimg[:, :, 1]) | ||
| subprocess.check_call([ | ||
| "potrace", | ||
| "tmp.pbm", | ||
| "--tight", "-s", | ||
| "-o", "tmp.svg" | ||
| ]) | ||
| subprocess.check_call(["inkscape", "-h", str(img.shape[0]), "-b", "white", "-e", "tmp.png", "tmp.svg"]) | ||
| subprocess.check_call(["inkscape", "-h", str(img.shape[0]), "-b", "white", "--export-type", "png", "--export-filename", "tmp.png", "tmp.svg"]) | ||
| svg = cv2.imread("tmp.png") | ||
|
|
||
| mh = img.shape[0] - svg.shape[0] | ||
|
|
@@ -241,7 +242,7 @@ def empty(): | |
| if mw <= 0: | ||
| mw = 0 | ||
|
|
||
| svg = cv2.copyMakeBorder(svg, mh/2, mh/2 + mh % 2, mw/2, mw/2 + mw % 2, cv2.BORDER_CONSTANT, value=(255, 255, 255, 255)) | ||
| svg = cv2.copyMakeBorder(svg, int(mh/2), int(mh/2 + mh % 2), int(mw/2), int(mw/2 + mw % 2), cv2.BORDER_CONSTANT, value=(255, 255, 255, 255)) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did this cause any errors previously? would be good to know :)
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think yes, but to be honest I did some update some months ago and maybe I had an error. |
||
|
|
||
| mask2 = np.where((mask==1) + (mask==3),255,0).astype('uint8') | ||
| output = cv2.bitwise_and(img2,img2,mask=mask2) | ||
|
|
@@ -261,6 +262,15 @@ def empty(): | |
|
|
||
|
|
||
| cv2.destroyAllWindows() | ||
| # Remove tmp file, that should be moved in another location... | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I found the tempfiles actually helpful in case something crashed. But maybe we can put this behind a flag. I will think about it :)
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, an option should be great, or even a folder, you can choose what do you want ;) |
||
| try: | ||
| os.remove("tmp.pbm") | ||
| os.remove("tmp.png") | ||
| os.remove("tmp.svg") | ||
| os.remove("grabcut_output.png") | ||
| os.remove("grabcut_summary.png") | ||
| except OSError: | ||
| pass | ||
| return | ||
|
|
||
| def main(argv=None): | ||
|
|
@@ -293,6 +303,10 @@ def main(argv=None): | |
| parser.add_argument("--thin-handle", dest="thin_handle", action='store_true', required=False, help="Use a thin handle suitable for impressioning grips") | ||
| parser.add_argument("--match-handle-connector", dest="match_handle_connector", action='store_true', required=False, help="Make the handle same thickness as the connector") | ||
|
|
||
| # Outname | ||
| parser.add_argument("--refinname", dest="refinname", action='store_true', required=False, help="Add the profile/description/keys in filename like key-AB95-E20-12345.stl") | ||
| parser.add_argument("--output", dest="output", required=False, help="Set the output name", metavar="FILE") | ||
|
|
||
| parser.add_argument('args', nargs=argparse.REMAINDER) | ||
|
|
||
| if len(argv) == 0: | ||
|
|
@@ -359,14 +373,14 @@ def main(argv=None): | |
|
|
||
| # Look for length in system definition for branding | ||
| for line in definition.splitlines(): | ||
| m = re.match("\s*kl\s*=\s*([\d\.]+)\s*;", line) | ||
| m = re.match(r"\s*kl\s*=\s*([\d\.]+)\s*;", line) | ||
| if m: | ||
| def_kl = m.group(1) | ||
| next | ||
|
|
||
| # Look for tolerance in profile definition for branding | ||
| for idx,line in enumerate(profile_definition.splitlines()): | ||
| m = re.match("\s*tol\s*=\s*([\d\.]+)\s*;", line) | ||
| m = re.match(r"\s*tol\s*=\s*([\d\.]+)\s*;", line) | ||
| if m: | ||
| def_tol = m.group(1) | ||
| def_tol_idx = idx | ||
|
|
@@ -389,13 +403,22 @@ def main(argv=None): | |
| branding = branding.replace("%model%", model) | ||
| branding = branding.replace("%length%", "%s" % def_kl) | ||
| branding = branding.replace("%tol%", "%s" % def_tol) | ||
| if opts.bumpkey: | ||
| branding = branding.replace("%code%", "%s" % "bumpkey") | ||
| elif opts.blank: | ||
| branding = branding.replace("%code%", "%s" % "blank") | ||
| elif opts.key: | ||
| branding = branding.replace("%code%", "%s" % (opts.key if opts.key else "NA")) | ||
| else: | ||
| branding = branding.replace("%code%", "%s" % "NA") | ||
|
|
||
| with open(os.path.join(BRAND_DIR, "branding.svg"), 'w') as f: | ||
| f.write(branding) | ||
|
|
||
| DEVNULL = open(os.devnull, 'w') | ||
|
|
||
| subprocess.check_call(["inkscape", "--export-eps", os.path.join(BRAND_DIR, "branding.eps"), os.path.join(BRAND_DIR, "branding.svg"),]) | ||
| subprocess.check_call(["pstoedit", "-nb", "-dt", "-f", "dxf:-polyaslines", os.path.join(BRAND_DIR, "branding.eps"), os.path.join(BRAND_DIR, "branding.dxf")], stderr=DEVNULL) | ||
| subprocess.check_call(["inkscape", "--export-type", "eps","--export-filename", os.path.join(BRAND_DIR, "branding.eps"), os.path.join(BRAND_DIR, "branding.svg"),]) | ||
| subprocess.check_call(["pstoedit", "-nb", "-dt", "-f", "dxf:-polyaslines", os.path.join(BRAND_DIR, "branding.eps"), os.path.join(BRAND_DIR, "branding.dxf")], stderr=subprocess.DEVNULL) | ||
|
|
||
| # Read base settings | ||
| with open(os.path.join(BASE_DIR, "base-settings.scad"), 'r') as f: | ||
|
|
@@ -434,7 +457,7 @@ def main(argv=None): | |
| combination = opts.key.split(",") | ||
| for idx in range(0, len(combination)): | ||
| try: | ||
| int(combination[idx]) | ||
| float(combination[idx]) | ||
| except ValueError: | ||
| combination[idx] = '"%s"' % combination[idx] | ||
| f.write("combination = [%s];\n" % ",".join(combination)) | ||
|
|
@@ -462,10 +485,22 @@ def main(argv=None): | |
| f.write("include <includes/default-keycombcuts.scad>;") | ||
| f.write("\n") | ||
|
|
||
| subprocess.check_call(["inkscape", "--export-eps", os.path.join(BASE_DIR, "profile.eps"), opts.profile]) | ||
| subprocess.check_call(["pstoedit", "-nb", "-dt", "-f", "dxf:-polyaslines", os.path.join(BASE_DIR, "profile.eps"), os.path.join(BASE_DIR, "profile.dxf")], stderr=DEVNULL) | ||
| subprocess.check_call(["openscad", os.path.join(BASE_DIR, "key.scad") ]) | ||
|
|
||
| outputname = "key.stl" | ||
| if opts.refinname: | ||
| # result | ||
| code = "NA" | ||
| if opts.bumpkey: | ||
| code = "bumbkey" | ||
| if opts.blank: | ||
| code = "blank" | ||
| if opts.key: | ||
| code = "".join(opts.key.split(",")) | ||
| outputname = "key_{}_{}_{}_{}_{}.stl".format(os.path.basename(opts.profile).replace(".svg", ""), model, code, def_kl, def_tol) | ||
| elif opts.output: | ||
| outputname = opts.output | ||
| subprocess.check_call(["inkscape", "--export-type", "eps","--export-filename", os.path.join(BASE_DIR, "profile.eps"), opts.profile]) | ||
| subprocess.check_call(["pstoedit", "-nb", "-dt", "-f", "dxf:-polyaslines", os.path.join(BASE_DIR, "profile.eps"), os.path.join(BASE_DIR, "profile.dxf")], stderr=subprocess.DEVNULL) | ||
| subprocess.check_call(["/usr/bin/openscad", os.path.join(BASE_DIR, "key.scad") ]) | ||
|
|
||
| if __name__ == "__main__": | ||
| sys.exit(main()) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| // This definition is also valid for: AB A90 | ||
|
|
||
| // Key length | ||
| kl=27.7; | ||
|
|
||
| // Combination cuts | ||
|
|
||
| // Shoulder | ||
| aspace = 4.7; | ||
|
|
||
| // Pin distance | ||
| pinspace = 4.05; | ||
|
|
||
|
|
||
| // not used | ||
| // Highest cut | ||
| hcut = ph - 2*tol - 4.45; | ||
|
|
||
| // Cut spacing | ||
| cutspace = 1; // Actually alternating between 0.43/0.44 | ||
|
|
||
| // Cut angle | ||
| cutangle = 112; | ||
|
|
||
| // Plateau spacing of the cut | ||
| platspace = 0.0; | ||
|
|
||
| // cur the key from the bottom by giving the size in milimeter. | ||
| realdim = true; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,26 +1,26 @@ | ||
| include <regularcut.scad>; | ||
|
|
||
| module keycombcuts(laser=false) { | ||
| module keycombcuts(laser=false, realdim=false) { | ||
| for (i = [0:len(keycomb)-1]) { | ||
| keycombcut(i, keycomb[i], aspace, laser); | ||
| keycombcut(i, keycomb[i], aspace, laser, realdim=realdim); | ||
| } | ||
| if (laser) { | ||
| keycombcuts_laser(); | ||
| keycombcuts_laser(realdim=realdim); | ||
| } | ||
| } | ||
|
|
||
| module keycombcuts_laser() { | ||
| module keycombcuts_laser(realdim=false) { | ||
| for (i = [0:len(keycomb)-1]) { | ||
| if (i < len(keycomb)-1) { | ||
| hull() { | ||
| keycombcut(i, keycomb[i], aspace, true, false, true); | ||
| keycombcut(i+1, keycomb[i+1], aspace, true, true, false); | ||
| keycombcut(i, keycomb[i], aspace, true, false, true, realdim=realdim); | ||
| keycombcut(i+1, keycomb[i+1], aspace, true, true, false, realdim=realdim); | ||
| } | ||
| } | ||
| } | ||
| hull() { | ||
| keycombcut(len(keycomb)-1, keycomb[len(keycomb)-1], aspace, true, false, true); | ||
| keycombcut(len(keycomb)-1, keycomb[len(keycomb)-1], aspace, true, false, true, realdim=realdim); | ||
| translate([0,0,-kl]) | ||
| keycombcut(len(keycomb)-1, keycomb[len(keycomb)-1], aspace, true, false, true); | ||
| keycombcut(len(keycomb)-1, keycomb[len(keycomb)-1], aspace, true, false, true, realdim=realdim); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -94,7 +94,7 @@ union() { | |
| keytipcuts(); | ||
|
|
||
| if (!blank) { | ||
| keycombcuts(lasercut); | ||
| keycombcuts(lasercut, realdim); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume your goal here was to allow the combination to be specified in mm rather than code? I would recommend doing this by specifying a system that has a cutspace resolution that is a 0.1mm (there is nothing under that precision happening usually with keys) and then just multiplying your values by 10 and going off the highest possible cut. I will think about adding this, however I am currently refactoring the combination system anyway, using 1 as the shallowest cut like most key programs do, so the codes stay comparable. It could take a while for me to merge things.
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, what profile is the svg (i.e. what lock/brand did it belong to?)
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That point was the main point for my PR in fact. So, I would like to have the possibility to enter the measure from the botom of the key in mm. So if you are refactoring all the tool, if you can think regarding this issue and adding a profile named "mm" or something like that it could be good. As I'm not a key expert, I'm not able to say "this key with this profile possess these definitions", I'm juste able to get the tooth length in mm, the space between the shoulder and the first pin, and le length of the key. From that, I Would be able to create the same key. Regarding the SVG, I don't know which profile is it. In the same way, I would like to create the profile from a picture and the key from a picture (with the measure from the KeyDecoder application) without knowing the brand, type, ... so from a "key noob" point of view ^^ I hope it was clear :) |
||
| } | ||
| } | ||
| khcyo = -(khcy-ph)/2; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| // The tolerance to use when removing material from the profile | ||
| tol = 0.2; | ||
|
|
||
| // Key profile height (including tolerance, i.e. measured on the lock, not the blank) | ||
| // If you have information on the key blank height, add 2*tol. | ||
| ph=8.8 + 2*tol; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently newer inkscape uses --export-filename while the older (Ubuntu LTS) does not support that. We likely need some logic to determine which switches to use. I can implement that later. That applies for all the inkscape invocations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using inkscape from Kali, so maybe another version (Inkscape v1.2.2 today), but the web version fix that point :)