CodeToCAD Examples

Repo: https://github.com/CodeToCAD/CodeToCAD
Docs: https://codetocad.github.io/CodeToCAD/docs.html
Analytics Materials Preset Materials Lights!Camera!Action! Scene Backgrounds (HDR or images) Bracelet D-Shaft D-Shaft Knob Simple Cube Calibration Cube Stackable Furniture Legs Import and Export Ball Joint Universal Joint Double Universal Joint Gear Landmarking OpenCascade Bottle Fillets and Chamfers Patterns Boolean operations Simple Humanoid 2D Sketching Extruding Donuts Sweeping coil Profile Pipe Text Advanced Text

Documentation

Analytics
From measuring distances and dimensions of objects, to logging, the Analytics class has the operations you need.
            
from codetocad import Analytics, Part





analytics = Analytics()



my_cube = Part("myCube").create_cube(1, 1, 1)



dimensions = analytics.get_dimensions(my_cube)



# This will write logs inside the provider or to the console:

# you can also just do print() to print to the console.

analytics.log(f"Dimensions for myCube are: {dimensions}")

            
Materials
Apply a material to Parts by creating a Material, and then assigning it to a Part.
Image
            
from codetocad import *



material = Material("material").set_color(169, 76, 181, 0.8)

Part("Cube").create_cube(1, 1, 1).set_material(material)



material_with_texture = Material("materialWithTexture").set_image_texture("./bark.jpg")

Part("Cylinder").create_cylinder(1, 4).set_material(

    material_with_texture

).translate_xyz(5, 0, 0)

            
Preset Materials
CodeToCAD defines some preset materials for your convinence, see preset_materials.py for more information
            
from codetocad import *

from codetocad.enums import PresetMaterial



Part("cube").create_cube(1, 1, 1).set_material(PresetMaterial.blue)



Part("Cylinder").create_cylinder(1, 4).set_material(PresetMaterial.red).translate_xyz(

    5, 0, 0

)

            
Lights!Camera!Action!
Create lights and add cameras to your scene!
Image
            
from codetocad import *



Part("Cube").create_cube(2, 2, 2)

light = Light("Light").create_sun(75)

light.set_color(73, 222, 190).translate_xyz(10, 10, 5)



camera = Camera("Camera").create_perspective()

camera.set_focal_length(20).translate_xyz(0, -5, 5).rotate_xyz(45, 0, 0)

            
Scene Backgrounds (HDR or images)
Add HDR and backgrounds to your rendered or animated scene.
Image
            
from codetocad import *



Part("Sphere").create_sphere(1)



Scene().set_background_image("./hdr_background_test.jpg", -300, 0)

            
Bracelet
You can use the boolean modifiers Subtract, Union and Intersect to manipulate parts, as shown in this 3D Printable bracelet.
            
from codetocad import *



Scene.default().set_default_unit("cm")

Scene.default().create_group("Bracelet")





class Bracelet:

    outer_diameter = "161cm"

    inner_diameter = "81cm"

    thickness = "83cm"



    def create(self):

        bracelet = Part("bracelet").create_torus(

            Dimension.from_string(self.inner_diameter) / 2,

            Dimension.from_string(self.outer_diameter) / 2,

        )

        bracelet.scale_z(self.thickness)



        return bracelet





class Button:

    radius = "60/2cm"

    depth = "13.6cm"

    inset_radius = "20cm"

    inset_depth = "3cm"



    def create(self):

        button = Part("button").create_cylinder(self.radius, self.depth)

        button_top = button.get_landmark("top")

        button.hole(button_top, self.inset_radius, self.inset_depth)

        button.fillet_faces("5cm", [button_top])

        return button





class Belt:

    outer_radius = "163/2cm"

    inner_radius = "150/2cm"

    thickness = "30cm"



    def create(self):

        belt = Part("belt").create_cylinder(self.outer_radius, self.thickness)

        belt.hole(belt.get_landmark("top"), self.inner_radius, self.thickness)

        return belt





if __name__ == "__main__":

    # MARK: Create components

    bracelet = Bracelet().create()

    button = Button().create()

    belt = Belt().create()



    # Mark: Joint the button to the front of the bracelet

    Joint(

        bracelet.get_landmark("front"), button.get_landmark("top")

    ).limit_location_xyz(0, 0, 0).limit_rotation_xyz(90, 0, 0)

    Joint(

        bracelet.get_landmark("center"), belt.get_landmark("center")

    ).limit_location_xyz(0, 0, 0).limit_rotation_xyz(0, 0, 0)



    # # Mark: subtract the button and belt from the bracelet:

    bracelet.subtract(belt, delete_after_subtract=False)



    bracelet.hole(

        belt.get_landmark("front"),

        button.get_dimensions().x / 2,

        button.get_dimensions().z,

        normal_axis="y",

        flip_axis=True,

    )

    belt.hole(

        belt.get_landmark("front"),

        button.get_dimensions().x / 2,

        belt.get_dimensions().z,

        normal_axis="y",

        flip_axis=True,

    )



    # # Mark: Assign to a group:



    # Scene().assign_to_group([bracelet, button, belt], "Bracelet")



    # Mark apply materials:

    red_material = Material("red").set_color(181, 16, 4)

    blue_material = Material("blue").set_color(19, 107, 181)



    bracelet.set_material(red_material)

    button.set_material(blue_material)

    belt.set_material(blue_material)

            
D-Shaft
A D-keyed shaft using Landmarks and the Subtract modifier.
            
from dataclasses import dataclass, field

from codetocad import *

from codetocad.interfaces.part_interface import PartInterface





@dataclass

class DShaft:

    shaft_length: Dimension

    radius: Dimension

    d_profile_radius: Dimension

    d_profile_length: Dimension

    tolerance: Dimension = field(default_factory=lambda: Dimension(0))



    def create(self, name, is_d_shaft_both_sides=False) -> PartInterface:

        shaft_length = self.shaft_length

        radius = self.radius - self.tolerance

        dProfileRadius = self.d_profile_radius - self.tolerance



        d_profile_width = (radius - dProfileRadius) * 2



        shaft = Part(name).create_cylinder(radius, shaft_length)



        d_profile = Part("dProfile").create_cube(

            d_profile_width, radius * 2, self.d_profile_length

        )



        shaft_left_side = shaft.get_landmark(PresetLandmark.leftTop)

        d_profile_left_side = d_profile.get_landmark(PresetLandmark.leftTop)



        Joint(shaft_left_side, d_profile_left_side).limit_location_xyz(0, 0, 0)



        if is_d_shaft_both_sides:

            d_profile.mirror(shaft, "z", None)



        shaft.subtract(d_profile)



        shaft.get_landmark(PresetLandmark.front).delete()



        return shaft





if __name__ == "__main__":

    shaft_length = Dimension.from_string("13.65mm")

    radius = Dimension.from_string("5.9/2mm")

    d_profile_radius = Dimension.from_string("5.3/2mm")

    d_profile_length = shaft_length / 2

    tolerance = Dimension.from_string("0.15mm")



    dShaft = DShaft(

        shaft_length=shaft_length,

        radius=radius,

        d_profile_radius=d_profile_radius,

        d_profile_length=d_profile_length,

        tolerance=tolerance,

    ).create("shaft")

            
D-Shaft Knob
You can import another CodeToCAD model, and uses the Union modifier to create new shapes.
            
from codetocad import *

from codetocad.interfaces.part_interface import PartInterface

from examples.d_shaft import DShaft





def create_d_shaft_sleeve(d_shaft: PartInterface, sleeve_thickness):

    d_shaft_diameter = d_shaft.get_dimensions().y



    sleeve = Part("sleeve").create_cylinder(

        d_shaft_diameter / 2 + sleeve_thickness, d_shaft.get_dimensions().z

    )



    sleeve.subtract(d_shaft, is_transfer_data=True)



    return sleeve





def create_knob(radius):

    knob = Sketch("knob").create_polygon(7, radius, radius).extrude(radius * 0.2)



    return knob





if __name__ == "__main__":

    Scene.default().set_default_unit("mm")



    shaft_length = Dimension.from_string("13.65mm")

    radius = Dimension.from_string("5.9/2mm")

    d_profile_radius = Dimension.from_string("5.3/2mm")

    d_profile_length = shaft_length

    tolerance = Dimension.from_string("0.15mm")



    d_shaft = DShaft(

        shaft_length=shaft_length,

        radius=radius,

        d_profile_radius=d_profile_radius,

        d_profile_length=d_profile_length,

        tolerance=tolerance,

    ).create("shaft")



    sleeve = create_d_shaft_sleeve(d_shaft, "1.5mm")



    knob = create_knob(sleeve.get_dimensions().x)



    Joint(

        sleeve.create_landmark("top", center, center, max),

        knob.create_landmark("bottom", center, center, min),

    ).limit_location_xyz(0, 0, 0)



    sleeve.union(knob)

    # sleeve.export("./appliance_knob.stl", scale=1000)

            
Simple Cube
The easiest CodeToCAD example.
            
from codetocad import *



myCube = Part("myCube").create_cube(1, 1, 1)

            
Calibration Cube
Calibration Cubes use Landmarks on both the Texts' Sketches and the Cube to define where the Text is positioned on the Cube.
Image
            
from codetocad import *

from codetocad.shortcuts import *





material = Material("material")

material.set_color(169, 76, 181, 255)





def create_cube(name, size):

    calibartion_cube = Part(name).create_cube(size, size, size)



    calibration_cube_x = calibartion_cube.create_landmark(

        "x", min + "5mm", max - "7mm", max

    )

    calibration_cube_y = calibartion_cube.create_landmark(

        "y", "max-5mm", "min+5mm", max

    )

    calibration_cube_z = calibartion_cube.create_landmark("z", center, min, center)

    calibration_cube_size = calibartion_cube.create_landmark(

        "size", "min+1mm", "min+2mm", max

    )



    z = Sketch("Z").create_text("Z^", "10mm").extrude("1.5mm").rotate_xyz(90, 0, 0)

    z_center = z.create_landmark("center", center, center, center)

    Joint(calibration_cube_z, z_center).limit_location_xyz(0, 0, 0)

    calibartion_cube.subtract(z)



    y = Sketch("Y").create_text("Y^", "8mm").extrude("1.5mm")

    y_center = y.create_landmark("center", center, center, center)

    Joint(calibration_cube_y, y_center).limit_location_xyz(0, 0, 0)

    calibartion_cube.subtract(y)



    x = Sketch("X").create_text("X^", "8mm").extrude("1.5mm").rotate_xyz(180, 0, 90)

    x_center = x.create_landmark("center", center, center, center)

    Joint(calibration_cube_x, x_center).limit_location_xyz(0, 0, 0)

    calibartion_cube.subtract(x)



    size = Sketch("size").create_text(str(size.value) + "mm", "4mm").extrude("1.5mm")

    size_center = size.create_landmark("min", min, center, center)

    Joint(calibration_cube_size, size_center).limit_location_xyz(0, 0, 0)

    calibartion_cube.subtract(size)



    calibartion_cube.set_material(material)



    return calibartion_cube





tolerance = "0.2mm"

size = Dimension(20, "mm")



create_cube("calibration_cube19_9", size - tolerance).export(

    "./calibration_cube19_8mm.stl", scale=1000

).translate_xyz("-25mm", 0, 0)

create_cube("calibration_cube20mm", size).export(

    "./calibration_cube20mm.stl", scale=1000

)

create_cube("calibration_cube20_2", size + tolerance).export(

    "./calibration_cube20_2mm.stl", scale=1000

).translate_xyz("25mm", 0, 0)

            
Stackable Furniture Legs
3D Printable furniture legs that grow as you stack them.
            
from codetocad import *



Scene().set_default_unit("mm")



ellipse_leg = Sketch("ellipse_leg").create_ellipse("14mm", "27mm").extrude("5/2in")

ellipse_leg_top = ellipse_leg.create_landmark("top", center, center, max)

ellipse_leg_bottom = ellipse_leg.create_landmark("bottom", center, center, min)



ellipse_leg_outer_cutout = (

    Sketch("ellipse_legOuterCutout").create_ellipse("14mm", "27mm").extrude("1in")

)

ellipse_leg_outer_cutout.hollow("3mm", "3mm", 0)

ellipse_leg_outer_cutout_top = ellipse_leg_outer_cutout.create_landmark(

    "top", center, center, max

)

ellipse_leg_outer_cutout.create_landmark("bottom", center, center, min)



Joint(ellipse_leg_top, ellipse_leg_outer_cutout_top).translate_landmark_onto_another()



ellipse_leg.hollow("5mm", "5mm", 0)

ellipse_leg.subtract(ellipse_leg_outer_cutout, is_transfer_data=True)



ellipse_leg2 = ellipse_leg.clone("Leg2")

Joint(

    ellipse_leg.get_landmark("ellipse_legOuterCutout_bottom"),

    ellipse_leg2.get_landmark("bottom"),

).limit_location_xyz(0, 0, 0).limit_location_z(0, 10).limit_rotation_xyz(0, 0, 0)





red_material = Material("red").set_color(0.709804, 0.109394, 0.245126, 0.9)

blue_material = Material("blue").set_color(0.0865257, 0.102776, 0.709804, 0.9)

ellipse_leg.set_material(red_material)

ellipse_leg2.set_material(blue_material)

            
Import and Export
You can import files by using the create_from_file() method, and export Entities using the export() method. The filename extension will be used to guess the filetype, but you can specify a filetype too.
            
from codetocad import *



imported_cube = Part("Imported Cube").create_from_file("./importableCube.stl")



Part("ExportedCube").create_cube(1, 1, 1).export("./exportedCube.stl").export(

    "./exportedCube.obj"

)

            
Ball Joint
Parts can be mated/jointed using Landmarks and Joints.
            
from codetocad import *

from codetocad.interfaces.landmark_interface import LandmarkInterface



ball = Part("ball").create_sphere(1)

ball_center = ball.get_landmark("center")  # or PresetLandmarks.center

ball_bottom: LandmarkInterface = ball.get_landmark(PresetLandmark.bottom)  # or "bottom"



link = Part("link").create_cube(1, 1, 2)

link_top = link.get_landmark("top")

link_bottom = link.get_landmark("bottom")



Joint(ball_center, link_bottom).limit_location_xyz(0, 0, 0).limit_rotation_xyz(0, 0, 0)



socket = Part("socket").create_sphere(1.2)

socket_cutoff = socket.create_landmark("cutoff", "center", "center", "min + 0.7")

socket_center = socket.get_landmark("center")



Joint(ball_bottom, socket_cutoff).translate_landmark_onto_another()



socket.subtract(ball, delete_after_subtract=False, is_transfer_data=False)



Joint(socket_center, ball).limit_rotation_x(-30, 30).limit_rotation_y(

    -30, 30

).limit_rotation_z(0, 0)





blue_material = Material("blue").set_color(0.0826006, 0.214978, 0.406714, 1.0)

green_material = Material("socket").set_color(0.249275, 0.709804, 0.392972, 0.8)

ball.set_material(blue_material)

link.set_material(blue_material)

socket.set_material(green_material)

            
Universal Joint
Parts can be mated/jointed using Landmarks and Joints.
Image
            
from dataclasses import dataclass

from codetocad import *



blue_metallic_material = (

    Material("blue").set_color(0.0865257, 0.102776, 0.709804, 0.8).set_reflectivity(1.0)

)

red_metallic_material = (

    Material("red").set_color(0.709804, 0.109394, 0.245126, 0.8).set_reflectivity(1.0)

)





@dataclass

class Yoke:

    """

     A class that creates the arm of a universal joint:

     ___  ____________  __

    ( )                   )  < hollow rod

     ⁻⁻⁻  ⁻⁻⁻⁻⁻⁻⁻⁻⁻⁻⁻⁻  ⁻⁻

         ^             ^

      setScrew       pinHole

    """



    shaft_radius: Dimension

    wall_thickness: Dimension

    shaft_length: Dimension



    pin_arm_length: Dimension

    pin_hole_radius: Dimension

    set_screw_radius: Dimension



    is_hollowed: bool = True



    def _createHollowRod(self, name: str, length: Dimension) -> Part:

        outerRadius = self.shaft_radius + self.wall_thickness



        rod = Part(name).create_cylinder(outerRadius, length)



        if self.is_hollowed:

            rod.hollow(

                self.wall_thickness,

                self.wall_thickness,

                self.wall_thickness / 2,

                flip_axis=True,

            )



        _ = rod.create_landmark(

            "wallFront", center, f"min + {self.wall_thickness/4}", max

        )



        return rod



    def _create_shaft_coupling(self) -> Part:

        shaft_coupling = self._createHollowRod("shaftCoupling", self.shaft_length)



        if self.is_hollowed:

            shaft_coupling.hole(

                shaft_coupling.get_landmark(PresetLandmark.back),

                self.set_screw_radius,

                shaft_coupling.get_dimensions().y,

                normal_axis="y",

            )



        return shaft_coupling



    def _create_pin_arm(self) -> Part:

        pin_arm = self._createHollowRod("pinArm", self.pin_arm_length)



        pin_arm_size = pin_arm.get_dimensions()



        pin_arm_discard_Amount = 1 / 15



        pin_arm.subtract(

            Part("pinArmDiscard")

            .create_cube(

                pin_arm_size.x,

                pin_arm_size.y * (1 - pin_arm_discard_Amount),

                pin_arm_size.z + "1mm",

            )

            .translate_y(pin_arm_size.y * pin_arm_discard_Amount)

        )



        pin_arm.rotate_y(180)



        pin_location = pin_arm.create_landmark(

            "pin", center, min, "max -  (max-min) * 1/4"

        )



        pin_arm.hole(

            pin_location,

            self.pin_hole_radius,

            pin_arm_size.y,

            normal_axis="y",

            flip_axis=True,

        )



        # pinArm.fillet_faces(

        #     "25mm",

        #     [pinArm.get_landmark(PresetLandmark.top)]

        # )



        return pin_arm



    def create(self, name: str) -> Part:

        shaft_coupling = self._create_shaft_coupling()



        pin_arm = self._create_pin_arm()



        Joint(

            shaft_coupling.get_landmark("wallFront"), pin_arm.get_landmark("wallFront")

        ).limit_location_xyz(0, 0, 0)



        pin_arm.mirror(shaft_coupling, "y", None)



        shaft_coupling.get_landmark(PresetLandmark.top)



        yoke = shaft_coupling.union(pin_arm, is_transfer_data=True)



        # shaftCoupling.fillet_faces(

        #     "25mm", [shaftCoupling.get_landmark(PresetLandmark.top)])



        yoke.rename(name)



        yoke.set_material(blue_metallic_material)



        return yoke





@dataclass

class Cross:

    width: Dimension

    pin_radius: Dimension

    pin_length: Dimension



    def create(self, name: str) -> Part:

        core = Part(name).create_cube(self.width, self.width, self.width)



        pin = Part("pin").create_cylinder(self.pin_radius, self.pin_length)



        Joint(

            core.get_landmark(PresetLandmark.top),

            pin.get_landmark(PresetLandmark.bottom),

        ).limit_location_xyz(0, 0, 0)



        pin.circular_pattern(

            4, 90, center_entity_or_landmark=core, normal_direction_axis="y"

        )



        core = core.union(pin)



        core.rotate_x(90)



        core.set_material(red_metallic_material)



        return core





def create_universal_joint():

    shaft_radius = Dimension.from_string("5mm")

    wall_thickness = Dimension.from_string("3mm")

    shaft_length = Dimension.from_string("15mm")

    pin_arm_length = Dimension.from_string("13mm")

    pin_hole_radius = Dimension.from_string("2mm")

    set_screw_radius = Dimension.from_string("3mm")



    yokeBottom = Yoke(

        shaft_radius=shaft_radius,

        wall_thickness=wall_thickness,

        shaft_length=shaft_length,

        pin_arm_length=pin_arm_length,

        pin_hole_radius=pin_hole_radius,

        set_screw_radius=set_screw_radius,

    ).create("yokeBottom")



    yoke_top = Yoke(

        shaft_radius=shaft_radius,

        wall_thickness=wall_thickness,

        shaft_length=shaft_length,

        pin_arm_length=pin_arm_length,

        pin_hole_radius=pin_hole_radius,

        set_screw_radius=set_screw_radius,

    ).create("yokeTop")

    yoke_top.rotate_y(180)

    yoke_top.rotate_z(90)



    cross = Cross(

        width=shaft_radius,

        pin_radius=pin_hole_radius,

        pin_length=shaft_radius / 2 + wall_thickness,

    ).create("cross")



    Joint(

        cross.get_landmark(PresetLandmark.front), yokeBottom.get_landmark("pinArm_pin")

    ).limit_location_xyz(0, 0, 0).limit_rotation_xyz(0, None, 0).limit_rotation_y(

        -45, 45

    )



    Joint(

        cross.get_landmark(PresetLandmark.right), yoke_top.get_landmark("pinArm_pin")

    ).limit_location_xyz(0, 0, 0).limit_rotation_xyz(None, 0, 0).limit_rotation_x(

        -45, 45

    )





if __name__ == "__main__":

    create_universal_joint()

            
Double Universal Joint
Parts can be mated/jointed using Landmarks and Joints.
Image
            
from codetocad import *

from universal_joint import Yoke, Cross





def createDoubleuniversal_joint():

    shaft_radius = Dimension.from_string("5mm")

    wall_thickness = Dimension.from_string("3mm")

    shaft_length = Dimension.from_string("15mm")

    center_yold_length = Dimension.from_string("5mm")

    pin_arm_length = Dimension.from_string("13mm")

    pin_hole_radius = Dimension.from_string("2mm")

    set_screw_radius = Dimension.from_string("3mm")



    yoke_center = Yoke(

        shaft_radius=shaft_radius,

        wall_thickness=wall_thickness,

        shaft_length=center_yold_length,

        pin_arm_length=pin_arm_length,

        pin_hole_radius=pin_hole_radius,

        set_screw_radius=set_screw_radius,

        is_hollowed=False,

    ).create("yokeCenter")

    yoke_center_pin_top = yoke_center.get_landmark("pinArm_pin")

    yoke_center_pin_top_location = yoke_center_pin_top.get_location_local()

    yoke_center_bottom_z = (

        yoke_center.get_landmark(PresetLandmark.bottom).get_location_local().z

    )

    yoke_center.mirror(yoke_center.get_landmark(PresetLandmark.bottom), "z", None)

    yoke_center_pin_bottom = yoke_center.create_landmark(

        "pinBottom",

        yoke_center_pin_top_location.x,

        yoke_center_pin_top_location.y,

        yoke_center_pin_top_location.z * -1 + yoke_center_bottom_z * 2,

    )



    yoke_top = Yoke(

        shaft_radius=shaft_radius,

        wall_thickness=wall_thickness,

        shaft_length=shaft_length,

        pin_arm_length=pin_arm_length,

        pin_hole_radius=pin_hole_radius,

        set_screw_radius=set_screw_radius,

    ).create("yokeTop")

    yoke_top.rotate_y(180)

    yoke_top.rotate_z(90)



    yokeBottom = Yoke(

        shaft_radius=shaft_radius,

        wall_thickness=wall_thickness,

        shaft_length=shaft_length,

        pin_arm_length=pin_arm_length,

        pin_hole_radius=pin_hole_radius,

        set_screw_radius=set_screw_radius,

    ).create("yokeBottom")

    yokeBottom.rotate_z(90)



    cross1 = Cross(

        width=shaft_radius,

        pin_radius=pin_hole_radius,

        pin_length=shaft_radius / 2 + wall_thickness,

    ).create("cross1")



    cross2 = Cross(

        width=shaft_radius,

        pin_radius=pin_hole_radius,

        pin_length=shaft_radius / 2 + wall_thickness,

    ).create("cross2")



    Joint(

        cross1.get_landmark(PresetLandmark.right),

        yoke_top.get_landmark("pinArm_pin"),

    ).limit_rotation_xyz(None, 0, 0).limit_rotation_x(-45, 45).limit_location_xyz(

        0, 0, 0

    )



    Joint(

        cross1.get_landmark(PresetLandmark.front), yoke_center_pin_top

    ).limit_rotation_xyz(0, None, 0).limit_rotation_y(-45, 45).limit_location_xyz(

        0, 0, 0

    )



    Joint(

        yoke_center_pin_bottom,

        cross2.get_landmark(PresetLandmark.front),

    ).limit_rotation_xyz(None, 0, 0).limit_rotation_x(-45, 45).limit_location_xyz(

        0, 0, 0

    )



    Joint(

        cross2.get_landmark(PresetLandmark.right), yokeBottom.get_landmark("pinArm_pin")

    ).limit_rotation_xyz(None, 0, 0).limit_rotation_x(-45, 45).limit_location_xyz(

        0, 0, 0

    )





if __name__ == "__main__":

    createDoubleuniversal_joint()

            
Gear
A simple gear constraint
            
from codetocad import *



gear = Part("gear").create_gear(1, 0.1, 0.8, 0.2, 0.2)



gear2 = Part("gear2").create_gear(0.5, 0.05, 0.4, 0.1, 0.2, "20d", 6)



gear2.translate_xyz(0, 1.515, 0)



Joint(gear, gear2).gear_ratio(2)

            
Landmarking
An important feature in CodeToCAD, allowing you to quickly reference locations in a geometry, for example, PresetLandmark.top will find the top-most face of a part.
            
from codetocad import *



wall_thickness = Dimension.from_string(0.1)



hollow_cube = Part("hollow_cube").create_cube(1, 1, 0.1)

hollow_cube.hollow(wall_thickness * 2, wall_thickness * 2, 0)



hollow_cube.translate_x(3)



c1 = Part("c1").create_cube(1, 1, 1)

c1.translate_x(2)

c1.translate_y(2)

c1.translate_z(2)



hollow_cube_left = hollow_cube.get_landmark(PresetLandmark.left)

hollow_cube_left_inner = hollow_cube_left.clone("left_inner")

hollow_cube_left_inner = hollow_cube_left.clone(

    "left_inner_2", offset=[wall_thickness, 0, 0]

)



hollow_cube_left_inner = hollow_cube_left.clone("left_inner_3", new_parent=c1)

            
OpenCascade Bottle
The famous OCC Bottle.
            
"""

A re-creation of the famous OpenCascade Bottle (https://dev.opencascade.org/doc/overview/html/occt__tutorial.html)



Code inspired by

- https://replicad.xyz/docs/examples/occt-bottle

- https://cadquery.readthedocs.io/en/latest/examples.html#the-classic-occ-bottle

"""



from codetocad import *



(L, w, t) = (20.0, 6.0, 3.0)

# s = cq.Workplane("XY")

# Sketch is missing the sketch plane

bottle_profile = Sketch("bottle_profile").create_line(w / 2.0)

arc = Sketch("bottle_arc").create_arc(L / 2)

# # Draw half the profile of the bottle and extrude it

# p = (

#     s.center(-L / 2.0, 0)

#     .vLine(w / 2.0)

#     .threePointArc((L / 2.0, w / 2.0 + t), (L, w / 2.0))

#     .vLine(-w / 2.0)

#     .mirrorX()

#     .extrude(30.0, True)

# )



# # Make the neck

# p = p.faces(">Z").workplane(centerOption="CenterOfMass").circle(3.0).extrude(2.0, True)



# # Make a shell

# result = p.faces(">Z").shell(0.3)

            
Fillets and Chamfers
You can apply fillets and chamfers to specific edges or faces, or to all the edges or faces. To target a specific edge or face, create a Landmark near the target.
Image
            
from codetocad import *



blue_material = Material("blue").set_color(0, 0.1, 1.0)

red_material = Material("red").set_color(1.0, 0.1, 0)



Part("fillet_all_edges").create_cube(1, 1, 1).fillet_all_edges("10cm").set_material(

    blue_material

)

Part("chamfer_all_edges").create_cube(1, 1, 1).translate_xyz(1.5, 0, 0).set_material(

    red_material

).chamfer_all_edges("10cm")



Part("fillet_all_edgesCylinder").create_cylinder(1 / 2, 2).translate_xyz(

    1.5 * 2, 0, 0

).fillet_all_edges("10cm").set_material(blue_material)

Part("chamfer_all_edgesCylinder").create_cylinder(1 / 2, 2).translate_xyz(

    1.5 * 3, 0, 0

).chamfer_all_edges("10cm").set_material(red_material)



fillet_two_edges = Part("filletTwoEdges").create_cube(1, 1, 1)

fillet_two_edges_edge1 = fillet_two_edges.create_landmark("edge1", max, 0, max)

fillet_two_edges_edge2 = fillet_two_edges.create_landmark("edge2", min, 0, min)

fillet_two_edges.fillet_edges(

    "10cm", [fillet_two_edges_edge1, fillet_two_edges_edge2]

).translate_xyz(0, 1.5, 0).set_material(blue_material)



chamfer_two_edges = Part("chamferTwoEdges").create_cube(1, 1, 1)

chamfer_two_edges_edge1 = chamfer_two_edges.create_landmark("edge1", max, 0, max)

chamfer_two_edges_edge2 = chamfer_two_edges.create_landmark("edge2", min, 0, min)

chamfer_two_edges.chamfer_edges(

    "10cm", [chamfer_two_edges_edge1, chamfer_two_edges_edge2]

).translate_xyz(1.5, 1.5, 0).set_material(red_material)



fillet_two_faces = Part("filletTwoFaces").create_cube(1, 1, 1)

fillet_two_faces_face1 = fillet_two_faces.create_landmark("face1", 0, 0, max)

fillet_two_faces_face2 = fillet_two_faces.create_landmark("face2", min, 0, 0)

fillet_two_faces.fillet_faces(

    "10cm", [fillet_two_faces_face1, fillet_two_faces_face2]

).translate_xyz(1.5 * 2, 1.5, 0).set_material(blue_material)



chamge_two_faces = Part("chamferTwoFaces").create_cube(1, 1, 1)

chamge_two_faces_face1 = chamge_two_faces.create_landmark("face1", 0, 0, max)

chamge_two_faces_face2 = chamge_two_faces.create_landmark("face2", min, 0, 0)

chamge_two_faces.chamfer_faces(

    "10cm", [chamge_two_faces_face1, chamge_two_faces_face2]

).translate_xyz(1.5 * 3, 1.5, 0).set_material(red_material)

            
Patterns
Use linear and circular patterns to create more of a Part or a Sketch. Note: the Hole method also allows you to pattern holes.
            
from codetocad import *



linear_cube = (

    Part("Linear Cube").create_cube("5cm", "5cm", "5cm").linear_pattern(10, "7cm", "x")

)



Part("Circular spheres").create_sphere(1).translate_xyz(0, 5, 0).circular_pattern(

    4, "90d", linear_cube, "z"

).circular_pattern(6, f"{360/6}d", linear_cube, "x")

            
Boolean operations
Basic CSG operations like Union, Intersect and Subtract can be used here.
            
from codetocad import *

from codetocad.enums import PresetMaterial



c1 = Part("c1").create_cube(1, 1, 1)

c1.set_material(PresetMaterial.blue)



c2 = Part("c2").create_cylinder(0.5, 1)

c2.set_material(PresetMaterial.red)

c2.translate_x(0.5)



c3 = Part("c3").create_cube(1, 1, 1)

c3.set_material(PresetMaterial.yellow)

c3.translate_x(-0.5)



c2.union(c1)

c2.union(c3)

            
Simple Humanoid
A simple person
Image
            
from codetocad import *



# MARK: Create body

body = Part("body").create_cube(1, 2, 3)

body_top = body.create_landmark("top", center, center, max)



# MARK: Create head

head = Part("head").create_sphere(0.5)

head_bottom = head.create_landmark("bottom", center, center, min)



# Mark: Create Eye

eye = Part("eye").create_cylinder(0.1, 0.1)

eye_bottom = eye.create_landmark("bottom", center, center, min)



eye.rotate_xyz(0, 90, 0)



# Mark: Attach head to Body

Joint(body_top, head_bottom).limit_location_xyz(0, 0, 0).limit_location_y(

    -0.3, 0.3

).limit_rotation_x(0, 0).limit_rotation_y(-20, 90).limit_rotation_z(-30, 30)



# Mark: Attach eye to head:

head_leftEye = head.create_landmark("leftEye", "max-0.1", -0.2, "max/3")

Joint(head_leftEye, eye_bottom).limit_location_xyz(0, 0, 0).limit_rotation_xyz(0, 0, 0)



# Mark: mirror the eyes

eye.mirror("head", "y", None)

            
2D Sketching
You can construct geometry using 2D sketching on planes or faces. You can also use extruding functions like extrude, loft, sweep and twist. You may also utilize the power of Landmarks at any time to quickly reference parts of a sketch. Sketches are made up of Wires, Edges and Vertices.
            
from codetocad import Sketch

from codetocad.enums.curve_types import CurveTypes



rectangle_points_sketch = Sketch(

    "rectangle_from_points", curve_type=CurveTypes.BEZIER

).create_from_vertices(["0,0,0", "1,0,0", "1,1,0", "0,1,0", "0,0,0"])





triangle_sketch = Sketch("triangle", curve_type=CurveTypes.NURBS)

line1 = triangle_sketch.create_line("0,0,0", "1,1,0")

line2 = triangle_sketch.create_line(line1.v2, "0,1,0")

line3 = triangle_sketch.create_line(line2.v2, line1.v1)

triangle_sketch.translate_y(1)





rectangle_lines_sketch = Sketch(

    name="rectangle_from_lines", curve_type=CurveTypes.BEZIER

)

line1 = rectangle_lines_sketch.create_line("0,0,0", "1,0,0")

line2 = rectangle_lines_sketch.create_line("0,1,0", "1,1,0")

line3 = rectangle_lines_sketch.create_line(line1.v1, line2.v1)

line4 = rectangle_lines_sketch.create_line(line1.v2, line2.v2)

rectangle_lines_sketch.translate_y(2)





loft_sketch1 = Sketch("loft_sketch1", curve_type=CurveTypes.BEZIER)

w1 = loft_sketch1.create_rectangle(1, 1)

loft_sketch2 = Sketch("loft_sketch2", curve_type=CurveTypes.BEZIER)

w2 = loft_sketch2.create_rectangle(0.5, 0.5)

loft_sketch2.translate_z(1).rotate_x(45)

lofted = w1.loft(w2).rename("loft")

lofted.translate_xyz(0.5, 3.5, 0)





circle_sketch = Sketch("circle", curve_type=CurveTypes.BEZIER)

circle_wire = circle_sketch.create_circle(0.5)

circle_sketch.translate_xyz(0.5, 4.5, 0)



arc_sketch = Sketch("arc", curve_type=CurveTypes.BEZIER)

arc_wire = arc_sketch.create_arc([-0.5, 0, 0], [1, 1, 0], 0.25)

arc_sketch.translate_xyz(0.5, 5.5, 0)





ellipse_sketch = Sketch("ellipse", curve_type=CurveTypes.BEZIER)

ellipse_wire = ellipse_sketch.create_ellipse(0.5, 0.25)

ellipse_sketch.translate_xyz(0.5, 6.5, 0)

            
Extruding
2D Sketches can be extruded into 3D shapes.
Image
            
from codetocad import Sketch





rectangle = Sketch("cube")

r_wire = rectangle.create_rectangle(1, 1)

rectangle.extrude(1)





rectangle = Sketch("cube2")

r_wire = rectangle.create_rectangle(1, 1)

rectangle.rotate_x(45)

rectangle.extrude(1)

            
Donuts
The famous revolve extrude.
            
from codetocad import *



Sketch("centerline").create_line([0, 0, 0], [0, 1, 0])



half_donut = Sketch("half-donut")

half_donut.create_circle("10cm")

half_donut.translate_xyz("-100cm", 0, 0).revolve("180d", "centerline", "y")



ribbon = Sketch("ribbon")

ribbon.create_arc([0, 0, 0], ["1cm", "1cm", 0], 0)

ribbon.twist("180d", "2.5cm", 100, "z")

            
Sweeping coil
Apply a sweep modifier to a Sketch to make it follow a profile path, to create a new Part. Note: make sure to sweep the profile, for example `myProfile.sweep('mySketch')`; see `grooveSpiral.sweep(groove)` below.
Image
            
from codetocad import *





drum_radius = Dimension.from_string("5mm")

drum_length = Dimension.from_string("15.0 mm")



wire_thickness = Dimension.from_string("1mm")

number_of_windings = 10



groove_spiral = Sketch("grooveSpiral").create_spiral(

    number_of_windings, drum_length, drum_radius

)



groove = Sketch("groove").create_circle(wire_thickness / 2)



groove_spiral.sweep(groove)

            
Profile Pipe
Sweeping a sketch is totally doable.
Image
            
from codetocad import *



# We are trying to draw a bull-horn shapes pipe:

"""

Pipe is 1/4" thick.

          |------------------21.5"----------------|

              __________________________________

                 B____________C______________D

            /   /                            \\   \

           /   /                              \\   \

          |_A_|                               |_E_|

               |------------18.5"------------|

"""



profile_vertices = [

    [0, 0, 0],  # start A

    "2,1,0,in",  # B

    # "21.5/2,1,0,in", #midpoint C

    "21.5-2,1,0,in",  # D

    "21.5,0,0,in",  # end E

]



circle = Sketch("circle")

circle.create_circle("1in")

circle.set_visible(False)



profile = Sketch("profile")

profile.create_from_vertices(profile_vertices)

profile.sweep("circle", fill_cap=False)

            
Text
Use Sketch('sketchName').create_text() to write text. You can apply different text fonts, decorations and sizes. You can also extrude text, or define landmarks relative to the Sketch to mate/joint text to other landmarks.
Image
            
from pathlib import Path

from codetocad import *



red_material = Material("red").set_color(0.709804, 0.109394, 0.245126, 1.0)

green_material = Material("green").set_color(0.118213, 0.709804, 0.109477, 0.8)

blue_material = Material("blue").set_color(0.0865257, 0.102776, 0.709804, 0.8)



Sketch("CodeToCAD").create_text("Code To CAD", underlined=True).extrude(

    "1cm"

).set_material(green_material)



Sketch("Small text!").create_text(

    "Small text!", font_size="15cm", underlined=True

).translate_xyz(0, -2, 0)



arial_font_path = str(Path(__file__).parent.absolute()) + "/fonts/arial.ttf"

Sketch("كود تو كاد").create_text(

    "كود تو كاد", font_file_path=arial_font_path

).translate_xyz(-5, 0, 0)





yi_gothic_font_path = str(Path(__file__).parent.absolute()) + "/fonts/yu_gothic.ttc"

Sketch("curvedTextPath").create_circle("1m").translate_xyz(-5, -5, 0).set_visible(False)

Sketch("コオデツカアド").create_text(

    "コオデツカアド", font_file_path=yi_gothic_font_path

).profile("curvedTextPath").translate_xyz(-5, -5, 0).extrude(0.1).set_material(

    red_material

)



Sketch("multiline").create_text(

    """Multiline

    Text

        Is

            Awesome!

"""

).translate_xyz(0, -5, 0).extrude(0.1).set_material(blue_material)

            
Advanced Text
Text with forloops and joints.
Image
            
from codetocad import *



starting_letter_ascii = ord("a")



for letter_ascii in range(starting_letter_ascii, starting_letter_ascii + 26):

    letter = chr(letter_ascii)



    extrude_amount = 0.2



    letter_sketch = Sketch(letter).create_text(letter)

    letter_sketch.extrude(extrude_amount)

    letter_sketch.rotate_xyz(90, 0, -90)



    if letter_ascii == starting_letter_ascii:

        continue



    previous_letter = chr(letter_ascii - 1)



    desired_spacing = 1



    limit_x = desired_spacing - extrude_amount * 2



    Joint(

        Sketch(previous_letter).get_landmark("center"),

        Sketch(letter).get_landmark("center"),

    ).limit_location_xyz(desired_spacing, 0, 0)