Пример #1
0
    def get_clipped(self) -> Optional[Line]:
        '''Return the line clipped if is inside the setup'''
        if not self.is_inside:
            return None

        positives = [
            d for d in self.pq_list if not close_to_zero(d['p']) and d['p'] > 0
        ]
        negatives = [
            d for d in self.pq_list if not close_to_zero(d['p']) and d['p'] < 0
        ]

        positives = [d['q'] / d['p'] for d in positives]
        negatives = [d['q'] / d['p'] for d in negatives]

        u1 = max([0] + negatives)
        u2 = min([1] + positives)

        if u1 > u2:
            return None

        new_line = deepcopy(self.line)

        new_line.p1 = Point3D(name='_p1',
                              x=self.line.p1.x + self.pq_list[1]['p'] * u1,
                              y=self.line.p1.y + self.pq_list[3]['p'] * u1,
                              z=0)

        new_line.p2 = Point3D(name='_p2',
                              x=self.line.p1.x + self.pq_list[1]['p'] * u2,
                              y=self.line.p1.y + self.pq_list[3]['p'] * u2,
                              z=0)

        return new_line
Пример #2
0
    def __init__(self, wireframe: Wireframe, setup: ClipperSetup):
        '''Initialize with internal properties'''
        self.setup = setup

        self.wireframe = wireframe

        self.top_left = Point3D('tl', x=setup.xmin, y=setup.ymax, z=0)
        self.top_right = Point3D('tr', x=setup.xmax, y=setup.xmax, z=0)
        self.bot_right = Point3D('br', x=setup.xmax, y=setup.ymin, z=0)
        self.bot_left = Point3D('bl', x=setup.xmin, y=setup.ymin, z=0)
Пример #3
0
    def viewpoert_transform_point(self, point: Point3D):
        """
        Apply viewport transformation to a point

        Parameters
        ----------
        p: Point3D

        Return
        ----------
        UnamedPoint3D(x, y) transformed to current viewport
        """

        # xwmax = self.window_xmax
        # ywmax = self.window_ymax
        # xwmin = self.window_xmin
        # ywmin = self.window_ymin
        xwmax = 1
        ywmax = 1
        xwmin = -1
        ywmin = -1

        xvpmax = self.xvp_max
        yvpmax = self.yvp_max
        xvpmin = self.xvp_min
        yvpmin = self.yvp_min

        xvp = ((point.x - xwmin)/(xwmax - xwmin)) * \
            (xvpmax - xvpmin) + xvpmin
        yvp = (1 - ((point.y - ywmin)/(ywmax - ywmin))) * \
            (yvpmax - yvpmin) + yvpmin

        return Point3D(name=point.name, x=xvp, y=yvp, z=point.z)
Пример #4
0
def create_line(name: str, tab: LineTab) -> Line:
    """
    Create Line object
    """
    x1 = int(tab.start_x_coord_line_input.text())
    y1 = int(tab.start_y_coord_line_input.text())
    z1 = int(tab.start_z_coord_line_input.text())

    x2 = int(tab.end_x_coord_line_input.text())
    y2 = int(tab.end_y_coord_line_input.text())
    z2 = int(tab.end_z_coord_line_input.text())

    p1 = Point3D('_p1', x1, y1, z1)
    p2 = Point3D('_p2', x2, y2, z2)

    return Line(name, p1, p2)
Пример #5
0
def create_point3D(name: str, tab: PointTab) -> Point3D:
    """
    Create Point3D object
    """
    x = int(tab.x_coord_pt_input.text())
    y = int(tab.y_coord_pt_input.text())
    z = int(tab.z_coord_pt_input.text())
    return Point3D(name, x, y, z)
Пример #6
0
def create_bspline(obj_name: str, tab: BSplineTab) -> BSplineCurve:
    '''Take BSpline tab and create the BSpline object'''
    points = []
    for i, point in enumerate(tab.points_list):
        x, y, z = point
        point = Point3D('Po' + str(i).zfill(3), x, y, z)
        points.append(point)

    return BSplineCurve(name=obj_name, control_points=points)
Пример #7
0
    def VPN(self) -> Tuple[Point3D, Point3D]:
        '''Return VRP and a Point3D'''
        vrp = self.VRP
        vpn = (vrp,
               Point3D('_vpn_end',
                       x=self._vpn_dir.x + vrp.x,
                       y=self._vpn_dir.y + vrp.y,
                       z=self._vpn_dir.z + vrp.z))

        return vpn
Пример #8
0
def create_wireframe(name: str, tab: WireframeTab) -> Wireframe:
    """
    Create Wireframe object
    """
    points = []
    for i, point in enumerate(tab.points_list):
        x, y, z = point
        point = Point3D('Po' + str(i).zfill(3), x, y, z)
        points.append(point)

    return Wireframe(name, points)
Пример #9
0
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)
Пример #10
0
def create_3dobject(obj_name: str, tab: _3dObjectTab) -> Object3D:
    '''Take 3D object tab and create the 3d object'''
    points = []
    faces = []

    for i, point in enumerate(tab.points_list_3d):
        x, y, z = point
        point = Point3D('Po' + str(i).zfill(3), x, y, z)
        points.append(point)
    
    faces = tab.faces_list_3d

    return Object3D(name=obj_name, points=points, faces=faces)
Пример #11
0
def create_bicubicSurface(obj_name: str, tab: _BicubicTab) -> BicubicSurface:
    '''Take 3D object tab and create the 3d object'''
    points = []

    for i, point in enumerate(tab.points_list):
        x, y, z = point
        point = Point3D('Po' + str(i).zfill(3), x, y, z)
        points.append(point)

    setup = BicubicSetup(points[0],points[1],points[2],points[3],points[4],points[5],points[6],
                        points[7],points[8],points[9],points[10],points[11],points[12],points[13],
                        points[14],points[15])

    return BicubicSurface(name=obj_name, setup=setup)
Пример #12
0
    def _rotate_internal_point_over_origin(self, angle: float) -> Point3D:
        '''Rotate when internal is a point and return copy of object'''
        if not isinstance(self._object, Point3D):
            error = 'Trying to operate as point over:'
            raise TypeError(error + str(type(self._object)))

        rotated = rotate_points_over_point_by_degrees(
            points=[self._object],
            point=Point3D('_', 0, 0, 0),
            angle=angle,
            rotation_axis=self._rotation_axis)[0]

        rotated.color = self._object.color
        return rotated
Пример #13
0
    def transform_rotate(self, obj, tab):
        '''Apply rotate transformation'''
        transformator = Transformator(obj)
        angle = float(tab.degrees_input.text())
        axis = tab.get_axis()

        if axis == 'arbitrary':
            p = Point3D(name='__p',
                        x=int(tab.p_x_input.text()),
                        y=int(tab.p_y_input.text()),
                        z=int(tab.p_z_input.text()))
            a = Point3D(name='__a',
                        x=int(tab.a_x_input.text()),
                        y=int(tab.a_y_input.text()),
                        z=int(tab.a_z_input.text()))

            new_obj = transformator.rotate_by_degrees_arbitrary_axis(
                p, a, angle)

        elif tab.over_obj_center_radio_btn.isChecked():
            new_obj = transformator.rotate_by_degrees_geometric_center(
                angle, axis)

        elif tab.over_world_center_radio_btn.isChecked():
            new_obj = transformator.rotate_by_degrees_origin(angle, axis)

        else:  # tab.over_point_radio_btn.isChecked()
            x = float(tab.x_input.text())
            y = float(tab.y_input.text())
            z = 0  # float(tab.z_input.text())
            new_obj = transformator.rotate_by_degrees_point(
                angle, Point3D('rotationPoint', x, y, z), axis)

        # inserting new obj in the same index as the transformed obj
        index = self.display_file.index(obj)
        self.display_file.pop(index)
        self.display_file.insert(index, new_obj)
Пример #14
0
def transform(points: List[Point3D], matrix: np.ndarray) -> List[Point3D]:
    '''Apply transformation'''
    new_points: List[Point3D] = []

    for point in points:
        np_point = np.array([point.x, point.y, point.z, 1])
        new_point = np_point.dot(matrix)
        w = new_point[-1]
        new_points.append(
            Point3D(name=point.name,
                    x=new_point[0] / w,
                    y=new_point[1] / w,
                    z=new_point[2] / w))

    return new_points
Пример #15
0
    def get_object_geometric_center(self) -> Point3D:
        '''Get geometrix center of intern object'''
        if isinstance(self._object, Point3D):
            points = [self._object]

        elif isinstance(self._object, BezierCurve):
            points = []
            for setup in self._object.curves:
                points.extend([setup.P1, setup.P2, setup.P3, setup.P4])

        else:  # Wireframe and BSpline
            points = self._object.points

        return Point3D(name='_geometric_center',
                       x=mean(map(lambda p: p.x, points)),
                       y=mean(map(lambda p: p.y, points)),
                       z=mean(map(lambda p: p.z, points)))
Пример #16
0
    def _rotate_internal_wireframe_over_origin(self,
                                               angle: float) -> Wireframe:
        '''Rotate when internal is a Wireframe and return copy of object'''
        if isinstance(self._object, Point3D):
            error = 'Trying to operate as line/wireframe over point'
            raise TypeError(error)

        new_points = rotate_points_over_point_by_degrees(
            points=self._object.points,
            point=Point3D('_', 0, 0, 0),
            angle=angle,
            rotation_axis=self._rotation_axis)

        new_obj = self._intern_copy()
        new_obj.points = new_points

        return new_obj
Пример #17
0
    def _rotate_internal_bezier_curve_over_origin(self,
                                                  angle: float) -> BezierCurve:
        '''Rotate when internal is a curve 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, Point3D('_', 0, 0, 0), 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
Пример #18
0
    def _rotate_internal_line_over_origin(self, angle: float) -> Line:
        '''Rotate when internal is a Line and return copy of object'''
        if isinstance(self._object, Point3D):
            error = 'Trying to operate as line/wireframe over point'
            raise TypeError(error)

        new_points = rotate_points_over_point_by_degrees(
            points=self._object.points,
            point=Point3D('_', 0, 0, 0),
            angle=angle,
            rotation_axis=self._rotation_axis)

        line = Line(
            name=self._object.name,
            p1=new_points[0],
            p2=new_points[1],
        )
        line.color = self._object.color

        return line
Пример #19
0
    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)
Пример #20
0
    def __init__(self):
        # Init the models structure
        self.display_file = []

        # Angle between the Vup vector and the world Y axis
        self._vup_angle_degrees = 0

        self._proj_type = _ProjectionType.PARALEL

        # Init main interface
        self.app = QApplication(sys.argv)

        self.main_window = MainWindow()
        self.main_window.show()
        self._add_main_window_handlers()

        # Instantiate dialog for adding objects
        self.add_object_dialog = NewObjectDialog()
        self.add_object_dialog.show()
        self.add_object_dialog.setVisible(False)
        self._add_new_obj_dialog_handlers()

        # Instantiate dialog to input transformations
        self.transform_dialog = TransformationDialog()
        self.transform_dialog.show()
        self.transform_dialog.setVisible(False)
        self._add_transform_dialog_handlers()

        # Initial window settings
        self.window_xmin = -300
        self.window_ymin = -300
        self.window_xmax = 300
        self.window_ymax = 300
        self._vrp_z = 500

        # Point to be the second extreme of the VPN
        self._vpn_dir = Point3D('_vpn_direction', x=0, y=0, z=-1)

        # Viewport values
        self.xvp_min = 10  # it was 0, changed for clipping proof
        self.yvp_min = 10  # it was 0, changed for clipping proof
        self.xvp_max = 590  # it was 600, changed for clipping proof
        self.yvp_max = 590  # it was 600, changed for clipping proof

        # self.add_object_to_list(
        #    BSplineCurve('Spline',
        #                 points=[
        #                     Point3D('_', x=0, y=0, z=0),
        #                     Point3D('_', x=-100, y=200, z=0),
        #                     Point3D('_', x=-200, y=0, z=0),
        #                     Point3D('_', x=-300, y=-200, z=0),
        #                     Point3D('_', x=-400, y=0, z=0),
        #                     Point3D('_', x=-500, y=500, z=0),
        #                 ])
        # )

        # self.add_object_to_list(
        #     Object3D(
        #         name='Objeto3D',
        #         points=[
        #             Point3D('0', x=0, y=0, z=0),
        #             Point3D('1', x=100, y=0, z=0),
        #             Point3D('2', x=100, y=100, z=0),
        #             Point3D('3', x=0, y=100, z=0),
        #             Point3D('4', x=0, y=0, z=100),
        #             Point3D('5', x=100, y=0, z=100),
        #             Point3D('6', x=100, y=100, z=100),
        #             Point3D('7', x=0, y=100, z=100),
        #         ],
        #         faces=[
        #             [0, 1, 2, 3],
        #             [0, 1, 5, 4],
        #             [0, 4, 7, 3],
        #             [3, 2, 6, 7],
        #             [1, 5, 6, 2],
        #             [4, 5, 6, 7]
        #         ]
        #     )
        # )

        # self.add_object_to_list(
        #     BSplineCurve('Spline',
        #                  control_points=[
        #                      Point3D('_', x=0, y=0, z=0),
        #                      Point3D('_', x=-100, y=200, z=0),
        #                      Point3D('_', x=-200, y=0, z=0),
        #                      Point3D('_', x=-300, y=-200, z=0),
        #                      Point3D('_', x=-400, y=0, z=0),
        #                      Point3D('_', x=-500, y=500, z=0),
        #                  ])
        # )

        # self.add_object_to_list(
        #     BicubicSurface('bicubic',
        #                  setup=BicubicSetup(
        #                      Point3D('_', x=0, y=0, z=0),
        #                      Point3D('_', x=-100, y=0, z=0),
        #                      Point3D('_', x=-200, y=0, z=0),
        #                      Point3D('_', x=-300, y=0, z=0),
        #                      Point3D('_', x=-400, y=0, z=0),
        #                      Point3D('_', x=-500, y=0, z=0),
        #                      Point3D('_', x=0, y=100, z=0),
        #                      Point3D('_', x=0, y=200, z=0),
        #                      Point3D('_', x=0, y=300, z=0),
        #                      Point3D('_', x=0, y=400, z=0),
        #                      Point3D('_', x=0, y=500, z=0),
        #                      Point3D('_', x=0, y=0, z=100),
        #                      Point3D('_', x=0, y=0, z=200),
        #                      Point3D('_', x=0, y=0, z=300),
        #                      Point3D('_', x=0, y=0, z=400),
        #                      Point3D('_', x=0, y=0, z=500),
        #                     ))
        # )

        self._process_viewport()
Пример #21
0
 def VRP(self) -> Point3D:
     '''Return window center'''
     wcx = (self.window_xmax + self.window_xmin) / 2
     wcy = (self.window_ymax + self.window_ymin) / 2
     return Point3D('VPN_start', x=wcx, y=wcy, z=self._vrp_z)