void onDraw(SkCanvas* canvas) override { SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100); SkAutoTUnref<SkSurface> surf(canvas->newSurface(info, nullptr)); if (!surf.get()) { surf.reset(SkSurface::NewRaster(info)); } drawInto(surf->getCanvas()); SkAutoTUnref<SkImage> image(surf->newImageSnapshot()); canvas->drawImage(image, 10, 10, nullptr); SkAutoTUnref<SkSurface> surf2(image->newSurface(info, nullptr)); drawInto(surf2->getCanvas()); // Assert that the props were communicated transitively through the first image SkASSERT(equal(surf->props(), surf2->props())); SkAutoTUnref<SkImage> image2(surf2->newImageSnapshot()); canvas->drawImage(image2, 10 + SkIntToScalar(image->width()) + 10, 10, nullptr); }
ASMmxBase::SurfaceVec ASMmxBase::establishBases(Go::SplineSurface* surf, MixedType type) { SurfaceVec result(2); // With mixed methods we need two separate spline spaces if (type == FULL_CONT_RAISE_BASIS1 || type == FULL_CONT_RAISE_BASIS2) { // basis1 should be one degree higher than basis2 and C^p-1 continuous int ndim = surf->dimension(); Go::BsplineBasis b1 = surf->basis(0).extendedBasis(surf->order_u()+1); Go::BsplineBasis b2 = surf->basis(1).extendedBasis(surf->order_v()+1); /* To lower order and regularity this can be used instead std::vector<double>::const_iterator first = ++surf->basis(0).begin(); std::vector<double>::const_iterator last = --surf->basis(0).end(); Go::BsplineBasis b1 = Go::BsplineBasis(surf->order_u()-1,first,last); first = ++surf->basis(1).begin(); last = --surf->basis(1).end(); Go::BsplineBasis b2 = Go::BsplineBasis(surf->order_v()-1,first,last); */ // Compute parameter values of the Greville points size_t i; RealArray ug(b1.numCoefs()), vg(b2.numCoefs()); for (i = 0; i < ug.size(); i++) ug[i] = b1.grevilleParameter(i); for (i = 0; i < vg.size(); i++) vg[i] = b2.grevilleParameter(i); if (surf->rational()) { std::vector<double> rCoefs(surf->rcoefs_begin(), surf->rcoefs_end()); // we normally would set coefs as (x*w, y*w, w) // however, gotools use this representation internally already. // instance a Bspline surface in ndim+1 Go::SplineSurface surf2(surf->basis(0), surf->basis(1), rCoefs.begin(), ndim+1, false); // interpolate the Bspline surface onto new basis RealArray XYZ((ndim+1)*ug.size()*vg.size()); surf2.gridEvaluator(XYZ,ug,vg); std::unique_ptr<Go::SplineSurface> surf3(Go::SurfaceInterpolator::regularInterpolation(b1,b2,ug,vg,XYZ,ndim+1,false,XYZ)); // new rational coefs are (x/w', y/w', w') // apparently gotools will rescale coeffs on surface creation. result[0].reset(new Go::SplineSurface(surf3->basis(0), surf3->basis(1), surf3->coefs_begin(), ndim, true)); } else { RealArray XYZ(ndim*ug.size()*vg.size()); // Evaluate the spline surface at all points surf->gridEvaluator(XYZ,ug,vg); // Project the coordinates onto the new basis (the 2nd XYZ is dummy here) result[0].reset(Go::SurfaceInterpolator::regularInterpolation(b1,b2, ug,vg,XYZ,ndim, false,XYZ)); } result[1].reset(new Go::SplineSurface(*surf)); } else if (type == REDUCED_CONT_RAISE_BASIS1 || type == REDUCED_CONT_RAISE_BASIS2) { // Order-elevate basis1 such that it is of one degree higher than basis2 // but only C^p-2 continuous result[0].reset(new Go::SplineSurface(*surf)); result[0]->raiseOrder(1,1); result[1].reset(new Go::SplineSurface(*surf)); } else if (ASMmxBase::Type == ASMmxBase::DIV_COMPATIBLE) { result.resize(3); // basis1 should be one degree higher than basis2 and C^p-1 continuous int ndim = surf->dimension(); Go::BsplineBasis a1 = surf->basis(0); Go::BsplineBasis a2 = surf->basis(1); Go::BsplineBasis b1 = surf->basis(0).extendedBasis(surf->order_u()+1); Go::BsplineBasis b2 = surf->basis(1).extendedBasis(surf->order_v()+1); // Compute parameter values of the Greville points size_t i; RealArray u0(a1.numCoefs()), v0(a2.numCoefs()); for (i = 0; i < u0.size(); i++) u0[i] = a1.grevilleParameter(i); for (i = 0; i < v0.size(); i++) v0[i] = a2.grevilleParameter(i); RealArray ug(b1.numCoefs()), vg(b2.numCoefs()); for (i = 0; i < ug.size(); i++) ug[i] = b1.grevilleParameter(i); for (i = 0; i < vg.size(); i++) vg[i] = b2.grevilleParameter(i); // Evaluate the spline surface at all points // Project the coordinates onto the new basis (the 2nd XYZ is dummy here) RealArray XYZ0(ndim*ug.size()*v0.size()), XYZ1(ndim*u0.size()*vg.size()); surf->gridEvaluator(XYZ0,ug,v0); surf->gridEvaluator(XYZ1,u0,vg); result[2].reset(new Go::SplineSurface(*surf)); result[0].reset(Go::SurfaceInterpolator::regularInterpolation(b1,a2, ug,v0,XYZ0,ndim, false,XYZ0)); result[1].reset(Go::SurfaceInterpolator::regularInterpolation(a1,b2, u0,vg,XYZ1,ndim, false,XYZ1)); geoBasis = 3; } if (type == FULL_CONT_RAISE_BASIS2 || type == REDUCED_CONT_RAISE_BASIS2) std::swap(result[0], result[1]); return result; }