Merge branch 'master' of github.com:rambo/MCAD

Conflicts:
	triangles.scad
This commit is contained in:
Eero af Heurlin 2010-08-26 12:27:55 +03:00
commit add07c01b0
7 changed files with 256 additions and 74 deletions

43
boxes.scad Normal file
View file

@ -0,0 +1,43 @@
// Library: boxes.scad
// Version: 1.0
// Author: Marius Kintel
// Copyright: 2010
// License: BSD
// roundedBox([width, height, depth], float radius, bool sidesonly);
// EXAMPLE USAGE:
// roundedBox([20, 30, 40], 5, true);
// size is a vector [w, h, d]
module roundedBox(size, radius, sidesonly)
{
rot = [ [0,0,0], [90,0,90], [90,90,0] ];
if (sidesonly) {
cube(size - [2*radius,0,0], true);
cube(size - [0,2*radius,0], true);
for (x = [radius-size[0]/2, -radius+size[0]/2],
y = [radius-size[1]/2, -radius+size[1]/2]) {
translate([x,y,0]) cylinder(r=radius, h=size[2], center=true);
}
}
else {
cube([size[0], size[1]-radius*2, size[2]-radius*2], center=true);
cube([size[0]-radius*2, size[1], size[2]-radius*2], center=true);
cube([size[0]-radius*2, size[1]-radius*2, size[2]], center=true);
for (axis = [0:2]) {
for (x = [radius-size[axis]/2, -radius+size[axis]/2],
y = [radius-size[(axis+1)%3]/2, -radius+size[(axis+1)%3]/2]) {
rotate(rot[axis])
translate([x,y,0])
cylinder(h=size[(axis+2)%3]-2*radius, r=radius, center=true);
}
}
for (x = [radius-size[0]/2, -radius+size[0]/2],
y = [radius-size[1]/2, -radius+size[1]/2],
z = [radius-size[2]/2, -radius+size[2]/2]) {
translate([x,y,z]) sphere(radius);
}
}
}

View file

@ -1,6 +1,6 @@
//test_involute_curve(); //test_involute_curve();
test_gears(); //test_gears();
demo_3d_gears(); //demo_3d_gears();
// Geometry Sources: // Geometry Sources:
// http://www.cartertools.com/involute.html // http://www.cartertools.com/involute.html

View file

@ -32,7 +32,7 @@ module test_bevel_gear_pair(){
module test_bevel_gear(){bevel_gear();} module test_bevel_gear(){bevel_gear();}
bevel_gear(); //bevel_gear();
pi=3.1415926535897932384626433832795; pi=3.1415926535897932384626433832795;

View file

@ -4,18 +4,19 @@ from subprocess import Popen, PIPE
mod_re = (r"\bmodule\s+(", r")\s*\(\s*") mod_re = (r"\bmodule\s+(", r")\s*\(\s*")
func_re = (r"\bfunction\s+(", r")\s*\(") func_re = (r"\bfunction\s+(", r")\s*\(")
def extract_mod_names(fpath, name_re=r"\w+"): def extract_definitions(fpath, name_re=r"\w+", def_re=""):
regex = name_re.join(mod_re) regex = name_re.join(def_re)
matcher = re.compile(regex) matcher = re.compile(regex)
return (m.group(1) for m in matcher.finditer(fpath.read())) return (m.group(1) for m in matcher.finditer(fpath.read()))
def extract_mod_names(fpath, name_re=r"\w+"):
return extract_definitions(fpath, name_re=name_re, def_re=mod_re)
def extract_func_names(fpath, name_re=r"\w+"): def extract_func_names(fpath, name_re=r"\w+"):
regex = name_re.join(func_re) return extract_definitions(fpath, name_re=name_re, def_re=func_re)
matcher = re.compile(regex)
return (m.group(1) for m in matcher.finditer(fpath.read()))
def collect_test_modules(): def collect_test_modules(dirpath=None):
dirpath = py.path.local("./") dirpath = dirpath or py.path.local("./")
print "Collecting openscad test module names" print "Collecting openscad test module names"
test_files = {} test_files = {}
@ -26,21 +27,24 @@ def collect_test_modules():
test_files[fpath] = modules test_files[fpath] = modules
return test_files return test_files
collect_test_modules() class Timeout(Exception): pass
def call_openscad(path, stlpath, timeout=20): def call_openscad(path, stlpath, timeout=1):
try: try:
proc = Popen(['openscad', '-s', str(stlpath), str(path)], command = ['openscad', '-s', str(stlpath), str(path)]
print command
proc = Popen(command,
stdout=PIPE, stderr=PIPE, close_fds=True) stdout=PIPE, stderr=PIPE, close_fds=True)
calltime = time.time() calltime = time.time()
time.sleep(0.01)
#print calltime #print calltime
while True: while True:
if proc.poll() is not None: if proc.poll() is not None:
break break
time.sleep(0.1) time.sleep(0.5)
#print time.time() #print time.time()
if time.time() > calltime + timeout: if time.time() > calltime + timeout:
raise Exception("Timeout") raise Timeout()
finally: finally:
try: try:
proc.terminate() proc.terminate()

135
shapes.scad Normal file
View file

@ -0,0 +1,135 @@
/*
* OpenSCAD Shapes Library (www.openscad.org)
* Copyright (C) 2009 Catarina Mota
*
* License: LGPL 2.1 or later
*/
//box(width, height, depth);
//roundedBox(width, height, depth, factor);
//cone(height, radius);
//oval(width, height, depth);
//tube(height, radius, wall);
//ovalTube(width, height, depth, wall);
//hexagon(height, depth);
//octagon(height, depth);
//dodecagon(height, depth);
//hexagram(height, depth);
//rightTriangle(adjacent, opposite, depth);
//equiTriangle(side, depth);
//12ptStar(height, depth);
//----------------------
// size is a vector [w, h, d]
module box(size) {
cube(size, true);
}
// size is a vector [w, h, d]
module roundedBox(size, radius) {
cube(size - [2*radius,0,0], true);
cube(size - [0,2*radius,0], true);
for (x = [radius-size[0]/2, -radius+size[0]/2],
y = [radius-size[1]/2, -radius+size[1]/2]) {
translate([x,y,0]) cylinder(r=radius, h=size[2], center=true);
}
}
module cone(height, radius, center = false) {
cylinder(height, radius, 0, center);
}
module oval(w,h, height, center = false) {
scale([1, h/w, 1]) cylinder(h=height, r=w, center=center);
}
// wall is wall thickness
module tube(height, radius, wall, center = false) {
difference() {
cylinder(h=height, r=radius, center=center);
cylinder(h=height, r=radius-wall, center=center);
}
}
// wall is wall thickness
module ovalTube(height, rx, ry, wall, center = false) {
difference() {
scale([1, ry/rx, 1]) cylinder(h=height, r=rx, center=center);
scale([(rx-wall)/rx, (ry-wall)/rx, 1]) cylinder(h=height, r=rx, center=center);
}
}
// size is the XY plane size, height in Z
module hexagon(size, height) {
boxWidth = size/1.75;
for (r = [-60, 0, 60]) rotate([0,0,r]) cube([boxWidth, size, height], true);
}
// size is the XY plane size, height in Z
module octagon(size, height) {
intersection() {
cube([size, size, height], true);
rotate([0,0,45]) cube([size, size, height], true);
}
}
// size is the XY plane size, height in Z
module dodecagon(size, height) {
intersection() {
hexagon(size, height);
rotate([0,0,90]) hexagon(size, height);
}
}
// size is the XY plane size, height in Z
module hexagram(size, height) {
boxWidth=size/1.75;
for (v = [[0,1],[0,-1],[1,-1]]) {
intersection() {
rotate([0,0,60*v[0]]) cube([size, boxWidth, height], true);
rotate([0,0,60*v[1]]) cube([size, boxWidth, height], true);
}
}
}
module rightTriangle(adjacent, opposite, height) {
difference() {
translate([-adjacent/2,opposite/2,0]) cube([adjacent, opposite, height], true);
translate([-adjacent,0,0]) {
rotate([0,0,atan(opposite/adjacent)]) dislocateBox(adjacent*2, opposite, height);
}
}
}
module equiTriangle(side, height) {
difference() {
translate([-side/2,side/2,0]) cube([side, side, height], true);
rotate([0,0,30]) dislocateBox(side*2, side, height);
translate([-side,0,0]) {
rotate([0,0,60]) dislocateBox(side*2, side, height);
}
}
}
module 12ptStar(size, height) {
starNum = 3;
starAngle = 360/starNum;
for (s = [1:starNum]) {
rotate([0, 0, s*starAngle]) cube([size, size, height], true);
}
}
//-----------------------
//MOVES THE ROTATION AXIS OF A BOX FROM ITS CENTER TO THE BOTTOM LEFT CORNER
//FIXME: Why are the dimensions changed?
// why not just translate([0,0,-d/2]) cube([w,h,d]);
module dislocateBox(w,h,d) {
translate([w/2,h,0]) {
difference() {
cube([w, h*2, d+1]);
translate([-w,0,0]) cube([w, h*2, d+1]);
}
}
}

View file

@ -2,21 +2,22 @@ import py
from openscad_utils import * from openscad_utils import *
def pytest_generate_tests(metafunc):
if "modpath" in metafunc.funcargnames:
if "modname" in metafunc.funcargnames:
for fpath, modnames in collect_test_modules().items():
for modname in modnames:
metafunc.addcall(funcargs=dict(modname=modname, modpath=fpath))
else:
dirpath = py.path.local("./")
for fpath in dirpath.visit('*.scad'):
metafunc.addcall(funcargs=dict(modpath=fpath))
temppath = py.test.ensuretemp('MCAD') temppath = py.test.ensuretemp('MCAD')
def pytest_generate_tests(metafunc):
if "modpath" in metafunc.funcargnames:
for fpath, modnames in collect_test_modules().items():
os.system("cp %s %s/" % (fpath, temppath))
if "modname" in metafunc.funcargnames:
for modname in modnames:
metafunc.addcall(funcargs=dict(modname=modname, modpath=fpath))
else:
metafunc.addcall(funcargs=dict(modpath=fpath))
def test_compile(modname, modpath): def test_compile(modname, modpath):
tempname = "test_" + modpath.basename + modname tempname = "test_" + modpath.basename + modname + '.scad'
fpath = temppath.join(tempname) fpath = temppath.join(tempname)
stlpath = temppath.join(tempname + ".stl") stlpath = temppath.join(tempname + ".stl")
f = fpath.open('w') f = fpath.open('w')
@ -24,10 +25,10 @@ def test_compile(modname, modpath):
//generated testfile //generated testfile
include <%s> include <%s>
%s() %s();
""" % (modpath, modname)) """ % (modpath, modname))
f.flush f.flush
output = call_openscad(path=fpath, stlpath=stlpath) output = call_openscad(path=fpath, stlpath=stlpath, timeout=5)
print output print output
assert output[0] is 0 assert output[0] is 0
assert "warning" or "error" not in output[2].strip().lowercase() assert "warning" or "error" not in output[2].strip().lowercase()
@ -40,5 +41,6 @@ def test_compile_default(modpath):
print output print output
assert output[0] is 0 assert output[0] is 0
assert "warning" or "error" not in output[2].strip().lowercase() assert "warning" or "error" not in output[2].strip().lowercase()
assert len(stlpath.readlines()) == 2

View file

@ -7,14 +7,12 @@
* License: LGPL 2.1 * License: LGPL 2.1
*/ */
/** /**
* Standard right-angled triangle * Standard right-angled triangle
* *
* @param number o_len Lenght of the opposite side * @param number o_len Lenght of the opposite side
* @param number a_len Lenght of the adjacent side * @param number a_len Lenght of the adjacent side
* @param number depth How wide/deep the triangle is in the 3rd dimension * @param number depth How wide/deep the triangle is in the 3rd dimension
* @todo a better way ?
*/ */
module triangle(o_len, a_len, depth) module triangle(o_len, a_len, depth)
{ {