def test_make_identical(self): basis1 = BSplineBasis(4, [-1,-1,0,0,1,1,2,2], periodic=1) basis2 = BSplineBasis(3, [-1,0,0,1,1,2], periodic=0) basis3 = BSplineBasis(2) vol1 = Volume() vol2 = Volume(basis1, basis2, basis3) vol1.refine(1) Volume.make_splines_identical(vol1,vol2) for v in (vol1, vol2): self.assertEqual(v.periodic(0), False) self.assertEqual(v.periodic(1), False) self.assertEqual(v.periodic(2), False) self.assertEqual(v.order(), (4,3,2)) self.assertAlmostEqual(len(v.knots(0, True)), 11) self.assertAlmostEqual(len(v.knots(1, True)), 8) self.assertAlmostEqual(len(v.knots(2, True)), 5)
def test_make_identical(self): basis1 = BSplineBasis(4, [-1, -1, 0, 0, 1, 1, 2, 2], periodic=1) basis2 = BSplineBasis(3, [-1, 0, 0, 1, 1, 2], periodic=0) basis3 = BSplineBasis(2) vol1 = Volume() vol2 = Volume(basis1, basis2, basis3) vol1.refine(1) Volume.make_splines_identical(vol1, vol2) for v in (vol1, vol2): self.assertEqual(v.periodic(0), False) self.assertEqual(v.periodic(1), False) self.assertEqual(v.periodic(2), False) self.assertEqual(v.order(), (4, 3, 2)) self.assertAlmostEqual(len(v.knots(0, True)), 11) self.assertAlmostEqual(len(v.knots(1, True)), 8) self.assertAlmostEqual(len(v.knots(2, True)), 5)
def edge_surfaces(*surfaces): """ Create the volume defined by the region between the input surfaces. In case of six input surfaces, these must be given in the order: bottom, top, left, right, back, front. Opposing sides must be parametrized in the same directions. :param [Surface] surfaces: Two or six edge surfaces :return: The enclosed volume :rtype: Volume :raises ValueError: If the length of *surfaces* is not two or six """ if len(surfaces ) == 1: # probably gives input as a list-like single variable surfaces = surfaces[0] if len(surfaces) == 2: surf1 = surfaces[0].clone() surf2 = surfaces[1].clone() Surface.make_splines_identical(surf1, surf2) (n1, n2, d) = surf1.controlpoints.shape # d = dimension + rational controlpoints = np.zeros((n1, n2, 2, d)) controlpoints[:, :, 0, :] = surf1.controlpoints controlpoints[:, :, 1, :] = surf2.controlpoints # Volume constructor orders control points in a different way, so we # create it from scratch here result = Volume(surf1.bases[0], surf1.bases[1], BSplineBasis(2), controlpoints, rational=surf1.rational, raw=True) return result elif len(surfaces) == 6: if any([surf.rational for surf in surfaces]): raise RuntimeError( 'edge_surfaces not supported for rational splines') # coons patch (https://en.wikipedia.org/wiki/Coons_patch) umin = surfaces[0] umax = surfaces[1] vmin = surfaces[2] vmax = surfaces[3] wmin = surfaces[4] wmax = surfaces[5] vol1 = edge_surfaces(umin, umax) vol2 = edge_surfaces(vmin, vmax) vol3 = edge_surfaces(wmin, wmax) vol4 = Volume(controlpoints=vol1.corners(order='F'), rational=vol1.rational) vol1.swap(0, 2) vol1.swap(1, 2) vol2.swap(1, 2) vol4.swap(1, 2) Volume.make_splines_identical(vol1, vol2) Volume.make_splines_identical(vol1, vol3) Volume.make_splines_identical(vol1, vol4) Volume.make_splines_identical(vol2, vol3) Volume.make_splines_identical(vol2, vol4) Volume.make_splines_identical(vol3, vol4) result = vol1.clone() result.controlpoints += vol2.controlpoints result.controlpoints += vol3.controlpoints result.controlpoints -= 2 * vol4.controlpoints return result else: raise ValueError('Requires two or six input surfaces')
def edge_surfaces(*surfaces): """ Create the volume defined by the region between the input surfaces. In case of six input surfaces, these must be given in the order: bottom, top, left, right, back, front. Opposing sides must be parametrized in the same directions. :param [Surface] surfaces: Two or six edge surfaces :return: The enclosed volume :rtype: Volume :raises ValueError: If the length of *surfaces* is not two or six """ if len(surfaces) == 1: # probably gives input as a list-like single variable surfaces = surfaces[0] if len(surfaces) == 2: surf1 = surfaces[0].clone() surf2 = surfaces[1].clone() Surface.make_splines_identical(surf1, surf2) (n1, n2, d) = surf1.controlpoints.shape # d = dimension + rational controlpoints = np.zeros((n1, n2, 2, d)) controlpoints[:, :, 0, :] = surf1.controlpoints controlpoints[:, :, 1, :] = surf2.controlpoints # Volume constructor orders control points in a different way, so we # create it from scratch here result = Volume(surf1.bases[0], surf1.bases[1], BSplineBasis(2), controlpoints, rational=surf1.rational, raw=True) return result elif len(surfaces) == 6: if any([surf.rational for surf in surfaces]): raise RuntimeError('edge_surfaces not supported for rational splines') # coons patch (https://en.wikipedia.org/wiki/Coons_patch) umin = surfaces[0] umax = surfaces[1] vmin = surfaces[2] vmax = surfaces[3] wmin = surfaces[4] wmax = surfaces[5] vol1 = edge_surfaces(umin,umax) vol2 = edge_surfaces(vmin,vmax) vol3 = edge_surfaces(wmin,wmax) vol4 = Volume(controlpoints=vol1.corners(order='F'), rational=vol1.rational) vol1.swap(0, 2) vol1.swap(1, 2) vol2.swap(1, 2) vol4.swap(1, 2) Volume.make_splines_identical(vol1, vol2) Volume.make_splines_identical(vol1, vol3) Volume.make_splines_identical(vol1, vol4) Volume.make_splines_identical(vol2, vol3) Volume.make_splines_identical(vol2, vol4) Volume.make_splines_identical(vol3, vol4) result = vol1.clone() result.controlpoints += vol2.controlpoints result.controlpoints += vol3.controlpoints result.controlpoints -= 2*vol4.controlpoints return result else: raise ValueError('Requires two or six input surfaces')