DeclaraCAD is slowly gaining support for different milling operations including animations of the toolpath.

Note: This is currently under development and may change in future versions.


The milling operations are combined into a Job node. The Job has a filename where it writes the generated gcode from each operation. The output file can be loaded on your CNC controller (LinuxCNC, Mach3, etc..).

Each operation added to the job can be disabled by setting disabled = True which will omit generation of that operation to do partial runs of a job. Each operation also has a feedrate, spindle_speed, and coolant attributes that can be set. Different operations may also provide attributes more control for different parts of the operation.

The JobSimulation node can be used to preview all operations. DeclaraCAD will animate each of the job's operations.

Feed and speed

DeclaraCAD will calculate the spindle_speed and feedrate based on the University of Florida's guidelines. Provide the surface_speed for the material you're cutting and it will calculate the speed / and feed adjusted to the tool provided and for some operations the toolpath parameters.

The defaults can provide a good starting points but will likely need tweaking. You can manually set the values or calculate them using your own python/enaml expressions.

Note: In practice these recommendations make nice looking chips but be can easily stall a lower powered "home shop" mill so each operation includes a slowdown_factor that defaults to 0.6.

Drilling cycle

The DrillingCycle operation can be used to generate G73, G81, G82, and G83. To use it pass in the tool (typically a TwistDrill) and specify the list of holes to drill.

Holes may be either a point, a circular edge selected from a part, or a cylindrical surface selected from the part. DeclaraCAD will obtain the X and Y positions from the holes specified and generate gcode and a path to visualize the operations.

The drilling cycle can be customized with the retract, depth, dwell, feedrate, peck depth, and full_retract options.

Note: By default full_retract will automatically be enabled and the speed/feed is divided by 3 for holes deeper than 3 x tool diameter. Additionally, the default peck value will be reduced to 1/2 the tool diameter holes deeper than 3 x tool diameter. It may be necessary to switch pulleys / reduced gear and increase the spindle_speed accordingly for very deep holes.

from declaracad.cnc.operations import Job, DrillingCycle, TwistDrill, JobSimulation

enamldef Assembly(Part):
    RouterAdapterPlate: plate:
        position = (0, 0, -1/4*inch)
    Job: milling_job:
        inches = True
        filename = f"{__name__}.tap"
            tool = TwistDrill(diameter=7, position=start_point)
            retract = 0.1*inch
            depth = -0.3*inch
            peck = 1
            full_retract = True
            start_point = (0, 0, 1*inch)
            holes = [
                f for i, f in enumerate(plate.topology.faces)
                if i in (44, 46, 50, 52)
            tool = TwistDrill(diameter=4.5, position=start_point)
            retract = 0.1*inch
            depth = -0.3*inch
            peck = 1
            start_point = (0, 0, 1*inch)
            color = 'blue'
            holes = [
                f for i, f in enumerate(plate.topology.faces)
                if i in (45, 48, 49, 51)
        job = milling_job
        rate = 0.9

Drilling operation

Circular pocket

The CircularPocket operation can be used to generate a path to mill a circular pocket from a cylindrical face. To use it pass in the tool (typically an EndMill) and specify the tool diameter and list of pockets to mill out. The operation does a helix down then a spiral out to the edge (less the tool offset). The step_down, step_over, feedrate, helix_radius, helix_pitch, top_clearance, bottom_clearance, and radial_clearance can be specified to customize the toolpath.

The helix_pitch and step_over default to 6% of the tool diameter. These can be adjusted to change the chip load. For deep pockets it is recommended to lower the step_over accordingly.

The top_clearance is added to the top height of the pocket. This will cause the toolpath helix to start above the top surface. The bottom_clearance is added to the bottom of the pocket, a postiive value leaves extra stock on the bottom of the pocket, while a negative number will take more stock away (or in the case of a hole can be used to increase the "cut through" amount). The radial_clearance defaults to 0 and is added to the cut diameter. A positive value will cut more away while a negative value will leave extra stock (eg for a second finishing operation).

Note: Each element in the pockets list can be a tuple that contains either a depth or second edge to define the bottom of the cut (eg to correct for fillets and chamfers at the bottom edge).

DeclaraCAD will show a simulation of the operation and generate gcode to perform the operation on a milling machine.

Circular pocket

Multiple pockets can be cut in a single operation block. DeclaraCAD will make a reasonable attempt to find the shortest path between all the operations.

Multiple pockets

Facing operation

The FacingOperation can be added to a job to create a "zig-zag" toolpath for facing. To use it, provide the tool (typically a FaceMill or EndMill) and specify the tool diameter and the face to clear. The operation creates a zig zag path joined by arcs. Multiple layers will be done if the depth is greater than the step_down. The step_over and step_past can be also be specified, they default to 90% tool diameter and 60% tool diameter respectively. The top_clearance can be used to adjust the entire toolpath up or down to leave more or less material or adjust for the z-zero value set on your machine.

Note: It currently does not handle avoidance regions (coming eventually).

Facing toolpath

Chamfer operation

The ChamferOperation is used to cut chamfers on holes and contours. To use it, pass in the tool (a ChamferMill), specify the tool diameter and tip angle. Next select the edges to chamfer from the part. Currently each item in the edges list is expected to be a chamfered face. The bit_offset can be used to adjust how much of an offset the bit is shifted from the chamfer plane in order to cut with a stronger part of the tool (instead of the tip).

Chamfer operation

Contour operation

The ContourOperation allows you to define your own paths in code and will generate G-code for the movement. Simply pass it a list of wires to follow and the tool to generate code for. It will do a vertical drop and lift to the height of the start point between each wire. It does not perform any arc-in or arc-out movements.

Note: It currently does not work with B-Spline or Beziers.

Side cut operation

For lack of a better name the SideCutOperation will do an outside in climb mill cut of faces surrounding an internal avoidance region. To use it pass in an EndMill (or a bull nose if you want an internal fillet) and specify the shape to avoid with the avoid name and the list of faces to cut up to the avoidance region. It is intended for cutting faces with open on multiple sides.

Slot milling

The SlottingOperation is used to mill a slot. If the tool diameter equals the slot width it will do a straight cut, otherwise it will create trochoidal loops. Set the faces to cut and the tool to cut the slot with.

The step_over defaults to 10% of the tool diameter. The radial_clearance and bottom_clearance can be used to leave or remove material from the walls and bottom respectively. If the slot is open on one or both ends the extend_start and extend_end distances can be specified to tell it how far to cut past.

Slot milling