def _translate_bezier_curve_by_vector(self, desloc_x: float, desloc_y: float, desloc_z: float) -> Line: '''Translate internal object when is a curve and return copy''' new_setups = [] for setup in self._object.curves: points = [setup.P1, setup.P2, setup.P3, setup.P4] new_points = translate_points(points, desloc_x, desloc_y, desloc_z) new_setups.append( BezierCurveSetup(P1=new_points[0], P2=new_points[1], P3=new_points[2], P4=new_points[3])) new_curve = deepcopy(self._object) new_curve.curves = new_setups return new_curve
def _rotate_internal_bezier_curve_over_point(self, angle: float, point: Point3D) -> Line: '''Rotate when internal is a Line and return copy of object''' new_setups = [] for setup in self._object.curves: points = [setup.P1, setup.P2, setup.P3, setup.P4] new_points = rotate_points_over_point_by_degrees( points, point, angle, self._rotation_axis) new_setups.append( BezierCurveSetup(P1=new_points[0], P2=new_points[1], P3=new_points[2], P4=new_points[3])) new_curve = deepcopy(self._object) new_curve.curves = new_setups return new_curve
def create_curve(name: str, tab: CurveTab) -> BezierCurve: """Create a bezier curve, compsoed by multipe P1 to P4 points""" points_groups = tab.curves_list setups: List[BezierCurveSetup] = [] for group in points_groups: p1 = group['P1'] p2 = group['P2'] p3 = group['P3'] p4 = group['P4'] setup = BezierCurveSetup( P1=Point3D('__', x=p1['x'], y=p1['y'], z=p1['z']), P2=Point3D('__', x=p2['x'], y=p2['y'], z=p2['z']), P3=Point3D('__', x=p3['x'], y=p3['y'], z=p3['z']), P4=Point3D('__', x=p4['x'], y=p4['y'], z=p4['z']), ) setups.append(setup) return BezierCurve(name=name, curve_setups=setups)
def _rotate_internal_bezier_curve_over_center(self, angle: float) -> BezierCurve: '''Rotate a bezier curve over the center os the points from setups''' center = self.get_object_geometric_center() new_setups = [] for setup in self._object.curves: points = [setup.P1, setup.P2, setup.P3, setup.P4] new_points = rotate_points_over_point_by_degrees( points, center, angle, self._rotation_axis) new_setups.append( BezierCurveSetup(P1=new_points[0], P2=new_points[1], P3=new_points[2], P4=new_points[3])) new_curve = deepcopy(self._object) new_curve.curves = new_setups return new_curve
def _scale_bezier_curve(self, scale_x: float, scale_y: float, scale_z: float) -> BezierCurve: '''Scale internal when is a wireframe and return copy''' new_setups = [] for setup in self._object.curves: points = [setup.P1, setup.P2, setup.P3, setup.P4] new_points = scale_points_by_point( points=points, point=self.get_object_geometric_center(), scale_x=scale_x, scale_y=scale_y, scale_z=scale_z) new_setups.append( BezierCurveSetup(P1=new_points[0], P2=new_points[1], P3=new_points[2], P4=new_points[3])) new_curve = deepcopy(self._object) new_curve.curves = new_setups return new_curve
def _import_from_file(self, file: str): '''Call wavefront loaders''' geoms = read_wavefront(file) for name, props in geoms.items(): if not 'v' and not 'cstype' in props: logger.error( f'Failed to load: {name}, no vertexes and its not a curve!' ) continue points: List[Point3D] = [] if 'v' in props: # its a point, line or polygon for x, y, z in props['v']: points.append(Point3D(name='', x=x, y=y, z=z)) if 'curv2' in props: for x, y, z in props['curv2']: points.append(Point3D(name='', x=x, y=y, z=z)) color = QColor(0, 0, 0) if 'material' in props and 'Kd' in props['material']: r, g, b = props['material']['Kd'] color = QColor(255 * r, 255 * g, 255 * b) if not self._validate_new_name(name): i = 1 new_name = f'{name}({i})' while not self._validate_new_name(new_name): i += 1 new_name = f'{name}({i})' name = new_name if len(points) == 1: # Is a point point = points[0] point.name = name point.color = color self.add_object_to_list(point) elif len(points) == 2: # Is a line line = Line(name=name, p1=points[0], p2=points[1]) line.color = color self.add_object_to_list(line) elif len(points) > 2: if props['cstype'] == 'bezier': beziersetup = [] for i in range(0, len(points), 4): p1 = points[i] p2 = points[i + 1] p3 = points[i + 2] p4 = points[i + 3] beziersetup.append(BezierCurveSetup(p1, p2, p3, p4)) bezier = BezierCurve(name=name, curve_setups=beziersetup) bezier.color = color self.add_object_to_list(bezier) elif props['cstype'] == 'bspline': bspline = BSplineCurve(name=name, control_points=points) bspline.color = color self.add_object_to_list(bspline) elif props['number_faces'] > 1: # its a 3d object faces = props['faces'] object3d = Object3D(name=name, points=points, faces=faces) object3d.color = color self.add_object_to_list(object3d) else: # Is a wireframe wireframe = Wireframe(name=name, points=points) wireframe.color = color self.add_object_to_list(wireframe)
def apply_matrix_to_objects( self, project_matrix: np.array ) -> Union[Point3D, Line, Wireframe, BezierCurve, BSplineCurve, Object3D]: '''Apply matrix to intern list of objects''' projected_objects = [] for obj in self._objects: if isinstance(obj, Point3D): new_point = transform([obj], project_matrix)[0] new_point.color = obj.color projected_objects.append(new_point) elif isinstance(obj, Line): new_points = transform(obj.points, project_matrix) new_obj = deepcopy(obj) new_obj.p1 = new_points[0] new_obj.p2 = new_points[1] projected_objects.append(new_obj) elif isinstance(obj, Wireframe) or \ isinstance(obj, Object3D) or isinstance(obj, BicubicSurface): new_points = transform(obj.points, project_matrix) new_obj = deepcopy(obj) new_obj.points = new_points projected_objects.append(new_obj) elif isinstance(obj, BSplineCurve): new_points = transform(obj.control_points, project_matrix) new_obj = deepcopy(obj) new_obj.points = new_points projected_objects.append(new_obj) elif isinstance(obj, BezierCurve): new_setups = [] for setup in obj.curves: points = [setup.P1, setup.P2, setup.P3, setup.P4] new_points = transform(points, project_matrix) new_setups.append( BezierCurveSetup(P1=new_points[0], P2=new_points[1], P3=new_points[2], P4=new_points[3])) new_curve = deepcopy(obj) new_curve.curves = new_setups projected_objects.append(new_curve) # elif isinstance(obj, BicubicSurface): # new_setups = [] # setup = obj.setup # points = [setup.P1, setup.P2, setup.P3, setup.P4,setup.P5, setup.P6, setup.P7, setup.P8,setup.P9, setup.P10, # setup.P11, setup.P12,setup.P13, setup.P14, setup.P15, setup.P16] # new_points = transform(points, project_matrix) # new_setups.append(BicubicSetup( # P1=new_points[0], # P2=new_points[1], # P3=new_points[2], # P4=new_points[3], # P5=new_points[4], # P6=new_points[5], # P7=new_points[6], # P8=new_points[7], # P9=new_points[8], # P10=new_points[9], # P11=new_points[2], # P12=new_points[3], # P13=new_points[0], # P14=new_points[1], # P15=new_points[2], # P16=new_points[3] # )) # new_surface = deepcopy(obj) # new_surface.setups = new_setups # projected_objects.append(new_surface) else: raise ValueError('Invalid object to project') return projected_objects
def rotate_by_degrees_arbitrary_axis(self, p: Point3D, a: Point3D, angle: float): '''Rotate points of a object over arbitrary angle''' a_moved = transform([a], get_translation_matrix(-p.x, -p.y, -p.z))[0] if a_moved.x != 0: angle_of_a_with_x = degrees(atan(a_moved.z / a_moved.x)) else: angle_of_a_with_x = degrees(atan(a_moved.z / a_moved.y)) obj_to_xy_matrix = get_rx_rotation_matrix_from_degrees( -angle_of_a_with_x) a_in_xy = transform([a_moved], obj_to_xy_matrix)[0] angle_of_a_in_xy_with_y = degrees(atan(a_in_xy.x / a_in_xy.y)) matrix = concat_transformation_matrixes([ get_translation_matrix(-p.x, -p.y, -p.z), get_rx_rotation_matrix_from_degrees(-angle_of_a_with_x), get_rz_rotation_matrix_from_degrees(angle_of_a_in_xy_with_y), get_ry_rotation_matrix_from_degrees(angle), get_rz_rotation_matrix_from_degrees(-angle_of_a_in_xy_with_y), get_rx_rotation_matrix_from_degrees(angle_of_a_with_x), get_translation_matrix(p.x, p.y, p.z) ]) if isinstance(self._object, Point3D): new_point = transform([self._object], matrix)[0] intern = self._intern_copy() intern.x = new_point.x intern.y = new_point.y intern.z = new_point.z return intern if isinstance(self._object, Line): new_points = transform(self._object.points(), matrix) new_line = self._intern_copy() new_line.p1 = new_points[0] new_line.p2 = new_points[1] return new_line if isinstance(self._object, Wireframe) \ or isinstance(self._object, Object3D) \ or isinstance(self._object, BSplineCurve): new_points = transform(self._object.points, matrix) new_obj = self._intern_copy() new_obj.points = new_points return new_obj if isinstance(self._object, BezierCurve): new_setups = [] for setup in self._object.curves: points = [setup.P1, setup.P2, setup.P3, setup.P4] new_points = transform(points, matrix) new_setups.append( BezierCurveSetup(P1=new_points[0], P2=new_points[1], P3=new_points[2], P4=new_points[3])) new_curve = self._intern_copy new_curve.curves = new_setups return new_curve