Solved Voronoi Fracture Glitch

Hello,

I am working on a plugin and running into an unusual visual glitch that seems to only happen when the scene includes a Voronoi Fracture in addition to my plugin. When I select the Voronoi and then switch to my plugin the issue occurs.

The problem manifests like this in the attribute manager for my pluginPlugin Visual.png

Inside the Voronoi Fracture it shows up like thisVoronoi Visual.png

I tried using other objects in place of the Voronoi and couldn't replicate the issue.

Below is the code from creating the Object tab in GetDDescription. I simplified my code to look into the issue so all of my controls are identical except for the ids and the names. The names are large so that the horizontal scrollbar will be needed.

    if (!description->LoadDescription(node->GetType()))
    {
    }
    BaseObject* op = static_cast<BaseObject*>(node);
    if (op == nullptr)
    {
        return FALSE;
    }
   

    const DescID *singleid = description->GetSingleDescID();
    
    Bool initbc2 = FALSE;
    BaseContainer bc2;
    DescID cid;
    BaseContainer* datainstance = op->GetDataInstance();
    DescID DescGroup = DescLevel(idGroup,  DTYPE_GROUP,  0);
    if (!singleid || DescGroup.IsPartOf(*singleid,  NULL))
    {
        BaseContainer bc;
        bc = GetCustomDataTypeDefault(DTYPE_GROUP);
        bc.SetString(DESC_NAME,  "Object"_s);
        
        
        bc.SetInt32(DESC_COLUMNS,  1);
        bc.SetFloat(DESC_DEFAULT,  1);
        bc.SetBool(DESC_SCALEH,  TRUE);
        bc.SetBool(DESC_DEFAULT,  TRUE);
        
        if (!description->SetParameter(DescGroup,  bc,  ID_GENSPLINE))
        {
            return TRUE;
        }
    }
    
	DescID DescTestGroup = DescLevel(98765, DTYPE_GROUP, 0);
	if (!singleid || DescGroup.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_GROUP);
		bc.SetInt32(DESC_COLUMNS, 2);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_SCALEH, FALSE);

		if (!description->SetParameter(DescTestGroup, bc, DescGroup))
			return TRUE;
	}

      // Repeated the controls below until the attribute manager is large enough for the vertical scrollbar to appear

	cid = DescLevel(987650, DTYPE_REAL, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_REAL);

		bc.SetInt32(DESC_UNIT, DESC_UNIT_METER);
		bc.SetInt32(DESC_STEP, 1);

		bc.SetInt32(DESC_DEFAULT, 0);

		bc.SetString(DESC_NAME, "Offset                                                                      "_s);
		if (!description->SetParameter(cid, bc, 98765))
			return TRUE;
	}


	cid = DescLevel(987649, DTYPE_BOOL, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))  
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_BOOL);

		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_BOOL);
		bc.SetString(DESC_NAME, "Fields   "_s);
		bc.SetBool(DESC_DEFAULT, FALSE);
		if (!description->SetParameter(cid, bc, 98765))
			return TRUE;
	}



	cid = DescLevel(987648, DTYPE_REAL, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_REAL);

		bc.SetInt32(DESC_UNIT, DESC_UNIT_METER);
		bc.SetInt32(DESC_STEP, 1);

		bc.SetInt32(DESC_DEFAULT, 0);

		bc.SetString(DESC_NAME, "Offset          "_s);
		if (!description->SetParameter(cid, bc, 98765))
			return TRUE;
	}

The same problem shows up if I create a number of user data on my plugin and switch the selections between my plugin and the Voronoi.

The problem seems to be limited to when the display size for my controls are larger than the attribute manager.

Any help would be greatly appreciated.

John Terenece

Dear Community,

this bug has been fixed with S26.1, the glitches in the Attribute Manger should not appear anymore.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

Hello @johnterenece,

thank you for reaching out to us. Unfortunately, your question is missing some information which makes it hard for us to answer it. From the looks of your screenshots, I would assume that you are on R23, right? Unclear is also to us:

  1. What would you consider going wrong for your plugin in these screenshots?
  2. How does the Voronoi Fracture come into play with this? If I am understanding you correctly, the error only does occur when you select the Voronoi Fracture object, your second screenshot. But a Voronoi Fracture does not incorporate the descriptions of other nodes into its own description (other than objects in general which incorporate some tags into their description.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

@ferdinand Thanks for the response Ferdinand.

Sorry I was unclear with what the issue is. I am working in R23, from the tests I did the problem doesn't seem to occur in R20.

I'm not sure what you would call it exactly but the line being drawn through the attribute manager like this is the issue.
Plugin Visual2.png

The same kind of issue appears on the Voronoi Fracture best seen in its effect on the scrollbar.
Voronoi Visual2.png

If I shift the scrollbar in my plugin or the Voronoi the issue disappears, also if I make a change to one of the controls that the line is drawn across that will fix that control while leaving the line effecting rest of the controls.

I am not sure why the issue only seems to occur when I utilize a Voronoi Fracture. Running tests with various other objects, effectors and such did not show this same problem.

From what I can tell it seems to appear when the attribute manager has both a vertical and horizontal scrollbar. If I increase the size of the attribute manager so that the scrollbars aren't needed the issue doesn't seem to happen.

John Terenece

Hello @johnterenece,

thank you for explaining your problem inmore detail, I do understand your issue now.

Your code does nothing out of the ordinary on first glance, so I will have to investigate this myself. Which will take me some time to write a test case. I'll answer here once I have come to a conclusion.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

Thank you Ferdinand.

Hello @johnterenece,

so, I gave your problem yesterday a spin, and I was unfortunately unable to reproduce it. You will find at the end of the posting the exact setup I did use.

When I ran the example code (with some minor modifications) I had no "stripes". I ran the plugin alongside a Voronoi fracture object and also made sure that the Attribute manger had both horizontal and vertical scroll bars. Which either means I inadvertently fixed your code or there are other factors at play. I would propose that you look at my example and see if any of the comments in it help (there were some problems in your code). Please also make sure to not post fragments in the future, i.e., post a complete version of GetDDescription which is compileable, as it will otherwise always be a guessing game for us. If this does not help, which I somehow suspect will be the case, we will need more information from you:

  • The exact revision of Cinema 4D with which the problem occurs. I ran R23 SP1 (R23.110), are you on SP2?
  • The OS enviornment(s) you are in.
  • The description resource you are using.
  • The whole ObjectData implementation of the example. Are you interfering with description related messages in NodeData::Message?

As stated in our forum guidelines, you can send us data confidentially if it becomes necessary.

Cheers,
Ferdinand

The result: Annotation 2021-07-26 221230.png

The code:

/* Test for PC13488 GetDDescription troubles.
* 
* User reports that running a Voronoi fracture object alongside this plugin will cause horizontal
* glitches in description elements.
*/

#include "c4d.h"
#include "c4d_symbols.h"
#include "lib_description.h"
#include "pc13488.h"
#include "main.h"

#define ID_PC13488 1057997
#define ID_SOMEGROUP 98765
#define DYNAMIC_ELEMENTS_COUNT 25

class PC13488 : public ObjectData
{
    INSTANCEOF(PC13488, ObjectData)

public:
    virtual Bool Init(GeListNode* node);
    virtual Bool GetDDescription(GeListNode* node, Description* description, DESCFLAGS_DESC& flags);

    static NodeData* Alloc() { return NewObjClear(PC13488); }
};

Bool PC13488::Init(GeListNode* node)
{
    BaseObject* op = (BaseObject*)node;
    BaseContainer* data = op->GetDataInstance();
    if (!data)
        return false;
    return true;
}

Bool PC13488::GetDDescription(GeListNode* node, Description* description, DESCFLAGS_DESC& flags)
{
  // Bail if there is no description for this node type. You did omit exiting here, which makes
  // little sense to me, since if there is no description, you cannot modify it.
  if (!description->LoadDescription(node->GetType()))
    return false;

  // Bail if we cannot get hold of the tangible node, i.e., the BaseObject.
  BaseObject* op = static_cast<BaseObject*>(node);
  if (op == nullptr)
    return false;

  // Removed some unused variables here.
  const DescID* singleid = description->GetSingleDescID();
  DescID cid;

  // Had to modify this, since you used a symbol undefined in your example code.
  DescID descGroup = DescLevel(2000, DTYPE_GROUP, 0);
  if (!singleid || descGroup.IsPartOf(*singleid, NULL))
  {
    BaseContainer bc;
    bc = GetCustomDataTypeDefault(DTYPE_GROUP);

    // What confuses me a bit is that you also call this group "Object", because that is already
    // the name of the group with the id ID_OBJECTPROPERTIES, i.e., the default generator object
    // group.
    bc.SetString(DESC_NAME, "Custom Object Group"_s);
    bc.SetInt32(DESC_COLUMNS, 1);
    bc.SetFloat(DESC_DEFAULT, 1);
    bc.SetBool(DESC_SCALEH, TRUE);
    bc.SetBool(DESC_DEFAULT, TRUE);

    // Had also to modify this for the same reason, I attached the group to the root, i.e., this
    // group will be its on tab. You should also return false when setting the parameter fails, as 
    // this seems a bit more appropriate, but it should not make a big difference in "normal" 
    // operation where nothing goes wrong.
    if (!description->SetParameter(descGroup, bc, DESCID_ROOT))
      return false;
  }

  // From here on out it gets a bit chaotic, as you do use these hard-coded, non-consecutive, high 
  // value range IDs which are a bit hard to follow. But apart from being odd, there is nothing
  // wrong about it. I did replace at least the group id by a symbol. 
  DescID descTestGroup = DescLevel(ID_SOMEGROUP, DTYPE_GROUP, 0);
  if (!singleid || descGroup.IsPartOf(*singleid, NULL))
  {
    BaseContainer bc;
    bc = GetCustomDataTypeDefault(DTYPE_GROUP);

    bc.SetInt32(DESC_COLUMNS, 2);
    bc.SetInt32(DESC_DEFAULT, 1);
    bc.SetBool(DESC_SCALEH, FALSE);

    if (!description->SetParameter(descTestGroup, bc, descGroup))
      return false;
  }

  cid = DescLevel(987650, DTYPE_REAL, 0);
  if (!singleid || cid.IsPartOf(*singleid, NULL))
  {
    BaseContainer bc;
    bc = GetCustomDataTypeDefault(DTYPE_REAL);

    bc.SetInt32(DESC_UNIT, DESC_UNIT_METER);
    bc.SetInt32(DESC_STEP, 1);
    bc.SetInt32(DESC_DEFAULT, 0);
    // Added X's to make clear if there is some unwanted truncating going on.
    bc.SetString(DESC_NAME, "Offset                                                                      X"_s);

    if (!description->SetParameter(cid, bc, ID_SOMEGROUP))
      return false;
  }

  cid = DescLevel(987649, DTYPE_BOOL, 0);
  if (!singleid || cid.IsPartOf(*singleid, NULL))
  {
    BaseContainer bc;
    bc = GetCustomDataTypeDefault(DTYPE_BOOL);

    bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_BOOL);
    bc.SetString(DESC_NAME, "Fields   X"_s);
    bc.SetBool(DESC_DEFAULT, FALSE);

    if (!description->SetParameter(cid, bc, ID_SOMEGROUP))
      return false;
  }

  cid = DescLevel(987648, DTYPE_REAL, 0);
  if (!singleid || cid.IsPartOf(*singleid, NULL))
  {
    BaseContainer bc;
    bc = GetCustomDataTypeDefault(DTYPE_REAL);

    bc.SetInt32(DESC_UNIT, DESC_UNIT_METER);
    bc.SetInt32(DESC_STEP, 1);
    bc.SetInt32(DESC_DEFAULT, 0);
    bc.SetString(DESC_NAME, "Offset          X"_s);

    if (!description->SetParameter(cid, bc, ID_SOMEGROUP))
      return false;
  }

  // Tell Cinema that we did modify the description and call the base implementation.
  flags |= DESCFLAGS_DESC::LOADED;
  return SUPER::GetDDescription(node, description, flags);
}

Bool RegisterPC1057997()
{
    return RegisterObjectPlugin(ID_PC13488, "pc13488"_s, OBJECT_GENERATOR, PC13488::Alloc, "pc13488"_s, nullptr, 0);
}

The res file:

CONTAINER pc13488
{
  NAME pc13488;
  INCLUDE Obase;
  
  GROUP ID_OBJECTPROPERTIES
  {
    STATICTEXT ID_SOMESTATICSTUFF { }
  }
}

The .h file (of the description):

#ifndef pc13488_H__
#define pc13488_H__

enum
{
    ID_SOMESTATICSTUFF = 1000,
};

#endif // pc13488_H__

The .str file:

STRINGTABLE pc13488
{
    pc13488 "pc13488";
    ID_SOMESTATICSTUFF "A static text";
}

MAXON SDK Specialist
developers.maxon.net

Thanks for the response Ferdinand.

I am running R23 SP1 (R23.110) on Windows 10 (OS build 19041.1110). I am also encountering the same problem when running it in R24 (R24.111).

Here is all of my code, trimmed down to the bare minimum that still showed the issue.

#include "c4d.h"
#include "c4d_symbols.h"
#include "lib_description.h"

#define ID_BREAKSPLINE 1058002

class BreakSpline : public ObjectData
{
	INSTANCEOF(BreakSpline, ObjectData)
public:

	virtual Bool Init(GeListNode *node);
	static NodeData *Alloc() { return NewObjClear(BreakSpline); }
	
	Bool GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags);  
	
};

Bool BreakSpline::GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags)
{
	if (!description->LoadDescription(node->GetType()))
		return FALSE;
	BaseObject* op = static_cast<BaseObject*>(node);

	if (op == nullptr)
		return FALSE;

	const DescID *singleid = description->GetSingleDescID();

	BaseObject *pp;
	Bool first = TRUE;

	DescID cid;
	BaseContainer* datainstance = op->GetDataInstance();
	
	DescID DescGroup = DescLevel(10000, DTYPE_GROUP, 0);
	if (!singleid || DescGroup.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_GROUP);
		bc.SetString(DESC_NAME, "Object"_s);

		bc.SetInt32(DESC_COLUMNS, 1);
		bc.SetFloat(DESC_DEFAULT, 1);
		bc.SetBool(DESC_SCALEH, TRUE);
		bc.SetBool(DESC_DEFAULT, TRUE);

		if (!description->SetParameter(DescGroup, bc, ID_BREAKSPLINE))
		{
			return TRUE;
		}
	}

	DescID subgroupthree = DescLevel(10001, DTYPE_GROUP, 0);
	if (!singleid || subgroupthree.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_GROUP);
		bc.SetInt32(DESC_COLUMNS, 3);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_SCALEH, false);

		if (!description->SetParameter(subgroupthree, bc, DescGroup))
			return TRUE;
	}


	cid = DescLevel(10002, DTYPE_LONG, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_LONG);
		bc.SetString(DESC_NAME, "Orientation  "_s);
		BaseContainer MeasureDivisionNames;
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);

		MeasureDivisionNames.SetString(-1, ""_s);
		MeasureDivisionNames.SetString(0, "X+"_s);
		MeasureDivisionNames.SetString(1, "Y+"_s);
		MeasureDivisionNames.SetString(2, "Z+"_s);

		bc.SetContainer(DESC_CYCLE, MeasureDivisionNames);
		if (!description->SetParameter(cid, bc, subgroupthree))
			return TRUE;
	}

	cid = DescLevel(10003, DTYPE_BOOL, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_BOOL);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Run With Matrix"_s);

		if (!description->SetParameter(cid, bc, subgroupthree))
			return TRUE;
	}

	cid = DescLevel(10004, DTYPE_BUTTON, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_BUTTON);
		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_BUTTON);
		bc.SetString(DESC_NAME, "Create Reference"_s);
		if (!description->SetParameter(cid, bc, subgroupthree))
			return TRUE;
	}

	DescID linkgroup = DescLevel(10005, DTYPE_GROUP, 0);
	if (!singleid || subgroupthree.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_GROUP);
		bc.SetInt32(DESC_COLUMNS, 3);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_SCALEH, false);

		if (!description->SetParameter(linkgroup, bc, DescGroup))
			return TRUE;
	}

	DescID linkgroup2 = DescLevel(10006, DTYPE_GROUP, 0);
	if (!singleid || subgroupthree.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_GROUP);
		bc.SetInt32(DESC_COLUMNS, 3);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_SCALEH, false);

		if (!description->SetParameter(linkgroup2, bc, DescGroup))
			return TRUE;
	}
	

	cid = DescLevel(10007, DTYPE_SEPARATOR, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_SEPARATOR);
		bc.SetBool(DESC_SEPARATORLINE, TRUE);
		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}

	cid = DescLevel(10008, DTYPE_LONG, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_LONG);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetInt32(DESC_MIN, 0);
		bc.SetInt32(DESC_MINSLIDER, 0);

		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LONGSLIDER);
		bc.SetInt32(DESC_MAXSLIDER, 100);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Row 1"_s);

		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}

	cid = DescLevel(10009, DTYPE_LONG, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_LONG);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetInt32(DESC_MIN, 0);
		bc.SetInt32(DESC_MINSLIDER, 0);

		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LONGSLIDER);
		bc.SetInt32(DESC_MAXSLIDER, 100);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Row 2"_s);
		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}
	cid = DescLevel(10010, DTYPE_LONG, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_LONG);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetInt32(DESC_MIN, 0);
		bc.SetInt32(DESC_MINSLIDER, 0);

		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LONGSLIDER);
		bc.SetInt32(DESC_MAXSLIDER, 100);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Row 3"_s);


		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}
	cid = DescLevel(10011, DTYPE_LONG, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_LONG);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetInt32(DESC_MIN, 0);
		bc.SetInt32(DESC_MINSLIDER, 0);

		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LONGSLIDER);
		bc.SetInt32(DESC_MAXSLIDER, 100);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Row 4"_s);
		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}
	cid = DescLevel(10012, DTYPE_LONG, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_LONG);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetInt32(DESC_MIN, 0);
		bc.SetInt32(DESC_MINSLIDER, 0);

		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LONGSLIDER);
		bc.SetInt32(DESC_MAXSLIDER, 100);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Row 5"_s);
		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}
	cid = DescLevel(10013, DTYPE_LONG, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_LONG);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetInt32(DESC_MIN, 0);
		bc.SetInt32(DESC_MINSLIDER, 0);

		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LONGSLIDER);
		bc.SetInt32(DESC_MAXSLIDER, 100);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Row 6"_s);

		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}
	cid = DescLevel(10014, DTYPE_LONG, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_LONG);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetInt32(DESC_MIN, 0);
		bc.SetInt32(DESC_MINSLIDER, 0);

		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LONGSLIDER);
		bc.SetInt32(DESC_MAXSLIDER, 100);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Row 7"_s);


		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}
	cid = DescLevel(10015, DTYPE_LONG, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_LONG);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetInt32(DESC_MIN, 0);
		bc.SetInt32(DESC_MINSLIDER, 0);

		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LONGSLIDER);
		bc.SetInt32(DESC_MAXSLIDER, 100);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Row 8"_s);

		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}
	cid = DescLevel(10016, DTYPE_LONG, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_LONG);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetInt32(DESC_MIN, 0);
		bc.SetInt32(DESC_MINSLIDER, 0);

		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LONGSLIDER);
		bc.SetInt32(DESC_MAXSLIDER, 100);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Row 9"_s);


		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}
	cid = DescLevel(10017, DTYPE_LONG, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_LONG);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetInt32(DESC_MIN, 0);
		bc.SetInt32(DESC_MINSLIDER, 0);

		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LONGSLIDER);
		bc.SetInt32(DESC_MAXSLIDER, 100);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Row 10"_s);

		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}


	cid = DescLevel(10018, DTYPE_REAL, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_REAL);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);

		bc.SetInt32(DESC_MINSLIDER, 0);
		bc.SetInt32(DESC_UNIT, DESC_UNIT_METER);
		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_REALSLIDER);
		bc.SetInt32(DESC_MAXSLIDER, 5);
		bc.SetFloat(DESC_DEFAULT, 0);
		bc.SetFloat(DESC_STEP, .01);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Expand"_s);

		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}
	cid = DescLevel(10019, DTYPE_LONG, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_LONG);
		bc.SetBool(DESC_FORBID_SCALING, TRUE);
		bc.SetFloat(DESC_MIN, 0);

		bc.SetInt32(DESC_MINSLIDER, 0);
		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_REALSLIDER);
		bc.SetInt32(DESC_MAXSLIDER, 10);
		bc.SetInt32(DESC_MAX, 500);
		bc.SetFloat(DESC_DEFAULT, 0);
		bc.SetBool(DESC_FORBID_INLINE_FOLDING, FALSE);
		bc.SetString(DESC_NAME, "Smoothing"_s);

		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}



	cid = DescLevel(10020, DTYPE_SEPARATOR, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_SEPARATOR);
		bc.SetBool(DESC_SEPARATORLINE, TRUE);
		if (!description->SetParameter(cid, bc, DescGroup))
			return TRUE;
	}
	DescID SubGroupOne = DescLevel(10024, DTYPE_GROUP, 0);
	if (!singleid || SubGroupOne.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_GROUP);


		bc.SetInt32(DESC_COLUMNS, 2);
		bc.SetBool(DESC_SCALEH, TRUE);

		if (!description->SetParameter(SubGroupOne, bc, DescGroup))
		{
			return TRUE;
		}
	}
	
	DescID DescDataSplineTab = DescLevel(10021, DTYPE_GROUP, 0);
	if (!singleid || DescDataSplineTab.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_GROUP);
		bc.SetString(DESC_NAME, "Spline Controls"_s);
		bc.SetInt32(DESC_COLUMNS, 1);
		bc.SetInt32(DESC_DEFAULT, 0);
		bc.SetBool(DESC_SCALEH, TRUE);

		if (!description->SetParameter(DescDataSplineTab, bc, DescLevel(ID_BREAKSPLINE)))
			return TRUE;
	}


	DescID DescSplineGroup = DescLevel(10022, DTYPE_GROUP, 0);
	if (!singleid || DescSplineGroup.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_GROUP);
		bc.SetInt32(DESC_COLUMNS, 1);
		bc.SetInt32(DESC_DEFAULT, 1);
		bc.SetBool(DESC_SCALEH, TRUE);

		if (!description->SetParameter(DescSplineGroup, bc, DescDataSplineTab))
			return TRUE;
	}


	cid = DescLevel(10023, DTYPE_BOOL, 0);
	if (!singleid || cid.IsPartOf(*singleid, NULL))
	{
		BaseContainer bc;
		bc = GetCustomDataTypeDefault(DTYPE_BOOL);

		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_BOOL);
		bc.SetString(DESC_NAME, "Reverse"_s);
		bc.SetBool(DESC_DEFAULT, TRUE);
		if (!description->SetParameter(cid, bc, DescSplineGroup))
			return TRUE;
	}

	flags |= DESCFLAGS_DESC::LOADED | DESCFLAGS_DESC::RECURSIONLOCK;

	return SUPER::GetDDescription(node, description, flags);
}

Bool BreakSpline::Init(GeListNode *node)
{
	BaseObject *op = (BaseObject*)node;
	if (!op)
	{
		return FALSE;
	}
	return TRUE;
}

Bool RegisterBreakSpline()
{

	Int32 flags = 0;
	flags = OBJECT_GENERATOR | OBJECT_ISSPLINE | OBJECT_INPUT | OBJECT_UNIQUEENUMERATION;

	return RegisterObjectPlugin(ID_BREAKSPLINE, "Break"_s, flags, BreakSpline::Alloc, "OBreak"_s, nullptr, 0);
}

The res file:

CONTAINER OBreak
{
	NAME OBreak;
	INCLUDE Obase;

	GROUP ID_OBJECTPROPERTIES
	{
		
	}

}

The .h file

#ifndef _OBreak_H_
#define _OBreak_H_

enum
{
	
};

#endif

The .str file

STRINGTABLE OBreak
{
	OBreak "Break";

	
}

John Terenece

Hello @JohnTerenece,

I was able to reproduce your problem, but I am frankly myself a bit perplexed why it is happening. At the end of the posting you will find a sort of solution.

Let us first establish some conditions:

  • The problem seems completely independent from scrollbars or the size of the Attribute Manger.
  • The length of description elements seems to also have no impact.
  • But the presence of a Voronoi Fracture Object is indeed a triggering factor.
  • What seems to be happening is that the redraw of the Attribute Manger is only done partially. What you did report as these horizontal lines, is actually the border between the old redraw and the erroneously placed new redraw of the Attribute manger.
  • This only happens under very specific conditions: Create an instance of your plugin, then an instance of the Fracture Object, and switch back to your plugin object.
  • Other plugins that do similar things in GetDDescription, e.g., my PC13488 example posted here or the SDK C++ MorphMixer plugin do not suffer from the same problem.

What stood out to me, is that you do pass the flag DESCFLAGS_DESC::RECURSIONLOCK which will prevent GetDDescription being called again (and is also marked as private, which usually should be read as a warning that one should know exactly what one is doing when using the stuff marked as private). But removing that flag alone, for which I do not fully understand the purpose in your case, won't fix your issue. What will however sort of fix the issue, is to bail the execution when that same flag is being passed in:

Bool BreakSpline::GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags)
{
  // Bail when we are not meant to execute GetDDescription.
  if (flags & DESCFLAGS_DESC::RECURSIONLOCK)
    return false;

  // Your stuff  
  if (!description->LoadDescription(node->GetType()))
    return false;
    BaseObject* op = static_cast<BaseObject*>(node);

    if (op == nullptr)
        return FALSE;

    ...
  // End of your stuff.

  // Haven't tried if the problem reappears if one passes in RECURSIONLOCK
  // again here. I just removed it as one the first things and kept it then
  // like this.
  flags |= DESCFLAGS_DESC::LOADED; // | DESCFLAGS_DESC::RECURSIONLOCK;
  return SUPER::GetDDescription(node, description, flags);
}

This will make the problem disappear for me. The reason why I called this a "sort of"-solution, is that this smells very much like a bug caused by the Fracture object or the RECURSIONLOCK flag which somehow seems to bleed from one plugin into another, but most surprisingly not in the case of my almost identical PC13488 plugin or the SDK C++ Morphmixer plugin which is also quite close. But this bailing on RECURSIONLOCK is something which is done internally by us, so maybe this is some sort of known limitation.

Please let me know if this solved your problem.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

Thanks for the response.

I made the two changes and the problem is still present.

John Terenece

Hello @JohnTerenece,

hm, you are right, for me it is also now back again. I won't have time to investigate this this week any further. And this probably will then go next weeks to the developers. The problem is, I still do not fully understand what the conditions are for this to appear or not to appear.

Bottom line is, please expect some waiting time here.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

Hello @JohnTerenece,

I am sorry, but I have currently no time to debug this any further, as we are closing into the next release and work starts piling up left and right. I have entered this topic and the described bug into our bug tracking system, which will cause it do go through QA and then reach a developer. I cannot provide here a shortened path, as the developers are currently as busy as we are.

I will try to pick up the topic once we have released R25 and are done with the tasks that come after the release, which will probably be in mid to late September. I have added the to_fix tag to your topic, so that it won't get lost.

Thank you for your understanding,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

Hello @JohnTerenece,

I am sorry for your long wait. I unfortunately can still give you no concrete answer, as this topic is still in our bug tracking pipeline. I just wanted to make clear that we have not forgotten this topic.

Thank you for your understanding,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

Dear Community,

this bug has been fixed with S26.1, the glitches in the Attribute Manger should not appear anymore.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net