SOLVED Reorder gradient knots by position

Hello,
I'm searching a method to get gradient Knot by position not by index, the problem with gradient->GetKnot(i) is that when user change the knots position and knots order, the knot index stay the same for each knot.

I had create the following python function to get knot by position and I sorted them from lower to higher knot position.

def GetKnotByPos(gradient, index): 
    KnotDict = {}
    
    knotCount = gradient.GetKnotCount()
    
    for i in range(knotCount) :
        KnotDict[gradient.GetKnot(i)['pos']] = gradient.GetKnot(i)
    
    # dictionary’s keys select.
    Ks = list(KnotDict.keys())
    Ks.sort()
    return KnotDict[Ks[index]]['col']

# Use
gradient = op[c4d.MYOBJECT_GRADIENT]
for index in range(gradient.GetKnotCount()):
    color = GetKnotByPos(gradient, index)

I'm searching how to do the same thing but using c++.

const Int32 knotCount = gradient->GetKnotCount();
for (Int32 i = 0; i < knotCount; i++)
{
	GradientKnot knot = gradient->GetKnot(i);
	const Vector color = knot.col;

	result += String::VectorToString(color) + "\n";
}

Hello,

you can use a maxon::BaseArray to store elements in a list. You can use maxon::BaseSort to define a class that is able to sort the elements of such a BaseArray.

In the case of GradientKnots, it could look like this:

// custom BaseSort based class
class GradientSort : public maxon::BaseSort<GradientSort, maxon::BASESORTFLAGS::NONE>
{
public:
  static inline Bool LessThan(GradientKnot a, GradientKnot b)
  {
    return a.pos < b.pos;
  }
};

const Int32 knotCount = gradient->GetKnotCount();

// prepare array
maxon::BaseArray<GradientKnot> knots;
knots.EnsureCapacity(knotCount) iferr_return;

// fill array
for (Int32 i = 0; i < knotCount; i++)
{
  GradientKnot knot = gradient->GetKnot(i);
  knots.Append(knot) iferr_return;
}

// sort the elements stored in the array
GradientSort sort;
sort.Sort(knots);

// check order
for (GradientKnot& knot : knots)
{
  DiagnosticOutput("Pos: @", knot.pos);
}

best wishes,
Sebastian

Hello,

you can use a maxon::BaseArray to store elements in a list. You can use maxon::BaseSort to define a class that is able to sort the elements of such a BaseArray.

In the case of GradientKnots, it could look like this:

// custom BaseSort based class
class GradientSort : public maxon::BaseSort<GradientSort, maxon::BASESORTFLAGS::NONE>
{
public:
  static inline Bool LessThan(GradientKnot a, GradientKnot b)
  {
    return a.pos < b.pos;
  }
};

const Int32 knotCount = gradient->GetKnotCount();

// prepare array
maxon::BaseArray<GradientKnot> knots;
knots.EnsureCapacity(knotCount) iferr_return;

// fill array
for (Int32 i = 0; i < knotCount; i++)
{
  GradientKnot knot = gradient->GetKnot(i);
  knots.Append(knot) iferr_return;
}

// sort the elements stored in the array
GradientSort sort;
sort.Sort(knots);

// check order
for (GradientKnot& knot : knots)
{
  DiagnosticOutput("Pos: @", knot.pos);
}

best wishes,
Sebastian

@s_bach

Hi Sebastian,
Perfect, thank you very much.

Best regards,
Mustapha