# Coffee Cup

> A cozy ceramic coffee cup on a matching saucer: a flared lathe-turned cup with a real hollow, a looped handle and a latte with heart-shaped foam art on top. Switch to cappuccino or espresso, change the cup color or drop the saucer — ideal for cafés, kitchens and office desks.

![Coffee Cup preview](https://codels.download/m/coffee-cup.png)

Multi-view sheet (3/4, front, side, top): https://codels.download/m/coffee-cup.sheet.png

## Facts

- Category: Food & Drink › Drinks
- Size (W × H × D): 0.15 × 0.08 × 0.15 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 1,108 · Meshes: 5 · Materials: 3
- License: CC0-1.0 (Codels built-in)
- Tags: coffee, cup, drink, saucer, cartoon, low-poly, stylized, kitchen, modern, office, city, interior, decoration, food, prop, ceramic, round, game-ready, mobile-friendly, parametric, color-white, size-tiny, poly-low
- Page: https://codels.download/models/coffee-cup

## Files

| Format | URL |
|---|---|
| three.js ES module (`createCoffeeCup()`) | https://codels.download/m/coffee-cup.js |
| React Three Fiber component (`<CoffeeCup />`) | https://codels.download/m/coffee-cup.jsx |
| Instancing module (`createCoffeeCupInstances(count, place)`, one draw call per material) | https://codels.download/m/coffee-cup.instanced.js |
| Standalone HTML demo | https://codels.download/m/coffee-cup.html |
| glTF binary | https://codels.download/m/coffee-cup.glb |
| glTF binary, Meshopt-compressed (2–3× smaller; GLTFLoader needs `setMeshoptDecoder(MeshoptDecoder)`) | https://codels.download/m/coffee-cup.glb?compress=meshopt |
| glTF JSON | https://codels.download/m/coffee-cup.gltf |
| OBJ (vertex colors) + MTL | https://codels.download/m/coffee-cup.obj · https://codels.download/m/coffee-cup.mtl |
| STL | https://codels.download/m/coffee-cup.stl |
| CodelSpec JSON | https://codels.download/m/coffee-cup.json |

## Parameters

Append them as query parameters to any URL above to get a customized variant (e.g. `?drink=...`).

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `drink` | select | latte \| cappuccino \| espresso | latte | latte |
| `cupColor` | color | #rrggbb | #f3eee6 | #f3eee6 |
| `saucer` | boolean | true \| false | true | true |

## Parts

- saucer (lathe · cup)
- cup (lathe · cup)
- coffee (cylinder · coffee)
- latteArt (extrude · art)
- handle (torus · cup)

## How to use

Save the code below as `coffee-cup.js`, then:

```js
import { createCoffeeCup } from './coffee-cup.js';
const model = createCoffeeCup();
scene.add(model);
```

## Code

```js
/**
 * Coffee Cup — Codels 3D model library (https://codels.download/models/coffee-cup)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,108 · Size (W × H × D): 0.15 × 0.08 × 0.15 m
 *
 * Usage:
 *   import { createCoffeeCup } from './coffee-cup.js';
 *   
 *   const model = createCoffeeCup();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

// Revolve a 2D profile [[radius, y], ...] around the Y axis.
function lathe(points, segments, phiStart = 0, phiLength = Math.PI * 2) {
  return new THREE.LatheGeometry(points.map(([x, y]) => new THREE.Vector2(x, y)), segments, phiStart, phiLength);
}

// Extrude a 2D outline along Z (centered). bevel = [thickness, size, segments].
function extrude(outline, depth, holes = [], bevel = null) {
  const shape = new THREE.Shape(outline.map(([x, y]) => new THREE.Vector2(x, y)));
  for (const hole of holes) shape.holes.push(new THREE.Path(hole.map(([x, y]) => new THREE.Vector2(x, y))));
  const options = bevel
    ? { depth, bevelEnabled: true, bevelThickness: bevel[0], bevelSize: bevel[1], bevelSegments: bevel[2] }
    : { depth, bevelEnabled: false };
  return new THREE.ExtrudeGeometry(shape, options).translate(0, 0, -depth / 2);
}

export function createCoffeeCup() {
  const root = new THREE.Group();
  root.name = 'CoffeeCup';

  // Materials
  const cupMat = new THREE.MeshStandardMaterial({ name: 'cup', color: 0xf3eee6, roughness: 0.25, flatShading: true });
  const coffeeMat = new THREE.MeshStandardMaterial({ name: 'coffee', color: 0xb97a4a, roughness: 0.2 });
  const artMat = new THREE.MeshStandardMaterial({ name: 'art', color: 0xf6ead8, roughness: 0.6, flatShading: true });

  // Parts
  const saucer = new THREE.Mesh(lathe([[0, 0], [0.045, 0], [0.066, 0.006], [0.076, 0.012], [0.074, 0.0145], [0.062, 0.0105], [0.036, 0.0075], [0, 0.0075]], 24), cupMat);
  saucer.name = 'saucer';
  root.add(saucer);
  const cup = new THREE.Mesh(lathe([[0, 0.0065], [0.025, 0.0065], [0.029, 0.0105], [0.033, 0.0175], [0.041, 0.0405], [0.0465, 0.0645], [0.049, 0.0805], [0.0475, 0.0833], [0.0448, 0.081], [0.0438, 0.0745], [0.036, 0.0485], [0.028, 0.0235], [0, 0.0205]], 20), cupMat);
  cup.name = 'cup';
  root.add(cup);
  const coffee = new THREE.Mesh(new THREE.CylinderGeometry(0.0438, 0.0438, 0.003, 20), coffeeMat);
  coffee.name = 'coffee';
  coffee.position.set(0, 0.071, 0);
  root.add(coffee);
  const latteArt = new THREE.Mesh(extrude([[0, 0.006], [0.0008, 0.0087], [0.0051, 0.0132], [0.0125, 0.0138], [0.0183, 0.0086], [0.0183, 0.0008], [0.0125, -0.0066], [0.0051, -0.0131], [0.0008, -0.0183], [0, -0.0204], [-0.0008, -0.0183], [-0.0051, -0.0131], [-0.0125, -0.0066], [-0.0183, 0.0008], [-0.0183, 0.0086], [-0.0125, 0.0138], [-0.0051, 0.0132], [-0.0008, 0.0087]], 0.0012), artMat);
  latteArt.name = 'latteArt';
  latteArt.position.set(0, 0.0731, 0.003);
  latteArt.rotation.set(deg(-90), 0, 0);
  root.add(latteArt);
  const handle = new THREE.Mesh(new THREE.TorusGeometry(0.0175, 0.0056, 6, 12, 3.6128), cupMat);
  handle.name = 'handle';
  handle.position.set(0.0445, 0.0485, 0);
  handle.rotation.set(0, 0, deg(-103.5));
  root.add(handle);

  root.traverse((o) => {
    if (o.isMesh) {
      o.castShadow = true;
      o.receiveShadow = true;
    }
  });
  return root;
}

export default createCoffeeCup;
```

---
Codels — 3D models as code for three.js. Search more: https://codels.download/api/v1/models?q=<query> · Guide: https://codels.download/llms.txt
