1.4K tris0.48 × 0.51 × 0.48 m
Use it in code
Remix in the editorwicker-basket.js · 319 lines
Self-contained ES module — only depends on three. Call the factory and add the group to your scene.
/**
* Wicker Basket — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,420 · Size (W × H × D): 0.48 × 0.51 × 0.48 m
*
* Usage:
* import { createWickerBasket } from './wicker-basket.js';
*
* const model = createWickerBasket();
* 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);
}
// Tube along a smooth curve through the given points.
function tube(path, radius, tubularSegments, radialSegments, closed = false) {
const curve = new THREE.CatmullRomCurve3(path.map(([x, y, z]) => new THREE.Vector3(x, y, z)), closed);
return new THREE.TubeGeometry(curve, tubularSegments, radius, radialSegments, closed);
}
export function createWickerBasket() {
const root = new THREE.Group();
root.name = 'WickerBasket';
// Materials
const wickerMat = new THREE.MeshStandardMaterial({ name: 'wicker', color: 0xc2914f, roughness: 0.95, flatShading: true });
const stakeMat = new THREE.MeshStandardMaterial({ name: 'stake', color: 0x8c6839, roughness: 0.95, flatShading: true });
const innerMat = new THREE.MeshStandardMaterial({ name: 'inner', color: 0x513d21, roughness: 1, flatShading: true });
const appleMat = new THREE.MeshStandardMaterial({ name: 'apple', color: 0xd1352b, roughness: 0.45, flatShading: true });
const appleAltMat = new THREE.MeshStandardMaterial({ name: 'appleAlt', color: 0x9cbf3a, roughness: 0.5, flatShading: true });
const stemMat = new THREE.MeshStandardMaterial({ name: 'stem', color: 0x4a3220, roughness: 0.9, flatShading: true });
const leafMat = new THREE.MeshStandardMaterial({ name: 'leaf', color: 0x3f8f3a, roughness: 0.8, flatShading: true });
// Shared geometries
const boxGeo = new THREE.BoxGeometry(0.016, 0.2109, 0.012);
const cylinderGeo = new THREE.CylinderGeometry(0.022, 0.022, 0.05, 6);
const sphereGeo = new THREE.SphereGeometry(0.05, 7, 5);
const cylinderGeo2 = new THREE.CylinderGeometry(0.004, 0.005, 0.03, 4);
const boxGeo2 = new THREE.BoxGeometry(0.03, 0.004, 0.016);
// Parts
const body = new THREE.Mesh(lathe([[0, 0.004], [0.148, 0], [0.16, 0.012], [0.1824, 0.0328], [0.1771, 0.0536], [0.1957, 0.0744], [0.1903, 0.0952], [0.2089, 0.116], [0.2035, 0.1368], [0.2221, 0.1576], [0.2168, 0.1784], [0.2354, 0.1992], [0.23, 0.22], [0.21, 0.22]], 12), wickerMat);
body.name = 'body';
root.add(body);
const interior = new THREE.Mesh(lathe([[0.21, 0.22], [0.1877, 0.15], [0, 0.15]], 12), innerMat);
interior.name = 'interior';
root.add(interior);
const stake1 = new THREE.Group();
stake1.name = 'stake1';
stake1.rotation.set(0, deg(15), 0);
root.add(stake1);
const stake = new THREE.Mesh(boxGeo, stakeMat);
stake.name = 'stake';
stake.position.set(0, 0.11, 0.2016);
stake.rotation.set(deg(17.6501), 0, 0);
stake1.add(stake);
const stake2 = new THREE.Group();
stake2.name = 'stake2';
stake2.rotation.set(0, deg(45), 0);
root.add(stake2);
const stake3 = new THREE.Mesh(boxGeo, stakeMat);
stake3.name = 'stake';
stake3.position.set(0, 0.11, 0.2016);
stake3.rotation.set(deg(17.6501), 0, 0);
stake2.add(stake3);
const stake32 = new THREE.Group();
stake32.name = 'stake3';
stake32.rotation.set(0, deg(75), 0);
root.add(stake32);
const stake4 = new THREE.Mesh(boxGeo, stakeMat);
stake4.name = 'stake';
stake4.position.set(0, 0.11, 0.2016);
stake4.rotation.set(deg(17.6501), 0, 0);
stake32.add(stake4);
const stake42 = new THREE.Group();
stake42.name = 'stake4';
stake42.rotation.set(0, deg(105), 0);
root.add(stake42);
const stake5 = new THREE.Mesh(boxGeo, stakeMat);
stake5.name = 'stake';
stake5.position.set(0, 0.11, 0.2016);
stake5.rotation.set(deg(17.6501), 0, 0);
stake42.add(stake5);
const stake52 = new THREE.Group();
stake52.name = 'stake5';
stake52.rotation.set(0, deg(135), 0);
root.add(stake52);
const stake6 = new THREE.Mesh(boxGeo, stakeMat);
stake6.name = 'stake';
stake6.position.set(0, 0.11, 0.2016);
stake6.rotation.set(deg(17.6501), 0, 0);
stake52.add(stake6);
const stake62 = new THREE.Group();
stake62.name = 'stake6';
stake62.rotation.set(0, deg(165), 0);
root.add(stake62);
const stake7 = new THREE.Mesh(boxGeo, stakeMat);
stake7.name = 'stake';
stake7.position.set(0, 0.11, 0.2016);
stake7.rotation.set(deg(17.6501), 0, 0);
stake62.add(stake7);
const stake72 = new THREE.Group();
stake72.name = 'stake7';
stake72.rotation.set(0, deg(195), 0);
root.add(stake72);
const stake8 = new THREE.Mesh(boxGeo, stakeMat);
stake8.name = 'stake';
stake8.position.set(0, 0.11, 0.2016);
stake8.rotation.set(deg(17.6501), 0, 0);
stake72.add(stake8);
const stake82 = new THREE.Group();
stake82.name = 'stake8';
stake82.rotation.set(0, deg(225), 0);
root.add(stake82);
const stake9 = new THREE.Mesh(boxGeo, stakeMat);
stake9.name = 'stake';
stake9.position.set(0, 0.11, 0.2016);
stake9.rotation.set(deg(17.6501), 0, 0);
stake82.add(stake9);
const stake92 = new THREE.Group();
stake92.name = 'stake9';
stake92.rotation.set(0, deg(255), 0);
root.add(stake92);
const stake10 = new THREE.Mesh(boxGeo, stakeMat);
stake10.name = 'stake';
stake10.position.set(0, 0.11, 0.2016);
stake10.rotation.set(deg(17.6501), 0, 0);
stake92.add(stake10);
const stake102 = new THREE.Group();
stake102.name = 'stake10';
stake102.rotation.set(0, deg(285), 0);
root.add(stake102);
const stake11 = new THREE.Mesh(boxGeo, stakeMat);
stake11.name = 'stake';
stake11.position.set(0, 0.11, 0.2016);
stake11.rotation.set(deg(17.6501), 0, 0);
stake102.add(stake11);
const stake112 = new THREE.Group();
stake112.name = 'stake11';
stake112.rotation.set(0, deg(315), 0);
root.add(stake112);
const stake12 = new THREE.Mesh(boxGeo, stakeMat);
stake12.name = 'stake';
stake12.position.set(0, 0.11, 0.2016);
stake12.rotation.set(deg(17.6501), 0, 0);
stake112.add(stake12);
const stake122 = new THREE.Group();
stake122.name = 'stake12';
stake122.rotation.set(0, deg(345), 0);
root.add(stake122);
const stake13 = new THREE.Mesh(boxGeo, stakeMat);
stake13.name = 'stake';
stake13.position.set(0, 0.11, 0.2016);
stake13.rotation.set(deg(17.6501), 0, 0);
stake122.add(stake13);
const rim = new THREE.Mesh(new THREE.TorusGeometry(0.224, 0.018, 4, 12), stakeMat);
rim.name = 'rim';
rim.position.set(0, 0.22, 0);
rim.rotation.set(deg(90), 0, 0);
root.add(rim);
const handle = new THREE.Mesh(tube([[-0.22, 0.21, 0], [-0.2024, 0.35, 0], [-0.121, 0.46, 0], [0, 0.495, 0], [0.121, 0.46, 0], [0.2024, 0.35, 0], [0.22, 0.21, 0]], 0.015, 16, 5), wickerMat);
handle.name = 'handle';
root.add(handle);
const handleWrap = new THREE.Mesh(cylinderGeo, stakeMat);
handleWrap.name = 'handleWrap';
handleWrap.position.set(-0.216, 0.245, 0);
handleWrap.rotation.set(0, 0, deg(-6));
root.add(handleWrap);
const handleWrap2 = new THREE.Mesh(cylinderGeo, stakeMat);
handleWrap2.name = 'handleWrap';
handleWrap2.position.set(0.216, 0.245, 0);
handleWrap2.rotation.set(0, 0, deg(6));
root.add(handleWrap2);
const apple1 = new THREE.Group();
apple1.name = 'apple1';
apple1.position.set(0, 0.2225, 0);
apple1.rotation.set(deg(4.5079), deg(306.2796), deg(1.9011));
root.add(apple1);
const fruit = new THREE.Mesh(sphereGeo, appleMat);
fruit.name = 'fruit';
fruit.scale.set(1, 0.9, 1);
apple1.add(fruit);
const stem = new THREE.Mesh(cylinderGeo2, stemMat);
stem.name = 'stem';
stem.position.set(0, 0.0475, 0);
stem.rotation.set(deg(0.3476), 0, deg(0.8984));
apple1.add(stem);
const leaf = new THREE.Mesh(boxGeo2, leafMat);
leaf.name = 'leaf';
leaf.position.set(0.016, 0.0475, 0);
leaf.rotation.set(0, deg(109.4613), deg(20));
apple1.add(leaf);
const apple2 = new THREE.Group();
apple2.name = 'apple2';
apple2.position.set(0.1194, 0.1925, 0.0369);
apple2.rotation.set(deg(5.3868), deg(162.117), deg(-0.9979));
root.add(apple2);
const fruit2 = new THREE.Mesh(sphereGeo, appleMat);
fruit2.name = 'fruit';
fruit2.scale.set(1, 0.9, 1);
apple2.add(fruit2);
const stem2 = new THREE.Mesh(cylinderGeo2, stemMat);
stem2.name = 'stem';
stem2.position.set(0, 0.0475, 0);
stem2.rotation.set(deg(-12.5992), 0, deg(0.9152));
apple2.add(stem2);
const apple3 = new THREE.Group();
apple3.name = 'apple3';
apple3.position.set(0.0018, 0.1925, 0.125);
apple3.rotation.set(deg(8.5104), deg(245.3503), deg(-16.9593));
root.add(apple3);
const fruit3 = new THREE.Mesh(sphereGeo, appleMat);
fruit3.name = 'fruit';
fruit3.scale.set(1, 0.9, 1);
apple3.add(fruit3);
const stem3 = new THREE.Mesh(cylinderGeo2, stemMat);
stem3.name = 'stem';
stem3.position.set(0, 0.0475, 0);
stem3.rotation.set(deg(10.3056), 0, deg(-2.4007));
apple3.add(stem3);
const apple4 = new THREE.Group();
apple4.name = 'apple4';
apple4.position.set(-0.1183, 0.1925, 0.0403);
apple4.rotation.set(deg(-6.1518), deg(209.7033), deg(-18.6259));
root.add(apple4);
const fruit4 = new THREE.Mesh(sphereGeo, appleAltMat);
fruit4.name = 'fruit';
fruit4.scale.set(1, 0.9, 1);
apple4.add(fruit4);
const stem4 = new THREE.Mesh(cylinderGeo2, stemMat);
stem4.name = 'stem';
stem4.position.set(0, 0.0475, 0);
stem4.rotation.set(deg(-9.6446), 0, deg(-6.7168));
apple4.add(stem4);
const leaf2 = new THREE.Mesh(boxGeo2, leafMat);
leaf2.name = 'leaf';
leaf2.position.set(0.016, 0.0475, 0);
leaf2.rotation.set(0, deg(71.2652), deg(20));
apple4.add(leaf2);
const apple5 = new THREE.Group();
apple5.name = 'apple5';
apple5.position.set(-0.0749, 0.1925, -0.1001);
apple5.rotation.set(deg(-4.0791), deg(303.9301), deg(15.2692));
root.add(apple5);
const fruit5 = new THREE.Mesh(sphereGeo, appleMat);
fruit5.name = 'fruit';
fruit5.scale.set(1, 0.9, 1);
apple5.add(fruit5);
const stem5 = new THREE.Mesh(cylinderGeo2, stemMat);
stem5.name = 'stem';
stem5.position.set(0, 0.0475, 0);
stem5.rotation.set(deg(2.9125), 0, deg(2.2962));
apple5.add(stem5);
const apple6 = new THREE.Group();
apple6.name = 'apple6';
apple6.position.set(0.072, 0.1925, -0.1022);
apple6.rotation.set(deg(6.1554), deg(90.6045), deg(-22.1883));
root.add(apple6);
const fruit6 = new THREE.Mesh(sphereGeo, appleMat);
fruit6.name = 'fruit';
fruit6.scale.set(1, 0.9, 1);
apple6.add(fruit6);
const stem6 = new THREE.Mesh(cylinderGeo2, stemMat);
stem6.name = 'stem';
stem6.position.set(0, 0.0475, 0);
stem6.rotation.set(deg(8.0641), 0, deg(-5.4717));
apple6.add(stem6);
const apple7 = new THREE.Group();
apple7.name = 'apple7';
apple7.position.set(0.0272, 0.2575, 0.0535);
apple7.rotation.set(deg(-17.6733), deg(267.6785), deg(-7.6393));
root.add(apple7);
const fruit7 = new THREE.Mesh(sphereGeo, appleMat);
fruit7.name = 'fruit';
fruit7.scale.set(1, 0.9, 1);
apple7.add(fruit7);
const stem7 = new THREE.Mesh(cylinderGeo2, stemMat);
stem7.name = 'stem';
stem7.position.set(0, 0.0475, 0);
stem7.rotation.set(deg(7.2273), 0, deg(14.3301));
apple7.add(stem7);
const leaf3 = new THREE.Mesh(boxGeo2, leafMat);
leaf3.name = 'leaf';
leaf3.position.set(0.016, 0.0475, 0);
leaf3.rotation.set(0, deg(53.4306), deg(20));
apple7.add(leaf3);
const apple8 = new THREE.Group();
apple8.name = 'apple8';
apple8.position.set(-0.0272, 0.2575, -0.0535);
apple8.rotation.set(deg(17.2753), deg(51.5586), deg(17.4854));
root.add(apple8);
const fruit8 = new THREE.Mesh(sphereGeo, appleMat);
fruit8.name = 'fruit';
fruit8.scale.set(1, 0.9, 1);
apple8.add(fruit8);
const stem8 = new THREE.Mesh(cylinderGeo2, stemMat);
stem8.name = 'stem';
stem8.position.set(0, 0.0475, 0);
stem8.rotation.set(deg(1.6034), 0, deg(2.3002));
apple8.add(stem8);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createWickerBasket;
Ratings & comments
0 comments
No comments yet. Share how you used this model or what could be better.
Related models
Same category or similar tags









