How to assign a parent layer using openNURBS

Hi, I’d like to create a Rhino file with hierarchical layers. I.e. I want to have Layer2 be the child of parent layer Layer1. How can I accomplish this?

I assume I have to assign the uuid of the parent layer to the child’s m_parent_layer_id attribute. But simple assignment didn’t do the trick. I’m not sure if the parent layer already has a uuid. How can I print the uuid, i.e. get a char* for diagnostic output?

Thanks in advance,
Gero.

Something like this should do it:

static bool write_layers_example(FILE* fp, int version, ON_TextLog& error_log)
{
  ONX_Model model;

  // Properties
  model.m_properties.m_RevisionHistory.NewRevision();
  model.m_properties.m_Application.m_application_name = "OpenNURBS write_layers_example() function";
  model.m_properties.m_Application.m_application_URL = "http://www.opennurbs.org";
  model.m_properties.m_Application.m_application_details = "Example program in OpenNURBS toolkit.";
  model.m_properties.m_Notes.m_notes = "This file was made with the OpenNURBS write_layers_example() function.";
  model.m_properties.m_Notes.m_bVisible = true;

  // Settings
  model.m_settings.m_ModelUnitsAndTolerances.m_unit_system = ON::millimeters;
  model.m_settings.m_ModelUnitsAndTolerances.m_absolute_tolerance = 0.01;
  model.m_settings.m_ModelUnitsAndTolerances.m_angle_tolerance = ON_PI/180.0;
  model.m_settings.m_ModelUnitsAndTolerances.m_relative_tolerance = 0.01;

  // Hierarchical layers
  for (int i = 0; i < 5; i++)
  {
    ON_wString name;
    name.Format(L"Layer %02d", i);

    ON_Layer layer;
    layer.SetLayerName(name);
    layer.SetVisible(true);
    layer.SetLocked(false);
    layer.SetLayerIndex(i);
    
    ON_CreateUuid(layer.m_layer_id);

    // Set the layer's parent
    if (i != 0)
      layer.m_parent_layer_id = model.m_layer_table[i-1].m_layer_id;

    model.m_layer_table.Append(layer);
  }

  // Finish...

  model.Polish();

  ON_BinaryFile archive(ON::write3dm, fp);
  const char* comment = __FILE__ "write_layers_example()" __DATE__;
  bool rc = model.Write(archive, version, comment, &error_log);

  return rc;
}

You can convert a UUID to a string using ON_UuidToString.

Hi Dale,

thanks a lot for your answer. It helped me a lot.

Btw: This example is not provided with the openNURBS source code, is it? Did I overlook something? Or are there more examples available?

My problem seems to be that ON_CreateUuid does not provide a reasonable uuid. In opennurbs_uuid.h it says “Only works on Windows.” My program is supposed to run on Linux. Have you got any suggestions for this case?

Thanks, kind regards,
Gero.

…just came to my mind:

Except for this parent layer functionality everything else runs fine on Linux. I.e. I can create a Rhino file with some (mesh-) objects in it, also layers. How come if Linux can’t create uuids? Is there another function that creates uuids which also works on Linux? Or is a Rhino file without uuids ok as well? Are missing uuids created when the file is imported?

If you could shed some light on those mysteries that would be awesome… Thanks again, Gero.

I found something on my own that might help: http://stackoverflow.com/questions/2174768/generating-random-uuids-in-linux

Something like this could be added to the openNURBS sources. If it’s not there already… (?)

My code is not found in the openNURBS source - it’s just something I typed up…

You should not have any problem finding some open source code that will generate unique GUIDs.

For example, the Boost library can generate GUIDs.

Another possibility is libuuid, which is part of the util-linux package Any Linux machine will have it installed already.

Because of this, I don’t see a reason to add anything to openNURBS specifically for Linux.

– Dale

Well, essentially openNURBS doesn’t work on Linux the way it is advertised in the examples. Wouldn’t that be a reason?

This inconsistency forces me to differentiate the code for Windows and Linux. What I will actually do is patch the ON_CreateUuid function to create uuids in Linux as well. Then my main program will be portable and identical for Windows and Linux.

Anyway, thanks for the information.

If there were not solutions available, we’d provide one. But there appears to be many - here is another:

http://linux.die.net/man/3/uuid_generate

– Dale

i’m using openNURBS 7.x, ON_Layer::SetParentLayerId() works for me:

for(int i = 0; i < 2;i++) {
            std::wstring layerName = fmt::format(L"Model_{}", i);
            int layerIndex = model.AddLayer(layerName.c_str(), ON_Color::UnsetColor);
            ON_Layer* curLayer = const_cast<ON_Layer*>(ON_Layer::Cast(model.LayerFromIndex(layerIndex).ModelComponent()));
            const ON_Layer* rootLayer = ON_Layer::Cast(model.LayerFromIndex(rootLayers[i]).ModelComponent());
            curLayer->SetParentLayerId(rootLayer->Id());