void TriangleVK::OnCreate(DeviceVK* pDevice, DynamicBufferRingVK *pConstantBufferRing, StaticBufferPoolVK *pStaticGeom, VkRenderPass renderPass) { m_pDevice = pDevice; m_pConstantBufferRing = pConstantBufferRing; VkResult res; struct Vertex { float posX, posY, posZ, posW; // Position data float r, g, b, a; // Color }; #define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f const Vertex g_vb_solid_face_colors_Data[] = { // red face { XYZ1(-1, -1, 1), XYZ1(1.f, 0.f, 0.f) }, { XYZ1(-1, 1, 1), XYZ1(1.f, 0.f, 0.f) }, { XYZ1(1, -1, 1), XYZ1(1.f, 0.f, 0.f) }, { XYZ1(1, -1, 1), XYZ1(1.f, 0.f, 0.f) }, { XYZ1(-1, 1, 1), XYZ1(1.f, 0.f, 0.f) }, { XYZ1(1, 1, 1), XYZ1(1.f, 0.f, 0.f) }, // green face { XYZ1(-1, -1, -1), XYZ1(0.f, 1.f, 0.f) }, { XYZ1(1, -1, -1), XYZ1(0.f, 1.f, 0.f) }, { XYZ1(-1, 1, -1), XYZ1(0.f, 1.f, 0.f) }, { XYZ1(-1, 1, -1), XYZ1(0.f, 1.f, 0.f) }, { XYZ1(1, -1, -1), XYZ1(0.f, 1.f, 0.f) }, { XYZ1(1, 1, -1), XYZ1(0.f, 1.f, 0.f) }, // blue face { XYZ1(-1, 1, 1), XYZ1(0.f, 0.f, 1.f) }, { XYZ1(-1, -1, 1), XYZ1(0.f, 0.f, 1.f) }, { XYZ1(-1, 1, -1), XYZ1(0.f, 0.f, 1.f) }, { XYZ1(-1, 1, -1), XYZ1(0.f, 0.f, 1.f) }, { XYZ1(-1, -1, 1), XYZ1(0.f, 0.f, 1.f) }, { XYZ1(-1, -1, -1), XYZ1(0.f, 0.f, 1.f) }, // yellow face { XYZ1(1, 1, 1), XYZ1(1.f, 1.f, 0.f) }, { XYZ1(1, 1, -1), XYZ1(1.f, 1.f, 0.f) }, { XYZ1(1, -1, 1), XYZ1(1.f, 1.f, 0.f) }, { XYZ1(1, -1, 1), XYZ1(1.f, 1.f, 0.f) }, { XYZ1(1, 1, -1), XYZ1(1.f, 1.f, 0.f) }, { XYZ1(1, -1, -1), XYZ1(1.f, 1.f, 0.f) }, // magenta face { XYZ1(1, 1, 1), XYZ1(1.f, 0.f, 1.f) }, { XYZ1(-1, 1, 1), XYZ1(1.f, 0.f, 1.f) }, { XYZ1(1, 1, -1), XYZ1(1.f, 0.f, 1.f) }, { XYZ1(1, 1, -1), XYZ1(1.f, 0.f, 1.f) }, { XYZ1(-1, 1, 1), XYZ1(1.f, 0.f, 1.f) }, { XYZ1(-1, 1, -1), XYZ1(1.f, 0.f, 1.f) }, // cyan face { XYZ1(1, -1, 1), XYZ1(0.f, 1.f, 1.f) }, { XYZ1(1, -1, -1), XYZ1(0.f, 1.f, 1.f) }, { XYZ1(-1, -1, 1), XYZ1(0.f, 1.f, 1.f) }, { XYZ1(-1, -1, 1), XYZ1(0.f, 1.f, 1.f) }, { XYZ1(1, -1, -1), XYZ1(0.f, 1.f, 1.f) }, { XYZ1(-1, -1, -1), XYZ1(0.f, 1.f, 1.f) }, }; int vertices = 6 * 6; int vertexSize = 8 * sizeof(float); void *pData; pStaticGeom->AllocVertexBuffer(vertices, vertexSize, &pData, &m_geometry); memcpy(pData, g_vb_solid_face_colors_Data, sizeof(g_vb_solid_face_colors_Data)); /////////////////////////////////////////////// // shaders const char *vertShaderText = "#version 400\n" "#extension GL_ARB_separate_shader_objects : enable\n" "#extension GL_ARB_shading_language_420pack : enable\n" "layout (std140, binding = 0) uniform bufferVals {\n" " mat4 mvp;\n" "} myBufferVals;\n" "layout (location = 0) in vec4 pos;\n" "layout (location = 1) in vec4 inColor;\n" "layout (location = 0) out vec4 outColor;\n" "void main() {\n" " outColor = inColor;\n" " gl_Position = myBufferVals.mvp * pos;\n" "}\n"; const char *fragShaderText = "#version 400\n" "#extension GL_ARB_separate_shader_objects : enable\n" "#extension GL_ARB_shading_language_420pack : enable\n" "layout (location = 0) in vec4 color;\n" "layout (location = 0) out vec4 outColor;\n" "void main() {\n" " outColor = color;\n" "}\n"; ///////////////////////////////////////////// // Compile and create shaders init_glslang(); std::map<std::string, std::string> attributeDefines; VkPipelineShaderStageCreateInfo m_vertexShader; res = VKCompile(pDevice->GetDevice(), SST_GLSL, VK_SHADER_STAGE_VERTEX_BIT, vertShaderText, "main", attributeDefines, &m_vertexShader); assert(res == VK_SUCCESS); VkPipelineShaderStageCreateInfo m_fragmentShader; res = VKCompile(pDevice->GetDevice(), SST_GLSL, VK_SHADER_STAGE_FRAGMENT_BIT, fragShaderText, "main", attributeDefines, &m_fragmentShader); assert(res == VK_SUCCESS); finalize_glslang(); std::vector<VkPipelineShaderStageCreateInfo> shaderStages = { m_vertexShader, m_fragmentShader }; ///////////////////////////////////////////// // Create descriptor pool std::vector<VkDescriptorPoolSize> type_count = { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1} }; VkDescriptorPoolCreateInfo descriptor_pool = {}; descriptor_pool.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; descriptor_pool.pNext = NULL; descriptor_pool.maxSets = 1; descriptor_pool.poolSizeCount = (uint32_t)type_count.size(); descriptor_pool.pPoolSizes = type_count.data(); res = vkCreateDescriptorPool(pDevice->GetDevice(), &descriptor_pool, NULL, &m_descriptorPool); assert(res == VK_SUCCESS); ///////////////////////////////////////////// // Create pipeline layout VkDescriptorSetLayoutBinding layout_bindings[1]; layout_bindings[0].binding = 0; layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; layout_bindings[0].descriptorCount = 1; layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; layout_bindings[0].pImmutableSamplers = NULL; /* Next take layout bindings and use them to create a descriptor set layout */ VkDescriptorSetLayoutCreateInfo descriptor_layout = {}; descriptor_layout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; descriptor_layout.pNext = NULL; descriptor_layout.flags = 0; descriptor_layout.bindingCount = 1; descriptor_layout.pBindings = layout_bindings; std::vector<VkDescriptorSetLayout> desc_layout; desc_layout.resize(1); res = vkCreateDescriptorSetLayout(pDevice->GetDevice(), &descriptor_layout, NULL, desc_layout.data()); assert(res == VK_SUCCESS); /* Now use the descriptor layout to create a pipeline layout */ VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = {}; pPipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pPipelineLayoutCreateInfo.pNext = NULL; pPipelineLayoutCreateInfo.pushConstantRangeCount = 0; pPipelineLayoutCreateInfo.pPushConstantRanges = NULL; pPipelineLayoutCreateInfo.setLayoutCount = (uint32_t)desc_layout.size(); pPipelineLayoutCreateInfo.pSetLayouts = desc_layout.data(); res = vkCreatePipelineLayout(pDevice->GetDevice(), &pPipelineLayoutCreateInfo, NULL, &m_pipelineLayout); assert(res == VK_SUCCESS); ///////////////////////////////////////////// // Create descriptor sets VkDescriptorSetAllocateInfo alloc_info[1]; alloc_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; alloc_info[0].pNext = NULL; alloc_info[0].descriptorPool = m_descriptorPool; alloc_info[0].descriptorSetCount = (uint32_t)desc_layout.size(); alloc_info[0].pSetLayouts = desc_layout.data(); m_descriptorSets.resize(desc_layout.size()); res = vkAllocateDescriptorSets(pDevice->GetDevice(), alloc_info, m_descriptorSets.data()); assert(res == VK_SUCCESS); ///////////////////////////////////////////// // Create pipeline // vertex input state VkVertexInputBindingDescription vi_binding = {}; vi_binding.binding = 0; vi_binding.stride = sizeof(float) * 8; vi_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; std::vector<VkVertexInputAttributeDescription> vi_attrs(2); // Position vi_attrs[0].location = 0; vi_attrs[0].binding = 0; vi_attrs[0].format = VK_FORMAT_R32G32B32A32_SFLOAT; vi_attrs[0].offset = 0; // Normal vi_attrs[1].location = 1; vi_attrs[1].binding = 0; vi_attrs[1].format = VK_FORMAT_R32G32B32A32_SFLOAT; vi_attrs[1].offset = sizeof(float) * 4; VkPipelineVertexInputStateCreateInfo vi = {}; vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vi.pNext = NULL; vi.flags = 0; vi.vertexBindingDescriptionCount = 1; vi.pVertexBindingDescriptions = &vi_binding; vi.vertexAttributeDescriptionCount = (uint32_t)vi_attrs.size(); vi.pVertexAttributeDescriptions = vi_attrs.data(); // input assembly state VkPipelineInputAssemblyStateCreateInfo ia; ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; ia.pNext = NULL; ia.flags = 0; ia.primitiveRestartEnable = VK_FALSE; ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; // rasterizer state VkPipelineRasterizationStateCreateInfo rs; rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rs.pNext = NULL; rs.flags = 0; rs.polygonMode = VK_POLYGON_MODE_FILL; rs.cullMode = VK_CULL_MODE_BACK_BIT; rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rs.depthClampEnable = VK_FALSE; rs.rasterizerDiscardEnable = VK_FALSE; rs.depthBiasEnable = VK_FALSE; rs.depthBiasConstantFactor = 0; rs.depthBiasClamp = 0; rs.depthBiasSlopeFactor = 0; rs.lineWidth = 1.0f; VkPipelineColorBlendAttachmentState att_state[1]; att_state[0].colorWriteMask = 0xf; att_state[0].blendEnable = VK_FALSE; att_state[0].alphaBlendOp = VK_BLEND_OP_ADD; att_state[0].colorBlendOp = VK_BLEND_OP_ADD; att_state[0].srcColorBlendFactor = VK_BLEND_FACTOR_ZERO; att_state[0].dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; att_state[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; att_state[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // Color blend state VkPipelineColorBlendStateCreateInfo cb; cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; cb.flags = 0; cb.pNext = NULL; cb.attachmentCount = 1; cb.pAttachments = att_state; cb.logicOpEnable = VK_FALSE; cb.logicOp = VK_LOGIC_OP_NO_OP; cb.blendConstants[0] = 1.0f; cb.blendConstants[1] = 1.0f; cb.blendConstants[2] = 1.0f; cb.blendConstants[3] = 1.0f; std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicState = {}; dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynamicState.pNext = NULL; dynamicState.pDynamicStates = dynamicStateEnables.data(); dynamicState.dynamicStateCount = (uint32_t)dynamicStateEnables.size(); // view port state VkPipelineViewportStateCreateInfo vp = {}; vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; vp.pNext = NULL; vp.flags = 0; vp.viewportCount = 1; vp.scissorCount = 1; vp.pScissors = NULL; vp.pViewports = NULL; // depth stencil state VkPipelineDepthStencilStateCreateInfo ds; ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; ds.pNext = NULL; ds.flags = 0; ds.depthTestEnable = true; ds.depthWriteEnable = true; ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; ds.depthBoundsTestEnable = VK_FALSE; ds.stencilTestEnable = VK_FALSE; ds.back.failOp = VK_STENCIL_OP_KEEP; ds.back.passOp = VK_STENCIL_OP_KEEP; ds.back.compareOp = VK_COMPARE_OP_ALWAYS; ds.back.compareMask = 0; ds.back.reference = 0; ds.back.depthFailOp = VK_STENCIL_OP_KEEP; ds.back.writeMask = 0; ds.minDepthBounds = 0; ds.maxDepthBounds = 0; ds.stencilTestEnable = VK_FALSE; ds.front = ds.back; // multi sample state VkPipelineMultisampleStateCreateInfo ms; ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; ms.pNext = NULL; ms.flags = 0; ms.pSampleMask = NULL; ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; ms.sampleShadingEnable = VK_FALSE; ms.alphaToCoverageEnable = VK_FALSE; ms.alphaToOneEnable = VK_FALSE; ms.minSampleShading = 0.0; // create pipeline cache VkPipelineCacheCreateInfo pipelineCache; pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; pipelineCache.pNext = NULL; pipelineCache.initialDataSize = 0; pipelineCache.pInitialData = NULL; pipelineCache.flags = 0; res = vkCreatePipelineCache(pDevice->GetDevice(), &pipelineCache, NULL, &m_pipelineCache); assert(res == VK_SUCCESS); // create pipeline VkGraphicsPipelineCreateInfo pipeline = {}; pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipeline.pNext = NULL; pipeline.layout = m_pipelineLayout; pipeline.basePipelineHandle = VK_NULL_HANDLE; pipeline.basePipelineIndex = 0; pipeline.flags = 0; pipeline.pVertexInputState = &vi; pipeline.pInputAssemblyState = &ia; pipeline.pRasterizationState = &rs; pipeline.pColorBlendState = &cb; pipeline.pTessellationState = NULL; pipeline.pMultisampleState = &ms; pipeline.pDynamicState = &dynamicState; pipeline.pViewportState = &vp; pipeline.pDepthStencilState = &ds; pipeline.pStages = shaderStages.data(); pipeline.stageCount = (uint32_t)shaderStages.size(); pipeline.renderPass = renderPass; pipeline.subpass = 0; res = vkCreateGraphicsPipelines(pDevice->GetDevice(), m_pipelineCache, 1, &pipeline, NULL, &m_pipeline); assert(res == VK_SUCCESS); }
* be used as a texture again. Use the second set of vertices to draw a quad to * the right of the first. Do this all in one command buffer. The image should * be a LunarG logo quad on the left and a green quad on the right. */ #include <util_init.hpp> #include <assert.h> #include <string.h> #include <cstdlib> #include <cube_data.h> // Using OpenGL based glm, so Y is upside down between OpenGL and Vulkan static const VertexUV vb_Data[] = { // Textured quad: {XYZ1(-2, -0.5, -1), UV(0.f, 0.f)}, // lft-top / Z {XYZ1(-1, -0.5, -1), UV(1.f, 0.f)}, // rgt-top / {XYZ1(-2, 0.5, -1), UV(0.f, 1.f)}, // lft-btm +------> X {XYZ1(-2, 0.5, -1), UV(0.f, 1.f)}, // lft-btm | {XYZ1(-1, -0.5, -1), UV(1.f, 0.f)}, // rgt-top | {XYZ1(-1, 0.5, -1), UV(1.f, 1.f)}, // rgt-btm v Y // Green quad: {XYZ1(1, -0.5, -1), UV(0.f, 0.f)}, // lft-top {XYZ1(2, -0.5, -1), UV(1.f, 0.f)}, // rgt-top {XYZ1(1, 0.5, -1), UV(0.f, 1.f)}, // lft-btm {XYZ1(1, 0.5, -1), UV(0.f, 1.f)}, // lft-btm {XYZ1(2, -0.5, -1), UV(1.f, 0.f)}, // rgt-top {XYZ1(2, 0.5, -1), UV(1.f, 1.f)}, // rgt-btm }; #define DEPTH_PRESENT false
/* Set up Vulkan pipeline and use three threads to create 3 */ /* command buffers, each using a vertex buffer to draw a triangle */ #include <util_init.hpp> #include <assert.h> #include <string.h> #include <cstdlib> #include <samples_platform.h> struct Vertex { float posX, posY, posZ, posW; // Position data float r, g, b, a; // Color }; #define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f static const Vertex triData[] = { {XYZ1(-0.25, -0.25, 0), XYZ1(1.f, 0.f, 0.f)}, {XYZ1(0.25, -0.25, 0), XYZ1(1.f, 0.f, 0.f)}, {XYZ1(0, 0.25, 0), XYZ1(1.f, 0.f, 0.f)}, {XYZ1(-0.75, -0.25, 0), XYZ1(0.f, 1.f, 0.f)}, {XYZ1(-0.25, -0.25, 0), XYZ1(0.f, 1.f, 0.f)}, {XYZ1(-0.5, 0.25, 0), XYZ1(0.f, 1.f, 0.f)}, {XYZ1(0.25, -0.25, 0), XYZ1(0.f, 0.f, 1.f)}, {XYZ1(0.75, -0.25, 0), XYZ1(0.f, 0.f, 1.f)}, {XYZ1(0.5, 0.25, 0), XYZ1(0.f, 0.f, 1.f)}, }; struct { VkBuffer buf; VkDeviceMemory mem; } vertex_buffer[3];
ASMmxBase::VolumeVec ASMmxBase::establishBases(Go::SplineVolume* svol, MixedType type) { VolumeVec 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 = svol->dimension(); Go::BsplineBasis b1 = svol->basis(0).extendedBasis(svol->order(0)+1); Go::BsplineBasis b2 = svol->basis(1).extendedBasis(svol->order(1)+1); Go::BsplineBasis b3 = svol->basis(2).extendedBasis(svol->order(2)+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()), wg(b3.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); for (i = 0; i < wg.size(); i++) wg[i] = b3.grevilleParameter(i); if (svol->rational()) { std::vector<double> rCoefs(svol->rcoefs_begin(), svol->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::SplineVolume vol2(svol->basis(0), svol->basis(1), svol->basis(2), rCoefs.begin(), ndim+1, false); // interpolate the Bspline surface onto new basis RealArray XYZ((ndim+1)*ug.size()*vg.size()*wg.size()); vol2.gridEvaluator(XYZ,ug,vg,wg); std::unique_ptr<Go::SplineVolume> svol3(Go::VolumeInterpolator::regularInterpolation(b1,b2,b3,ug,vg,wg,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::SplineVolume(svol3->basis(0), svol3->basis(1), svol3->basis(2), svol3->coefs_begin(), ndim, true)); } else { RealArray XYZ(ndim*ug.size()*vg.size()*wg.size()); // Evaluate the spline surface at all points svol->gridEvaluator(ug,vg,wg,XYZ); // Project the coordinates onto the new basis (the 2nd XYZ is dummy here) result[0].reset(Go::VolumeInterpolator::regularInterpolation(b1,b2,b3, ug,vg,wg,XYZ,ndim, false,XYZ)); } result[1].reset(new Go::SplineVolume(*svol)); } 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::SplineVolume(*svol)); result[0]->raiseOrder(1,1,1); result[1].reset(new Go::SplineVolume(*svol)); } else if (ASMmxBase::Type == ASMmxBase::DIV_COMPATIBLE) { result.resize(4); // basis1 should be one degree higher than basis2 and C^p-1 continuous int ndim = svol->dimension(); Go::BsplineBasis a1 = svol->basis(0); Go::BsplineBasis a2 = svol->basis(1); Go::BsplineBasis a3 = svol->basis(2); Go::BsplineBasis b1 = svol->basis(0).extendedBasis(svol->order(0)+1); Go::BsplineBasis b2 = svol->basis(1).extendedBasis(svol->order(1)+1); Go::BsplineBasis b3 = svol->basis(2).extendedBasis(svol->order(2)+1); // Compute parameter values of the Greville points size_t i; RealArray u0(a1.numCoefs()), v0(a2.numCoefs()), w0(a3.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); for (i = 0; i < w0.size(); i++) w0[i] = a3.grevilleParameter(i); RealArray ug(b1.numCoefs()), vg(b2.numCoefs()), wg(b3.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); for (i = 0; i < wg.size(); i++) wg[i] = b3.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()*w0.size()), XYZ1(ndim*u0.size()*vg.size()*w0.size()), XYZ2(ndim*u0.size()*v0.size()*wg.size()); svol->gridEvaluator(ug,v0,w0,XYZ0); svol->gridEvaluator(u0,vg,w0,XYZ1); svol->gridEvaluator(u0,v0,wg,XYZ2); result[0].reset(Go::VolumeInterpolator::regularInterpolation(b1,a2,a3, ug,v0,w0,XYZ0,ndim, false,XYZ0)); result[1].reset(Go::VolumeInterpolator::regularInterpolation(a1,b2,a3, u0,vg,w0,XYZ1,ndim, false,XYZ1)); result[2].reset(Go::VolumeInterpolator::regularInterpolation(a1,a2,b3, u0,v0,wg,XYZ2,ndim, false,XYZ2)); result[3].reset(new Go::SplineVolume(*svol)); geoBasis = 4; } if (type == FULL_CONT_RAISE_BASIS2 || type == REDUCED_CONT_RAISE_BASIS2) std::swap(result[0], result[1]); return result; }