Skip to content

Commit

Permalink
Added Ollama and update other AI script generation features (#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
openvmp authored Sep 3, 2024
1 parent 26be3fb commit df6cc68
Show file tree
Hide file tree
Showing 38 changed files with 845 additions and 161 deletions.
2 changes: 1 addition & 1 deletion docs/source/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ Generate CadQuery or OpenSCAD scripts with Generative AI using the following syn
parts:
<part name>:
type: <ai-openscad|ai-cadquery>
provider: <google|openai, the model provider to use>
provider: <google|openai|ollama, the model provider to use>
tokens: <(optional) the limit of token context>
top_p: <(optional, openai only) the top_p parameter>
images: <(optional) contextual images as input for AI>
Expand Down
26 changes: 25 additions & 1 deletion docs/source/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,37 @@ Last but not least, they are powering accessibility features,
allowing blind users to navigate the catalog of parts or to interactively
create their own designs.

Google and OpenAI models are supported. The following configuration is required:
Google Gemini, OpenAI and Ollama APIs are supported.
The following configuration is required:

.. code-block:: yaml
# ~/.partcad/config.yaml
googleApiKey: <...>
openaiApiKey: <...>
The following configuration is optional:

.. code-block:: yaml
# ~/.partcad/config.yaml
# ollamaNumThread is the number of CPU threads Ollama should utilize
ollamaNumThread: <integer>
PartCAD AI agents are designed to query AI multiple times,
so that a range of options is considered and the best result is found.
The following configuration options can be used to influence that bahavior:

.. code-block:: yaml
# ~/.partcad/config.yaml
# maxGeometricModeling is the number of attempts for geometric modelling
maxGeometricModeling: 4
# maxModelGeneration is the number of attempts for CAD script generation
maxModelGeneration: 3
# maxScriptCorrection is the number of attempts to incrementally fix the script if it's not working
maxScriptCorrection: 2
Design
------
Expand All @@ -42,6 +65,7 @@ The generated part definitions are persisted as Python or CAD scripts.
pc inspect "generated-case"
To use ChatGPT instead of Gemini, pass "openai" instead of "google" as the "--ai" parameter.
To use Ollama, pass "ollama".

If needed, the part can be regenerated by truncating the generated files.

Expand Down
35 changes: 35 additions & 0 deletions examples/produce_part_ai_build123d/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# /pub/examples/partcad/produce_part_ai_build123d

PartCAD parts defined using AI-generated build123d scripts.

## Usage
```shell
pc inspect cube
pc inspect prism
pc inspect tetrahedron
```


## Parts

### cube
<table><tr>
<td valign=top><img src="././cube.svg" width="200" height="200"></td>
<td valign=top>A cube</td>
</tr></table>

### prism
<table><tr>
<td valign=top><img src="././prism.svg" width="200" height="200"></td>
<td valign=top>A hexagonal prism</td>
</tr></table>

### tetrahedron
<table><tr>
<td valign=top><img src="././tetrahedron.svg" width="200" height="200"></td>
<td valign=top>A tetrahedron</td>
</tr></table>

<br/><br/>

*Generated by [PartCAD](https://partcad.org/)*
6 changes: 6 additions & 0 deletions examples/produce_part_ai_build123d/cube.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from build123d import *

with BuildPart() as cube:
Box(length=10, width=10, height=10)

show_object(cube)
16 changes: 16 additions & 0 deletions examples/produce_part_ai_build123d/cube.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions examples/produce_part_ai_build123d/partcad.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
desc: PartCAD parts defined using AI-generated build123d scripts.

docs:
usage: |
```shell
pc inspect cube
pc inspect prism
pc inspect tetrahedron
```
parts:
cube:
type: ai-build123d
provider: google
desc: A cube
properties:
length: 10
prism:
type: ai-build123d
provider: openai
# provider: ollama # TODO(clairbee): find an Ollama model that works with build123d
desc: A hexagonal prism
properties:
length: 10
tetrahedron:
type: ai-build123d
provider: openai
tokens:
top_p: 0.9
desc: A tetrahedron
properties:
length: 10

render:
readme:
svg:
27 changes: 27 additions & 0 deletions examples/produce_part_ai_build123d/prism.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import math
from build123d import *

# Define the side length of the hexagon
s = 5 # Example side length, can be adjusted

# Calculate the radius of the circumscribed circle
r = s / math.sqrt(3)

# Define the vertices of the hexagon
vertices = [
(r, 0, 0),
(r * math.cos(math.radians(60)), r * math.sin(math.radians(60)), 0),
(r * math.cos(math.radians(120)), r * math.sin(math.radians(120)), 0),
(-r, 0, 0),
(r * math.cos(math.radians(240)), r * math.sin(math.radians(240)), 0),
(r * math.cos(math.radians(300)), r * math.sin(math.radians(300)), 0)
]

# Create the hexagon base
hexagon = Polygon(vertices)

# Extrude the hexagon to form the prism
hex_prism = extrude(hexagon, 10)

# Display the part
show_object(hex_prism)
20 changes: 20 additions & 0 deletions examples/produce_part_ai_build123d/prism.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions examples/produce_part_ai_build123d/tetrahedron.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import math
from build123d import *

# Define vertices of the tetrahedron
A = (0, 0, 0)
B = (10, 0, 0)
C = (5, 8.66, 0)
D = (5, 2.89, 4.71)

# Create edges
edge_AB = Edge.make_line(A, B)
edge_AC = Edge.make_line(A, C)
edge_AD = Edge.make_line(A, D)
edge_BC = Edge.make_line(B, C)
edge_BD = Edge.make_line(B, D)
edge_CD = Edge.make_line(C, D)

# Create faces from edges
face_ABC = Face.make_from_wires(Wire.make_wire([edge_AB, edge_BC, edge_AC]))
face_ABD = Face.make_from_wires(Wire.make_wire([edge_AB, edge_BD, edge_AD]))
face_ACD = Face.make_from_wires(Wire.make_wire([edge_AC, edge_CD, edge_AD]))
face_BCD = Face.make_from_wires(Wire.make_wire([edge_BC, edge_CD, edge_BD]))

# Create the tetrahedron by combining faces
tetrahedron = Solid.make_solid(Shell([face_ABC, face_ABD, face_ACD, face_BCD]))

show_object(tetrahedron)
12 changes: 12 additions & 0 deletions examples/produce_part_ai_build123d/tetrahedron.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 5 additions & 3 deletions examples/produce_part_ai_cadquery/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,22 @@ pc inspect tetrahedron

### cube
<table><tr>
<td valign=top><img src="./cube.svg" width="200" height="200"></td>
<td valign=top><img src="././cube.svg" width="200" height="200"></td>
<td valign=top>A cube</td>
</tr></table>

### prism
<table><tr>
<td valign=top><img src="./prism.svg" width="200" height="200"></td>
<td valign=top><img src="././prism.svg" width="200" height="200"></td>
<td valign=top>A hexagonal prism</td>
</tr></table>

### tetrahedron
<table><tr>
<td valign=top><img src="./tetrahedron.svg" width="200" height="200"></td>
<td valign=top><img src="././tetrahedron.svg" width="200" height="200"></td>
<td valign=top>A tetrahedron</td>
</tr></table>

<br/><br/>

*Generated by [PartCAD](https://partcad.org/)*
3 changes: 2 additions & 1 deletion examples/produce_part_ai_cadquery/partcad.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ parts:
length: 10
prism:
type: ai-cadquery
provider: openai
provider: ollama
model: llama3.1:70b
desc: A hexagonal prism
properties:
length: 10
Expand Down
25 changes: 20 additions & 5 deletions examples/produce_part_ai_cadquery/prism.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
import cadquery as cq
import math
from cadquery import *

# Define the hexagonal prism
length = 10
hex_prism = cq.Workplane("XY").polygon(6, length).extrude(length)
s = 10 # assuming a side length of 10 mm for demonstration purposes

show_object(hex_prism)
# calculate radius of circumscribed circle using trigonometry
r = s / (2 * math.sin(math.radians(60)))

# create the hexagonal prism
hexagon_prism = (
Workplane("XY")
.moveTo(r, 0)
.lineTo(r + s/2, r*math.sqrt(3)/2)
.lineTo(-r - s/2, r*math.sqrt(3)/2)
.lineTo(-r, 0)
.lineTo(-r - s/2, -r*math.sqrt(3)/2)
.lineTo(r + s/2, -r*math.sqrt(3)/2)
.close()
.extrude(10) # extrude to create the prism
)

show_object(hexagon_prism)
28 changes: 13 additions & 15 deletions examples/produce_part_ai_cadquery/prism.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 24 additions & 17 deletions examples/produce_part_ai_cadquery/tetrahedron.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
import math
import cadquery as cq

length = 10
# Define vertices
A = (0, 0, 0)
B = (10, 0, 0)
C = (5, 8.66, 0)
D = (3.33, 2.89, 8.16)

def create_tetrahedron(length):
height = math.sqrt(2/3) * length
radius = math.sqrt(6)/3 * length

v0 = cq.Vector(0, 0, 0)
v1 = cq.Vector(length, 0, 0)
v2 = cq.Vector(length/2, height, 0)
v3 = cq.Vector(length/2, height/3, radius)

tetrahedron = cq.Workplane("XY").polyline([v0, v1, v2, v0]) \
.polyline([v0, v2, v3, v0]) \
.polyline([v1, v3, v2, v1]) \
.polyline([v1, v0, v3, v1]) \
.close()
# Create edges
edges = [
cq.Edge.makeLine(A, B),
cq.Edge.makeLine(A, C),
cq.Edge.makeLine(A, D),
cq.Edge.makeLine(B, C),
cq.Edge.makeLine(B, D),
cq.Edge.makeLine(C, D)
]

return tetrahedron
# Create faces
faces = [
cq.Face.makeFromWires(cq.Wire.assembleEdges([edges[0], edges[1], edges[3]])),
cq.Face.makeFromWires(cq.Wire.assembleEdges([edges[0], edges[2], edges[4]])),
cq.Face.makeFromWires(cq.Wire.assembleEdges([edges[1], edges[2], edges[5]])),
cq.Face.makeFromWires(cq.Wire.assembleEdges([edges[3], edges[4], edges[5]]))
]

# Create solid
tetrahedron = cq.Solid.makeSolid(cq.Shell.makeShell(faces))

tetrahedron = create_tetrahedron(length)
show_object(tetrahedron)
Loading

0 comments on commit df6cc68

Please sign in to comment.