DirectSample doc



  • Hi guys,

    Trying to sample some points against the fields in R21. Referring to doc wrote this

      if fields:
        fieldInput = c4d.modules.mograph.FieldInput(pPos, pCount)
        fieldInfo = c4d.modules.mograph.FieldInfo.Create(c4d.FIELDSAMPLE_FLAG_VALUE, None, doc, 0, 1, fieldInput, op)
        fieldOutput = c4d.modules.mograph.FieldOutput.Create(pCount, c4d.FIELDSAMPLE_FLAG_VALUE)
        fields.DirectInitSampling(fieldInfo)
        fields.DirectSample(fieldInput, fieldOutput, fieldInfo)
        fields.DirectFreeSampling(fieldInfo)
    
    

    But it fires error:

    TypeError: argument 2 must be c4d.modules.mograph.FieldOutputBlock, not c4d.modules.mograph.FieldOutput
    

    Tried to change code to:

    fields.DirectSample(fieldInput, fieldOutput, fieldInfo.GetBlock())
    

    Code executes but output values are 0. Any recommendations?



  • I don't know about your code. But a field is typically sampled using the "Sample" functions. There is an example using SampleListSimple().



  • hi ,

    thanks for the links @PluginStudent

    i'm surprised that you code execute.

    GetBlock() should be used in your FieldOutput.

            fields.DirectSample(fieldInput, fieldOutput.GetBlock(), fieldInfo)
            fields.DirectFreeSampling(fieldInfo)
    

    It's working here. Are you sure you are sampling value that should be different than 0 ?

    Cheers,
    Manuel



  • @m_magalhaes Thanks for reply.
    I was mistaken with GetBlock() when wrote a post: it should be applied to the FieldOutput object.

    I clear my issue now - I have custom point positions list (based on object's polygon center points), and I want to sample them.
    But code below:

        pPos = [c4d.Vector(-100, 0, -100), c4d.Vector(100, 0, -100), c4d.Vector(-100, 0, 100), c4d.Vector(100, 0, 100)]
        fieldInput = c4d.modules.mograph.FieldInput(pPos, len(pPos))
        fieldInfo = c4d.modules.mograph.FieldInfo.Create(c4d.FIELDSAMPLE_FLAG_VALUE, None, doc, 0, 1, fieldInput)
        fieldOutput = c4d.modules.mograph.FieldOutput.Create(pCount, c4d.FIELDSAMPLE_FLAG_VALUE)
        fields.DirectInitSampling(fieldInfo)
        samplingSuccess = fields.DirectSample(fieldInput, fieldOutput, fieldInfo)
        fields.DirectFreeSampling(fieldInfo)
        print samplingSuccess, fieldOutput._value
    

    prints False [0.0, 0.0, 0.0, 0.0]

    I see that documentation FieldInfo says callers parameter is optional, but is it true?
    Any recommendations?



  • I made a hack with temporary object

        pPos = [c4d.Vector(-100, 0, -100), c4d.Vector(100, 0, -100), c4d.Vector(-100, 0, 100), c4d.Vector(100, 0, 100)]
        pCount = len(pPos)
        tmpPoly = c4d.BaseObject(c4d.Opolygon)
        tmpPoly.ResizeObject(pCount , 0)
        tmpPoly.SetAllPoints(pPos)
        fieldInput = c4d.modules.mograph.FieldInput(pPos, pCount)
        fieldInfo = c4d.modules.mograph.FieldInfo.Create(c4d.FIELDSAMPLE_FLAG_VALUE, None, doc, 0, 1, fieldInput, tmpPoly)
        fieldOutput = c4d.modules.mograph.FieldOutput.Create(pCount, c4d.FIELDSAMPLE_FLAG_VALUE)
        fields.DirectInitSampling(fieldInfo)
        samplingSuccess = fields.DirectSample(fieldInput, fieldOutput, fieldInfo)
        fields.DirectFreeSampling(fieldInfo)
        print samplingSuccess, fieldOutput._value
    

    Seems it works fine - prints True and list of values

    Now I'm facing issue with sampling uvw as well:

        pPos = [c4d.Vector(-100, 0, -100), c4d.Vector(100, 0, -100), c4d.Vector(-100, 0, 100), c4d.Vector(100, 0, 100)]
        pCount = len(pPos)
        uvw = [c4d.Vector(0, 0, 0), c4d.Vector(1, 0, 0), c4d.Vector(0, 1, 0), c4d.Vector(1, 1, 0)]
        tmpPoly = c4d.BaseObject(c4d.Opolygon)
        tmpPoly.ResizeObject(pCount , 0)
        tmpPoly.SetAllPoints(pPos)
        fieldInput = c4d.modules.mograph.FieldInput(position=pPos, allocatedCount=pCount, transform=op.GetMg(), uvw=uvw)
        fieldInfo = c4d.modules.mograph.FieldInfo.Create(c4d.FIELDSAMPLE_FLAG_VALUE, None, doc, 0, 1, fieldInput, tmpPoly)
        fieldOutput = c4d.modules.mograph.FieldOutput.Create(pCount, c4d.FIELDSAMPLE_FLAG_VALUE)
        fields.DirectInitSampling(fieldInfo)
        samplingSuccess = fields.DirectSample(fieldInput, fieldOutput, fieldInfo)
        fields.DirectFreeSampling(fieldInfo)
        print samplingSuccess, fieldOutput._value
    

    prints False [0.0, 0.0, 0.0, 0.0]

    Alternative code:

        fieldInput = c4d.modules.mograph.FieldInput(pPos, pCount, op.GetMg(), pCount, None, uvw)
    

    returns error:

    StandardError: The arguments don't match any supplied constructors
    

    Would appreciate your help



  • Hi @baca sorry for the long delay we forget you, but here you are.

    The culprit is in the FieldInput initialization, that fail (you can check it by calling fieldInput.IsPopulated() will return False in your case).

    First, there is a little bug, if no arguments are passed then an empty FieldInfo is returned, but we don't check for keywords only for argument, so be sure to pass at least one parameter, not as a keyword argument.

    Then because in C++ you have multiple overrides of a function (aka multiple signatures for one function) but in python, this is not possible and we have to handle it internally by emulating it and by marking argument optimal while they are not really.

    So only few constructors are possibles which are:

    • no parameters passed = an empty FieldInput is returned.
    • position, allocatedCount.
    • position, allocatedCount, transform.
    • position, allocatedCount, transform, fullCount.
    • position, direction, allocatedCount, transform, fullCount.
    • position, direction, uvw, allocatedCount, transform, fullCount.

    So that means if you want to define the uvw you also need to define the position, direction, uvw(of course) the allocatedCount, transform, and the fullCount.

    So this gives us

    import c4d
    
    fields = op[c4d.FIELDS]
    
    pPos = [c4d.Vector(-100, 0, -100), c4d.Vector(100, 0, -100), c4d.Vector(-100, 0, 100), c4d.Vector(100, 0, 100)]
    pCount = len(pPos)
    uvw = [c4d.Vector(0, 0, 0), c4d.Vector(1, 0, 0), c4d.Vector(0, 1, 0), c4d.Vector(1, 1, 0)]
    
    tmpPoly = c4d.BaseObject(c4d.Opolygon)
    tmpPoly.ResizeObject(pCount , 0)
    tmpPoly.SetAllPoints(pPos)
    
    # This is important to pass pPos without a keyword due to a bug see my post https://plugincafe.maxon.net/topic/12723/directsample-doc/6
    fieldInput = c4d.modules.mograph.FieldInput(pPos, direction=uvw,  uvw=uvw, allocatedCount=pCount, transform=op.GetMg(), fullCount=pCount)
    fieldInfo = c4d.modules.mograph.FieldInfo.Create(c4d.FIELDSAMPLE_FLAG_VALUE, None, doc, 0, 1, fieldInput, tmpPoly)
    fieldOutput = c4d.modules.mograph.FieldOutput.Create(pCount, c4d.FIELDSAMPLE_FLAG_VALUE)
    
    fields.DirectInitSampling(fieldInfo)
    samplingSuccess = fields.DirectSample(fieldInput, fieldOutput.GetBlock(), fieldInfo)
    fields.DirectFreeSampling(fieldInfo)
    print(samplingSuccess, fieldOutput._value)
    

    Hope this helps. In any case, I will try to improve the documentation on this topic and I will create a bug report about the fact that if you pass only keyword argument then the default empty FieldList is returned.

    Cheers,
    Maxime.



  • @m_adam said in DirectSample doc:

    position, direction, uvw, allocatedCount, transform, fullCount

    Thanks Maxime, this is works now. Much appreciated your details and solution.

    PS: I noticed it's still necessary to create temporary Polygon Object, otherwise it wouldn't sample

    tmpPoly = c4d.BaseObject(c4d.Opolygon)
    tmpPoly.ResizeObject(pCount , 0)
    tmpPoly.SetAllPoints(pPos)
    

Log in to reply