Just for Fun

Dalton

molecule representation with Dalton element symbols

Elements as described in John Dalton’s New System of Chemical Philosophy

../_images/dalton.svg ../_images/dalton-elements.jpg
dalton.py
#!/usr/bin/env python3
# (C) 2026 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.

"""Depict molecule with Dalton element symbols for H, C, O, N, S, P."""

import argparse
import io
import math
import os
import pathlib
import sys

from openeye import oechem, oedepict
from PIL import Image
from rich_argparse import HelpPreviewAction, RichHelpFormatter

__SCRIPT_NAME__ = pathlib.Path(__file__).absolute().stem
__SCRIPT_DESC__ = "Depict molecule with Dalton element symbols."
__SCRIPT_TOOLKITS__ = ["oechem", "oedepict"]


def parse_options() -> argparse.Namespace:
    """Set up command line options."""
    parser = argparse.ArgumentParser(
        add_help=True,
        formatter_class=RichHelpFormatter,
        description="[yellow]" + __SCRIPT_DESC__ + "[/yellow]",
    )
    parser.add_argument("--help-image", action=HelpPreviewAction)

    input_group = parser.add_argument_group("Input options")
    input_group.add_argument(
        "--mol",
        type=str,
        required=True,
        metavar="MOL-FILE",
        help="input molecule file (oeb, sdf)",
    )

    image_group = parser.add_argument_group("Image options")
    image_group.add_argument(
        "--image",
        type=str,
        required=False,
        metavar="IMAGE-FILE",
        help="output image file (PNG, SVG) (required: %(required)s) -- if no output is provided the image will be displayed on the  screen",
    )
    image_group.add_argument(
        "--width",
        type=int,
        default=900,
        help="width of output image (default: %(default)s)",
    )
    image_group.add_argument(
        "--height",
        type=int,
        default=600,
        help="height of output image (default: %(default)s)",
    )
    return parser.parse_args()


def main() -> int:
    """Depict molecule with Dalton element symbols."""
    args = parse_options()
    _check_image_file(args)

    ifs = oechem.oemolistream()
    if not ifs.open(args.mol):
        oechem.OEThrow.Fatal("Cannot open input file!")

    mol = oechem.OEGraphMol()
    if not oechem.OEReadMolecule(ifs, mol):
        oechem.OEThrow.Fatal("Cannot read input file!")

    image = oedepict.OEImage(args.width, args.height)
    depict_dalton(image, mol)

    if args.image:
        oedepict.OEWriteImage(args.image, image)
    else:
        _img = Image.open(io.BytesIO(oedepict.OEWriteImageToBytes("png", image)))
        _img.show()

    return os.EX_OK


def draw_hydrogen(
    image: oedepict.OEImageBase,
    center: oedepict.OE2DPoint,
    radius: float,
    pen: oedepict.OEPen,
) -> None:
    """Draw a Dalton hydrogen symbol (filled dot) at the given position."""
    pen.SetBackColor(pen.GetForeColor())
    pen.SetFill(oedepict.OEFill_On)
    image.DrawCircle(center, radius / 8.0, pen)


def draw_carbon(
    image: oedepict.OEImageBase,
    center: oedepict.OE2DPoint,
    radius: float,
    pen: oedepict.OEPen,
) -> None:
    """Draw a Dalton carbon symbol (filled grey circle) at the given position."""
    pen.SetBackColor(oechem.OELightGrey)
    pen.SetFill(oedepict.OEFill_On)
    image.DrawCircle(center, radius, pen)


def draw_nitrogen(
    image: oedepict.OEImageBase,
    center: oedepict.OE2DPoint,
    radius: float,
    pen: oedepict.OEPen,
) -> None:
    """Draw a Dalton nitrogen symbol (vertical line) at the given position."""
    image.DrawLine(
        center + oedepict.OE2DPoint(0.0, -radius),
        center + oedepict.OE2DPoint(0.0, +radius),
        pen,
    )


def draw_oxygen(
    image: oedepict.OEImageBase,
    center: oedepict.OE2DPoint,
    radius: float,
    pen: oedepict.OEPen,
) -> None:
    """Draw a Dalton oxygen symbol (empty circle) at the given position."""


def draw_sulphur(
    image: oedepict.OEImageBase,
    center: oedepict.OE2DPoint,
    radius: float,
    pen: oedepict.OEPen,
) -> None:
    """Draw a Dalton sulphur symbol (cross) at the given position."""
    image.DrawLine(
        center + oedepict.OE2DPoint(0.0, -radius),
        center + oedepict.OE2DPoint(0.0, +radius),
        pen,
    )
    image.DrawLine(
        center + oedepict.OE2DPoint(-radius, 0.0),
        center + oedepict.OE2DPoint(+radius, 0.0),
        pen,
    )


def draw_phosphorus(
    image: oedepict.OEImageBase,
    center: oedepict.OE2DPoint,
    radius: float,
    pen: oedepict.OEPen,
) -> None:
    """Draw a Dalton phosphorus symbol (three-pronged fork) at the given position."""
    r = math.sqrt((radius * radius) / 2.0)
    image.DrawLine(center, center + oedepict.OE2DPoint(0.0, -radius), pen)
    image.DrawLine(center, center + oedepict.OE2DPoint(+r, r), pen)
    image.DrawLine(center, center + oedepict.OE2DPoint(-r, r), pen)


def depict_dalton(image: oedepict.OEImageBase, mol: oechem.OEMolBase) -> None:
    """
    Depict a molecule using Dalton element symbols for supported atoms.

    Prepares the molecule for 2D depiction and overlays Dalton-style
    element symbols (H, C, N, O, S, P) on top of the standard depiction.
    """
    opts = oedepict.OE2DMolDisplayOptions(
        image.GetWidth(), image.GetHeight(), oedepict.OEScale_AutoScale
    )
    pen = oedepict.OEPen(oechem.OEBlack, oechem.OEBlack, oedepict.OEFill_Off, 3.0)
    opts.SetDefaultBondPen(pen)

    oedepict.OEPrepareDepiction(mol)
    disp = oedepict.OE2DMolDisplay(mol, opts)

    layer = disp.GetLayer(oedepict.OELayerPosition_Above)

    atomic_draw_functions = {
        oechem.OEElemNo_H: draw_hydrogen,
        oechem.OEElemNo_C: draw_carbon,
        oechem.OEElemNo_N: draw_nitrogen,
        oechem.OEElemNo_O: draw_oxygen,
        oechem.OEElemNo_S: draw_sulphur,
        oechem.OEElemNo_P: draw_phosphorus,
    }

    scale = disp.GetScale()

    for atom in mol.GetAtoms():
        atomic_num = atom.GetAtomicNum()
        if atomic_num not in atomic_draw_functions:
            continue

        atom_disp = disp.GetAtomDisplay(atom)
        if atom_disp is None or not atom_disp.IsVisible():
            continue
        atom_disp.SetLabel("")

        center = atom_disp.GetCoords()
        radius = scale / 3.5
        linewidth = scale / 10.0

        color = oedepict.OEGetDefaultAtomColor(atomic_num)
        pen = oedepict.OEPen(oechem.OEWhite, color, oedepict.OEFill_Off, linewidth)

        layer.DrawCircle(center, radius, oedepict.OEWhiteBoxPen)
        atomic_draw_functions[atomic_num](layer, center, radius, pen)

        pen = oedepict.OEPen(oechem.OEWhite, color, oedepict.OEFill_Off, linewidth)
        layer.DrawCircle(center, radius, pen)

    oedepict.OERenderMolecule(image, disp)


def _check_image_file(args: argparse.Namespace) -> None:
    # script will terminate if there is some issues
    if not args.image:
        # image will be displayed on the screen
        return
    ext = pathlib.Path(args.image).suffix[1:].upper()
    if not oedepict.OEIsRegisteredImageFile(ext):
        oechem.OEThrow.Fatal("Unknown image output type!")

    ofs = oechem.oeofstream()
    if not ofs.open(args.image):
        oechem.OEThrow.Fatal("Cannot open output image file!")


setattr(main, "__SCRIPT_NAME__", __SCRIPT_NAME__)
setattr(main, "__SCRIPT_DESC__", __SCRIPT_DESC__)
setattr(main, "__SCRIPT_TOOLKITS__", __SCRIPT_TOOLKITS__)

if __name__ == "__main__":
    sys.exit(main())

Picasso

../_images/picasso.svg
picasso.py
#!/usr/bin/env python3
# (C) 2023 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.

"""Depict Pablo Picasso's dog sketch."""

import os
import sys

from openeye import oechem, oedepict


def main() -> int:
    """Depict Pablo Picasso's dog sketch."""
    image = oedepict.OEImage(500, 250)

    pen = oedepict.OEPen(oechem.OEWhite, oechem.OEBlack, oedepict.OEFill_Off, 4.0)
    image.DrawCubicBezier(
        oedepict.OE2DPoint(180, 180),
        oedepict.OE2DPoint(183, 168),
        oedepict.OE2DPoint(186, 156),
        oedepict.OE2DPoint(189, 144),
        pen,
    )
    image.DrawCubicBezier(
        oedepict.OE2DPoint(191, 144),
        oedepict.OE2DPoint(290, 144),
        oedepict.OE2DPoint(300, 130),
        oedepict.OE2DPoint(339, 145),
        pen,
    )
    image.DrawCubicBezier(
        oedepict.OE2DPoint(340, 146),
        oedepict.OE2DPoint(350, 190),
        oedepict.OE2DPoint(360, 200),
        oedepict.OE2DPoint(355, 110),
        pen,
    )
    image.DrawCubicBezier(
        oedepict.OE2DPoint(353, 110),
        oedepict.OE2DPoint(370, 107),
        oedepict.OE2DPoint(380, 96),
        oedepict.OE2DPoint(375, 93),
        pen,
    )
    image.DrawCubicBezier(
        oedepict.OE2DPoint(375, 93),
        oedepict.OE2DPoint(310, 120),
        oedepict.OE2DPoint(190, 120),
        oedepict.OE2DPoint(164, 105),
        pen,
    )
    image.DrawCubicBezier(
        oedepict.OE2DPoint(164, 105),
        oedepict.OE2DPoint(135, 94),
        oedepict.OE2DPoint(135, 165),
        oedepict.OE2DPoint(153, 175),
        pen,
    )
    image.DrawCubicBezier(
        oedepict.OE2DPoint(153, 175),
        oedepict.OE2DPoint(168, 175),
        oedepict.OE2DPoint(170, 80),
        oedepict.OE2DPoint(150, 90),
        pen,
    )
    image.DrawCubicBezier(
        oedepict.OE2DPoint(149, 90),
        oedepict.OE2DPoint(122, 114),
        oedepict.OE2DPoint(142, 104),
        oedepict.OE2DPoint(85, 140),
        pen,
    )
    image.DrawCubicBezier(
        oedepict.OE2DPoint(86, 140),
        oedepict.OE2DPoint(100, 147),
        oedepict.OE2DPoint(125, 133),
        oedepict.OE2DPoint(140, 138),
        pen,
    )

    # add OEDepict TK watermark

    font = oedepict.OEFont(
        oedepict.OEFontFamily_Default,
        oedepict.OEFontStyle_Default,
        10,
        oedepict.OEAlignment_Right,
        oechem.OELightGrey,
    )
    text = "Generated by OEDepict TK after Picasso"
    position = oedepict.OE2DPoint(image.GetWidth() - 10.0, image.GetHeight() - 10.0)
    image.DrawText(position, text, font)

    oedepict.OEDrawCurvedBorder(image, oedepict.OELightGreyPen, 10)
    oedepict.OEWriteImage("picasso.svg", image)

    return os.EX_OK


if __name__ == "__main__":
    sys.exit(main())

OELove

../_images/oelove.svg
oelove.py
#!/usr/bin/env python3
# (C) 2026 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.

"""Depict molecule with oxygen atoms rendered as hearts."""

import argparse
import io
import os
import pathlib
import sys

from openeye import oechem, oedepict
from PIL import Image
from rich_argparse import HelpPreviewAction, RichHelpFormatter

__SCRIPT_NAME__ = pathlib.Path(__file__).absolute().stem
__SCRIPT_DESC__ = "Depict molecule with oxygen atoms rendered as hearts."
__SCRIPT_TOOLKITS__ = ["oechem", "oedepict"]


def parse_options() -> argparse.Namespace:
    """Set up command line options."""
    parser = argparse.ArgumentParser(
        add_help=True,
        formatter_class=RichHelpFormatter,
        description="[yellow]" + __SCRIPT_DESC__ + "[/yellow]",
    )
    parser.add_argument("--help-image", action=HelpPreviewAction)

    input_group = parser.add_argument_group("Input options")
    input_group.add_argument(
        "--mol",
        type=str,
        required=True,
        metavar="MOL-FILE",
        help="input molecule file (oeb, sdf)",
    )

    image_group = parser.add_argument_group("Image options")
    image_group.add_argument(
        "--image",
        type=str,
        required=False,
        metavar="IMAGE-FILE",
        help="output image file (PNG, SVG) (required: %(required)s) -- if no output is provided the image will be displayed on the  screen",
    )
    image_group.add_argument(
        "--width",
        type=int,
        default=900,
        help="width of output image (default: %(default)s)",
    )
    image_group.add_argument(
        "--height",
        type=int,
        default=600,
        help="height of output image (default: %(default)s)",
    )
    return parser.parse_args()


def main() -> int:
    """Depict molecule with oxygen atoms as hearts."""
    args = parse_options()
    _check_image_file(args)

    ifs = oechem.oemolistream()
    if not ifs.open(args.mol):
        oechem.OEThrow.Fatal("Cannot open input file!")
    mol = oechem.OEGraphMol()
    if not oechem.OEReadMolecule(ifs, mol):
        oechem.OEThrow.Fatal("Cannot read input file!")

    image = oedepict.OEImage(args.width, args.height)
    depict_love(image, mol)

    if args.image:
        oedepict.OEWriteImage(args.image, image)
    else:
        _img = Image.open(io.BytesIO(oedepict.OEWriteImageToBytes("png", image)))
        _img.show()

    return os.EX_OK


def draw_heart(
    image: oedepict.OEImageBase,
    center: oedepict.OE2DPoint,
    scale: float,
) -> None:
    """Draw a heart shape at the given position on the image."""
    pen = oedepict.OEPen(oedepict.OERedBoxPen)
    image.DrawCircle(
        center + oedepict.OE2DPoint(-scale / 8.0, -scale / 9.0), scale / 8.0, pen
    )
    image.DrawCircle(
        center + oedepict.OE2DPoint(+scale / 8.0, -scale / 9.0), scale / 8.0, pen
    )

    polygon = [
        oedepict.OE2DPoint(-scale / 4.4, 0.0),
        oedepict.OE2DPoint(-scale / 4.0, -scale / 9.0),
        oedepict.OE2DPoint(+scale / 4.0, -scale / 9.0),
        oedepict.OE2DPoint(+scale / 4.4, 0.0),
        oedepict.OE2DPoint(0.0, scale / 5.0),
    ]

    heart = [center + p for p in polygon]
    image.DrawPolygon(heart, oedepict.OERedBoxPen)


def depict_love(image: oedepict.OEImageBase, mol: oechem.OEMolBase) -> None:
    """Depict a molecule with oxygen atoms replaced by heart symbols."""
    opts = oedepict.OE2DMolDisplayOptions(
        image.GetWidth(), image.GetHeight(), oedepict.OEScale_AutoScale
    )
    pen = oedepict.OEPen(oechem.OEBlack, oechem.OEBlack, oedepict.OEFill_Off, 3.0)
    opts.SetDefaultBondPen(pen)

    oedepict.OEPrepareDepiction(mol)
    disp = oedepict.OE2DMolDisplay(mol, opts)

    layer = disp.GetLayer(oedepict.OELayerPosition_Above)
    for atom_disp in disp.GetAtomDisplays(oechem.OEHasAtomicNum(oechem.OEElemNo_O)):
        if atom_disp.IsVisible():
            atom_disp.SetLabel("")
            draw_heart(layer, atom_disp.GetCoords(), disp.GetScale())

    oedepict.OERenderMolecule(image, disp)


def _check_image_file(args: argparse.Namespace) -> None:
    # script will terminate if there is some issues
    if not args.image:
        # image will be displayed on the screen
        return
    ext = pathlib.Path(args.image).suffix[1:].upper()
    if not oedepict.OEIsRegisteredImageFile(ext):
        oechem.OEThrow.Fatal("Unknown image output type!")

    ofs = oechem.oeofstream()
    if not ofs.open(args.image):
        oechem.OEThrow.Fatal("Cannot open output image file!")


setattr(main, "__SCRIPT_NAME__", __SCRIPT_NAME__)
setattr(main, "__SCRIPT_DESC__", __SCRIPT_DESC__)
setattr(main, "__SCRIPT_TOOLKITS__", __SCRIPT_TOOLKITS__)

if __name__ == "__main__":
    sys.exit(main())

Flag of New Mexico

../_images/flag.svg
flag.py
#!/usr/bin/env python3
# (C) 2023 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.

"""Depict flag of New Mexico."""

import os
import sys

from openeye import oechem, oedepict


def main() -> int:
    """Depict flag of New Mexico."""
    image_width, image_height = 300, 200
    yellow = oechem.OEColor(255, 215, 0)
    image = oedepict.OEImage(image_width, image_height, yellow)

    c = oedepict.OEGetCenter(image)

    pen = oedepict.OEPen(yellow, oechem.OERed, oedepict.OEFill_On, 5.0)
    image.DrawCircle(c, 4.0, oedepict.OEBluePen)

    image.DrawLine(
        c + oedepict.OE2DPoint(-5.0, -70.0), c + oedepict.OE2DPoint(-5.0, +70.0), pen
    )
    image.DrawLine(
        c + oedepict.OE2DPoint(-15.0, -55.0), c + oedepict.OE2DPoint(-15.0, +55.0), pen
    )
    image.DrawLine(
        c + oedepict.OE2DPoint(+15.0, -55.0), c + oedepict.OE2DPoint(+15.0, +55.0), pen
    )
    image.DrawLine(
        c + oedepict.OE2DPoint(+5.0, -70.0), c + oedepict.OE2DPoint(+5.0, +70.0), pen
    )

    image.DrawLine(
        c + oedepict.OE2DPoint(-55.0, -15.0), c + oedepict.OE2DPoint(+55.0, -15.0), pen
    )
    image.DrawLine(
        c + oedepict.OE2DPoint(-70.0, -5.0), c + oedepict.OE2DPoint(+70.0, -5.0), pen
    )
    image.DrawLine(
        c + oedepict.OE2DPoint(-70.0, +5.0), c + oedepict.OE2DPoint(+70.0, +5.0), pen
    )
    image.DrawLine(
        c + oedepict.OE2DPoint(-55.0, +15.0), c + oedepict.OE2DPoint(+55.0, +15.0), pen
    )

    image.DrawCircle(c, 25.0, pen)

    # write image

    oedepict.OEWriteImage("flag.svg", image)

    return os.EX_OK


if __name__ == "__main__":
    sys.exit(main())

See also

OEHolidays

../_images/oeholidays.svg
❄️ oeholidays.py
#!/usr/bin/env python3
# (C) 2023 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.

"""Depict Happy Holidays Card."""

import math
import os
import sys

from openeye import oechem, oedepict


def main() -> int:
    """Depict Happy Holidays Card."""
    image_width, image_height = 350, 350
    image = oedepict.OEImage(image_width, image_height)
    image.Clear(oechem.OEBlueTint)

    font = oedepict.OEFont(
        oedepict.OEFontFamily_Default,
        oedepict.OEFontStyle_Bold,
        30,
        oedepict.OEAlignment_Center,
        oechem.OEWhite,
    )
    image.DrawText(
        oedepict.OE2DPoint(image_height / 2.0, 30.0), "Happy Holidays!", font
    )

    center = oedepict.OEGetCenter(image) + oedepict.OE2DPoint(0.0, 15.0)

    color = oechem.OEColor(oechem.OEWhite)
    length = 240.0
    for i in range(4, 1, -1):
        cursor = center + oedepict.OE2DPoint(length / 2.0, -length / 3.0 + 15.0)
        direction = oedepict.OE2DPoint(-1.0, 0.0)

        snowflake = []
        snowflake.append(cursor)

        _get_snowflake_polygon(cursor, direction, i, length, snowflake)

        pen = oedepict.OEPen(color, color, oedepict.OEFill_On, 1.0)
        image.DrawPolygon(snowflake, pen)

        length -= 70.0
        color = oechem.OEBlueTint if color == oechem.OEWhite else oechem.OEWhite

    font = oedepict.OEFont(
        oedepict.OEFontFamily_Default,
        oedepict.OEFontStyle_Bold,
        12,
        oedepict.OEAlignment_Right,
        oechem.OEWhite,
    )
    text = "Generated by OEDepict TK"
    image.DrawText(
        oedepict.OE2DPoint(image_width - 10.0, image_height - 10.0), text, font
    )

    oedepict.OEWriteImage("oeholidays.svg", image)

    return os.EX_OK


def _koch_fractal(
    cursor: oedepict.OE2DPoint,
    direction: oedepict.OE2DPoint,
    order: int,
    length: float,
    polygon: list[oedepict.OE2DPoint],
) -> oedepict.OE2DPoint:
    if order == 0:
        next_point = cursor + _lengthen(direction, length)
        polygon.append(next_point)
        return next_point
    length /= 3.0
    for angle in [60, -120, 60, 0]:
        cursor = _koch_fractal(cursor, direction, order - 1, length, polygon)
        direction = _rotate_point(direction, angle)
    return cursor


def _get_snowflake_polygon(
    cursor: oedepict.OE2DPoint,
    direction: oedepict.OE2DPoint,
    order: int,
    length: float,
    polygon: list[oedepict.OE2DPoint],
) -> None:
    for _ in range(3):
        cursor = _koch_fractal(cursor, direction, order, length, polygon)
        direction = _rotate_point(direction, -120.0)


def _lengthen(p: oedepict.OE2DPoint, length: float) -> oedepict.OE2DPoint:
    dist = math.sqrt(p.GetX() * p.GetX() + p.GetY() * p.GetY())
    dist = dist / length
    if dist == 0.0:
        return p
    return oedepict.OE2DPoint(p.GetX() / dist, p.GetY() / dist)


def _rotate_point(p: oedepict.OE2DPoint, degree: float) -> oedepict.OE2DPoint:
    rad = degree * oechem.Deg2Rad
    cos_rad = math.cos(rad)
    sin_rad = math.sin(rad)
    return oedepict.OE2DPoint(
        cos_rad * p.GetX() - sin_rad * p.GetY(), sin_rad * p.GetX() + cos_rad * p.GetY()
    )


if __name__ == "__main__":
    sys.exit(main())

See also

Depicting molecule with shadow

../_images/molshadow2img.png
molshadow2img.py
#!/usr/bin/env python3
# (C) 2026 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.

"""Depict a molecule with a drop shadow effect."""

import argparse
import io
import os
import pathlib
import sys

from openeye import oechem, oedepict
from PIL import Image
from rich_argparse import HelpPreviewAction, RichHelpFormatter

__SCRIPT_NAME__ = pathlib.Path(__file__).absolute().stem
__SCRIPT_DESC__ = "Depict a molecule with a drop shadow effect."
__SCRIPT_TOOLKITS__ = ["oechem", "oedepict"]


def parse_options() -> argparse.Namespace:
    """Set up command line options."""
    parser = argparse.ArgumentParser(
        add_help=True,
        formatter_class=RichHelpFormatter,
        description="[yellow]" + __SCRIPT_DESC__ + "[/yellow]",
    )
    parser.add_argument("--help-image", action=HelpPreviewAction)

    input_group = parser.add_argument_group("Input options")
    input_group.add_argument(
        "--mol",
        type=str,
        required=True,
        metavar="MOL-FILE",
        help="input molecule file (oeb, sdf)",
    )

    image_group = parser.add_argument_group("Image options")
    image_group.add_argument(
        "--image",
        type=str,
        required=False,
        metavar="IMAGE-FILE",
        help="output image file (PNG, SVG) (required: %(required)s) -- if no output is provided the image will be displayed on the  screen",
    )
    image_group.add_argument(
        "--width",
        type=int,
        default=900,
        help="width of output image (default: %(default)s)",
    )
    image_group.add_argument(
        "--height",
        type=int,
        default=600,
        help="height of output image (default: %(default)s)",
    )
    return parser.parse_args()


def main() -> int:
    """Depict a molecule with a drop shadow effect."""
    args = parse_options()
    _check_image_file(args)

    ifs = oechem.oemolistream()
    if not ifs.open(args.mol):
        oechem.OEThrow.Fatal("Cannot open input file!")
    mol = oechem.OEGraphMol()
    if not oechem.OEReadMolecule(ifs, mol):
        oechem.OEThrow.Fatal("Cannot read input file!")
    oedepict.OEPrepareDepiction(mol)

    image = oedepict.OEImage(args.width, args.height)
    render_molecule_with_shadow(image, mol)

    if args.image:
        oedepict.OEWriteImage(args.image, image)
    else:
        _img = Image.open(io.BytesIO(oedepict.OEWriteImageToBytes("png", image)))
        _img.show()

    return os.EX_OK


def render_molecule_with_shadow(
    image: oedepict.OEImageBase, mol: oechem.OEMolBase
) -> None:
    """Render a molecule image with a grey drop shadow underneath."""
    opts = oedepict.OE2DMolDisplayOptions(
        image.GetWidth(), image.GetHeight(), oedepict.OEScale_AutoScale
    )

    shadow_opts = oedepict.OE2DMolDisplayOptions(opts)
    shadow_opts.SetAtomColorStyle(oedepict.OEAtomColorStyle_WhiteMonochrome)
    shadow_opts.SetAtomColor(oechem.OEElemNo_C, oechem.OEGrey)
    shadow_opts.SetAtomLabelFontScale(1.2)

    font = shadow_opts.GetAtomLabelFont()
    font.SetStyle(oedepict.OEFontStyle_Bold)
    shadow_opts.SetAtomLabelFont(font)

    pen = shadow_opts.GetDefaultBondPen()
    pen.SetLineWidth(pen.GetLineWidth() * 2.0)
    shadow_opts.SetDefaultBondPen(pen)

    disp = oedepict.OE2DMolDisplay(mol, shadow_opts)

    oedepict.OEOffsetMolDisplay(disp, oedepict.OE2DPoint(+5, +5))
    oedepict.OERenderMolecule(image, disp)

    disp = oedepict.OE2DMolDisplay(mol, opts)
    oedepict.OERenderMolecule(image, disp, False)


def _check_image_file(args: argparse.Namespace) -> None:
    # script will terminate if there is some issues
    if not args.image:
        # image will be displayed on the screen
        return
    ext = pathlib.Path(args.image).suffix[1:].upper()
    if not oedepict.OEIsRegisteredImageFile(ext):
        oechem.OEThrow.Fatal("Unknown image output type!")

    ofs = oechem.oeofstream()
    if not ofs.open(args.image):
        oechem.OEThrow.Fatal("Cannot open output image file!")


setattr(main, "__SCRIPT_NAME__", __SCRIPT_NAME__)
setattr(main, "__SCRIPT_DESC__", __SCRIPT_DESC__)
setattr(main, "__SCRIPT_TOOLKITS__", __SCRIPT_TOOLKITS__)

if __name__ == "__main__":
    sys.exit(main())

spring

summer

../_images/spring.svg ../_images/summer.svg

fall

winter

../_images/fall.svg ../_images/winter.svg
oetree.py
#!/usr/bin/env python3
# (C) 2026 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.
# ruff: noqa: S311

"""Generate a tree depiction in different seasons."""

import argparse
import math
import os
import random
import sys
from pathlib import Path

from openeye import oechem, oedepict
from rich_argparse import HelpPreviewAction, RichHelpFormatter

__SCRIPT_NAME__ = Path(__file__).absolute().stem
__SCRIPT_DESC__ = "Generate a tree depiction in different seasons."
__SCRIPT_TOOLKITS__ = ["oechem", "oedepict"]


def parse_options() -> argparse.Namespace:
    """Set up command line options."""
    parser = argparse.ArgumentParser(
        add_help=True,
        formatter_class=RichHelpFormatter,
        description="[yellow]" + __SCRIPT_DESC__ + "[/yellow]",
    )
    parser.add_argument("--help-image", action=HelpPreviewAction)

    parser.add_argument(
        "--season",
        "-s",
        type=str,
        required=True,
        choices=["spring", "summer", "fall", "winter"],
        help="season to depict",
    )
    return parser.parse_args()


def _lengthen(p: oedepict.OE2DPoint, length: float) -> oedepict.OE2DPoint:
    """Scale a direction vector to the given length."""
    mag = math.sqrt(p.GetX() * p.GetX() + p.GetY() * p.GetY())
    if mag == 0.0:
        return p
    scale = length / mag
    return oedepict.OE2DPoint(p.GetX() * scale, p.GetY() * scale)


def _rotate(p: oedepict.OE2DPoint, degree: float) -> oedepict.OE2DPoint:
    """Rotate a 2D point by the given angle in degrees."""
    rad = degree * oechem.Deg2Rad
    cos_rad = math.cos(rad)
    sin_rad = math.sin(rad)
    return oedepict.OE2DPoint(
        cos_rad * p.GetX() - sin_rad * p.GetY(),
        sin_rad * p.GetX() + cos_rad * p.GetY(),
    )


def draw_leaf(
    image: oedepict.OEImageBase,
    cursor: oedepict.OE2DPoint,
    direction: oedepict.OE2DPoint,
    length: float,
    color: oechem.OEColor,
) -> None:
    """Draw a leaf shape using two quadratic Bezier curves."""
    bgn = cursor
    end = cursor + _lengthen(direction, length)
    pen = oedepict.OEPen(color, color, oedepict.OEFill_On, 2.0)

    c1 = bgn + _lengthen(_rotate(direction, +55), length / 1.6)
    c2 = bgn + _lengthen(_rotate(direction, -55), length / 1.6)

    image.DrawQuadraticBezier(bgn, c1, end, pen)
    image.DrawQuadraticBezier(bgn, c2, end, pen)


def _koch_fractal(
    cursor: oedepict.OE2DPoint,
    direction: oedepict.OE2DPoint,
    order: int,
    length: float,
    polygon: list,
) -> oedepict.OE2DPoint:
    """Recursively generate Koch fractal points."""
    if order == 0:
        next_pt = cursor + _lengthen(direction, length)
        polygon.append(next_pt)
        return next_pt
    length /= 3.0
    for angle in [60, -120, 60, 0]:
        cursor = _koch_fractal(cursor, direction, order - 1, length, polygon)
        direction = _rotate(direction, angle)
    return cursor


def _get_snowflake_polygon(
    cursor: oedepict.OE2DPoint,
    direction: oedepict.OE2DPoint,
    order: int,
    length: float,
    polygon: list,
) -> None:
    """Generate the polygon points for a Koch snowflake."""
    for _ in range(3):
        cursor = _koch_fractal(cursor, direction, order, length, polygon)
        direction = _rotate(direction, -120.0)


def draw_snowflake(
    image: oedepict.OEImageBase,
    position: oedepict.OE2DPoint,
    size: float,
    color: oechem.OEColor,
) -> None:
    """Draw a Koch snowflake at the given position."""
    color.SetA(180)
    snowflake: list = []
    _get_snowflake_polygon(
        position, oedepict.OE2DPoint(0.0, 1.0), 3, size * 1.5, snowflake
    )
    snow_pen = oedepict.OEPen(
        color, oechem.OELightBlue, oedepict.OEFill_On, 1.0, oedepict.OEStipple_NoLine
    )
    image.DrawPolygon(snowflake, snow_pen)


def draw_flower(
    image: oedepict.OEImageBase,
    cursor: oedepict.OE2DPoint,
    length: float,
    color: oechem.OEColor,
) -> None:
    """Draw a flower with eight petals at the given position."""
    direction = oedepict.OE2DPoint(0.0, 1.0)
    for _ in range(8):
        direction = _rotate(direction, 45.0)
        draw_leaf(image, cursor, direction, length, color)
    image.DrawCircle(cursor, length / 6.0, oedepict.OEWhiteBoxPen)


def draw_tree(  # noqa: PLR0913, PLR0917
    image: oedepict.OEImageBase,
    cursor: oedepict.OE2DPoint,
    direction: oedepict.OE2DPoint,
    depth: int,
    length: float,
    pen: oedepict.OEPen,
    rand_branch: bool,
    leaves: list,
    flowers: list,
) -> None:
    """Recursively draw a fractal tree with branches."""
    if depth <= 1:
        leaves.append((cursor, direction, length))
        flowers.append((cursor, length / 4.0))
    if depth > 0:
        p = oedepict.OEPen(pen)
        p.SetLineWidth(depth * 2.5)

        next_pt = cursor + _lengthen(direction, length)
        image.DrawLine(cursor, next_pt, p)

        for angle in [45.0, -45.0, -45.0]:
            direction = (
                _rotate(direction, angle * (0.5 + 0.5 * random.random()))
                if rand_branch
                else _rotate(direction, angle)
            )
            draw_tree(
                image,
                next_pt,
                direction,
                depth - 1,
                length * 0.85,
                pen,
                True,
                leaves,
                flowers,
            )


def generate_tree(season: str) -> oedepict.OEImage:
    """Generate a tree image for the given season."""
    image_width, image_height = 300, 300
    image = oedepict.OEImage(image_width, image_height)

    cursor = oedepict.OE2DPoint(150, 250)
    direction = oedepict.OE2DPoint(0.0, -1.0)
    branch_length = 50.0
    branch_pen = oedepict.OEPen(oechem.OEBrown, oechem.OEBlack, oedepict.OEFill_On, 5.0)

    leaves: list = []
    flowers: list = []
    draw_tree(
        image, cursor, direction, 5, branch_length, branch_pen, False, leaves, flowers
    )

    # draw leaves
    if season != "winter":
        leaf_color_gradient = oechem.OELinearColorGradient()

        if season == "spring":
            leaf_color_gradient.AddStop(oechem.OEColorStop(0.0, oechem.OELightGreen))
            leaf_color_gradient.AddStop(oechem.OEColorStop(1.0, oechem.OEDarkGreen))
        elif season == "summer":
            leaf_color_gradient.AddStop(oechem.OEColorStop(0.0, oechem.OEGreen))
            leaf_color_gradient.AddStop(oechem.OEColorStop(1.0, oechem.OEDarkGreen))
        elif season == "fall":
            leaf_color_gradient.AddStop(oechem.OEColorStop(0.0, oechem.OEYellow))
            leaf_color_gradient.AddStop(oechem.OEColorStop(1.0, oechem.OEDarkRed))

        for position, leaf_direction, size in leaves:
            color = leaf_color_gradient.GetColorAt(random.random())
            draw_leaf(image, position, leaf_direction, size, color)

    if season == "winter":
        # draw snowflakes
        snow_color_gradient = oechem.OELinearColorGradient()
        snow_color_gradient.AddStop(
            oechem.OEColorStop(0.0, oechem.OEColor(245, 245, 245))
        )
        snow_color_gradient.AddStop(oechem.OEColorStop(1.0, oechem.OELightBlue))

        for position, size in flowers:
            color = snow_color_gradient.GetColorAt(random.random())
            draw_snowflake(image, position, size, color)

    if season == "spring":
        # draw flowers
        color_gradient = oechem.OELinearColorGradient()
        color_gradient.AddStop(oechem.OEColorStop(0.0, oechem.OEPinkTint))
        color_gradient.AddStop(oechem.OEColorStop(1.0, oechem.OEDarkPurple))

        for position, size in flowers:
            color = color_gradient.GetColorAt(random.random())
            draw_flower(image, position, size, color)

    # draw earth mound
    earth_colors = {
        "winter": oechem.OELightBlue,
        "spring": oechem.OELightGreen,
        "summer": oechem.OEDarkGreen,
        "fall": oechem.OEDarkOrange,
    }
    earth_color = oechem.OEColor(earth_colors[season])

    pos = oedepict.OE2DPoint(150, 260)
    bgn = pos - oedepict.OE2DPoint(80, 0)
    end = pos + oedepict.OE2DPoint(80, 0)
    c = pos - oedepict.OE2DPoint(0.0, 40)

    earth_pen = oedepict.OEPen(earth_color, earth_color, oedepict.OEFill_On, 1.0)
    image.DrawQuadraticBezier(bgn, c, end, earth_pen)

    # add watermark
    font = oedepict.OEFont(
        oedepict.OEFontFamily_Default,
        oedepict.OEFontStyle_Default,
        10,
        oedepict.OEAlignment_Right,
        oechem.OELightGrey,
    )
    text = "Generated by OEDepict TK"
    image.DrawText(
        oedepict.OE2DPoint(image_width - 20.0, image_height - 20.0), text, font
    )

    return image


def main() -> int:
    """Generate a tree depiction in different seasons."""
    args = parse_options()

    image = generate_tree(args.season)
    oedepict.OEWriteImage(f"{args.season}.svg", image)

    return os.EX_OK


setattr(main, "__SCRIPT_NAME__", __SCRIPT_NAME__)
setattr(main, "__SCRIPT_DESC__", __SCRIPT_DESC__)
setattr(main, "__SCRIPT_TOOLKITS__", __SCRIPT_TOOLKITS__)

if __name__ == "__main__":
    sys.exit(main())

OEAnime

../_images/soot.svg ../_images/totoro.svg ../_images/jiji.svg

Download code

soot.py, totoro.py, and jiji.py

soot.py
#!/usr/bin/env python3
# (C) 2023 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.


"""Generates image of soot ball from the Miyazaki's film Spirited Away."""


import os
import sys

from openeye import oechem, oedepict, oegrapheme


def main() -> int:
    """Depict sooth ball."""
    image_width, image_height = 200, 200
    image = oedepict.OEImage(image_width, image_height)

    center = oedepict.OE2DPoint(image_width / 2.0, image_height / 2.0)
    radius = min(image_width / 3.0, image_height / 3.0)

    black_pen = oedepict.OEPen(oechem.OEBlack, oechem.OEBlack, oedepict.OEFill_On, 6.0)
    oegrapheme.OEDrawEyelashCircle(image, center, radius, black_pen)

    white_pen = oedepict.OEPen(oechem.OEWhite, oechem.OEWhite, oedepict.OEFill_On, 1.0)

    _draw_ellipse(image, center + oedepict.OE2DPoint(+30, 0), 60, 50, white_pen)
    image.DrawCircle(center + oedepict.OE2DPoint(+20, 0), 3.0, black_pen)
    _draw_ellipse(image, center + oedepict.OE2DPoint(-30, 0), 60, 50, white_pen)
    image.DrawCircle(center + oedepict.OE2DPoint(-20, 0), 3.0, black_pen)

    # add OEDepict TK watermark

    font = oedepict.OEFont(
        oedepict.OEFontFamily_Default,
        oedepict.OEFontStyle_Default,
        10,
        oedepict.OEAlignment_Right,
        oechem.OELightGrey,
    )
    text = "Generated by OEDepict TK"
    image.DrawText(
        oedepict.OE2DPoint(image_width - 5.0, image_height - 5.0), text, font
    )

    # write image

    oedepict.OEWriteImage("soot.svg", image)

    return os.EX_OK


def _draw_ellipse(
    image: oedepict.OEImageBase,
    center: oedepict.OE2DPoint,
    width: float,
    height: float,
    pen: oedepict.OEPen,
) -> None:
    image.DrawCubicBezier(
        center + oedepict.OE2DPoint(0.0, -height / 2.0),
        center + oedepict.OE2DPoint(+width / 2.0, -height / 2.0),
        center + oedepict.OE2DPoint(+width / 2.0, +height / 2.0),
        center + oedepict.OE2DPoint(0.0, +height / 2.0),
        pen,
    )

    image.DrawCubicBezier(
        center + oedepict.OE2DPoint(0.0, +height / 2.0),
        center + oedepict.OE2DPoint(-width / 2.0, +height / 2.0),
        center + oedepict.OE2DPoint(-width / 2.0, -height / 2.0),
        center + oedepict.OE2DPoint(0.0, -height / 2.0),
        pen,
    )


if __name__ == "__main__":
    sys.exit(main())
totoro.py
#!/usr/bin/env python3
# (C) 2023 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.


"""Generates image of Totoro from the Miyazaki's film My Neighbor Totoro."""

import os
import sys

from openeye import oechem, oedepict


def main() -> int:
    """Depict Totoro."""
    image_width, image_height = 200, 200
    image = oedepict.OEImage(image_width, image_height)

    white_pen = oedepict.OEPen(oechem.OEWhite, oechem.OEWhite, oedepict.OEFill_On, 1.0)
    black_pen = oedepict.OEPen(oechem.OEBlack, oechem.OEBlack, oedepict.OEFill_On, 1.0)
    light_grey_pen = oedepict.OEPen(
        oechem.OEColor(170, 160, 160),
        oechem.OEColor(170, 160, 160),
        oedepict.OEFill_On,
        1.0,
    )
    med_grey_pen = oedepict.OEPen(
        oechem.OEColor(100, 90, 90),
        oechem.OEColor(100, 90, 90),
        oedepict.OEFill_On,
        4.0,
    )

    center = oedepict.OE2DPoint(100, 120)

    # head

    to = center + oedepict.OE2DPoint(0, -45)
    rt = center + oedepict.OE2DPoint(+80, +20)
    lf = center + oedepict.OE2DPoint(-80, +20)

    image.DrawCubicBezier(
        to,
        to + oedepict.OE2DPoint(+20, -15),
        rt + oedepict.OE2DPoint(+15, -20),
        rt,
        light_grey_pen,
    )
    image.DrawCubicBezier(
        to,
        to + oedepict.OE2DPoint(-20, -15),
        lf + oedepict.OE2DPoint(-15, -20),
        lf,
        light_grey_pen,
    )
    image.DrawTriangle(to, rt, lf, light_grey_pen)
    image.DrawCircle(to, 3, light_grey_pen)

    _draw_ellipse(image, center + oedepict.OE2DPoint(0, +20), 210, 30, light_grey_pen)

    # ears

    _draw_ellipse(image, center + oedepict.OE2DPoint(-40, -50), 40, 80, light_grey_pen)
    _draw_ellipse(image, center + oedepict.OE2DPoint(+40, -50), 40, 80, light_grey_pen)

    # eyes

    image.DrawCircle(center + oedepict.OE2DPoint(-40, -10), 10, white_pen)
    image.DrawCircle(center + oedepict.OE2DPoint(-42, -15), 4, black_pen)
    image.DrawCircle(center + oedepict.OE2DPoint(-43, -16), 1, white_pen)

    image.DrawCircle(center + oedepict.OE2DPoint(+40, -10), 10, white_pen)
    image.DrawCircle(center + oedepict.OE2DPoint(+38, -15), 4, black_pen)
    image.DrawCircle(center + oedepict.OE2DPoint(+38, -16), 1, white_pen)

    # nose

    image.DrawCircle(center + oedepict.OE2DPoint(0, -10), 2, med_grey_pen)
    image.DrawArc(center + oedepict.OE2DPoint(0, 20), 345, 15, 31, med_grey_pen)

    # whiskers

    image.DrawLine(
        center + oedepict.OE2DPoint(+55, 0),
        center + oedepict.OE2DPoint(+90, -15),
        med_grey_pen,
    )
    image.DrawLine(
        center + oedepict.OE2DPoint(-55, 0),
        center + oedepict.OE2DPoint(-90, -15),
        med_grey_pen,
    )

    image.DrawLine(
        center + oedepict.OE2DPoint(+60, 5),
        center + oedepict.OE2DPoint(+95, +5),
        med_grey_pen,
    )
    image.DrawLine(
        center + oedepict.OE2DPoint(-60, 5),
        center + oedepict.OE2DPoint(-95, +5),
        med_grey_pen,
    )

    image.DrawLine(
        center + oedepict.OE2DPoint(+55, 10),
        center + oedepict.OE2DPoint(+95, +20),
        med_grey_pen,
    )
    image.DrawLine(
        center + oedepict.OE2DPoint(-55, 10),
        center + oedepict.OE2DPoint(-95, +20),
        med_grey_pen,
    )

    # add OEDepict TK watermark

    font = oedepict.OEFont(
        oedepict.OEFontFamily_Default,
        oedepict.OEFontStyle_Default,
        10,
        oedepict.OEAlignment_Right,
        oechem.OELightGrey,
    )
    text = "Generated by OEDepict TK"
    image.DrawText(
        oedepict.OE2DPoint(image_width - 5.0, image_height - 5.0), text, font
    )

    # write image

    oedepict.OEWriteImage("totoro.svg", image)

    return os.EX_OK


def _draw_ellipse(
    image: oedepict.OEImageBase,
    center: oedepict.OE2DPoint,
    width: float,
    height: float,
    pen: oedepict.OEPen,
) -> None:
    image.DrawCubicBezier(
        center + oedepict.OE2DPoint(0.0, -height / 2.0),
        center + oedepict.OE2DPoint(+width / 2.0, -height / 2.0),
        center + oedepict.OE2DPoint(+width / 2.0, +height / 2.0),
        center + oedepict.OE2DPoint(0.0, +height / 2.0),
        pen,
    )

    image.DrawCubicBezier(
        center + oedepict.OE2DPoint(0.0, +height / 2.0),
        center + oedepict.OE2DPoint(-width / 2.0, +height / 2.0),
        center + oedepict.OE2DPoint(-width / 2.0, -height / 2.0),
        center + oedepict.OE2DPoint(0.0, -height / 2.0),
        pen,
    )


if __name__ == "__main__":
    sys.exit(main())
🐱 jiji.py
#!/usr/bin/env python3
# (C) 2026 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.


"""Generates image of Jiji from the Miyazaki's film Kiki's Delivery Service."""

import os
import sys

from openeye import oechem, oedepict


def main() -> int:
    """Depict Jiji."""
    image_width, image_height = (
        200,
        200,
    )
    image = oedepict.OEImage(image_width, image_height, oechem.OEWhite)

    black_pen = oedepict.OEPen(oechem.OEBlack, oechem.OEBlack, oedepict.OEFill_On, 1.0)
    white_pen = oedepict.OEPen(oechem.OEWhite, oechem.OEWhite, oedepict.OEFill_On, 1.0)
    pink_pen = oedepict.OEPen(
        oechem.OEColor(250, 190, 200),
        oechem.OEColor(250, 190, 200),
        oedepict.OEFill_On,
        1.0,
    )

    center = oedepict.OE2DPoint(100, 120)

    # ears

    to = center + oedepict.OE2DPoint(-60, -110)
    rt = center + oedepict.OE2DPoint(-15, -55)
    lf = center + oedepict.OE2DPoint(-60, -25)

    image.DrawCubicBezier(
        to,
        to + oedepict.OE2DPoint(+5, -15),
        rt + oedepict.OE2DPoint(0, -25),
        rt,
        black_pen,
    )
    image.DrawCubicBezier(
        to,
        to + oedepict.OE2DPoint(-15, +25),
        lf + oedepict.OE2DPoint(-15, -25),
        lf,
        black_pen,
    )
    image.DrawTriangle(to, rt, lf, black_pen)

    to += oedepict.OE2DPoint(0, 5)
    rt += oedepict.OE2DPoint(-15, 5)
    lf += oedepict.OE2DPoint(+10, 5)
    image.DrawCubicBezier(
        to,
        to + oedepict.OE2DPoint(5, -15),
        rt + oedepict.OE2DPoint(0, -25),
        rt,
        pink_pen,
    )
    image.DrawCubicBezier(
        to,
        to + oedepict.OE2DPoint(-15, +25),
        lf + oedepict.OE2DPoint(-15, -25),
        lf,
        pink_pen,
    )
    image.DrawTriangle(to, rt, lf, pink_pen)

    to = center + oedepict.OE2DPoint(+60, -110)
    lf = center + oedepict.OE2DPoint(+15, -55)
    rt = center + oedepict.OE2DPoint(+60, -25)

    image.DrawCubicBezier(
        to,
        to + oedepict.OE2DPoint(-5, -15),
        lf + oedepict.OE2DPoint(0, -25),
        lf,
        black_pen,
    )
    image.DrawCubicBezier(
        to,
        to + oedepict.OE2DPoint(15, +25),
        rt + oedepict.OE2DPoint(+15, -25),
        rt,
        black_pen,
    )
    image.DrawTriangle(to, lf, rt, black_pen)

    to += oedepict.OE2DPoint(0, 5)
    lf += oedepict.OE2DPoint(+15, 5)
    rt += oedepict.OE2DPoint(-10, 5)

    image.DrawCubicBezier(
        to,
        to + oedepict.OE2DPoint(-5, -15),
        lf + oedepict.OE2DPoint(0, -25),
        lf,
        pink_pen,
    )
    image.DrawCubicBezier(
        to,
        to + oedepict.OE2DPoint(+15, +25),
        rt + oedepict.OE2DPoint(+15, -25),
        rt,
        pink_pen,
    )
    image.DrawTriangle(to, lf, rt, pink_pen)

    # head

    _draw_ellipse(image, center, 180, 110, black_pen)

    # eyes

    _draw_ellipse(image, center + oedepict.OE2DPoint(+30, 0), 50, 40, white_pen)
    _draw_ellipse(image, center + oedepict.OE2DPoint(+20, 0), 10, 10, black_pen)
    _draw_ellipse(image, center + oedepict.OE2DPoint(-30, 0), 50, 40, white_pen)
    _draw_ellipse(image, center + oedepict.OE2DPoint(-20, 0), 10, 10, black_pen)

    # nose

    _draw_ellipse(image, center + oedepict.OE2DPoint(0, 20), 20, 10, pink_pen)

    # add OEDepict TK watermark

    font = oedepict.OEFont(
        oedepict.OEFontFamily_Default,
        oedepict.OEFontStyle_Default,
        10,
        oedepict.OEAlignment_Right,
        oechem.OELightGrey,
    )
    text = "Generated by OEDepict TK"
    image.DrawText(
        oedepict.OE2DPoint(image_width - 5.0, image_height - 5.0), text, font
    )

    # write image

    oedepict.OEWriteImage("jiji.svg", image)
    return os.EX_OK


def _draw_ellipse(
    image: oedepict.OEImageBase,
    center: oedepict.OE2DPoint,
    width: float,
    height: float,
    pen: oedepict.OEPen,
) -> None:
    image.DrawCubicBezier(
        center + oedepict.OE2DPoint(0.0, -height / 2.0),
        center + oedepict.OE2DPoint(+width / 2.0, -height / 2.0),
        center + oedepict.OE2DPoint(+width / 2.0, +height / 2.0),
        center + oedepict.OE2DPoint(0.0, +height / 2.0),
        pen,
    )

    image.DrawCubicBezier(
        center + oedepict.OE2DPoint(0.0, +height / 2.0),
        center + oedepict.OE2DPoint(-width / 2.0, +height / 2.0),
        center + oedepict.OE2DPoint(-width / 2.0, -height / 2.0),
        center + oedepict.OE2DPoint(0.0, -height / 2.0),
        pen,
    )


if __name__ == "__main__":
    sys.exit(main())

Christmas Card

../_images/oexmas.svg

Download code

oexmas.py

🎄 oexmas.py
#!/usr/bin/env python3
# (C) 2023 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of Cadence products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. Cadence claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable Cadence offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be
# liable for any damages or liability in connection with the Sample Code
# or its use.


"""Generates an OpenEye Christmas card."""


import math
import os
import sys
from random import Random

from openeye import oechem, oedepict


def main() -> int:  # noqa: PLR0915
    """Depict Christmas card."""
    image_width, image_height = 400, 500
    image = oedepict.OEImage(image_width, image_height)

    # draw fir tree trunk
    trunk = []
    treetop = oedepict.OE2DPoint(image_width / 2.0, 100.0)
    trunk.append(oedepict.OE2DPoint(treetop.GetX(), treetop.GetY() + 40.0))
    trunk.append(oedepict.OE2DPoint(treetop.GetX() - 10.0, treetop.GetY() + 330.0))
    trunk.append(oedepict.OE2DPoint(treetop.GetX() + 10.0, treetop.GetY() + 330.0))

    trunk_pen = oedepict.OEPen(
        oechem.OEBrown,
        oechem.OEBrown,
        oedepict.OEFill_On,
        1.0,
        oedepict.OEStipple_NoLine,
    )
    image.DrawPolygon(trunk, trunk_pen)

    # draw fir tree branches
    branches = []
    branches.append(treetop)
    for i in range(1, 8):
        p = oedepict.OE2DPoint(treetop.GetX() + i * 20.0, treetop.GetY() + i * 40.0)
        branches.append(p)
        branches.append(oedepict.OE2DPoint(p.GetX() - i * 7.0, p.GetY()))
        p = oedepict.OE2DPoint(treetop.GetX() - i * 20.0, treetop.GetY() + i * 40.0)
        branches.insert(0, p)
        branches.insert(0, oedepict.OE2DPoint(p.GetX() + i * 7.0, p.GetY()))

    branch_color = oechem.OEColor(oechem.OEDarkGreen)
    branch_color.SetA(200)
    branch_pen = oedepict.OEPen(
        branch_color, branch_color, oedepict.OEFill_On, 1.0, oedepict.OEStipple_NoLine
    )
    image.DrawPolygon(branches, branch_pen)

    # draw star
    octo = []
    for i in range(5):
        x = treetop.GetX() + 20.0 * math.cos(i * 2.0 * math.pi / 5.0)
        y = treetop.GetY() + 20.0 * math.sin(i * 2.0 * math.pi / 5.0)
        octo.append(oedepict.OE2DPoint(x, y))
    star = [octo[0], octo[2], octo[4], octo[1], octo[3]]

    star_pen = oedepict.OEPen(
        oechem.OEYellow,
        oechem.OEYellow,
        oedepict.OEFill_On,
        1.0,
        oedepict.OEStipple_NoLine,
    )
    image.DrawPolygon(star, star_pen)

    font = oedepict.OEFont(
        oedepict.OEFontFamily_Default,
        oedepict.OEFontStyle_Default,
        30,
        oedepict.OEAlignment_Center,
        oechem.OEDarkRed,
    )
    center = treetop + oedepict.OE2DPoint(0.0, 100.0)
    radius = 150.0

    text = "Happy Christmas"
    axis = oedepict.OE2DPoint(0.0, -radius)
    angle_inc = 120.0 / len(text)
    angle = 300.0 + angle_inc / 2.0
    for letter in text:
        pos = center + _rotate_2d_point(axis, angle)
        font.SetRotationAngle((360 - angle) % 360)
        image.DrawText(pos, letter, font)
        angle += angle_inc

    # draw presents
    box_color_gradient = oechem.OELinearColorGradient()
    box_color_gradient.AddStop(oechem.OEColorStop(0.0, oechem.OELightBlue))
    box_color_gradient.AddStop(oechem.OEColorStop(1.0, oechem.OEDarkPurple))

    rand = Random(0)  # noqa: S311

    for i in range(1, 5):
        box_color = box_color_gradient.GetColorAt(rand.random())
        pos = oedepict.OE2DPoint(treetop.GetX() - i * 30.0, treetop.GetY() + 330.0)
        _draw_present(image, rand, pos, box_color)

        box_color = box_color_gradient.GetColorAt(rand.random())
        pos = oedepict.OE2DPoint(treetop.GetX() + i * 30.0, treetop.GetY() + 330.0)
        _draw_present(image, rand, pos, box_color)

    # draw ornaments
    ball_color_gradient = oechem.OELinearColorGradient()
    ball_color_gradient.AddStop(oechem.OEColorStop(0.0, oechem.OEYellow))
    ball_color_gradient.AddStop(oechem.OEColorStop(1.0, oechem.OEDarkRed))

    for i in range(2, 9):
        ball_color = ball_color_gradient.GetColorAt(rand.random())
        ball_pos = oedepict.OE2DPoint(treetop.GetX(), treetop.GetY() + i * 30)
        _draw_ball(image, rand, ball_pos, ball_color)

    for i in range(2, 8):
        for x_sign in [10.0, -10.0]:
            ball_color = ball_color_gradient.GetColorAt(rand.random())
            ball_pos = oedepict.OE2DPoint(
                treetop.GetX() + i * x_sign, treetop.GetY() + i * 35
            )
            _draw_ball(image, rand, ball_pos, ball_color)

    for i in range(2, 9):
        for x_sign in [5.0, -5.0]:
            ball_color = ball_color_gradient.GetColorAt(rand.random())
            ball_pos = oedepict.OE2DPoint(
                treetop.GetX() + i * x_sign, treetop.GetY() + 50 + i * 25
            )
            _draw_ball(image, rand, ball_pos, ball_color)

    font = oedepict.OEFont(
        oedepict.OEFontFamily_Default,
        oedepict.OEFontStyle_Default,
        10,
        oedepict.OEAlignment_Right,
        oechem.OELightGrey,
    )
    text = "Generated by OEDepict TK"
    image.DrawText(
        oedepict.OE2DPoint(image_width - 20.0, image_height - 20.0), text, font
    )

    oedepict.OEWriteImage("oexmas.svg", image)

    return os.EX_OK


def _draw_present(
    image: oedepict.OEImageBase,
    rand: Random,
    box_pos: oedepict.OE2DPoint,
    box_color: oechem.OEColor,
) -> None:

    box_pen = oedepict.OEPen(
        box_color, box_color, oedepict.OEFill_On, 1.0, oedepict.OEStipple_NoLine
    )
    box_size = rand.randint(15, 28)

    tl = oedepict.OE2DPoint(box_pos.GetX() - box_size / 2.0, box_pos.GetY() - box_size)
    br = oedepict.OE2DPoint(box_pos.GetX() + box_size / 2.0, box_pos.GetY())
    image.DrawRectangle(tl, br, box_pen)

    ribbon_pen = oedepict.OEPen(
        oechem.OELightGrey, oechem.OELightGrey, oedepict.OEFill_On, 3.0
    )
    ribbon_pen.SetLineCap(oedepict.OELineCap_Butt)
    bgn = box_pos
    end = box_pos + oedepict.OE2DPoint(0.0, -box_size)
    image.DrawLine(bgn, end, ribbon_pen)

    bgn = oedepict.OE2DPoint(
        box_pos.GetX() - box_size / 2.0, box_pos.GetY() - box_size / 2.0
    )
    end = oedepict.OE2DPoint(
        box_pos.GetX() + box_size / 2.0, box_pos.GetY() - box_size / 2.0
    )
    image.DrawLine(bgn, end, ribbon_pen)


def _draw_ball(
    image: oedepict.OEImageBase,
    rand: Random,
    ball_pos: oedepict.OE2DPoint,
    ball_color: oechem.OEColor,
) -> None:
    # randomize position
    ball_pos.SetX(ball_pos.GetX() + rand.uniform(0, ball_pos.GetX() / 25.0))
    ball_pos.SetY(ball_pos.GetY() + rand.uniform(0, ball_pos.GetY() / 25.0))

    ball_pen = oedepict.OEPen(ball_color, ball_color, oedepict.OEFill_On, 1.0)
    ball_radius = rand.randint(3, 6)
    image.DrawCircle(ball_pos, ball_radius, ball_pen)


def _rotate_2d_point(p: oedepict.OE2DPoint, degree: float) -> oedepict.OE2DPoint:
    rad = degree * oechem.Deg2Rad
    cos_rad = math.cos(rad)
    sin_rad = math.sin(rad)
    return oedepict.OE2DPoint(
        cos_rad * p.GetX() - sin_rad * p.GetY(), sin_rad * p.GetX() + cos_rad * p.GetY()
    )


if __name__ == "__main__":
    sys.exit(main())