diff --git a/.idea/fluency.iml b/.idea/fluency.iml
new file mode 100644
index 0000000..b10ce10
--- /dev/null
+++ b/.idea/fluency.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..0604130
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..3064ac6
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..f267c84
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..57f2ca5
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..13a4842
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "associatedIndex": 6
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1703867682707
+
+
+ 1703867682707
+
+
+
+ 1703951701948
+
+
+
+ 1703951701948
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2dtest.py b/2dtest.py
new file mode 100644
index 0000000..4f7d97c
--- /dev/null
+++ b/2dtest.py
@@ -0,0 +1,62 @@
+import sys
+from PySide6.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton
+from PySide6.QtGui import QPainter, QPen
+from PySide6.QtCore import Qt
+
+class CADWindow(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.setWindowTitle("CAD")
+ self.resize(800, 600)
+
+ # Create a label for the dimensions input
+ self.dimension_label = QLabel("Dimensions:", self)
+ self.dimension_label.move(10, 10)
+
+ # Create a line edit for the user to enter the dimensions
+ self.dimension_input = QLineEdit()
+ self.dimension_input.setPlaceholderText("Enter dimensions...")
+ self.dimension_input.setFixedWidth(300)
+ self.dimension_input.move(10, 40)
+
+ # Create a button for the user to confirm the dimensions
+ self.confirm_button = QPushButton("Confirm", self)
+ self.confirm_button.clicked.connect(self.confirm_dimensions)
+ self.confirm_button.move(10, 70)
+
+ # Create a label for the canvas
+ self.canvas_label = QLabel("Canvas:", self)
+ self.canvas_label.move(400, 10)
+
+ # Create a canvas widget for the user to draw on
+ self.canvas = QWidget()
+ self.canvas.setFixedSize(300, 300)
+ self.canvas.move(400, 40)
+
+ # Set the default dimensions of the canvas
+ self.dimensions = (300, 300)
+
+ def confirm_dimensions(self):
+ # Get the dimensions from the line edit and convert to a tuple
+ dimensions = self.dimension_input.text().split(",")
+ dimensions = [int(d) for d in dimensions]
+ self.dimensions = dimensions
+
+ # Resize the canvas widget to match the new dimensions
+ self.canvas.setFixedSize(*self.dimensions)
+
+ def paintEvent(self, event):
+ # Get a painter object for painting on the canvas
+ painter = QPainter(self.canvas)
+
+ # Set the pen color and width
+ painter.pen = QPen(Qt.black, 2)
+
+ # Draw a line across the canvas using the dimensions from the user input
+ painter.drawLine(0, 0, *self.dimensions)
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ window = CADWindow()
+ window.show()
+ sys.exit(app.exec_())
\ No newline at end of file
diff --git a/fluency.py b/fluency.py
index 5585b61..9c23ef7 100644
--- a/fluency.py
+++ b/fluency.py
@@ -1,8 +1,57 @@
+from math import pi, sin, cos
+from direct.showbase.ShowBase import ShowBase
+from direct.task import Task
+from direct.gui.DirectGui import DirectEntry, DirectButton
from sdf import *
-f = sphere(1) & box(0.9)
-c = cylinder(0.3)
-f -= c.orient(X) | c.orient(Y) | c.orient(Z)
+class MyApp(ShowBase):
+ def __init__(self):
+ ShowBase.__init__(self)
-f.save('out.stl', step=0.001)
\ No newline at end of file
+ """# Load the environment model.
+ self.scene = self.loader.loadModel("station_alpha_ripped.glb")
+ # Reparent the model to render.
+ self.scene.reparentTo(self.render)
+ # Apply scale and position transforms on the model.
+ self.scene.setScale(1, 1, 1)
+ self.scene.setPos(0, 0, 0)"""
+
+ # Add the spinCameraTask procedure to the task manager.
+ self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")
+
+ # Create a DirectEntry widget for text input
+ self.textEntry = DirectEntry(
+ text="", scale=0.05, command=self.setText, initialText="Type here"
+ )
+ self.textEntry.reparentTo(self.aspect2d)
+ self.textEntry.setPos(-1.1, 0, -0.95)
+
+ self.apply = DirectButton(text="Make Cube",scale=0.05, command=self.buttonClicked)
+ self.apply.reparentTo(self.aspect2d)
+ self.apply.setPos(-1, -1, 0.8)
+
+ def setText(self, textEntered):
+ print("Text entered:", textEntered)
+
+ def buttonClicked(self):
+ print("Clciked")
+ obj = box(0.9)
+ model = obj.save("model.stl" , step=0.01)
+ self.scene = self.loader.loadModel("model.stl")
+ self.scene.reparentTo(self.render)
+ self.scene.setScale(1, 1, 1)
+ self.scene.setPos(0, 0, 0)
+
+
+ # Define a procedure to move the camera.
+ def spinCameraTask(self, task):
+ angleDegrees = task.time * 6.0
+ angleRadians = angleDegrees * (pi / 180.0)
+ self.camera.setPos(20 * sin(angleRadians), -20 * cos(angleRadians), 3)
+ self.camera.setHpr(angleDegrees, 0, 0)
+ return Task.cont
+
+
+app = MyApp()
+app.run()
diff --git a/fluencyb.py b/fluencyb.py
new file mode 100644
index 0000000..890ca89
--- /dev/null
+++ b/fluencyb.py
@@ -0,0 +1,51 @@
+import pygame
+from pygame.locals import *
+
+class Button:
+ def __init__(self, text, position, size):
+ self.text = text
+ self.font = pygame.font.Font(None, 36)
+ self.position = position
+ self.size = size
+ self.rect = pygame.Rect(position, size)
+ self.clicked = False
+
+ def draw(self, surface):
+ pygame.draw.rect(surface, (255, 255, 255), self.rect, 2)
+ text_surface = self.font.render(self.text, True, (255, 255, 255))
+ text_rect = text_surface.get_rect(center=self.rect.center)
+ surface.blit(text_surface, text_rect)
+
+ def is_clicked(self, pos):
+ if self.rect.collidepoint(pos):
+ self.clicked = True
+ return True
+ return False
+
+def main():
+ pygame.init()
+ display = (800, 600)
+ screen = pygame.display.set_mode(display)
+ clock = pygame.time.Clock()
+
+ button = Button("Click Me!", (300, 250), (200, 50))
+
+ running = True
+ while running:
+ for event in pygame.event.get():
+ if event.type == QUIT:
+ running = False
+ elif event.type == MOUSEBUTTONDOWN:
+ if event.button == 1:
+ if button.is_clicked(event.pos):
+ print("Button Clicked!")
+
+ screen.fill((0, 0, 0))
+ button.draw(screen)
+ pygame.display.flip()
+ clock.tick(60)
+
+ pygame.quit()
+
+if __name__ == "__main__":
+ main()
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..15e7418
--- /dev/null
+++ b/main.py
@@ -0,0 +1,30 @@
+from PySide6.QtWidgets import QApplication, QMainWindow, QSizePolicy
+from Gui import Ui_fluencyCAD # Import the generated GUI module
+from modules.gl_widget import OpenGLWidget
+
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ super().__init__()
+
+ # Set up the UI from the generated GUI module
+ self.ui = Ui_fluencyCAD()
+ self.ui.setupUi(self)
+
+ self.openGLWidget = OpenGLWidget()
+ self.openGLWidget.setParent(self.ui.gl_canvas)
+ # Connect the resizeEvent of the parent widget to a function
+ self.ui.gl_canvas.resizeEvent = self.glCanvasResized
+
+ def glCanvasResized(self, event):
+ # Get the size of the gl_canvas
+ canvas_size = self.ui.gl_canvas.size()
+ # Resize the OpenGL widget to match the size of the gl_canvas
+ self.openGLWidget.resize(canvas_size)
+
+
+if __name__ == "__main__":
+ app = QApplication([])
+ window = MainWindow()
+ window.show()
+ app.exec()
\ No newline at end of file
diff --git a/meshtest.py b/meshtest.py
new file mode 100644
index 0000000..d85e81d
--- /dev/null
+++ b/meshtest.py
@@ -0,0 +1,8 @@
+from sdf import *
+
+f = sphere(1) & box(0.9)
+
+c = cylinder(0.3)
+f -= c.orient(X) | c.orient(Y) | c.orient(Z)
+stl_object = None
+f.save("out.stl", step=0.05)
\ No newline at end of file
diff --git a/modules/gl_widget.py b/modules/gl_widget.py
new file mode 100644
index 0000000..37929bd
--- /dev/null
+++ b/modules/gl_widget.py
@@ -0,0 +1,93 @@
+from PySide6.QtOpenGLWidgets import QOpenGLWidget
+from PySide6.QtCore import QSize, Qt, QPoint
+from OpenGL.GL import *
+from OpenGL.GLU import *
+from stl import mesh
+
+
+class OpenGLWidget(QOpenGLWidget):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.stl_file = "out.stl" # Replace with your STL file path
+ self.lastPos = QPoint()
+ self.xRot = 0
+ self.yRot = 0
+ self.zoom = -10.0
+
+ def load_stl(self, filename):
+ try:
+ stl_mesh = mesh.Mesh.from_file(filename)
+ return stl_mesh.vectors
+ except FileNotFoundError:
+ print(f"Error: File {filename} not found.")
+ except Exception as e:
+ print(f"Error loading {filename}: {e}")
+ return []
+
+ def initializeGL(self):
+ glClearColor(0, 0, 0, 1)
+ glEnable(GL_DEPTH_TEST)
+
+ def resizeGL(self, w, h):
+ glViewport(0, 0, w, h)
+ glMatrixMode(GL_PROJECTION)
+ glLoadIdentity()
+ gluPerspective(45, w/h, 0.1, 100.0)
+ glMatrixMode(GL_MODELVIEW)
+
+ def paintGL(self):
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
+ glLoadIdentity()
+ glTranslatef(0.0, 0.0, self.zoom)
+ glRotatef(self.xRot, 1.0, 0.0, 0.0)
+ glRotatef(self.yRot, 0.0, 1.0, 0.0)
+ glColor3f(1.0, 1.0, 1.0)
+
+ mesh_data = self.load_stl(self.stl_file)
+ if mesh_data.any():
+ self.draw_stl(mesh_data)
+
+ def draw_stl(self, vertices):
+ glEnable(GL_LIGHTING)
+ glEnable(GL_LIGHT0)
+ glEnable(GL_DEPTH_TEST)
+ glEnable(GL_COLOR_MATERIAL)
+ glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
+
+ glLightfv(GL_LIGHT0, GL_POSITION, (0, 1, 1, 0))
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, (0.6, 0.6, 0.6, 0.6))
+
+ glBegin(GL_TRIANGLES)
+ for triangle in vertices:
+ for vertex in triangle:
+ glVertex3fv(vertex)
+ glEnd()
+
+ # Draw outer vertices as points
+ glDisable(GL_LIGHTING)
+ glColor3f(1.0, 0.0, 0.0) # Set color to red
+ glPointSize(5.0) # Set point size
+ glBegin(GL_POINTS)
+ for triangle in vertices:
+ for vertex in triangle:
+ glVertex3fv(vertex)
+ glEnd()
+
+ def mousePressEvent(self, event):
+ self.lastPos = event.pos()
+
+ def mouseMoveEvent(self, event):
+ dx = event.x() - self.lastPos.x()
+ dy = event.y() - self.lastPos.y()
+
+ if event.buttons() & Qt.LeftButton:
+ self.xRot += 0.5 * dy
+ self.yRot += 0.5 * dx
+ self.update()
+
+ self.lastPos = event.pos()
+
+ def wheelEvent(self, event):
+ delta = event.angleDelta().y()
+ self.zoom += delta / 120
+ self.update()
diff --git a/modules/out.stl b/modules/out.stl
new file mode 100644
index 0000000..811aa0d
Binary files /dev/null and b/modules/out.stl differ
diff --git a/side_fluency.py b/side_fluency.py
new file mode 100644
index 0000000..9017fc6
--- /dev/null
+++ b/side_fluency.py
@@ -0,0 +1,170 @@
+import sys
+from PySide6.QtOpenGLWidgets import QOpenGLWidget
+from PySide6.QtWidgets import (QApplication, QMainWindow, QHBoxLayout, QVBoxLayout, QWidget, QPushButton, QGroupBox,
+ QTextEdit, QSizePolicy)
+from PySide6.QtCore import QSize, Qt, QPoint
+from OpenGL.GL import *
+from OpenGL.GLU import *
+from stl import mesh
+
+
+class OpenGLWidget(QOpenGLWidget):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.stl_file = "out.stl" # Replace with your STL file path
+ self.lastPos = QPoint()
+ self.xRot = 0
+ self.yRot = 0
+ self.zoom = -10.0
+
+ def load_stl(self, filename):
+ try:
+ stl_mesh = mesh.Mesh.from_file(filename)
+ return stl_mesh.vectors
+ except FileNotFoundError:
+ print(f"Error: File {filename} not found.")
+ except Exception as e:
+ print(f"Error loading {filename}: {e}")
+ return []
+
+ def initializeGL(self):
+ glClearColor(0, 0, 0, 1)
+ glEnable(GL_DEPTH_TEST)
+
+ def resizeGL(self, w, h):
+ glViewport(0, 0, w, h)
+ glMatrixMode(GL_PROJECTION)
+ glLoadIdentity()
+ gluPerspective(45, w/h, 0.1, 100.0)
+ glMatrixMode(GL_MODELVIEW)
+
+ def paintGL(self):
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
+ glLoadIdentity()
+ glTranslatef(0.0, 0.0, self.zoom)
+ glRotatef(self.xRot, 1.0, 0.0, 0.0)
+ glRotatef(self.yRot, 0.0, 1.0, 0.0)
+ glColor3f(1.0, 1.0, 1.0)
+
+ mesh_data = self.load_stl(self.stl_file)
+ if mesh_data.any():
+ self.draw_stl(mesh_data)
+
+ def draw_stl(self, vertices):
+ glEnable(GL_LIGHTING)
+ glEnable(GL_LIGHT0)
+ glEnable(GL_DEPTH_TEST)
+ glEnable(GL_COLOR_MATERIAL)
+ glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
+
+ glLightfv(GL_LIGHT0, GL_POSITION, (0, 1, 1, 0))
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, (0.6, 0.6, 0.6, 0.6))
+
+ glBegin(GL_TRIANGLES)
+ for triangle in vertices:
+ for vertex in triangle:
+ glVertex3fv(vertex)
+ glEnd()
+
+ # Draw outer vertices as points
+ glDisable(GL_LIGHTING)
+ glColor3f(1.0, 0.0, 0.0) # Set color to red
+ glPointSize(5.0) # Set point size
+ glBegin(GL_POINTS)
+ for triangle in vertices:
+ for vertex in triangle:
+ glVertex3fv(vertex)
+ glEnd()
+
+ def mousePressEvent(self, event):
+ self.lastPos = event.pos()
+
+ def mouseMoveEvent(self, event):
+ dx = event.x() - self.lastPos.x()
+ dy = event.y() - self.lastPos.y()
+
+ if event.buttons() & Qt.LeftButton:
+ self.xRot += 0.5 * dy
+ self.yRot += 0.5 * dx
+ self.update()
+
+ self.lastPos = event.pos()
+
+ def wheelEvent(self, event):
+ delta = event.angleDelta().y()
+ self.zoom += delta / 120
+ self.update()
+
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ super().__init__()
+
+ self.setWindowTitle("fluencyCAD")
+ self.height = 1080
+ self.width = 1920
+ self.setFixedSize(QSize(self.width, self.height))
+
+ # Main central widget
+ central_widget = QWidget()
+ self.setCentralWidget(central_widget)
+
+ layout = QHBoxLayout(central_widget)
+
+ # Left tools area
+ left_tools_layout = QVBoxLayout()
+
+ self.left_tools = QGroupBox("Left Tools")
+ self.left_tools.setFixedSize(100, self.height)
+
+ self.draw_rectangle = QPushButton("Draw Rectangle")
+ self.draw_rectangle.setFixedSize(80, 30)
+ left_tools_layout.addWidget(self.draw_rectangle)
+
+ self.draw_rectangle = QPushButton("Draw Rectangle2")
+ self.draw_rectangle.setFixedSize(80, 30)
+ left_tools_layout.addWidget(self.draw_rectangle) # Align the button to the top
+
+ self.draw_rectangle = QPushButton("Draw Rectangle3")
+ self.draw_rectangle.setFixedSize(80, 30)
+ left_tools_layout.addWidget(self.draw_rectangle)
+
+ self.left_tools.setLayout(left_tools_layout)
+ self.left_tools.setAlignment(Qt.AlignTop)
+ layout.addWidget(self.left_tools)
+
+ # Center OpenGL widget and QTextEdit
+ center_layout = QVBoxLayout()
+
+ self.openGLWidget = OpenGLWidget()
+ center_layout.addWidget(self.openGLWidget)
+ self.openGLWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+
+ self.enter_code = QTextEdit()
+ self.enter_code.setFixedSize(QSize(self.width, self.height // 4))
+ center_layout.addWidget(self.enter_code)
+
+ self.code_tools = QGroupBox("Code Tools")
+ self.code_tools.setFixedSize(QSize(self.width, self.height // 18))
+
+ code_tools_layout = QHBoxLayout() # Layout for code tools
+
+ self.apply_code = QPushButton("Apply Code") # Creating QPushButton
+ self.apply_code.setFixedSize(80,30)
+
+ code_tools_layout.addWidget(self.apply_code) # Adding QPushButton to QHBoxLayout
+
+ self.code_tools.setLayout(code_tools_layout) # Setting QHBoxLayout to QGroupBox
+ self.code_tools.setAlignment(Qt.AlignLeft)
+
+ center_layout.addWidget(self.code_tools) # Adding QGroupBox to the center layout
+
+ layout.addLayout(center_layout) # Adding center layout to the main layout
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ window = MainWindow()
+ window.show()
+ sys.exit(app.exec())
+
diff --git a/vulkan.py b/vulkan.py
new file mode 100644
index 0000000..c0b2dfe
--- /dev/null
+++ b/vulkan.py
@@ -0,0 +1,37 @@
+import vtk
+
+def loadStl(fname):
+ """Load the given STL file, and return a vtkPolyData object for it."""
+ reader = vtk.vtkSTLReader()
+ reader.SetFileName(fname)
+ reader.Update()
+ polydata = reader.GetOutput()
+ return polydata
+
+def polyDataToActor(polydata):
+ """Wrap the provided vtkPolyData object in a mapper and an actor, returning the actor."""
+ mapper = vtk.vtkPolyDataMapper()
+ mapper.SetInputData(polydata)
+ actor = vtk.vtkActor()
+ actor.SetMapper(mapper)
+ return actor
+
+# Create a rendering window and renderer
+ren = vtk.vtkRenderer()
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren)
+
+# Create a RenderWindowInteractor to permit manipulating the camera
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+style = vtk.vtkInteractorStyleTrackballCamera()
+iren.SetInteractorStyle(style)
+
+stlFilename = "out.stl"
+polydata = loadStl(stlFilename)
+ren.AddActor(polyDataToActor(polydata))
+
+# Enable user interface interactor
+iren.Initialize()
+renWin.Render()
+iren.Start()
\ No newline at end of file