Beispiel #1
0
    def test_203_Bingol_3D_surface(self):
        """Tests creation and plotting of BSpline surface, compared to
        GitHub repository orbingol
        https://nurbs-python.readthedocs.io/en/5.x/visualization-3.py

        Example usage:

        $ conda activate nurbspyenv
        $ cd nurbspy/
        $ python
        > from geomdl import BSpline
        > from geomdl.visualization import VisMPL as vis
        >
        > surf = BSpline.Surface()
        >
        > surf.degree_u = 3
        > surf.degree_v = 3
        >
        > control_points = [
            [
                [-25.0, -25.0, -10.0],
                [-25.0, -15.0, -5.0],
                [-25.0, -5.0, 0.0],
                [-25.0, 5.0, 0.0],
                [-25.0, 15.0, -5.0],
                [-25.0, 25.0, -10.0]
            ],
            [
                [-15.0, -25.0, -8.0],
                [-15.0, -15.0, -4.0],
                [-15.0, -5.0, -4.0],
                [-15.0, 5.0, -4.0],
                [-15.0, 15.0, -4.0],
                [-15.0, 25.0, -8.0]
            ],
            [
                [-5.0, -25.0, -5.0],
                [-5.0, -15.0, -3.0],
                [-5.0, -5.0, -8.0],
                [-5.0, 5.0, -8.0],
                [-5.0, 15.0, -3.0],
                [-5.0, 25.0, -5.0]
            ],
            [
                [5.0, -25.0, -3.0],
                [5.0, -15.0, -2.0],
                [5.0, -5.0, -8.0],
                [5.0, 5.0, -8.0],
                [5.0, 15.0, -2.0],
                [5.0, 25.0, -3.0]
            ],
            [
                [15.0, -25.0, -8.0],
                [15.0, -15.0, -4.0],
                [15.0, -5.0, -4.0],
                [15.0, 5.0, -4.0],
                [15.0, 15.0, -4.0],
                [15.0, 25.0, -8.0]
            ],
            [
                [25.0, -25.0, -10.0],
                [25.0, -15.0, -5.0],
                [25.0, -5.0, 2.0],
                [25.0, 5.0, 2.0],
                [25.0, 15.0, -5.0],
                [25.0, 25.0, -10.0]
            ]
        ]
        > surf.ctrlpts2d = control_points
        > surf.knotvector_u = [0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 3.0, 3.0]
        > surf.knotvector_v = [0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 3.0, 3.0]
        > surf.delta = 1.0/7.0  # seven intervals for testing, originally 0.025 for smoothness
        > surf.evaluate()

        > surf.vis = vis.VisSurface(vis.VisConfig(alpha=0.8))
        >
        > surface_points = surf.evalpts
        > surf.render()
        # delta of 1.0 / 7.0
        # gives a matrix of [7x7] evalution (x, y, z) points found by
        > surf.evalpts
        > len(surf.evalpts)  # is 49, a 7x7 grid
        """
        kv_t = tuple(map(float, [0, 0, 0, 0, 1, 2, 3, 3, 3, 3]))  # cubic
        kv_u = tuple(map(float, [0, 0, 0, 0, 1, 2, 3, 3, 3, 3]))  # cubic
        control_points = (
            (
                (-25.0, -25.0, -10.0),
                (-25.0, -15.0, -5.0),
                (-25.0, -5.0, 0.0),
                (-25.0, 5.0, 0.0),
                (-25.0, 15.0, -5.0),
                (-25.0, 25.0, -10.0),
            ),
            (
                (-15.0, -25.0, -8.0),
                (-15.0, -15.0, -4.0),
                (-15.0, -5.0, -4.0),
                (-15.0, 5.0, -4.0),
                (-15.0, 15.0, -4.0),
                (-15.0, 25.0, -8.0),
            ),
            (
                (-5.0, -25.0, -5.0),
                (-5.0, -15.0, -3.0),
                (-5.0, -5.0, -8.0),
                (-5.0, 5.0, -8.0),
                (-5.0, 15.0, -3.0),
                (-5.0, 25.0, -5.0),
            ),
            (
                (5.0, -25.0, -3.0),
                (5.0, -15.0, -2.0),
                (5.0, -5.0, -8.0),
                (5.0, 5.0, -8.0),
                (5.0, 15.0, -2.0),
                (5.0, 25.0, -3.0),
            ),
            (
                (15.0, -25.0, -8.0),
                (15.0, -15.0, -4.0),
                (15.0, -5.0, -4.0),
                (15.0, 5.0, -4.0),
                (15.0, 15.0, -4.0),
                (15.0, 25.0, -8.0),
            ),
            (
                (25.0, -25.0, -10.0),
                (25.0, -15.0, -5.0),
                (25.0, -5.0, 2.0),
                (25.0, 5.0, 2.0),
                (25.0, 15.0, -5.0),
                (25.0, 25.0, -10.0),
            ),
        )
        degree_t = 3  # cubic
        degree_u = 3  # cubic
        nbi = 1  # number of bisections per knot interval

        S = bsp.Surface(
            kv_t,
            kv_u,
            control_points,
            degree_t,
            degree_u,
            n_bisections=nbi,
            verbose=True,
        )

        (
            calc_surface_evaluations_x,
            calc_surface_evaluations_y,
            calc_surface_evaluations_z,
        ) = S.evaluations

        known_surface_evaluation_points = np.array([
            [-25.0, -25.0, -10.0],
            [-25.0, -13.229166666666668, -4.21875],
            [-25.0, -5.833333333333334, -1.25],
            [-24.999999999999993, 4.440892098500626e-16, -0.3124999999999999],
            [-25.0, 5.833333333333331, -1.2499999999999996],
            [-25.0, 13.22916666666667, -4.218750000000002],
            [-25.0, 25.0, -10.0],
            [-13.229166666666668, -25.0, -7.364583333333334],
            [-13.229166666666668, -13.229166666666668, -4.4912109375],
            [-13.229166666666668, -5.833333333333334, -4.424479166666667],
            [-13.229166666666664, 4.440892098500626e-16, -4.574869791666666],
            [-13.229166666666666, 5.833333333333331, -4.424479166666667],
            [-13.229166666666668, 13.22916666666667, -4.491210937500001],
            [-13.229166666666668, 25.0, -7.364583333333334],
            [-5.833333333333334, -25.0, -5.416666666666667],
            [-5.833333333333334, -13.229166666666668, -4.476562500000001],
            [-5.833333333333334, -5.833333333333334, -6.020833333333333],
            [-5.833333333333333, 4.440892098500626e-16, -6.755208333333332],
            [-5.833333333333333, 5.833333333333332, -6.020833333333333],
            [-5.833333333333334, 13.229166666666671, -4.4765625],
            [-5.833333333333334, 25.0, -5.416666666666667],
            [4.440892098500626e-16, -24.999999999999993, -4.249999999999999],
            [4.440892098500626e-16, -13.229166666666666, -4.2509765625],
            [4.440892098500626e-16, -5.833333333333333, -6.460937499999998],
            [
                3.3306690738754696e-16, 4.440892098500625e-16,
                -7.4277343749999964
            ],
            [3.3306690738754696e-16, 5.83333333333333, -6.460937499999998],
            [4.440892098500626e-16, 13.229166666666668, -4.250976562499999],
            [4.440892098500626e-16, 24.999999999999993, -4.249999999999999],
            [5.833333333333331, -25.0, -4.583333333333332],
            [5.833333333333332, -13.229166666666666, -4.125],
            [5.833333333333331, -5.833333333333333, -5.916666666666666],
            [5.83333333333333, 4.4408920985006257e-16, -6.729166666666664],
            [5.83333333333333, 5.83333333333333, -5.916666666666666],
            [5.833333333333331, 13.229166666666668, -4.124999999999999],
            [5.833333333333331, 25.0, -4.583333333333332],
            [13.22916666666667, -25.0, -6.885416666666668],
            [13.22916666666667, -13.229166666666668, -4.21875],
            [13.22916666666667, -5.833333333333334, -4.177083333333332],
            [13.229166666666668, 4.440892098500626e-16, -4.325520833333332],
            [13.229166666666668, 5.833333333333331, -4.177083333333332],
            [13.22916666666667, 13.22916666666667, -4.218750000000001],
            [13.22916666666667, 25.0, -6.885416666666668],
            [25.0, -25.0, -10.0],
            [25.0, -13.229166666666668, -3.65625],
            [25.0, -5.833333333333334, 0.25000000000000006],
            [24.999999999999993, 4.440892098500626e-16, 1.5624999999999998],
            [25.0, 5.833333333333331, 0.25000000000000044],
            [25.0, 13.22916666666667, -3.6562500000000013],
            [25.0, 25.0, -10.0],
        ])

        ix, iy, iz = 0, 1, 2  # index for x, y, z

        self.assertTrue(
            self.same(
                known_surface_evaluation_points[:, ix],
                calc_surface_evaluations_x.flatten(),
            ))

        self.assertTrue(
            self.same(
                known_surface_evaluation_points[:, iy],
                calc_surface_evaluations_y.flatten(),
            ))

        self.assertTrue(
            self.same(
                known_surface_evaluation_points[:, iz],
                calc_surface_evaluations_z.flatten(),
            ))
Beispiel #2
0
    def test_202_Bingol_3D_surface(self):
        """Tests creation and plotting of BSpline surface, compared to
        GitHub repository orbingol
        https://github.com/orbingol/NURBS-Python/blob/5.x/geomdl/BSpline.py

        Example usage:

        $ conda activate nurbspyenv
        $ cd nurbspy/
        $ python
        > from geomdl import BSpline
        > from geomdl.visualization import VisMPL as vis
        >
        > surf = BSpline.Surface()
        > surf.degree_u = 3
        > surf.degree_v = 2
        > control_points = [
            [0, 0, 0], [0, 4, 0], [0, 8, -3],
            [2, 0, 6], [2, 4, 0], [2, 8, 0],
            [4, 0, 0], [4, 4, 0], [4, 8, 3],
            [6, 0, 0], [6, 4, -3], [6, 8, 0]
        ]
        > surf.set_ctrlpts(control_points, 4, 3)
        > surf.knotvector_u = [0, 0, 0, 0, 1, 1, 1, 1]
        > surf.knotvector_v = [0, 0, 0, 1, 1, 1]
        > surf.delta = 0.20  # 0.20 for testing, was originally 0.05 for smoothness
        > surf.vis = vis.VisSurface()
        # or alternatively, for a transparent surface, set the alpha to non-unity
        > surf.vis = vis.VisSurface(vis.VisConfig(alpha=0.8))
        >
        > surface_points = surf.evalpts
        > surf.render()
        # 0.20, with 1.0 / 0.20 = 5.0,
        # gives a matrix of [5x5] evalution (x, y, z) points found by
        > surf.evalpts
        """
        kv_t = tuple(map(float, [0, 0, 0, 0, 1, 1, 1, 1]))  # cubic
        kv_u = tuple(map(float, [0, 0, 0, 1, 1, 1]))  # quadratic
        control_points = (
            ((0, 0, 0), (0, 4, 0), (0, 8, -3)),
            ((2, 0, 6), (2, 4, 0), (2, 8, 0)),
            ((4, 0, 0), (4, 4, 0), (4, 8, 3)),
            ((6, 0, 0), (6, 4, -3), (6, 8, 0)),
        )
        degree_t = 3  # cubic
        degree_u = 2  # quadratic
        nbi = 2  # number of bisections per knot interval

        S = bsp.Surface(
            kv_t,
            kv_u,
            control_points,
            degree_t,
            degree_u,
            n_bisections=nbi,
            verbose=True,
        )

        (
            calc_surface_evaluations_x,
            calc_surface_evaluations_y,
            calc_surface_evaluations_z,
        ) = S.evaluations

        known_surface_evaluation_points = np.array([
            [
                [0.0, 0.0, 0.0],
                [0.0, 2.0, -0.1875],
                [0.0, 4.0, -0.75],
                [0.0, 6.0, -1.6875],
                [0.0, 8.0, -3.0],
            ],
            [
                [1.5, 0.0, 2.53125],
                [1.5, 2.0, 1.353515625],
                [1.5, 4.0, 0.3984375],
                [1.5, 6.0, -0.333984375],
                [1.5, 8.0, -0.84375],
            ],
            [
                [3.0, 0.0, 2.25],
                [3.0, 2.0, 1.171875],
                [3.0, 4.0, 0.5625],
                [3.0, 6.0, 0.421875],
                [3.0, 8.0, 0.75],
            ],
            [
                [4.5, 0.0, 0.84375],
                [4.5, 2.0, 0.076171875],
                [4.5, 4.0, -0.1171875],
                [4.5, 6.0, 0.263671875],
                [4.5, 8.0, 1.21875],
            ],
            [
                [6.0, 0.0, 0.0],
                [6.0, 2.0, -1.125],
                [6.0, 4.0, -1.5],
                [6.0, 6.0, -1.125],
                [6.0, 8.0, 0.0],
            ],
        ])

        ix, iy, iz = 0, 1, 2  # index for x, y, z

        known_surface_evaluation_points_x = known_surface_evaluation_points[:, :,
                                                                            ix].flatten(
                                                                            )

        known_surface_evaluation_points_y = known_surface_evaluation_points[:, :,
                                                                            iy].flatten(
                                                                            )

        known_surface_evaluation_points_z = known_surface_evaluation_points[:, :,
                                                                            iz].flatten(
                                                                            )

        self.assertTrue(
            self.same(known_surface_evaluation_points_x,
                      calc_surface_evaluations_x.flatten()))
        self.assertTrue(
            self.same(known_surface_evaluation_points_y,
                      calc_surface_evaluations_y.flatten()))
        self.assertTrue(
            self.same(known_surface_evaluation_points_z,
                      calc_surface_evaluations_z.flatten()))
Beispiel #3
0
    def test_201_recover_bezier_bilinear_B00_p1_surface(self):
        kv_t = (0.0, 0.0, 1.0, 1.0)  # knot vector for t parameter
        kv_u = (0.0, 0.0, 1.0, 1.0)  # knot vector for u parameter
        # control_points = [
        #     [[-15.0, -10.0, 1.0], [-15.0, 10.0, 1.0]],
        #     [[15.0, -10.0, 1.0], [15.0, 10.0, 1.0]],
        # ]
        control_points = (
            ((0.0, 0.0, 1.0), (0.0, 1.0, 0.0)),
            ((1.0, 0.0, 0.0), (1.0, 1.0, 0.0)),
        )
        degree_t = 1  # linear
        degree_u = 1  # linear
        nbi = 1  # number of bisections per knot interval

        S = bsp.Surface(
            kv_t,
            kv_u,
            control_points,
            degree_t,
            degree_u,
            n_bisections=nbi,
            verbose=True,
        )

        (
            calc_surface_evaluations_x,
            calc_surface_evaluations_y,
            calc_surface_evaluations_z,
        ) = S.evaluations

        known_surface_evaluations_x = np.array(
            ((0.0, 0.0, 0.0), (0.5, 0.5, 0.5), (1.0, 1.0, 1.0)))

        known_surface_evaluations_y = np.array(
            ((0.0, 0.5, 1.0), (0.0, 0.5, 1.0), (0.0, 0.5, 1.0)))

        known_surface_evaluations_z = np.array(
            ((1.0, 0.5, 0.0), (0.5, 0.25, 0.0), (0.0, 0.0, 0.0)))

        difference_matrix_x = calc_surface_evaluations_x - known_surface_evaluations_x
        difference_matrix_y = calc_surface_evaluations_y - known_surface_evaluations_y
        difference_matrix_z = calc_surface_evaluations_z - known_surface_evaluations_z

        Frobenius_norm_x = np.linalg.norm(difference_matrix_x, ord="fro")
        Frobenius_norm_y = np.linalg.norm(difference_matrix_y, ord="fro")
        Frobenius_norm_z = np.linalg.norm(difference_matrix_z, ord="fro")

        self.assertTrue(Frobenius_norm_x < self.tol)
        self.assertTrue(Frobenius_norm_y < self.tol)
        self.assertTrue(Frobenius_norm_z < self.tol)

        known_evaluation_times_t = (0.0, 0.5, 1.0)
        known_evaluation_times_u = (0.0, 0.5, 1.0)

        calc_evaluation_times_t = S.evaluation_times_t
        calc_evaluation_times_u = S.evaluation_times_u

        self.assertTrue(
            self.same(known_evaluation_times_t, calc_evaluation_times_t))
        self.assertTrue(
            self.same(known_evaluation_times_u, calc_evaluation_times_u))
Beispiel #4
0
if control_points_shown:
    cp_x = np.array(surfaces)[:, :, :,
                              ix].flatten()  # control points x-coordinates
    cp_y = np.array(surfaces)[:, :, :,
                              iy].flatten()  # control points y-coordinates
    cp_z = np.array(surfaces)[:, :, :,
                              iz].flatten()  # control points z-coordinates

    ax.plot3D(cp_x, cp_y, cp_z, **vbsp.defaults["control_points_kwargs"])

for control_points in surfaces:
    S = bsp.Surface(
        kv_t,
        kv_u,
        control_points,
        degree_t,
        degree_u,
        n_bisections=nbi,
        verbose=True,
    )
    (surf_x, surf_y, surf_z) = S.evaluations

    ax.plot3D(
        surf_x.flatten(),
        surf_y.flatten(),
        surf_z.flatten(),
        **vbsp.defaults["evaluation_points_kwargs"],
    )

    u, t = np.meshgrid(S.evaluation_times_u, S.evaluation_times_t)
    u, t = u.flatten(), t.flatten()
Beispiel #5
0
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.plot3d = True  # overwrite the base class
        COEF = kwargs.get(
            "coefficients", None
        )  # None is basis, not None is curve, surface, or volume
        assert COEF is not None

        _NSD = len(COEF[0][0])  # number of space dimensions
        assert _NSD == 3  # only 2D curves implemented for now, do 3D later

        # plot B-spline curve, assume 2D for now
        self.fig = plt.figure(dpi=self.dpi)
        # ax = self.fig.gca()
        ax = self.fig.add_subplot(111, projection="3d")

        # avoid "magic" numbers, assign (0, 1, 2) to variables
        idx, idy, idz = (0, 1, 2)

        # self.control_net_alpha = kwargs.get("control_net_alpha", 0.5)
        # self.control_net_color = kwargs.get("control_net_color", "magenta")
        # self.control_net_linestyle = kwargs.get("control_net_linestyle", "dashed")
        # self.control_net_linewidth = kwargs.get("control_net_linewidth", 1)
        # self.control_net_shown = kwargs.get("control_net_shown", True)

        if self.control_net_shown:
            # create control net object
            cn = ControlNet(COEF)

            # draw control net rows
            _row_points = cn.rows
            for r in _row_points:
                ax.plot3D(
                    r[:, idx],
                    r[:, idy],
                    r[:, idz],
                    alpha=self.control_net_alpha,
                    color=self.control_net_color,
                    linestyle=self.control_net_linestyle,
                    linewidth=self.control_net_linewidth,
                )

            # draw control net columns
            _col_points = cn.columns
            for c in _col_points:
                ax.plot3D(
                    c[:, idx],
                    c[:, idy],
                    c[:, idz],
                    alpha=self.control_net_alpha,
                    color=self.control_net_color,
                    linestyle=self.control_net_linestyle,
                    linewidth=self.control_net_linewidth,
                )

        if self.control_points_shown:

            # plot control points
            _cp_x = np.array(COEF)[:, :, idx].flatten()  # control points x-coordinates
            _cp_y = np.array(COEF)[:, :, idy].flatten()  # control points y-coordinates
            _cp_z = np.array(COEF)[:, :, idz].flatten()  # control points z-coordinates

            ax.plot3D(
                _cp_x,
                _cp_y,
                _cp_z,
                alpha=self.control_points_alpha,
                color=self.control_points_color,
                linestyle=self.control_points_linestyle,
                linewidth=self.control_points_linewidth,
                marker=self.control_points_marker,
                markerfacecolor=self.control_points_marker_facecolor,
                markersize=self.control_points_marker_size,
            )

        if self.evaluation_points_shown or self.surface_triangulation:

            kv_t = kwargs.get("knot_vector_t")
            kv_u = kwargs.get("knot_vector_u")
            # control_poiknts argument already exists as COEF variable

            # S = bsp.Surface(
            #     kv_t, kv_u, COEF, self.degree_t, self.degree_u, verbose=self.verbosity
            # )
            S = bsp.Surface(
                knot_vector_t=kv_t,
                knot_vector_u=kv_u,
                coefficients=COEF,
                degree_t=self.degree_t,
                degree_u=self.degree_u,
                n_bisections=self.nbi,
                verbose=self.verbosity,
            )

            (_surf_x, _surf_y, _surf_z) = S.evaluations

            if self.evaluation_points_shown:
                ax.plot3D(
                    _surf_x.flatten(),
                    _surf_y.flatten(),
                    _surf_z.flatten(),
                    alpha=self.evaluation_points_alpha,
                    color=self.evaluation_points_color,
                    linestyle=self.evaluation_points_linestyle,
                    linewidth=self.evaluation_points_linewidth,
                    marker=self.evaluation_points_marker,
                    markersize=self.evaluation_points_marker_size,
                )
                # markerfacecolor=self.evaluation_points_marker_facecolor,

            if self.surface_triangulation:
                # convention here is reverse of the (x, y) convention of
                # mesh grid, see
                # https://numpy.org/doc/stable/reference/generated/numpy.meshgrid.html
                u, t = np.meshgrid(S.evaluation_times_u, S.evaluation_times_t)
                u, t = u.flatten(), t.flatten()

                tri = mtri.Triangulation(u, t)
                ax.plot_trisurf(
                    _surf_x.flatten(),
                    _surf_y.flatten(),
                    _surf_z.flatten(),
                    alpha=self.surface_triangulation_alpha,
                    triangles=tri.triangles,
                )

                # color=self.surface_triangulation_color,

        xlabel = kwargs.get("xlabel", "x")
        ylabel = kwargs.get("ylabel", "y")
        zlabel = kwargs.get("zlabel", "z")

        # ax.set_xlabel(r"$x$")
        # ax.set_ylabel(r"$y$")

        ax.set_xlabel(r"" + xlabel + "")
        ax.set_ylabel(r"" + ylabel + "")
        ax.set_zlabel(r"" + zlabel + "")

        if self.xlim:
            ax.set_xlim(self.xlim)

        if self.ylim:
            ax.set_ylim(self.ylim)

        if self.zlim:
            ax.set_zlim(self.zlim)

        # finish figure by calling method with common figure functions
        ViewBSplineFigure(self)
Beispiel #6
0
    pass

if control_points_shown:
    for p in patches:
        cp_x = np.array(p.coefficients)[:, :, ix].flatten()
        cp_y = np.array(p.coefficients)[:, :, iy].flatten()
        cp_z = np.array(p.coefficients)[:, :, iz].flatten()

        ax.plot3D(cp_x, cp_y, cp_z, **vbsp.defaults["control_points_kwargs"])

for p in patches:

    S = bsp.Surface(
        knot_vector_t=p.knot_vector_t,
        knot_vector_u=p.knot_vector_u,
        coefficients=p.coefficients,
        degree_t=p.degree_t,
        degree_u=p.degree_u,
        n_bisections=p.n_bisections,
    )
    (surf_x, surf_y, surf_z) = S.evaluations

    ax.plot3D(
        surf_x.flatten(),
        surf_y.flatten(),
        surf_z.flatten(),
        **vbsp.defaults["evaluation_points_kwargs"],
    )

    u, t = np.meshgrid(S.evaluation_times_u, S.evaluation_times_t)
    u, t = u.flatten(), t.flatten()
    tri = mtri.Triangulation(u, t)