Fixed interactor
Added proj lines selected
This commit is contained in:
		@@ -5,7 +5,7 @@ from copy import copy
 | 
			
		||||
import numpy as np
 | 
			
		||||
from PySide6.QtWidgets import QApplication, QWidget, QMessageBox, QInputDialog
 | 
			
		||||
from PySide6.QtGui import QPainter, QPen, QColor, QTransform
 | 
			
		||||
from PySide6.QtCore import Qt, QPoint, QPointF, Signal
 | 
			
		||||
from PySide6.QtCore import Qt, QPoint, QPointF, Signal, QLine
 | 
			
		||||
from python_solvespace import SolverSystem, ResultFlag
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -51,13 +51,11 @@ class SketchWidget(QWidget):
 | 
			
		||||
    def create_workplane_projected(self):
 | 
			
		||||
        self.wp = self.solv.create_2d_base()
 | 
			
		||||
 | 
			
		||||
    def create_proj_lines(self, lines):
 | 
			
		||||
    def create_proj_points(self, proj_points):
 | 
			
		||||
        """Lines as orientation projected from the sketch"""
 | 
			
		||||
 | 
			
		||||
        for point in lines:
 | 
			
		||||
        for point in proj_points:
 | 
			
		||||
            x, y = point
 | 
			
		||||
            self.proj_snap_lines = lines
 | 
			
		||||
            # Invert X from projection might be happening in the projection for some reason Careful
 | 
			
		||||
            coord = QPoint(x, y)
 | 
			
		||||
            self.proj_snap_points.append(coord)
 | 
			
		||||
 | 
			
		||||
@@ -69,6 +67,24 @@ class SketchWidget(QWidget):
 | 
			
		||||
 | 
			
		||||
            self.slv_points_main.append(relation_point)"""
 | 
			
		||||
 | 
			
		||||
    def create_proj_lines(self, sel_edges):
 | 
			
		||||
        """Lines as orientation projected from the sketch"""
 | 
			
		||||
        print("Incoming corrd lines", sel_edges)
 | 
			
		||||
        for line in sel_edges:
 | 
			
		||||
 | 
			
		||||
            start = QPoint(line[0][0], line[0][1] )
 | 
			
		||||
            end = QPoint(line[1][0], line[1][1])
 | 
			
		||||
            coord = QLine(start, end)
 | 
			
		||||
            self.proj_snap_lines.append(coord)
 | 
			
		||||
 | 
			
		||||
            """relation_point = {}  # Reinitialize the dictionary
 | 
			
		||||
            #handle_nr = self.get_handle_nr(str(point))
 | 
			
		||||
            #relation_point['handle_nr'] = handle_nr
 | 
			
		||||
            #relation_point['solv_handle'] = point
 | 
			
		||||
            relation_point['ui_point'] = QPoint(x, y)
 | 
			
		||||
 | 
			
		||||
            self.slv_points_main.append(relation_point)"""
 | 
			
		||||
 | 
			
		||||
    def find_duplicate_points_2d(self, edges):
 | 
			
		||||
        points = []
 | 
			
		||||
        seen = set()
 | 
			
		||||
@@ -675,11 +691,11 @@ class SketchWidget(QWidget):
 | 
			
		||||
        return QPoint(int(widget_x), int(widget_y))
 | 
			
		||||
 | 
			
		||||
    def from_quadrant_coords_no_center(self, point):
 | 
			
		||||
        """Translate quadrant coordinates to linear coordinates."""
 | 
			
		||||
        """Invert Y Coordinate for mesh"""
 | 
			
		||||
        center_x = 0
 | 
			
		||||
        center_y = 0
 | 
			
		||||
        widget_x = center_x + point.x() * self.zoom
 | 
			
		||||
        widget_y = center_y - point.y() * self.zoom  # Note the subtraction here
 | 
			
		||||
        widget_x = point.x()
 | 
			
		||||
        widget_y = -point.y()
 | 
			
		||||
        return QPoint(int(widget_x), int(widget_y))
 | 
			
		||||
 | 
			
		||||
    def paintEvent(self, event):
 | 
			
		||||
@@ -746,6 +762,11 @@ class SketchWidget(QWidget):
 | 
			
		||||
        for cross in self.proj_snap_points:
 | 
			
		||||
            self.draw_cross(painter, cross, 10 / self.zoom)
 | 
			
		||||
 | 
			
		||||
        for selected in self.proj_snap_lines:
 | 
			
		||||
            pen = QPen(Qt.white, 1, Qt.DashLine)
 | 
			
		||||
            painter.setPen(pen)
 | 
			
		||||
            painter.drawLine(selected)
 | 
			
		||||
 | 
			
		||||
        painter.end()
 | 
			
		||||
 | 
			
		||||
    def wheelEvent(self, event):
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ class VTKWidget(QtWidgets.QWidget):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, parent=None):
 | 
			
		||||
        super().__init__(parent)
 | 
			
		||||
        self.selected_vtk_line = []
 | 
			
		||||
        self.access_selected_points = []
 | 
			
		||||
        self.selected_normal = None
 | 
			
		||||
        self.centroid = None
 | 
			
		||||
@@ -21,7 +22,8 @@ class VTKWidget(QtWidgets.QWidget):
 | 
			
		||||
 | 
			
		||||
        self.local_matrix = None
 | 
			
		||||
 | 
			
		||||
        self.project_tosketch_edge = []
 | 
			
		||||
        self.project_tosketch_points = []
 | 
			
		||||
        self.project_tosketch_lines = []
 | 
			
		||||
 | 
			
		||||
        self.vtk_widget = QVTKRenderWindowInteractor(self)
 | 
			
		||||
 | 
			
		||||
@@ -112,10 +114,12 @@ class VTKWidget(QtWidgets.QWidget):
 | 
			
		||||
        mapper.SetInputData(grid)
 | 
			
		||||
 | 
			
		||||
        actor = vtk.vtkActor()
 | 
			
		||||
        actor.SetPickable(False)
 | 
			
		||||
        actor.SetMapper(mapper)
 | 
			
		||||
        actor.GetProperty().SetColor(0.5, 0.5, 0.5)  # Set grid color to gray
 | 
			
		||||
 | 
			
		||||
        self.renderer.AddActor(actor)
 | 
			
		||||
 | 
			
		||||
    def create_grid(self, size=100, spacing=10):
 | 
			
		||||
        # Create a vtkPoints object and store the points in it
 | 
			
		||||
        points = vtk.vtkPoints()
 | 
			
		||||
@@ -169,7 +173,7 @@ class VTKWidget(QtWidgets.QWidget):
 | 
			
		||||
        normal = normal / np.linalg.norm(normal)
 | 
			
		||||
        return normal
 | 
			
		||||
 | 
			
		||||
    def load_interactor_mesh(self, edges):
 | 
			
		||||
    def load_interactor_mesh(self, edges, off_vector):
 | 
			
		||||
        # Create vtkPoints to store all points
 | 
			
		||||
        points = vtk.vtkPoints()
 | 
			
		||||
 | 
			
		||||
@@ -195,28 +199,34 @@ class VTKWidget(QtWidgets.QWidget):
 | 
			
		||||
        polydata.SetLines(lines)
 | 
			
		||||
 | 
			
		||||
        # Create a transform for mirroring across the y-axis
 | 
			
		||||
        mirror_transform = vtk.vtkTransform()
 | 
			
		||||
        matrix_transform = vtk.vtkTransform()
 | 
			
		||||
 | 
			
		||||
        """if self.local_matrix:
 | 
			
		||||
        if self.local_matrix:
 | 
			
		||||
            print(self.local_matrix)
 | 
			
		||||
            matrix = vtk.vtkMatrix4x4()
 | 
			
		||||
            matrix.DeepCopy(self.local_matrix)
 | 
			
		||||
            matrix.Invert()
 | 
			
		||||
            mirror_transform.SetMatrix(matrix)
 | 
			
		||||
            matrix_transform.SetMatrix(matrix)
 | 
			
		||||
            #matrix_transform.Scale(1, 1, 1)  # This mirrors across the y-axis
 | 
			
		||||
 | 
			
		||||
            mirror_transform.Scale(-1, -1, 1)  # Inverting the original mirror look down
 | 
			
		||||
        
 | 
			
		||||
            mirror_transform.Scale(1, 1, 1)  # This mirrors across the y-axis"""
 | 
			
		||||
 | 
			
		||||
        # Apply the transform to the polydata
 | 
			
		||||
        # Apply the matrix transform
 | 
			
		||||
        transformFilter = vtk.vtkTransformPolyDataFilter()
 | 
			
		||||
        transformFilter.SetInputData(polydata)
 | 
			
		||||
        transformFilter.SetTransform(mirror_transform)
 | 
			
		||||
        transformFilter.SetTransform(matrix_transform)
 | 
			
		||||
        transformFilter.Update()
 | 
			
		||||
 | 
			
		||||
        # Create and apply the offset transform
 | 
			
		||||
        offset_transform = vtk.vtkTransform()
 | 
			
		||||
        offset_transform.Translate(off_vector[0], off_vector[1], off_vector[2])
 | 
			
		||||
 | 
			
		||||
        offsetFilter = vtk.vtkTransformPolyDataFilter()
 | 
			
		||||
        offsetFilter.SetInputConnection(transformFilter.GetOutputPort())
 | 
			
		||||
        offsetFilter.SetTransform(offset_transform)
 | 
			
		||||
        offsetFilter.Update()
 | 
			
		||||
 | 
			
		||||
        # Create a mapper and actor
 | 
			
		||||
        mapper = vtk.vtkPolyDataMapper()
 | 
			
		||||
        mapper.SetInputData(transformFilter.GetOutput())
 | 
			
		||||
        mapper.SetInputConnection(offsetFilter.GetOutputPort())
 | 
			
		||||
 | 
			
		||||
        actor = vtk.vtkActor()
 | 
			
		||||
        actor.SetMapper(mapper)
 | 
			
		||||
@@ -270,6 +280,9 @@ class VTKWidget(QtWidgets.QWidget):
 | 
			
		||||
        actor.GetProperty().SetColor(color)
 | 
			
		||||
        actor.GetProperty().EdgeVisibilityOff()
 | 
			
		||||
        actor.GetProperty().SetLineWidth(line_width)
 | 
			
		||||
        actor.GetProperty().SetMetallic(1)
 | 
			
		||||
        actor.GetProperty().SetOpacity(0.8)
 | 
			
		||||
        actor.SetPickable(False)
 | 
			
		||||
 | 
			
		||||
        self.renderer.AddActor(actor)
 | 
			
		||||
        self.body_actors_orig.append(actor)
 | 
			
		||||
@@ -385,6 +398,62 @@ class VTKWidget(QtWidgets.QWidget):
 | 
			
		||||
 | 
			
		||||
        return xy_coordinates
 | 
			
		||||
 | 
			
		||||
    def compute_2d_coordinates_line(self, line_cell, normal):
 | 
			
		||||
        # Ensure the input is a vtkLine
 | 
			
		||||
        if not isinstance(line_cell, vtk.vtkLine):
 | 
			
		||||
            raise ValueError("Input must be a vtkLine cell")
 | 
			
		||||
 | 
			
		||||
        # Normalize the normal vector
 | 
			
		||||
        normal = np.array(normal)
 | 
			
		||||
        normal = normal / np.linalg.norm(normal)
 | 
			
		||||
 | 
			
		||||
        # Create a vtkTransform
 | 
			
		||||
        transform = vtk.vtkTransform()
 | 
			
		||||
        transform.PostMultiply()  # This ensures transforms are applied in the order we specify
 | 
			
		||||
 | 
			
		||||
        # Rotate so that the normal aligns with the Z-axis
 | 
			
		||||
        rotation_axis = np.cross(normal, [0, 0, 1])
 | 
			
		||||
        angle = np.arccos(np.dot(normal, [0, 0, 1])) * 180 / np.pi  # Convert to degrees
 | 
			
		||||
 | 
			
		||||
        if np.linalg.norm(rotation_axis) > 1e-6:  # Check if rotation is needed
 | 
			
		||||
            transform.RotateWXYZ(angle, rotation_axis[0], rotation_axis[1], rotation_axis[2])
 | 
			
		||||
 | 
			
		||||
        # Get the transformation matrix
 | 
			
		||||
        matrix = transform.GetMatrix()
 | 
			
		||||
        local_matrix = [matrix.GetElement(i, j) for i in range(4) for j in range(4)]
 | 
			
		||||
 | 
			
		||||
        # Create a vtkPoints object to store the line points
 | 
			
		||||
        points = vtk.vtkPoints()
 | 
			
		||||
        points.InsertNextPoint(line_cell.GetPoints().GetPoint(0))
 | 
			
		||||
        points.InsertNextPoint(line_cell.GetPoints().GetPoint(1))
 | 
			
		||||
 | 
			
		||||
        # Create a vtkPolyData to represent the line
 | 
			
		||||
        polydata = vtk.vtkPolyData()
 | 
			
		||||
        polydata.SetPoints(points)
 | 
			
		||||
 | 
			
		||||
        # Create a vtkCellArray to store the line cell
 | 
			
		||||
        cells = vtk.vtkCellArray()
 | 
			
		||||
        cells.InsertNextCell(line_cell)
 | 
			
		||||
        polydata.SetLines(cells)
 | 
			
		||||
 | 
			
		||||
        # Apply the transform to the polydata
 | 
			
		||||
        transform_filter = vtk.vtkTransformPolyDataFilter()
 | 
			
		||||
        transform_filter.SetInputData(polydata)
 | 
			
		||||
        transform_filter.SetTransform(transform)
 | 
			
		||||
        transform_filter.Update()
 | 
			
		||||
 | 
			
		||||
        # Get the transformed points
 | 
			
		||||
        transformed_polydata = transform_filter.GetOutput()
 | 
			
		||||
        transformed_points = transformed_polydata.GetPoints()
 | 
			
		||||
 | 
			
		||||
        # Extract 2D coordinates
 | 
			
		||||
        xy_coordinates = []
 | 
			
		||||
        for i in range(transformed_points.GetNumberOfPoints()):
 | 
			
		||||
            point = transformed_points.GetPoint(i)
 | 
			
		||||
            xy_coordinates.append((point[0], point[1]))
 | 
			
		||||
 | 
			
		||||
        return xy_coordinates
 | 
			
		||||
 | 
			
		||||
    def project_2d_to_3d(self, xy_coordinates, normal):
 | 
			
		||||
        # Normalize the normal vector
 | 
			
		||||
        normal = np.array(normal)
 | 
			
		||||
@@ -494,6 +563,8 @@ class VTKWidget(QtWidgets.QWidget):
 | 
			
		||||
 | 
			
		||||
            # Ensure it's a line
 | 
			
		||||
            if cell.GetCellType() == vtk.VTK_LINE:
 | 
			
		||||
                self.selected_vtk_line.append(cell)
 | 
			
		||||
 | 
			
		||||
                # Get the two points of the line
 | 
			
		||||
                point_id1 = cell.GetPointId(0)
 | 
			
		||||
                point_id2 = cell.GetPointId(1)
 | 
			
		||||
@@ -533,9 +604,11 @@ class VTKWidget(QtWidgets.QWidget):
 | 
			
		||||
                if len(self.selected_edges) == 2:
 | 
			
		||||
                    self.compute_projection(False)
 | 
			
		||||
 | 
			
		||||
                elif len(self.selected_edges) > 2:
 | 
			
		||||
                    del self.selected_edges[0]
 | 
			
		||||
                    pass
 | 
			
		||||
                if len(self.selected_edges) > 2:
 | 
			
		||||
                    self.selected_vtk_line.clear()
 | 
			
		||||
                    self.selected_edges.clear()
 | 
			
		||||
                    self.clear_actors_projection()
 | 
			
		||||
                    self.clear_edge_select()
 | 
			
		||||
 | 
			
		||||
    def find_origin_vertex(self, edge1, edge2):
 | 
			
		||||
        if edge1[0] == edge2[0]or edge1[0] == edge2[1]:
 | 
			
		||||
@@ -559,6 +632,7 @@ class VTKWidget(QtWidgets.QWidget):
 | 
			
		||||
            self.renderer.RemoveActor(normals)
 | 
			
		||||
 | 
			
		||||
    def compute_projection(self, direction_invert: bool= False):
 | 
			
		||||
 | 
			
		||||
        # Compute the normal from the two selected edges        )
 | 
			
		||||
        edge1 = self.selected_edges[0][1] - self.selected_edges[0][0]
 | 
			
		||||
        edge2 = self.selected_edges[1][1] - self.selected_edges[1][0]
 | 
			
		||||
@@ -583,11 +657,14 @@ class VTKWidget(QtWidgets.QWidget):
 | 
			
		||||
        polydata = self.picker.GetActor().GetMapper().GetInput()
 | 
			
		||||
 | 
			
		||||
        projected_polydata = self.project_mesh_to_plane(polydata, self.selected_normal, self.centroid)
 | 
			
		||||
        projected_points = projected_polydata.GetPoints()
 | 
			
		||||
        #print("proj_points", projected_points)
 | 
			
		||||
 | 
			
		||||
        # Extract 2D coordinates
 | 
			
		||||
        self.project_tosketch_edge = self.compute_2d_coordinates(projected_polydata,  self.selected_normal)
 | 
			
		||||
        self.project_tosketch_points = self.compute_2d_coordinates(projected_polydata, self.selected_normal)
 | 
			
		||||
 | 
			
		||||
        # Seperately rotate selected edges for drawing
 | 
			
		||||
        for vtk_line in self.selected_vtk_line:
 | 
			
		||||
            proj_vtk_line = self.compute_2d_coordinates_line(vtk_line, self.selected_normal)
 | 
			
		||||
            self.project_tosketch_lines.append(proj_vtk_line)
 | 
			
		||||
 | 
			
		||||
        # Create a mapper and actor for the projected data
 | 
			
		||||
        mapper = vtk.vtkPolyDataMapper()
 | 
			
		||||
@@ -595,13 +672,14 @@ class VTKWidget(QtWidgets.QWidget):
 | 
			
		||||
 | 
			
		||||
        actor = vtk.vtkActor()
 | 
			
		||||
        actor.SetMapper(mapper)
 | 
			
		||||
        #actor.GetProperty().SetRenderLinesAsTubes(True)
 | 
			
		||||
        actor.GetProperty().SetColor(0.0, 1.0, 0.0)  # Set color to green
 | 
			
		||||
        actor.GetProperty().SetLineWidth(4)  # Set line width
 | 
			
		||||
        actor.GetProperty().SetLineWidth(8)  # Set line width
 | 
			
		||||
 | 
			
		||||
        self.renderer.AddActor(normal_actor)
 | 
			
		||||
        self.displayed_normal_actors.append(normal_actor)
 | 
			
		||||
 | 
			
		||||
        # Add the actor to the scene
 | 
			
		||||
        # Add the edge lines actor to the scene
 | 
			
		||||
        self.renderer.AddActor(actor)
 | 
			
		||||
        self.picked_edge_actors.append(actor)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										87
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								main.py
									
									
									
									
									
								
							@@ -133,11 +133,14 @@ class MainWindow(QMainWindow):
 | 
			
		||||
    def add_new_sketch_wp(self):
 | 
			
		||||
        self.sketchWidget.clear_sketch()
 | 
			
		||||
        #edges = [((-158.0, -20.0, -25.0), (286.0, -195.0, -25.0)), ((-158.0, -20.0, 25.0), (-158.0, -20.0, -25.0))]
 | 
			
		||||
        edges = self.custom_3D_Widget.project_tosketch_edge
 | 
			
		||||
        points = self.custom_3D_Widget.project_tosketch_points
 | 
			
		||||
        normal = self.custom_3D_Widget.selected_normal
 | 
			
		||||
        selected_lines = self.custom_3D_Widget.project_tosketch_lines
 | 
			
		||||
        print("Selected lines", selected_lines)
 | 
			
		||||
 | 
			
		||||
        self.sketchWidget.create_workplane_projected()
 | 
			
		||||
        self.sketchWidget.create_proj_lines(edges)
 | 
			
		||||
        self.sketchWidget.create_proj_points(points)
 | 
			
		||||
        self.sketchWidget.create_proj_lines(selected_lines)
 | 
			
		||||
 | 
			
		||||
        # CLear all selections after it has been projected
 | 
			
		||||
        #self.custom_3D_Widget.clear_edge_select()
 | 
			
		||||
@@ -377,7 +380,6 @@ class MainWindow(QMainWindow):
 | 
			
		||||
        selected = self.ui.sketch_list.currentItem()
 | 
			
		||||
        name = selected.text()
 | 
			
		||||
        points = self.model['sketch'][name]['sketch_points']
 | 
			
		||||
        lines = self.convert_lines_for_interactor()
 | 
			
		||||
 | 
			
		||||
        if points[-1] == points[0]:
 | 
			
		||||
            #detect loop that causes problems in mesh generation
 | 
			
		||||
@@ -391,12 +393,8 @@ class MainWindow(QMainWindow):
 | 
			
		||||
            length = 0
 | 
			
		||||
            print("Extrude cancelled")
 | 
			
		||||
 | 
			
		||||
        #Create and draw Interactor
 | 
			
		||||
        geo = Geometry()
 | 
			
		||||
 | 
			
		||||
        # Rotation is done in vtk matrix trans
 | 
			
		||||
        angle = 0
 | 
			
		||||
 | 
			
		||||
        normal = self.custom_3D_Widget.selected_normal
 | 
			
		||||
        print("Normie enter", normal)
 | 
			
		||||
        if normal is None:
 | 
			
		||||
@@ -407,20 +405,9 @@ class MainWindow(QMainWindow):
 | 
			
		||||
            centroid = [0, 0, 0]
 | 
			
		||||
        else:
 | 
			
		||||
            centroid = list(centroid)
 | 
			
		||||
        print("THis centroid ",centroid)
 | 
			
		||||
        print("This centroid ", centroid)
 | 
			
		||||
 | 
			
		||||
        f = geo.extrude_shape(points, length, angle, normal, centroid, is_symmetric, invert)
 | 
			
		||||
 | 
			
		||||
        z_origin = centroid[2]
 | 
			
		||||
        if is_symmetric:
 | 
			
		||||
            z_origin = z_origin - length / 2
 | 
			
		||||
 | 
			
		||||
        if invert:
 | 
			
		||||
            edges = interactor_mesh.generate_mesh(lines, z_origin, length, True)
 | 
			
		||||
        else:
 | 
			
		||||
            edges = interactor_mesh.generate_mesh(lines, z_origin, length, False)
 | 
			
		||||
 | 
			
		||||
        self.custom_3D_Widget.load_interactor_mesh(edges)
 | 
			
		||||
        f = geo.extrude_shape(points, length, normal, centroid, is_symmetric, invert, 0)
 | 
			
		||||
 | 
			
		||||
        name_op = f"extrd-{name}"
 | 
			
		||||
        element = {
 | 
			
		||||
@@ -428,7 +415,18 @@ class MainWindow(QMainWindow):
 | 
			
		||||
            'type': 'extrude',
 | 
			
		||||
            'sdf_object': f,
 | 
			
		||||
        }
 | 
			
		||||
        #print(element)
 | 
			
		||||
 | 
			
		||||
        ### Interactor
 | 
			
		||||
        lines = self.convert_lines_for_interactor()
 | 
			
		||||
 | 
			
		||||
        edges = interactor_mesh.generate_mesh(lines, 0, length)
 | 
			
		||||
 | 
			
		||||
        offset_vector = geo.vector_to_centroid(None, centroid, normal)
 | 
			
		||||
        #print("off_ved", offset_vector)
 | 
			
		||||
        if len(offset_vector) == 0 :
 | 
			
		||||
            offset_vector = [0, 0, 0]
 | 
			
		||||
 | 
			
		||||
        self.custom_3D_Widget.load_interactor_mesh(edges, offset_vector)
 | 
			
		||||
 | 
			
		||||
        self.model['operation'][name_op] = element
 | 
			
		||||
        self.ui.body_list.addItem(name_op)
 | 
			
		||||
@@ -500,7 +498,22 @@ class Geometry:
 | 
			
		||||
        print("p2", p2)
 | 
			
		||||
        return math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
 | 
			
		||||
 | 
			
		||||
    def extrude_shape(self, points, length: float, angle, normal, centroid, symet: bool = True, invert: bool = False):
 | 
			
		||||
    def vector_to_centroid(self, shape_center, centroid, normal):
 | 
			
		||||
 | 
			
		||||
        if not shape_center:
 | 
			
		||||
            # Calculate the current center of the shape
 | 
			
		||||
            shape_center = [0, 0, 0]
 | 
			
		||||
 | 
			
		||||
        # Calculate the vector from the shape's center to the centroid
 | 
			
		||||
        center_to_centroid = np.array(centroid) - np.array(shape_center)
 | 
			
		||||
 | 
			
		||||
        # Project this vector onto the normal to get the required translation along the normal
 | 
			
		||||
        translation_along_normal = np.dot(center_to_centroid, normal) * normal
 | 
			
		||||
 | 
			
		||||
        return translation_along_normal
 | 
			
		||||
 | 
			
		||||
    def extrude_shape(self, points, length: float, normal, centroid, symet: bool = True, invert: bool = False,
 | 
			
		||||
                      offset_length: float = None):
 | 
			
		||||
        """
 | 
			
		||||
        Extrude a 2D shape into 3D, orient it along the normal, and position it relative to the centroid.
 | 
			
		||||
        """
 | 
			
		||||
@@ -520,17 +533,29 @@ class Geometry:
 | 
			
		||||
        # Orient the shape along the normal vector
 | 
			
		||||
        f = f.orient(normal)
 | 
			
		||||
 | 
			
		||||
        # Calculate the current center of the shape
 | 
			
		||||
        shape_center = [0,0,0]
 | 
			
		||||
        offset_vector = self.vector_to_centroid(None, centroid, normal)
 | 
			
		||||
        # Adjust the offset vector by subtracting the inset distance along the normal direction
 | 
			
		||||
        adjusted_offset = offset_vector - (normal * length)
 | 
			
		||||
        if invert:
 | 
			
		||||
            # Translate the shape along the adjusted offset vector
 | 
			
		||||
            f = f.translate(adjusted_offset)
 | 
			
		||||
        else:
 | 
			
		||||
            f = f.translate(offset_vector)
 | 
			
		||||
 | 
			
		||||
        # Calculate the vector from the shape's center to the centroid
 | 
			
		||||
        center_to_centroid = np.array(centroid) - np.array(shape_center)
 | 
			
		||||
        # If offset_length is provided, adjust the offset_vector
 | 
			
		||||
        if offset_length is not None:
 | 
			
		||||
            # Check if offset_vector is not a zero vector
 | 
			
		||||
            offset_vector_magnitude = np.linalg.norm(offset_vector)
 | 
			
		||||
            if offset_vector_magnitude > 1e-10:  # Use a small threshold to avoid floating-point issues
 | 
			
		||||
                # Normalize the offset vector
 | 
			
		||||
                offset_vector_norm = offset_vector / offset_vector_magnitude
 | 
			
		||||
                # Scale the normalized vector by the desired length
 | 
			
		||||
                offset_vector = offset_vector_norm * offset_length
 | 
			
		||||
                f = f.translate(offset_vector)
 | 
			
		||||
            else:
 | 
			
		||||
                print("Warning: Offset vector has zero magnitude. Using original vector.")
 | 
			
		||||
 | 
			
		||||
        # Project this vector onto the normal to get the required translation along the normal
 | 
			
		||||
        translation_along_normal = np.dot(center_to_centroid, normal) * normal
 | 
			
		||||
 | 
			
		||||
        # Translate the shape along the normal
 | 
			
		||||
        f = f.translate(translation_along_normal)
 | 
			
		||||
        # Translate the shape along the adjusted offset vector
 | 
			
		||||
 | 
			
		||||
        return f
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,9 @@
 | 
			
		||||
# Draw simple boundary based on the lines and depth
 | 
			
		||||
 | 
			
		||||
def generate_mesh(lines: list, z_origin: float, depth: float, invert :bool = False):
 | 
			
		||||
def generate_mesh(lines: list, z_origin: float, depth: float, invert: bool = False):
 | 
			
		||||
 | 
			
		||||
    origin = create_3D(lines, z_origin)
 | 
			
		||||
 | 
			
		||||
    if invert :
 | 
			
		||||
        extruded = create_3D(lines, z_origin - depth)
 | 
			
		||||
    else:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user