update readme
parent
d6377a86a4
commit
e844a96c66
41
readme.md
41
readme.md
|
@ -5,13 +5,44 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<img style="width:min(600px,100%)" src="https://raw.githubusercontent.com/twpride/three.cad/master/dist/sketch.gif"></img>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img style="width:min(600px,100%)" src="https://raw.githubusercontent.com/twpride/three.cad/master/dist/site_preview.gif"></img>
|
<img style="width:min(600px,100%)" src="https://raw.githubusercontent.com/twpride/three.cad/master/dist/site_preview.gif"></img>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
# About
|
||||||
|
Three.cad is a 3D modelling web app built using [three.js](https://threejs.org/), [React](https://reactjs.org/), and [Web Assembly](https://webassembly.org/). It features parametric sketching and constructive solid geometry (CSG) capabilities.
|
||||||
|
|
||||||
Three.cad is a 3D modelling software built using Three.js, React, and Web Assembly. It features parametric sketching and constructive solid geometry (CSG) capabilities.
|
# Highlights
|
||||||
|
|
||||||
|
## 2D Sketching
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img style="width:min(600px,100%)" src="https://raw.githubusercontent.com/twpride/three.cad/master/dist/sketch.gif"></img>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
Made possible by the raycasting and matrix transformation features provided by three.js, the user can sketch on any arbitrary 2D plane in 3D space. With the provided the line and the arc tools, the user can sketch almost all the geometry commonly found in engineering applications.
|
||||||
|
|
||||||
|
### Geometric Constraint Solver
|
||||||
|
|
||||||
|
At the heart of three.cad is its parametric sketching environment. Initially, after a line is drawn, the user can drag the vertex endpoints and freely alter their positions. If however a constraint (such as an angle or distance) is added to a sketched line, the program will enforce these constraints whenever modifications are made to the vertex positions. With constraints like coincidence, distance, angle, and tangency, the user is empowered to draw sketches that are entirely controlled by geometric relationships.
|
||||||
|
|
||||||
|
In the backend, the parametric sketching capability is powered by a third-party C++ [library](https://github.com/solvespace/solvespace) compiled into a Web Assembly binary. Provided the initial vertex positions and constraints, the library calculates the final vertex positions that satisfy all the constraints. This calculation is done whenever a modification is made to the sketch which potentially can be as often as 60 times per second (dragging of a vertex).
|
||||||
|
|
||||||
|
## Solid Modelling
|
||||||
|
|
||||||
|
### Finding a loop
|
||||||
|
|
||||||
|
When the user decides to extrude a 2D sketch to 3D, the program employs a loop finding algorithm to search for a closed loop in the sketch. Once a loop is found, it is extruded using the [ExtrudeGeometry](https://threejs.org/docs/#api/en/geometries/ExtrudeGeometry) method.
|
||||||
|
|
||||||
|
### Constructive Solid Geometry
|
||||||
|
|
||||||
|
Once a multiple solids are formed via extrusion of 2D sketches, the user can perform boolean operations such as union, subtract, and intersect between them to form new composite solids. The capability, called constructive solid geometry, is powered by a third-party [library](https://github.com/manthrax/THREE-CSGMesh) (which itself is based on another [libary](https://github.com/evanw/csg.js/).
|
||||||
|
|
||||||
|
### Design Tree
|
||||||
|
|
||||||
|
The ability to combine existing solids to form new ones, enables the formation of complex design trees in which a solid is created from two parent solids which themselves are descendents of other solids. Managing this design tree requires keeping track of the parent/child relationship between the solids and utilizing a depth first search to update all descendents whenever a node(solid or sketch) is changed.
|
||||||
|
|
||||||
|
|
||||||
|
## Local File System
|
||||||
|
|
||||||
|
three.cad takes advantage of the [FileSystem API](https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API) available in Chromium based browers. The user can open, edit, and save solid models directly from the local disk.
|
||||||
|
|
|
@ -27,8 +27,6 @@ export class DepTree {
|
||||||
this.addParent(childId)
|
this.addParent(childId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getDescendents(id) {
|
getDescendents(id) {
|
||||||
const dfs = (id) => {
|
const dfs = (id) => {
|
||||||
visited.add(id)
|
visited.add(id)
|
||||||
|
@ -52,7 +50,6 @@ export class DepTree {
|
||||||
|
|
||||||
deleteNode(id) {
|
deleteNode(id) {
|
||||||
|
|
||||||
|
|
||||||
const nodesToDel = this.getDescendents(id)
|
const nodesToDel = this.getDescendents(id)
|
||||||
|
|
||||||
nodesToDel.sort((a, b) => this.order[b] - this.order[a])
|
nodesToDel.sort((a, b) => this.order[b] - this.order[a])
|
||||||
|
@ -64,7 +61,6 @@ export class DepTree {
|
||||||
|
|
||||||
this.allIds.splice(spliceIdx, 1)
|
this.allIds.splice(spliceIdx, 1)
|
||||||
|
|
||||||
// const deletedObj = sc.obj3d.children.splice(spliceIdx + 1, 1)[0] // first 1 elements are non geom
|
|
||||||
const deletedObj = sce.obj3d.children.splice(spliceIdx + 1, 1)[0] // first 1 elements are non geom
|
const deletedObj = sce.obj3d.children.splice(spliceIdx + 1, 1)[0] // first 1 elements are non geom
|
||||||
|
|
||||||
deletedObj.traverse((obj) => {
|
deletedObj.traverse((obj) => {
|
||||||
|
@ -93,40 +89,7 @@ export class DepTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// const dt = new DepTree()
|
|
||||||
// dt.addParent('r1')
|
|
||||||
// dt.addParent('r2')
|
|
||||||
// dt.addChild('r3', 'r1', 'r2')s
|
|
||||||
// dt.addParent('r4')
|
|
||||||
// dt.addChild('r5', 'r4', 'r3')
|
|
||||||
// dt.addChild('r6', 'r1', 'r5')
|
|
||||||
// dt.addChild('r7', 'r3', 'r5')
|
|
||||||
|
|
||||||
// dt.addParent('r8')
|
|
||||||
|
|
||||||
// // console.log(dt)
|
|
||||||
|
|
||||||
// // const x = dt.deleteNode('r3')
|
|
||||||
// // console.log(x)
|
|
||||||
// // console.log(dt.allIds, dt.order)
|
|
||||||
// // [ 6, 5, 4, 2 ]
|
|
||||||
// // [ 'r1', 'r2', 'r4' ] { r1: 0, r2: 1, r4: 2 }
|
|
||||||
|
|
||||||
|
|
||||||
// const x = dt.deleteNode('r5')
|
|
||||||
// console.log(dt)
|
|
||||||
// DepTree {
|
|
||||||
// tree: { r1: { r3: true }, r2: { r3: true }, r3: {}, r4: {}, r8: {} },
|
|
||||||
// order: { r1: 0, r2: 1, r3: 2, r4: 3, r8: 4 },
|
|
||||||
// allIds: [ 'r1', 'r2', 'r3', 'r4', 'r8' ]
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue