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 + + + + + + + + + + + + + + \ 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