/* Loial Raven's Gear code... this is about a year of work(or a week... something like that)... well, this is the most reacent... it should be quite quick... and powerful... there are a few different gear's... gear(n, pr, mdl, pa, th) <-- basic, require all info gear_n_pr (n, pr, th) -- gear_pr_mdl (pr, mdl, th) |-- only some required info... displays the last info when render gear_n_mdl (n, mdl, th) -- gear_dp_n (dp, n, th) ----- if you use imperial, dimetrical pitch is used instead gear_dp_pr (dp, pr, th) --/ (gear_n_pr also works for this without using mdl and it will tell the autoset dp if you declare imperial_gears) each of these has a different set of variables... all of them work ------------- the different variables you can set before you make the gears ------------------------------------- use_megapov - set this to 1 if you are using megapov, this will enable solid triangle meshes quality_gear_involute, quality_gear_base, quality_gear_end - these define how many points are made for each part of the gear. the base and end qualities only apply if you are using non-0 types quality_gear_layers - the number of layers to use. this only applies if you have any helical angle gear_tooth_end_style - the type of tooth end to use. 0 = semiflat(cylinder about basepoint); uses difference 1 = bezier 2 = triangle form semiflat (default) gear_tooth_base_style - the type of tooth base to use 0 = cylindrical (default) 1 = bezier helical_gear_angle - this is the angle of helical twist to use, if any... remember that meshing gears should have oposite twist angles! gear_fillet_distance - distance to fillet from the tip, only used with gear_tooth_end_style = 1; 0.6 is the maximum under ANSI, 0.1-0.5 looks good. gear_type - the type of gear to make 1 = Full-depth involute, pa=14.5 2 = Full-depth involute, pa=20 (default) 3 = Stub involute, pa=20 4 = coarse-pitch involute spur gears, pa=20 5 = coarse-pitch involute spur gears, pa=25 6 = Fine-pitched involute, pa=20 gear_debug - don't use this unless your playing with the code... outputs a few things to the screen, and changes a few variables from local's to declare's. if you wish to use it, just declare it gear_quiet - this turns off the displaying of the auto-set data. gear_use_prism - the old prism style tooth... this not smooth and it's slower, but i'll leave it in place if you wish to use solid gears without megapov. if you wish to use it, just declare it one_tooth - again, another debug tool... shouldn't be usefull for much... gear_solid - set this to 1 if you want to make glass gears... you must use gear_use_prism or use megapov for this to work properly. metric_gears & imperial_gears - these do not change the behavior of the gear at all, it just changes the output messages. just declare the one you will be using before you #include gears.inc or you can declare it afterwards too... both can work in unison and will if you declare imperial_gears after you've included gears.inc and if you don't #undef metric_gears. it defaults to metric. ----- all of these have defaults and do not have to be set for the gears to be created. find_mesh_angle is a tool for getting multiple gears to mesh. it does support helical gears too. pretty much it should be pretty self explanitory. any #declares you do for the gears should happen before this, you could even define the gears before this... well, accually, the only thing that must be declared before this macro is used, is the helical_gear_angle, if you use that. find_mesh_angle(gear1_pr, gear1_point, gear1_angle_y, gear2_pr, gear2_point) */ #ifdef (use_megapov) #version unofficial MegaPov 0.5; #declare gear_use_megapov = 1; #else #declare gear_use_megapov = 0; #end #ifndef (GEAR_INC) #declare GEAR_INC = 1; #ifndef (metric_gears) #ifndef (imperial_gears) #declare metric_gears=1; #end #end #macro gear_n_pr (n, pr, th) #local mdl = (pr*2)/n; #ifndef (gear_quiet) #ifdef (metric_gears) #render concat("\r\n mdl of gear is auto-set to: ", str(mdl, 5,5), "\r\n") #end #ifdef (imperial_gears) #render concat("\r\n dp of gear is auto-set to: ", str(1/mdl, 5,5), "\r\n") #end #end gear(n, pr, mdl, th) #end #macro gear_pr_mdl (pr, mdl, th) #local n = ceil(((pr*2)/mdl)-0.5); #local pr = (mdl*n)/2; #ifndef (gear_quiet) #render concat("\r\n n of gear is auto-set to: ", str(n, 5,0), "\r\n") #render concat("pr of gear is auto-set to: ", str(pr, 5,5), "\r\n") #ifdef (imperial_gears) #render concat("\r\n dp of gear is auto-set to: ", str(1/mdl, 5,5), "\r\n") #end #end gear(n, pr, mdl, th) #end #macro gear_n_mdl (n, mdl, th) #local pr = (mdl*n)/2; #ifndef (gear_quiet) #render concat("\r\n pr of gear is auto-set to: ", str(pr, 5,5), "\r\n") #ifdef (imperial_gears) #render concat("\r\n dp of gear is auto-set to: ", str(1/mdl, 5,5), "\r\n") #end #end gear(n, pr, mdl, th) #end #macro gear_dp_n (dp, n, th) #local mdl = 1/dp; #local pr = (mdl*n)/2; #ifndef (gear_quiet) #ifdef (metric_gears) #render concat("\r\n mdl of gear is auto-set to: ", str(mdl, 5,5), "\r\n") #end #render concat("\r\n pr of gear is auto-set to: ", str(pr, 5,5), "\r\n") #end gear(n, pr, mdl, th) #end #macro gear_pr_dp (pr, dp, th) #local mdl = 1/dp; #local n = ceil(((pr*2)/mdl)-0.5); #local pr = (mdl*n)/2; #ifndef (gear_quiet) #ifdef (metric_gears) #render concat("\r\n mdl of gear is auto-set to: ", str(mdl, 5,5), "\r\n") #end #render concat("\r\n n of gear is auto-set to: ", str(n, 5,0), "\r\n") #render concat("pr of gear is auto-set to: ", str(pr, 5,5), "\r\n") #end gear(n, pr, mdl, th) #end #macro find_mesh_angle (gear1_pr, gear1_point, gear1_angle_y, gear2_pr, gear2_point) #local angle_change = (-(gear1_point.y*tan(helical_gear_angle*pi/180)/gear1_pr)*180/pi - (gear2_point.y*tan(-helical_gear_angle*pi/180)/gear2_pr)*180/pi); #local delta_point = gear2_point-gear1_point; #local difference_angle = atan2(delta_point.z, delta_point.x)*180/pi; #local difference_angles_gear1 = difference_angle-gear1_angle_y+angle_change; #local offset_angle_gear2 = gear1_pr*difference_angles_gear1/gear2_pr; #local end_angle = 180+difference_angle + offset_angle_gear2; #while (end_angle > 360) #local end_angle = end_angle - 360; #end #while (end_angle < 0) #local end_angle = end_angle + 360; #end end_angle #end #macro vcross3 (point1, basepoint, point2) #local ipoint1 = point1-basepoint; #local ipoint2 = point2-basepoint; vcross(ipoint1, ipoint2) #end #macro involute_point (r_theta) #end #macro rotate_point (r_theta, _angle) #end #macro find_involute_angle (bc, _r) #if (_r/bc >= 1) acos(bc/_r) #else 0 #end #end #macro find_angle(bc, _r) #if (_r/bc >= 1) involute_point().v #else 0 #end #end #macro make_2d_point (r_theta) #end #macro make_3d_point (r_theta) #end #macro gear(n, pr, mdl, th) // ---------------- default settings ------------------------------------- #ifndef (quality_gear_involute) #declare quality_gear_involute = 4; #end #ifndef (quality_gear_end) #declare quality_gear_end = 4; #end #ifndef (quality_gear_base) #declare quality_gear_base = 6; #end #ifndef (quality_gear_layers) #declare quality_gear_layers = 1; #end #ifndef (gear_tooth_end_style) #declare gear_tooth_end_style = 2; // semi-flat - no difference #end #ifndef (gear_tooth_base_style) #declare gear_tooth_base_style = 0; // semi-flat #end #ifndef (helical_gear_angle) #declare helical_gear_angle = 0; // no twist #end #ifndef (gear_fillet_distance) #declare gear_fillet_distance = 0; // no fillet #end #ifndef (gear_solid) #declare gear_solid = 0; #end #ifndef (gear_type) #declare gear_type = 2; #end #if (helical_gear_angle = 0) #declare quality_gear_layers = 1; #end // ---------------- end of defaults -------------------------------------- // ---------------- gear type settings ----------------------------------- #if (gear_type = 1) // -- #local pa = 14.5; // | #local a = mdl; // |-- Full-depth involute, pa=14.5 #local b = mdl*1.157; // | ANSI B6.1 AGMA 201.02 #local fr = mdl*pi/7.5; // -- #end #if (gear_type = 2) // -- #local pa = 20; // | #local a = mdl; // |-- Full-depth involute, pa=20 #local b = mdl*1.157; // | ANSI B6.1 #local fr = mdl*pi*2/3; // -- #end #if (gear_type = 3) // -- #local pa = 20; // | #local a = mdl*0.8; // |-- Stub involute, pa=20 #local b = mdl; // | ANSI B6.1 AGMA 201.02 #local fr = mdl*pi/7.5; // -- #end #if (gear_type = 4) // -- #local pa = 20; // | #local a = mdl; // |-- coarse-pitch involute spur gears, pa=20 #local b = mdl*1.25; // | AGMA 201.02 #local fr = mdl*0.3; // -- #end #if (gear_type = 5) // -- #local pa = 25; // | #local a = mdl; // |-- coarse-pitch involute spur gears, pa=25 #local b = mdl*1.25; // | AGMA 201.02 #local fr = mdl*0.3; // -- #end #if (gear_type = 6) // -- #local pa = 20; // | #local a = mdl; // |-- Fine-pitched involute, pa=20 #local b = mdl*1.2+0.002; // | AGMA 1,003-G93 #local fr = mdl*pi/7.5; // -- #end #if (gear_type > 6 | gear_type < 1) // -- #render concat( // | "\r\nGear type out of range: ", // | str(gear_type,0,0), "\r\n") // |-- Default: #local pa = 20; // | output to error and default to geartype 2 #local a = mdl; // | #local b = mdl*1.157; // | #local fr = mdl*pi*2/3; // -- #end // ---------------- end of gear type settings ---------------------------- // ---------------- internal declarations -------------------------------- #local _bc = pr * cos(pa*pi/180); #local _or = pr + a; #local _rr = pr - b; #local _cp = (2*pi)/n; #ifdef (gear_debug) // if in debug mode, make many variables accessable from outside of file #declare bc = _bc; #declare or = _or; #declare rr = _rr; #declare cp = _cp; #else #local bc = _bc; #local or = _or; #local rr = _rr; #local cp = _cp; #end #undef _bc #undef _or #undef _rr #undef _cp #if (gear_tooth_end_style = 0) #local num_outer_points = 3; #local adjusted_or = or; #end #if (gear_tooth_end_style > 0) #local num_outer_points = quality_gear_end + 1; #switch (gear_tooth_end_style) #case (1) #local adjusted_or = or-gear_fillet_distance*mdl; #break #case (2) #local adjusted_or = or; #break #end #end #if (gear_tooth_base_style = 0) #local num_inner_points = 2; #local adjusted_rr = rr; #end #if (gear_tooth_base_style != 0) #local num_inner_points = quality_gear_base + 2; #local adjusted_rr = pr-mdl; #end #ifdef (gear_debug) #render concat("arr = ", str(pr-mdl, 10, 10), "\r\n") #end #local number_of_points = quality_gear_involute*2+num_inner_points+num_outer_points; #declare _gear_points = array[number_of_points] #declare _gear_normals = array[number_of_points] #local involute_begin = (find_involute_angle(bc, adjusted_rr)); #local involute1_offset = (-find_angle(bc, pr)-(cp/4)); #local involute2_offset = -(involute1_offset); #local involute_length = (find_involute_angle(bc, adjusted_or)); #local circle_offset_val = (find_angle(bc,adjusted_or)); #local involute_step = ((involute_length-involute_begin)/(quality_gear_involute)); #local base_circle1_offset = (find_angle(bc, adjusted_rr) + involute1_offset); #local base_circle2_offset = -base_circle1_offset; #local angle_to_turn = (involute2_offset-(find_angle(bc, pr)))*180/pi; #local _count = 0; // ---------------- end of internal declarations ------------------------- // ------- MAKE POINTS -------------------------------------------------------------------- // -------------------- left involute #local i = 0; #while (i < quality_gear_involute) #local i = i + 1; #local theta = i*involute_step+involute_begin; #declare _gear_points[_count] = make_3d_point(rotate_point(involute_point(), involute1_offset)); #declare _gear_normals[_count] = vnormalize(vcross3( make_3d_point(rotate_point(involute_point(), involute1_offset)), make_3d_point(rotate_point(involute_point(), involute1_offset)), make_3d_point(rotate_point(involute_point(), involute1_offset))+y*0.001)); #local _count = _count+1; #local involute_end_theta = theta; #end // -------------------- outer points #if (gear_tooth_end_style = 0) #local theta = involute1_offset+circle_offset_val; #declare _gear_points[_count] = make_3d_point(); #declare _gear_normals[_count] = vnormalize(vcross3( make_3d_point(), make_3d_point(), make_3d_point()+y*0.001)); #local _count = _count+1; #declare _gear_points[_count] = make_3d_point(); #declare _gear_normals[_count] = vnormalize(vcross3( make_3d_point()+x*0.001, make_3d_point(), make_3d_point()+y*0.001)); #local _count = _count+1; #local theta = -(involute1_offset+circle_offset_val); #declare _gear_points[_count] = make_3d_point(); #declare _gear_normals[_count] = vnormalize(vcross3( make_3d_point(), make_3d_point(), make_3d_point()+y*0.001)); #local _count = _count+1; #end #if (gear_tooth_end_style = 1) // bezier #ifndef (__bicubic_line_inc) #include "bicubic_line.inc" #end #declare _bezier_points = array [4] #local theta = involute1_offset+circle_offset_val; #declare _bezier_points[0] = ; #local point_normal = vrotate( make_2d_point(involute_point())- make_2d_point(involute_point()), 0); #local point_angle = atan2(point_normal.x,point_normal.y); #local point_distance = (or-adjusted_or)*4/3; #declare _bezier_points[1] = _bezier_points[0]+; #declare _bezier_points[2] = <-1,1>*_bezier_points[1]; #declare _bezier_points[3] = <-1,1>*_bezier_points[0]; #local step = 1/quality_gear_end; #local i = 0; #while (i <= quality_gear_end) #declare _gear_points[_count] = make_3d_point( ); #local offset_point = _gear_points[_count]; #declare _gear_normals[_count] = vnormalize(vcross3( make_3d_point(), make_3d_point(), make_3d_point()+y*0.001)); #local _count = _count+1; #local i = i + 1; #end #end #if (gear_tooth_end_style = 2) // circular, but with triangles #local i = quality_gear_end/2; #local step = (involute1_offset+circle_offset_val)*2/quality_gear_end; #while (i >= -quality_gear_end/2) #local theta = step*i; #declare _gear_points[_count] = make_3d_point(); #declare _gear_normals[_count] = vnormalize(vcross3( make_3d_point(), make_3d_point(), make_3d_point()+y*0.001)); #local _count = _count+1; #local i = i - 1; #end #end // -------------------- right involute #local i = quality_gear_involute; #while (i > 0) #local theta = i*involute_step+involute_begin; #declare _gear_points[_count] = make_3d_point(rotate_point(involute_point(),involute1_offset))*<-1,1,1>; #declare _gear_normals[_count] = vnormalize(vcross3( make_3d_point(rotate_point(involute_point(),involute1_offset))*<-1,1,1>, make_3d_point(rotate_point(involute_point(),involute1_offset))*<-1,1,1>, make_3d_point(rotate_point(involute_point(),involute1_offset))*<-1,1,1>+y*0.001)); #local _count = _count+1; #local i = i - 1; #end // -------------------- inside points #if (gear_tooth_base_style = 0) // semi-flat #declare _gear_points[_count] = make_3d_point(); #declare _gear_normals[_count] = vnormalize(vcross3( make_3d_point(), make_3d_point(), make_3d_point()+y*0.001)); #local _count = _count+1; #declare _gear_points[_count] = make_3d_point(); #declare _gear_normals[_count] = vnormalize(vcross3( make_3d_point(), make_3d_point(), make_3d_point()+y*0.001)); #local _count = _count+1; #end #if (gear_tooth_base_style = 1) // bezier #ifndef (__bicubic_line_inc) #include "bicubic_line.inc" #end #declare _bezier_points = array [4] #declare _bezier_points[0] = ; #declare _bezier_points[3] = ; #if (involute_begin > 0) #local point_normal = <1,1,0>*rotate_point( involute_point()- involute_point(), involute1_offset); #ifdef(gear_debug) #render concat("point_normal = <", str(point_normal.u,10,10),", ", str(point_normal.v,10,10),">\r\n") #end #declare _bezier_points[1] = _bezier_points[0]-<((b-mdl)*4/3),((b-mdl)*4/3)*-point_normal.x/point_normal.y>; #declare _bezier_points[2] = _bezier_points[3]-<((b-mdl)*4/3),((b-mdl)*4/3)*point_normal.x/point_normal.y>; #else #declare _bezier_points[1] = _bezier_points[0]-<((b-mdl)*4/3),0>; #declare _bezier_points[2] = _bezier_points[3]-<((b-mdl)*4/3),0>; #end #local step = 1/quality_gear_base; #local i = 0; #while (i <= quality_gear_base/2) #declare _gear_points[_count] = make_3d_point(); #declare _gear_normals[_count] = vnormalize(vcross3( make_3d_point(), make_3d_point(), (make_3d_point())+y*0.001)); #local _count = _count+1; #local i = i + 1; #end #local i = i - 1; #declare _bezier_points[0] = <1,-1>*_bezier_points[0]; #declare _bezier_points[1] = <1,-1>*_bezier_points[1]; #declare _bezier_points[2] = <1,-1>*_bezier_points[2]; #declare _bezier_points[3] = <1,-1>*_bezier_points[3]; #while (i >= 0) #declare _gear_points[_count] = make_3d_point(); #declare _gear_normals[_count] = vnormalize(vcross3( make_3d_point(), make_3d_point(), (make_3d_point())+y*0.001)); #local _count = _count+1; #local i = i - 1; #end #end // -------------- END MAKE POINTS ---------------------------------------------------------- // ---------------- tooth declaration ------------------------------------ #local tooth = object { #if (gear_tooth_end_style = 0) intersection { // } <-- these are so my editor doesn't get confused #end #ifdef (gear_use_prism) prism { linear_spline linear_sweep 0, th, number_of_points+1, #local i = 0; #while (i < number_of_points) <_gear_points[i].x,_gear_points[i].z>, #local i = i + 1; #end _gear_points[0] } #else mesh { #local layer = 0; #local th_step = th/quality_gear_layers; #local angle_change = -(th*tan(helical_gear_angle*pi/180)/pr)*180/pi; #local offset_angle_step = y*angle_change/quality_gear_layers; #local coff = <0,0,0>; #local noff = coff+offset_angle_step; #local _normoff = helical_gear_angle; #ifdef (gear_debug) #declare normoff = _normoff; #end #while (layer < quality_gear_layers) #local ath = th_step*layer; #local bth = th_step*(layer+1); #local i = 0; #while (i < number_of_points-1) smooth_triangle { vrotate(_gear_points[i]+y*ath ,coff), vrotate(vrotate(_gear_normals[i] ,z*_normoff),coff), vrotate(_gear_points[i+1]+y*bth,noff), vrotate(vrotate(_gear_normals[i+1],z*_normoff),noff), vrotate(_gear_points[i+1]+y*ath,coff), vrotate(vrotate(_gear_normals[i+1],z*_normoff),coff) } smooth_triangle { vrotate(_gear_points[i]+y*ath ,coff), vrotate(vrotate(_gear_normals[i] ,z*_normoff),coff), vrotate(_gear_points[i]+y*bth ,noff), vrotate(vrotate(_gear_normals[i] ,z*_normoff),noff), vrotate(_gear_points[i+1]+y*bth,noff), vrotate(vrotate(_gear_normals[i+1],z*_normoff),noff) } #local i = i+1; #end smooth_triangle { vrotate(_gear_points[i]+y*ath,coff), vrotate(vrotate(_gear_normals[i],z*_normoff),coff), vrotate(_gear_points[0]+y*bth,noff), vrotate(vrotate(_gear_normals[0],z*_normoff),noff), vrotate(_gear_points[0]+y*ath,coff), vrotate(vrotate(_gear_normals[0],z*_normoff),coff) } smooth_triangle { vrotate(_gear_points[i]+y*ath,coff), vrotate(vrotate(_gear_normals[i],z*_normoff),coff), vrotate(_gear_points[i]+y*bth,noff), vrotate(vrotate(_gear_normals[i],z*_normoff),noff), vrotate(_gear_points[0]+y*bth,noff), vrotate(vrotate(_gear_normals[0],z*_normoff),noff) } #local coff = coff+offset_angle_step; #local noff = noff+offset_angle_step; #local layer = layer + 1; #end #local _gear_center_point = make_3d_point(); #local i = 0; #while (i < number_of_points-1) triangle { _gear_points[i], _gear_points[i+1], _gear_center_point } triangle { vrotate(_gear_points[i]+y*th ,coff), vrotate(_gear_points[i+1]+y*th ,coff), vrotate(_gear_center_point+y*th,coff) } #local i = i + 1; #end triangle { _gear_points[i], _gear_points[0], _gear_center_point } triangle { vrotate(_gear_points[i]+y*th ,coff), vrotate(_gear_points[0]+y*th ,coff), vrotate(_gear_center_point+y*th,coff) } #if (gear_use_megapov) inside_vector y #end } #end // --- again here #if (gear_tooth_end_style = 0) // v cylinder { <0,-0.00001,0>, <0,0.00001+th,0>, or } /* { */ } bounded_by { cylinder { <0,-0.1,pr>, <0,0.1+th,pr>, 1.5*mdl } } #end } // ---------------- end of tooth declaration ----------------------------- // ---------------- accual gear creation --------------------------------- #if (gear_solid) merge { // } <--- and again here #else union { #end // } { <--- and again here #ifndef (center) #local center = 1; #end #if (center != 0) cylinder { <0,-0.00001,0>, <0,0.00001+th,0>, rr } #end #ifdef (onetooth) object { tooth } #else union { #local i = 0; #while (i < n) #local i = i + 1; object { tooth rotate y*(i*(360/n)) } #end } rotate y*angle_to_turn #end } // ---------------- clean up some variables, if not in debug ------------- #ifndef (gear_debug) #undef _gear_points #undef _gear_normals #undef _bezier_points #end #end #end