Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,59 @@ Bit By Bit Developers company will keep these core algorithms that you can find
## About Bit By Bit Developers platform
Bit By Bit Developers web platform allows creators to program geometry through simple visual programming language or choose monaco typescript editor with full intellisense of bitbybit API. This cloud platform can fulfil many practical, educational and artistic needs of its users. Through familiar programming interface used in tools such as Scratch and Blockly.Games we expose powerful 3D algorithms that make it easier to implement various parametric tasks. Our goal is to make it very simple for users to share their ideas and designs. We want to encourage everyone to engage in the future of this tool.

# Development Setup

## First Time Setup and Testing

For first-time developers working on this project, follow these steps to set up the development environment and run all unit tests:

### Prerequisites
- Node.js (v16 or higher recommended)
- npm (comes with Node.js)
- Git

### Quick Start
1. Clone the repository:
```bash
git clone https://github.com/bitbybit-dev/bitbybit.git
cd bitbybit
```

2. Run the complete first-time setup (this will install all dependencies, build all packages, and run all unit tests):
```bash
npm run first-time-setup
```

### Available Commands

- `npm run first-time-setup` - Complete setup for new developers (installs dependencies, builds packages, runs tests)
- `npm run setup` - Install dependencies and build all packages without running tests
- `npm run setup-and-test` - Install dependencies, build packages, and run all unit tests
- `npm run test` - Run all unit tests (requires packages to be built first)
- `npm run ci-packages` - Install dependencies for all packages
- `npm run build-packages` - Build all packages
- `npm run rebuild-all-packages` - Clean and rebuild all packages

### Cross-Platform Compatibility
All commands are now cross-platform compatible and work on Windows, macOS, and Linux. The project uses:
- `rimraf` for cross-platform file deletion
- Standard npm scripts for package management

### Running Individual Package Tests
You can also run tests for individual packages:
- `npm run test-base` - Test base package
- `npm run test-occt` - Test OCCT package
- `npm run test-core` - Test core package
- `npm run test-jscad` - Test JSCAD package
- `npm run test-manifold` - Test Manifold package
- `npm run test-threejs` - Test ThreeJS package

### Troubleshooting
If you encounter issues during setup:
1. Make sure you have Node.js v16+ installed
2. Clear npm cache: `npm cache clean --force`
3. Delete node_modules and package-lock.json, then run `npm install`
4. If on Windows, make sure to run commands in a proper terminal (Command Prompt, PowerShell, or WSL)

## Major Dependencies
BabylonJS, ThreeJS, OpenCascade, Manifold, JSCAD, Verbnurbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"label": "Parametric Art",
"position": 2,
"link": {
"type": "generated-index",
"title": "Parametric Art",
"description": "Explore the world of parametric art and learn how to create stunning designs using algorithms.",
"slug": "/code/common/occt/modeling/parametric-art"
}
}
114 changes: 114 additions & 0 deletions docs/learn/code/common/occt/modeling/parametric-art/simple-flower.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"label": "Compound",
"position": 6,
"position": 7,
"link": {
"type": "generated-index",
"title": "Compound Shapes",
Expand Down
10 changes: 10 additions & 0 deletions docs/learn/code/common/occt/shapes/face/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"label": "Face",
"position": 4,
"link": {
"type": "generated-index",
"title": "Faces",
"description": "Faces are one of the most fundamental pieces of geometry that you can create inside OCCT kernel. These tutorials will help you understand how to create and manipulate faces in your 3D models.",
"slug": "/code/common/occt/shapes/face"
}
}
51 changes: 51 additions & 0 deletions docs/learn/code/common/occt/shapes/face/face-basic-primitives.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
sidebar_position: 2
title: Face Basic Primitives
sidebar_label: Face Basic Primitives
description: Learn how to create basic face primitives that define surfaces and areas
tags: [code, occt, rete, blockly, typescript]
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import BitByBitRenderCanvas from '@site/src/components/BitByBitRenderCanvas';

<img
class="category-icon-small"
src="https://s.bitbybit.dev/assets/icons/white/occt-icon.svg"
alt="OCCT category icon with a stylized logo representation"
title="OCCT category icon" />

# Introduction to OCCT Face Basic Primitives

Faces are two-dimensional surfaces that fill geometric boundaries to create areas in 3D space. While wires define outlines and curves, faces create actual surfaces that can be visualized with materials, analyzed for properties, and used to build 3D solids.

Think of wires as the frame of a window, and faces as the glass that fills the frame. This tutorial demonstrates creating circle, square, rectangle, and ellipse faces using different programming approaches.

<Tabs groupId="creating-basic-face-primitives">
<TabItem value="rete" label="Rete">
<BitByBitRenderCanvas
requireManualStart={true}
script={{"script":"{\"id\":\"rete-v2-json\",\"nodes\":{\"9d2950eb42d026eb\":{\"id\":\"9d2950eb42d026eb\",\"name\":\"bitbybit.occt.shapes.face.createCircleFace\",\"customName\":\"circle face\",\"async\":true,\"drawable\":true,\"data\":{\"genericNodeData\":{\"hide\":false,\"oneOnOne\":false,\"flatten\":0,\"forceExecution\":false},\"radius\":4,\"center\":[0,0,0],\"direction\":[0,1,0]},\"inputs\":{},\"position\":[913.703125,436.41015625]},\"c863eef64ddee2c8\":{\"id\":\"c863eef64ddee2c8\",\"name\":\"bitbybit.occt.shapes.face.createEllipseFace\",\"customName\":\"ellipse face\",\"async\":true,\"drawable\":true,\"data\":{\"genericNodeData\":{\"hide\":false,\"oneOnOne\":false,\"flatten\":0,\"forceExecution\":false},\"center\":[0,0,0],\"direction\":[0,1,0],\"radiusMinor\":1,\"radiusMajor\":3},\"inputs\":{\"center\":{\"connections\":[{\"node\":\"5f27a0fdde38d7ea\",\"output\":\"result\",\"data\":{}}]}},\"position\":[905.5502310832453,1678.0205681556072]},\"ddacad79d6942524\":{\"id\":\"ddacad79d6942524\",\"name\":\"bitbybit.occt.shapes.face.createSquareFace\",\"customName\":\"square face\",\"async\":true,\"drawable\":true,\"data\":{\"genericNodeData\":{\"hide\":false,\"oneOnOne\":false,\"flatten\":0,\"forceExecution\":false},\"size\":3,\"center\":[0,0,0],\"direction\":[0,1,0]},\"inputs\":{\"center\":{\"connections\":[{\"node\":\"2014565152a68ddc\",\"output\":\"result\",\"data\":{}}]}},\"position\":[916.0273536742325,838.3467683139284]},\"915c753679d2ae7b\":{\"id\":\"915c753679d2ae7b\",\"name\":\"bitbybit.occt.shapes.face.createRectangleFace\",\"customName\":\"rectangle face\",\"async\":true,\"drawable\":true,\"data\":{\"genericNodeData\":{\"hide\":false,\"oneOnOne\":false,\"flatten\":0,\"forceExecution\":false},\"width\":3,\"length\":7,\"center\":[0,0,0],\"direction\":[0,1,0]},\"inputs\":{\"center\":{\"connections\":[{\"node\":\"305e88c644ea099a\",\"output\":\"result\",\"data\":{}}]}},\"position\":[910.5168109763998,1219.3530266682635]},\"2014565152a68ddc\":{\"id\":\"2014565152a68ddc\",\"name\":\"bitbybit.vector.vectorXYZ\",\"customName\":\"vector xyz\",\"async\":false,\"drawable\":true,\"data\":{\"genericNodeData\":{\"hide\":true,\"oneOnOne\":false,\"flatten\":0,\"forceExecution\":false},\"x\":7,\"y\":0,\"z\":0},\"inputs\":{},\"position\":[501.7924955588585,880.408747068502]},\"305e88c644ea099a\":{\"id\":\"305e88c644ea099a\",\"name\":\"bitbybit.vector.vectorXYZ\",\"customName\":\"vector xyz\",\"async\":false,\"drawable\":true,\"data\":{\"genericNodeData\":{\"hide\":true,\"oneOnOne\":false,\"flatten\":0,\"forceExecution\":false},\"x\":-7,\"y\":0,\"z\":0},\"inputs\":{},\"position\":[518.7778459924483,1299.4829635556591]},\"5f27a0fdde38d7ea\":{\"id\":\"5f27a0fdde38d7ea\",\"name\":\"bitbybit.vector.vectorXYZ\",\"customName\":\"vector xyz\",\"async\":false,\"drawable\":true,\"data\":{\"genericNodeData\":{\"hide\":true,\"oneOnOne\":false,\"flatten\":0,\"forceExecution\":false},\"x\":0,\"y\":0,\"z\":-9},\"inputs\":{},\"position\":[507.829978040304,1682.2323868383787]}}}","version":"0.20.7","type":"rete"}}
title="Creating basic face primitives"
/>
</TabItem>
<TabItem value="blockly" label="Blockly">
<BitByBitRenderCanvas
requireManualStart={true}
script={{"script":"<xml xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable id=\"circleFace\">circleFace</variable><variable id=\"squareFace\">squareFace</variable><variable id=\"rectangleFace\">rectangleFace</variable><variable id=\"ellipseFace\">ellipseFace</variable></variables><block type=\"variables_set\" id=\"create_circle_face\" x=\"50\" y=\"50\"><field name=\"VAR\" id=\"circleFace\">circleFace</field><value name=\"VALUE\"><block type=\"bitbybit.occt.shapes.face.createCircleFace\" id=\"circle_face\"><value name=\"Radius\"><block type=\"math_number\" id=\"circle_radius\"><field name=\"NUM\">4</field></block></value><value name=\"Center\"><block type=\"bitbybit.point.pointXYZ\" id=\"circle_center\"><value name=\"X\"><block type=\"math_number\" id=\"circle_center_x\"><field name=\"NUM\">0</field></block></value><value name=\"Y\"><block type=\"math_number\" id=\"circle_center_y\"><field name=\"NUM\">0</field></block></value><value name=\"Z\"><block type=\"math_number\" id=\"circle_center_z\"><field name=\"NUM\">0</field></block></value></block></value><value name=\"Direction\"><block type=\"bitbybit.vector.vectorXYZ\" id=\"circle_direction\"><value name=\"X\"><block type=\"math_number\" id=\"circle_dir_x\"><field name=\"NUM\">0</field></block></value><value name=\"Y\"><block type=\"math_number\" id=\"circle_dir_y\"><field name=\"NUM\">1</field></block></value><value name=\"Z\"><block type=\"math_number\" id=\"circle_dir_z\"><field name=\"NUM\">0</field></block></value></block></value></block></value><next><block type=\"variables_set\" id=\"create_square_face\" x=\"50\" y=\"150\"><field name=\"VAR\" id=\"squareFace\">squareFace</field><value name=\"VALUE\"><block type=\"bitbybit.occt.shapes.face.createSquareFace\" id=\"square_face\"><value name=\"Size\"><block type=\"math_number\" id=\"square_size\"><field name=\"NUM\">3</field></block></value><value name=\"Center\"><block type=\"bitbybit.point.pointXYZ\" id=\"square_center\"><value name=\"X\"><block type=\"math_number\" id=\"square_center_x\"><field name=\"NUM\">7</field></block></value><value name=\"Y\"><block type=\"math_number\" id=\"square_center_y\"><field name=\"NUM\">0</field></block></value><value name=\"Z\"><block type=\"math_number\" id=\"square_center_z\"><field name=\"NUM\">0</field></block></value></block></value><value name=\"Direction\"><block type=\"bitbybit.vector.vectorXYZ\" id=\"square_direction\"><value name=\"X\"><block type=\"math_number\" id=\"square_dir_x\"><field name=\"NUM\">0</field></block></value><value name=\"Y\"><block type=\"math_number\" id=\"square_dir_y\"><field name=\"NUM\">1</field></block></value><value name=\"Z\"><block type=\"math_number\" id=\"square_dir_z\"><field name=\"NUM\">0</field></block></value></block></value></block></value><next><block type=\"variables_set\" id=\"create_rectangle_face\" x=\"50\" y=\"250\"><field name=\"VAR\" id=\"rectangleFace\">rectangleFace</field><value name=\"VALUE\"><block type=\"bitbybit.occt.shapes.face.createRectangleFace\" id=\"rectangle_face\"><value name=\"Width\"><block type=\"math_number\" id=\"rectangle_width\"><field name=\"NUM\">3</field></block></value><value name=\"Length\"><block type=\"math_number\" id=\"rectangle_length\"><field name=\"NUM\">7</field></block></value><value name=\"Center\"><block type=\"bitbybit.point.pointXYZ\" id=\"rectangle_center\"><value name=\"X\"><block type=\"math_number\" id=\"rectangle_center_x\"><field name=\"NUM\">-7</field></block></value><value name=\"Y\"><block type=\"math_number\" id=\"rectangle_center_y\"><field name=\"NUM\">0</field></block></value><value name=\"Z\"><block type=\"math_number\" id=\"rectangle_center_z\"><field name=\"NUM\">0</field></block></value></block></value><value name=\"Direction\"><block type=\"bitbybit.vector.vectorXYZ\" id=\"rectangle_direction\"><value name=\"X\"><block type=\"math_number\" id=\"rectangle_dir_x\"><field name=\"NUM\">0</field></block></value><value name=\"Y\"><block type=\"math_number\" id=\"rectangle_dir_y\"><field name=\"NUM\">1</field></block></value><value name=\"Z\"><block type=\"math_number\" id=\"rectangle_dir_z\"><field name=\"NUM\">0</field></block></value></block></value></block></value><next><block type=\"variables_set\" id=\"create_ellipse_face\" x=\"50\" y=\"350\"><field name=\"VAR\" id=\"ellipseFace\">ellipseFace</field><value name=\"VALUE\"><block type=\"bitbybit.occt.shapes.face.createEllipseFace\" id=\"ellipse_face\"><value name=\"Center\"><block type=\"bitbybit.point.pointXYZ\" id=\"ellipse_center\"><value name=\"X\"><block type=\"math_number\" id=\"ellipse_center_x\"><field name=\"NUM\">0</field></block></value><value name=\"Y\"><block type=\"math_number\" id=\"ellipse_center_y\"><field name=\"NUM\">0</field></block></value><value name=\"Z\"><block type=\"math_number\" id=\"ellipse_center_z\"><field name=\"NUM\">-9</field></block></value></block></value><value name=\"Direction\"><block type=\"bitbybit.vector.vectorXYZ\" id=\"ellipse_direction\"><value name=\"X\"><block type=\"math_number\" id=\"ellipse_dir_x\"><field name=\"NUM\">0</field></block></value><value name=\"Y\"><block type=\"math_number\" id=\"ellipse_dir_y\"><field name=\"NUM\">1</field></block></value><value name=\"Z\"><block type=\"math_number\" id=\"ellipse_dir_z\"><field name=\"NUM\">0</field></block></value></block></value><value name=\"RadiusMinor\"><block type=\"math_number\" id=\"ellipse_radius_minor\"><field name=\"NUM\">1</field></block></value><value name=\"RadiusMajor\"><block type=\"math_number\" id=\"ellipse_radius_major\"><field name=\"NUM\">3</field></block></value></block></value><next><block type=\"bitbybit.draw.drawAnyAsyncNoReturn\" id=\"draw_circle_face\" x=\"50\" y=\"450\"><value name=\"Entity\"><block type=\"variables_get\" id=\"get_circle_face\"><field name=\"VAR\" id=\"circleFace\">circleFace</field></block></value><next><block type=\"bitbybit.draw.drawAnyAsyncNoReturn\" id=\"draw_square_face\" x=\"50\" y=\"550\"><value name=\"Entity\"><block type=\"variables_get\" id=\"get_square_face\"><field name=\"VAR\" id=\"squareFace\">squareFace</field></block></value><next><block type=\"bitbybit.draw.drawAnyAsyncNoReturn\" id=\"draw_rectangle_face\" x=\"50\" y=\"650\"><value name=\"Entity\"><block type=\"variables_get\" id=\"get_rectangle_face\"><field name=\"VAR\" id=\"rectangleFace\">rectangleFace</field></block></value><next><block type=\"bitbybit.draw.drawAnyAsyncNoReturn\" id=\"draw_ellipse_face\" x=\"50\" y=\"750\"><value name=\"Entity\"><block type=\"variables_get\" id=\"get_ellipse_face\"><field name=\"VAR\" id=\"ellipseFace\">ellipseFace</field></block></value></block></next></block></next></block></next></block></next></block></next></block></next></block></next></block></xml>","version":"0.20.7","type":"blockly"}}
title="Creating basic face primitives"
/>
</TabItem>
<TabItem value="typescript" label="TypeScript">
<BitByBitRenderCanvas
requireManualStart={true}
script={{"script":"// Import required DTOs and types for face creation\nconst { CircleDto, SquareDto, RectangleDto, EllipseDto } = Bit.Inputs.OCCT;\ntype Point3 = Bit.Inputs.Base.Point3;\ntype Vector3 = Bit.Inputs.Base.Vector3;\n\n// Get access to OCCT face creation functions\nconst { face } = bitbybit.occt.shapes;\n\n// Define the main function to create various primitive faces\nconst start = async () => {\n // Create a circle face\n const circleOptions = new CircleDto();\n circleOptions.radius = 4;\n circleOptions.center = [0, 0, 0] as Point3;\n circleOptions.direction = [0, 1, 0] as Vector3;\n\n const circleFace = await face.createCircleFace(circleOptions);\n\n // Create a square face at a different position\n const squareOptions = new SquareDto();\n squareOptions.size = 3;\n squareOptions.center = [7, 0, 0] as Point3;\n squareOptions.direction = [0, 1, 0] as Vector3;\n\n const squareFace = await face.createSquareFace(squareOptions);\n\n // Create a rectangle face\n const rectangleOptions = new RectangleDto();\n rectangleOptions.width = 3;\n rectangleOptions.length = 7;\n rectangleOptions.center = [-7, 0, 0] as Point3;\n rectangleOptions.direction = [0, 1, 0] as Vector3;\n\n const rectangleFace = await face.createRectangleFace(rectangleOptions);\n\n // Create an ellipse face\n const ellipseOptions = new EllipseDto();\n ellipseOptions.center = [0, 0, -9] as Point3;\n ellipseOptions.direction = [0, 1, 0] as Vector3;\n ellipseOptions.radiusMinor = 1;\n ellipseOptions.radiusMajor = 3;\n\n const ellipseFace = await face.createEllipseFace(ellipseOptions);\n\n // Draw all the created faces\n bitbybit.draw.drawAnyAsync({ entity: circleFace });\n bitbybit.draw.drawAnyAsync({ entity: squareFace });\n bitbybit.draw.drawAnyAsync({ entity: rectangleFace });\n bitbybit.draw.drawAnyAsync({ entity: ellipseFace });\n}\n\n// Execute the function\nstart();","version":"0.20.7","type":"typescript"}}
title="Creating basic face primitives"
/>
</TabItem>
</Tabs>

Each face primitive requires basic parameters: a center point for positioning, a direction vector for orientation (typically [0,1,0] for horizontal faces), and size parameters like radius for circles or width/length for rectangles. The examples create four different face types at separate positions so you can see them clearly.

These face primitives serve as building blocks for more complex modeling operations. You can extrude them into 3D solids, combine them with boolean operations, or use them as surfaces for analysis and visualization. They're commonly used in architectural modeling, manufacturing design, and any application where you need precise geometric surfaces.
Loading