Hi Roger, thanks for following up.
With regard to the Spline Shader I confirm that it can be properly sampled without specifying the VolumeData (which is instead needed by VertexMap Shader)
The following test code works flawlessly on my side
EXECUTIONRESULT PC_11051_TagData::Execute (BaseTag *tag, BaseDocument *doc, BaseObject *op, BaseThread *bt, Int32 priority, EXECUTIONFLAGS flags)
{
if (!tag || !doc || !op || !bt)
return EXECUTIONRESULT::OUTOFMEMORY;
// allocate and init the InitRenderStruct
InitRenderStruct irs(doc);
// check the color space
COLORSPACETRANSFORMATION transform = COLORSPACETRANSFORMATION::NONE;
// check if linear workflow is enabled
if (irs.linear_workflow)
transform = COLORSPACETRANSFORMATION::LINEAR_TO_SRGB;
// find for the attached TextureTag and the related material
TextureTag* opTTag = (TextureTag*)op->GetTag(Ttexture);
if (!opTTag)
return EXECUTIONRESULT::OK;
BaseMaterial* opMat = opTTag->GetMaterial();
if (!opMat)
return EXECUTIONRESULT::OK;
// look for the material BaseContainer and the BaseList2D associated to the color param
BaseContainer* activeMatBC = opMat->GetDataInstance();
if (!activeMatBC)
return EXECUTIONRESULT::OK;
BaseList2D* activeMatColorBL = activeMatBC->GetLink(MATERIAL_COLOR_SHADER, doc);
if (!activeMatColorBL)
return EXECUTIONRESULT::OK;
// cast to BaseShader
BaseShader* activeMatColorBS = (BaseShader*)activeMatColorBL;
// define the ChannelData and set the u/v coords for sampling
ChannelData chData;
chData.p = Vector(0.5, 0.5, 0);
// call the InitRender before executing sampling
const INITRENDERRESULT res = activeMatColorBS->InitRender(irs);
if (res != INITRENDERRESULT::OK)
return EXECUTIONRESULT::OK;
// sample
const Vector sampledValue = activeMatColorBS->Sample(&chData);
// correct based on the color space transformation
const Vector transformedColor = TransformColor(sampledValue, transform).Clamp01();
// just print
DiagnosticOutput("Shader '@' sample at [@,@]: @ / @", maxon::String(activeMatColorBL->GetName()), chData.p.x, chData.p.y, sampledValue, transformedColor);
// call the FreeRender to release allocated memory used for sampling
activeMatColorBS->FreeRender();
return EXECUTIONRESULT::OK;
}
The "same" code used inside a PythonTag works as well
def main():
# look for an attached TextureTag
textureTag = op.GetObject().GetTag(c4d.Ttexture)
if textureTag is None:
return
# look for the referred material
mat = textureTag.GetMaterial()
if mat is None:
return
# look for the shader in the color param
shd = mat[c4d.MATERIAL_COLOR_SHADER]
if shd is None:
return
# init, sample and free
initRS = c4d.modules.render.InitRenderStruct()
c4d.INITRENDERRESULT_OK == shd.InitRender(initRS)
chanData = c4d.modules.render.ChannelData()
chanData.p = c4d.Vector(0.5,0.5,0)
print "Shader '",shd.GetName(),"' sample at [",chanData.p.x,",",chanData.p.y,"]: ", shd.Sample(chanData)
shd.FreeRender()
Finally a screenshot of the test scene

Hoping it helps, don't hesitate to get back for any further help.
Riccardo