ahmetcemturan/SFACT — Issue #17: SFACT generates unnecessary overhang in internal pipe
Author: DavidGoodenough
Created: 2011-12-15 15:42:44+00:00
State: open

I generated an STL file from the scad file below and then looked at the gcode after sfact had sliced it using the slice walking window in pronterface. As you rise up through the left hand vertical pipe in the model, the pipe bends through 90 degrees and becomes horizontal. If you move up to where the pipe void starts to narrow, rather than filling in the roof of the pipe uniformly, the bottom (as you look at the model on pronterface) side of the pipe next to the bend has a odd jig in its walls. This is not in the scad model, and if you fly through the model with meshlab it should not be there. Slic3r gets this pipe right, but has problems with parts of the vertical pipes which it leaves filled rather than hollow.

I have not tried building this model as if the pronterface rendering is right this overhang will sag into the pipe which will render it useless.

>>>>>>>>>>>>>>>>.scad file>>>>>>>>>>>>>>>>

// Hydrocyclone
// Copyright(C) David Goodenough 2011
// Licenced under GPL V3
// Much of the calculations for this parametric cyclone come from a paper
// found on the web called "The Sizing and Selection of Cyclones" by Richard
// A. Arterburn.

$fs=0.01;

cyclone(supplyIR=3,underflowIR=2,pipeWall=2,pipeLen=15,vesselWall=3);

// A pipe is an outer cylinder from which is removed an inner cylinder
module pipe(len,ir,wall) {
difference() {
cylinder(len,r=ir+wall);
#	translate(v=[0,0,-0.5]) cylinder(len+1,r=ir);
}
}
// A funnel is an outer cone from which is removed an inner cone
module funnel(len,ir1,ir2,wall) {
difference() {
cylinder(len,r1=ir1+wall,r2=ir2+wall);
#	translate(v=[0,0,-0.5]) cylinder(len+1,r1=ir1,r2=ir2);
}
}
// This is like a pipe, but has a side pipe entering it. This side pipe has
// to be clipped by the inside of the main cylinder. But actually the side
// pipe is a block, its easier that way. Also no need to remove the inside
// the pipe as we remove that later.
module chamber(cylLen,cylIr,cylWall,pipeLen,pipeIr,pipeWall, inletOffset,inletAngle) {
xlen = (2*cylIr) + pipeIr + pipeWall;
ylen = 2*( pipeIr + pipeWall );
zlen = 2*pipeIr + cylWall;
difference() {
union() {
cylinder(cylLen,r=cylIr+cylWall);
rotate([0,0,inletAngle])
translate([inletOffset+pipeIr,-(ylen + pipeWall/2),zlen/2])
cube(size=[xlen,ylen,zlen],center=true);
}
#	translate([0,0,-0.5]) cylinder(cylLen+ 1,r=cylIr);
}
}

// This creates the inside of the inlet pipe, which has a 90 degree bend in it
// We remove this from a solid block to create the pipe, and union that with a
// real pipe for the outside connector.
//
//pipeCorder
// Build a pipe with a 90 degree corner
// @param cylR object radius
// @param bendR bend radius
// @param upperL length of upper pipe
// @param lowerL length of lower pipe
//
module pipeCorner(cylR,bendR,upperL,lowerL) {
translate([-(bendR+cylR),0,0])
union() {
// lower arm
translate([bendR+cylR, 0 /*.02 */, 0])
rotate([90, 0, 0])
cylinder(r=cylR, h=lowerL+2);
// upper arm
rotate([0, 0, 90])
translate([bendR + cylR, -0 /*.02 */, 0])
rotate([-90, 0, 0])
cylinder(r=cylR, h=upperL+2);
// bend
difference() {
// torus
rotate_extrude()
translate([bendR + cylR, 0, 0])
circle(r=cylR);
// lower cutout
translate([-50, -100, -50]) cube([100, 100, 100]);
// upper cutout
rotate([0, 0, 90]) translate([-50, 0, -50]) cube([100, 100, 100]);
}
}
}

// Cyclone takes several arguements:-
// supplyIR the internal radius of the inflow and outflow pipes
// underflowIR the internal radius of the underflow pipe
// pipeWall the thickness of the pipe walls
// pipeLen the length of the pipes outside the vessel, ie the length the pipe fits to
// vesselWall the thickness of the main vessel walls
//
// Everything else is calculated. The only two bits of this that are not from
// "the sizing and selection of hydrocyclones" by Richard Arterburn are the height
// of the chamber (which is set to its diameter) and and angle for the cone
// (which is set to 15 degrees, the doc says 10-20 degrees).
//
module cyclone(supplyIR,underflowIR,pipeWall,pipeLen,vesselWall) {
cylinderHeightMultiplier = 2;
coneAngle = 15;
// cylinder internal radius is such that the input pipe area is 0.05
// times the cyclone diameter
cylinderIR = sqrt(80 * supplyIR * supplyIR) / 2;
echo("cylinderIR=",cylinderIR);
// cylinder height is twice the cylinder internal radius
cylinderHeight = cylinderIR * cylinderHeightMultiplier;
echo("cylinderHeight=",cylinderHeight);
// the vortex finder depth (in the cylinder) is 0.7 times the cylinderIR
vortexLen = cylinderIR * 0.7;
echo("vortexLen=",vortexLen);
// cone height is such that the angle of the cone is coneAngle degrees (the
// book says between 10 and 20 degrees).
coneHeight = (cylinderIR - underflowIR) / tan(coneAngle);
echo("coneHeight=",coneHeight);
echo("total Height=",pipeLen + pipeLen + cylinderHeight + coneHeight);
removeOffset = cylinderIR + vesselWall;
pipeSeparation = cylinderIR * 2; // may change this if we add a screw fit connector
inletOffset = cylinderIR - supplyIR;
inletAngle = asin(inletOffset/pipeSeparation) + 180;
// Now build it.
// We build it upside down so that it does not need internal support
// First a plate so that it adheres to the build surface.
difference() {
union() {
difference() {
union() {
translate([-50-(removeOffset/2),-25,0]) cube(size=[100,50,2]);
translate([-(cylinderIR+vesselWall)*2.5,-cylinderIR-vesselWall,0])
cube(size=[(cylinderIR+vesselWall)*3.5,
2*(cylinderIR+vesselWall),
pipeLen],
center=false);
}
#	union() {
translate([-(cylinderIR),0,0])
cube(size=[(cylinderIR*3)+vesselWall,
2*cylinderIR,
pipeLen-vesselWall],
center=true);
cylinder(h=pipeLen,r=supplyIR);
translate([-pipeSeparation,0,0])
cylinder(h=pipeLen,r=supplyIR);
}
}
// First the outlet pipe
pipe(vortexLen + vesselWall + pipeLen,supplyIR,pipeWall);
// and the end of the inlet pipe
translate([-pipeSeparation,0,0])
pipe(pipeLen+(vesselWall-pipeWall),supplyIR,pipeWall);
// the bend of the inlet pipe
#	translate([-pipeSeparation,/*1.5*/ 0,pipeLen+pipeWall-(vesselWall-pipeWall)/2])
rotate([90,0,inletAngle])
pipeCorner(supplyIR,vesselWall-pipeWall,pipeLen+vesselWall,pipeLen);
// end plate
translate([0,0,pipeLen]) pipe(vesselWall,supplyIR,cylinderIR);
// Now the chamber
translate([0,0,pipeLen]) chamber(cylinderHeight,cylinderIR,vesselWall,
cylinderIR+vesselWall,supplyIR,pipeWall,
inletOffset,inletAngle);
// now the cone
translate([0,0,pipeLen + cylinderHeight])
funnel(coneHeight,cylinderIR,underflowIR,vesselWall);
// The underflow pipe is unnecessary, so ignore it
// finally the underflow pipe
//	translate([0,0,pipeLen + cylinderHeight + coneHeight])
//	pipe(pipeLen,underflowIR,pipeWall);
}
// the bend of the inlet pipe
#	translate([-pipeSeparation,/*1.5*/ 0,pipeLen+pipeWall-(vesselWall-pipeWall)/2])
rotate([90,0,inletAngle])
pipeCorner(supplyIR,vesselWall-pipeWall,pipeLen+vesselWall,pipeLen);

}
}