ladlibertine wrote
This is my first time using OpenSCAD, and I've been encountering problems
rendering
this object https://app.box.com/s/1rtawzal0b6a55d4ftezfbc7ixlflb30
.
The recurring problem is an "invalid 2-manifold" error. However, I am not
always presented with this error when I render. It seems to be more likely
to throw an error when I increase the number of facets for my cylinders
(half the time when n_facet = 4, almost every time when n_facet = 1000).
Checking non-manifold edges and vertices in MeshLab shows me the error is
with the inside faces of 4 of my gear teeth (at positions 0, PI/2, PI,
3*PI/2 around the part), but these are made symmetrically by a simple for
loop... No idea why the problem would be limited to only 4 teeth.
I've checked the CW/CCW sense of all my face contours. They're consistent.
As a sanity check, when looking at the bottom face of a cube from beneath
it, you see (in CCW order) the vertices 0, 1, 2, 3 with vertices 4, 5, 6,
7 above them, respectively. This implies the faces:
[3, 2, 1, 0] // base
[4, 5, 6, 7] // lid
[4, 7, 3, 0] // face1
[6, 5, 1, 2] // opposite face1
[5, 4, 0, 1] // face2
[7, 6, 2, 3] // opposite face2
As it stands, I got lucky and was able to render with n_facet = 1000, but
any help to avoid this problem in the future would be greatly appreciated.
Welcome to the forum.
However, I am not always presented with this error when I render.
That could be due to caching of CGAL renders, you only get the error when it
processes that chunk, if it's cached you don't get the error again.
Those errors tend to be when two objects share a edge, CGAL can't tell if it
is one geometry or two, usually chooses well, but not always. The $fn
changes the angles slightly and probably also complicates it by introducing
small floating point anomalies. You need to either have them separated by a
small amount or embedded into each other by a small amount.
In this case the edges in question are at the interface of the gears the
gear cylinder and the tapered cylinder, all at the boundary of
h_base+h_gears and the inside radius of the gears and gear cylinder.
You have the same potential issue at every interface level of your stack of
cylinders, they should overlap a smidgen, rather than butting up.
A common method is something like;
epsilon=0.05;
h1=5;
h2=10;
cylinder(r=10,h=h1);
translate([0,0,h1-e])
cylinder(r=5,h=h2+e);
This works.
encoder_gear ();
module encoder_gear ()
{
// Dimensions for part base
h_base = 5;
h_gears = 7;
h_taper = 2;
h_cap = 1;
r_base = 12.3;
r_gears = 8.5;
r_axle = 3;
side_taxle = 4.5;
depth_taxle = 1;
offset_taxle = r_axle - depth_taxle;
h_notch = 8;
n_facet = 1000;
e=0.05; // epsilon
// Padding to ensure good cut for axle
h_pad = 5;
// Dimensions for gears
n_tooth = 36;
side_tri = 1;
// Triangular gears
h_tri = sqrt(pow(side_tri,2)-pow(side_tri/2,2));
gear_angle = 360/12;
// Truncated triangular gears
trunc_tri = 0.36;
h_tri2 = sqrt(pow(side_tri,2)-pow((side_tri-trunc_tri)/2,2));
gear_angle2 = 360-360/4;
// Define gear points (triangular, truncated)
gear_points = [
[ -side_tri/2 , 0 , 0 ], // 0
[ 0 , h_tri , 0 ], // 1
[ side_tri/2 , 0 , 0 ], // 2
[ -side_tri/2 , 0 , h_gears ], // 3 (pairs with 0)
[ 0 , h_tri , h_gears ], // 4 (pairs with 1)
[ side_tri/2 , 0 , h_gears ] // 5 (pairs with 2)
];
gear_points2 = [
[ -side_tri/2 , 0 , 0 ], // 0
[ -trunc_tri/2, h_tri2, 0 ], // 1
[ trunc_tri/2, h_tri2, 0 ], // 2
[ side_tri/2 , 0 , 0 ], // 3
[ -side_tri/2 , 0 , h_gears ], // 4 (0)
[ -trunc_tri/2, h_tri2, h_gears ], // 5 (1)
[ trunc_tri/2, h_tri2, h_gears ], // 6 (2)
[ side_tri/2 , 0 , h_gears ], // 7 (3)
];
// Define gear faces (points given in CW sense, looking in from
outside)
gear_faces = [
[4,3,0,1], // face1
[1,2,5,4], // face2
[0,3,5,2], // face3
[2,1,0], // base
[4,5,3] // lid
];
gear_faces2 = [
[7,6,2,3], // face1
[3,0,4,7], // face2
[1,5,4,0], // face3
[2,6,5,1], // face4
[3,2,1,0], // base
[5,6,7,4] // lid
];
// Draw encoder gears
difference ()
{
// Solid parts
union ()
{
// Draw base cylinder
cylinder(h = h_base, r1 = r_base, r2 = r_base, center = false,
$fn = n_facet);
// Draw gear cylinder (translated to stack)
#translate ([0,0,h_base-e])
{
cylinder(h = h_gears+e, r1 = r_gears, r2 = r_gears, center
= false, $fn = n_facet);
}
// Draw tapered cylinder (translated to stack)
translate ([0,0,h_base+h_gears-e])
{
cylinder(h = h_taper+e, r1 = r_gears+h_tri, r2 = r_base+1,
center = false, $fn = n_facet);
}
// Draw tapered cylinder (translated to stack)
translate ([0,0,h_base+h_gears+h_taper-e])
{
cylinder(h = h_cap+e, r1 = r_base+1, r2 = r_base+1, center
= false, $fn = n_facet);
}
// Draw gears (translated and rotated to stack at equal
offset; to face outward)
for (i=[0:n_tooth-1])
{
rotate( [0,0,i*360/n_tooth] ) translate(
[r_gears-e,0,h_base] )
{
rotate([0,0,gear_angle2]) // 360-360/4
{
polyhedron( gear_points2, gear_faces2 );
}
}
}
}
// Axle hole
union ()
{
difference() {
// Draw hole (padded to avoid printing errors)
translate ([0,0,-h_pad/2])
{
cylinder(h = h_base + h_gears + h_taper + h_cap +
h_pad, r1 = r_axle, r2 = r_axle, center = false, $fn = n_facet);
}
// Draw axle truncation for snug fit
translate ([offset_taxle+side_taxle/2,0,(h_base + h_gears
h_taper + h_cap)/2])
{
box = [side_taxle, side_taxle, h_base + h_gears +
h_taper + h_cap];
cube(box, center = true);
}
}
// Finish hole (to account for notch length)
translate ([0,0,-h_pad/2])
{
cylinder(h = h_base + h_gears + h_taper + h_pad/2 -
h_notch, r1 = r_axle, r2 = r_axle, center = false, $fn = n_facet);
}
}
}
}
Admin - PM me if you need anything, or if I've done something stupid...
Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.
View this message in context: http://forum.openscad.org/Changing-Facet-Number-Creates-Invalid-2-Manifold-tp19666p19673.html
Sent from the OpenSCAD mailing list archive at Nabble.com.