Group of breps vs polysurface

Hello,

I wonder what are the differences between a set of breps joined as polysurface or the same set joined as a group.

Does a polysurface have a unique id (and a group several ids)?

Can one attach a single instance of ON_UserData to a whole group, like with polysurfaces?

Also, when a single brep is modified, does its whole corresponding polysurface have to be replaced (but not the whole group)?

Thanks,
Pablo

Hi @Pablo_Garcia-Amorena,

A surface is a Brep with a single face. A polysurface is just a Brep with more than one face. Both objects are represented in Rhino as a CRhinoBrepObject.

Just one

Yes, you can attach user data to a CRhinoGroupObject and/or an ON_Group.

Yes

– Dale

Hi @dale,

How can I select and attach user data to a group? I tried the following:

CRhinoGetObject go;
go.SetCommandPrompt(L"Select group");
go.EnableGroupSelect(TRUE);
go.EnableSubObjectSelect(FALSE);
go.GetObjects(1, 0);
if (go.CommandResult() != CRhinoCommand::success) return go.CommandResult();

for (int i = 0; i < go.ObjectCount(); i++)
{
	const CRhinoObjRef& obj_ref = go.Object(i);
	const CRhinoObject* obj = obj_ref.Object();
	if (nullptr != obj)
	{
		const CRhinoGroupObject* groupObj = CRhinoGroupObject::Cast(obj);
		if (nullptr != groupObj) 
		{
			RhinoApp().Print("Selected group\n");
			//Do something with this group, attach user data, etc
		}
	}
}

The code above seems to properly select groups, but the objects referenced by the GetObject getter are the ones belonging to the group, not the group itself. So I can’t cast CRhinoGroupObject

Pablo

Hi @Pablo_Garcia-Amorena,

See if this helps.

CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
{
  CRhinoGetObject go;
  go.SetCommandPrompt(L"Select grouped objects");
  go.EnableGroupSelect(TRUE);
  go.EnableSubObjectSelect(FALSE);
  go.GetObjects(1, 0);
  if (go.CommandResult() != CRhinoCommand::success) 
    return go.CommandResult();

  ON_SimpleArray<int> indices;
  for (int i = 0; i < go.ObjectCount(); i++)
  {
    const CRhinoObjRef& obj_ref = go.Object(i);
    const CRhinoObject* obj = obj_ref.Object();
    if (nullptr != obj)
      indices.Append(obj->Attributes().GroupCount(), obj->Attributes().GroupList());
  }

  // sort
  indices.QuickSort(&ON_CompareIncreasing<int>);

  // cull
  int index = -1;
  for (int i = indices.Count() - 1; i >= 0; i--)
  {
    if (indices[i] == index)
      indices.Remove(i);
    else
      index = indices[i];
  }

  const CRhinoGroupTable& groups = context.m_doc.m_group_table;
  for (int i = 0; i < indices.Count(); i++)
  {
    index = indices[i];
    if (0 <= index && index < groups.GroupCount())
    {
      const CRhinoGroup* group = groups[index];
      if (nullptr != group)
        RhinoApp().Print(L"Group %d = %s\n", index, group->Name().Array());
    }
  }

  return CRhinoCommand::success;
}

– Dale

Great, thank you @dale !

To attach user data, I use ON_Group::AttachUserData(ON_UserData *pUserData) over a duplicate of the group and calling
context.m_doc.m_group_table.ModifyGroup(const ON_Group& group, int group_index)
with this duplicate as input and the index. Hope this is the right way to do.

Pablo