Adding ON_Text to ONX_Model

I’m having some trouble adding text to an ONX_Model. Whenever I open the saved .3dm in Rhino, the text size is always 0.125 Decimal Inches. It doesn’t matter what I set the text height to on the ON_Text object or ON_DimScale object, it’s always 0.125 Decimal Inches.

Is there a sample anywhere showing the correct way to add text to a ONX_Model?

Thanks,

-Luke

Hey @lukeniwranski,

What version of openNURBS are you using? If you are using openNURBS 6 or greater, then you should be controlling the text height using an ON_DimStyle.

– Dale

Hi Dale,

I’m using openNURBS 7.x. I’ve tried setting the text height on both the ON_Text and ON_DimStyle object, neither produce the result I’m looking for. I suspect I’m not adding the ON_DimStyle to the document correctly or the ID of the ON_DimStyle referenced by the ON_Text is changing after adding.

Here is a snippit of the last thing I tried. Here I’m just using the ID of the DimStyle before adding it to the model. I’ve also tried casting dimRef to a ON_DimStyle to retrieve the ID, but that didn’t work.

ONX_Model = ...;    
ON_Text* pText = someText.Duplicate();

// Create the attributes
ON_3dmObjectAttributes *pObjAttribs = someAttributes.Duplicate();
pObjAttribs->SetName(L"some name");
pObjAttribs->SetColorSource(ON::color_from_object);
pObjAttribs->m_color.SetRGB(255, 0, 0);

// Create and add the DimStyle
// ON_DimStyle::DefaultMillimeterSmall fails here for some reason
ON_DimStyle* pTextDimStyle = pText->DimensionStyle(ON_DimStyle::SystemDimstyleFromIndex(-5)).Duplicate();
pTextDimStyle->SetTextHeight(20.0);
ON_ModelComponentReference dimRef = model.AddManagedModelGeometryComponent(pTextDimStyle, nullptr);

// Add the text to the document
pText->SetDimensionStyleId(pTextDimStyle->Id());
ON_ModelComponentReference ref = model.AddManagedModelGeometryComponent(pText, pObjAttribs);

I’m really not sure of the proper way to handle the ON_DimStyles. I’ve never worked with them before. My assumption is this that I need to create a new ON_DimStyle, set the text height, then add it to the ONX_Model. Then I need to get the ID of the newly added DimStyle and use ON_Text::SetDimensionStyleId to set the text ON_DimStyle before adding it to the ONX_Model. Is this correct?

I was able to create some text and a DimStyle and add them to a Rhino document just fine. But for whatever reason, I just can’t get it to work in openNURBS.

Is there an example of how to do this?

Thanks!

Hi @lukeniwranski,

Here is an example of how to write text objects to a 3dm file using an ON_Model object. You should be a able to copy this into the openNURBS example_write project.

static bool write_text_example(const wchar_t* filename, ON_TextLog& error_log)
{
  ONX_Model model;
  INTERNAL_INITIALIZE_MODEL(model);

  model.m_settings.m_ModelUnitsAndTolerances.m_unit_system = ON::LengthUnitSystem::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;

  model.AddDefaultLayer(nullptr, ON_Color::Black);

  const wchar_t* string = L"Hello Rhino!";
  ON_Plane plane = ON_Plane::World_xy;
  double height = 20.0;

  // Add a default dimension style
  const ON_DimStyle* parent_dimstyle = nullptr;
  {
    ON_DimStyle default_dimstyle(ON_DimStyle::Default);
    default_dimstyle.ClearIndex();
    default_dimstyle.ClearParentId();
    default_dimstyle.SetId();
    default_dimstyle.SetName(model.Manifest().UnusedName(default_dimstyle));
    ON_ModelComponentReference mcr = model.AddModelComponent(default_dimstyle, true);
    parent_dimstyle = ON_DimStyle::FromModelComponentRef(mcr, nullptr);
  }
  if (nullptr == parent_dimstyle)
  {
    ON_ERROR("Failed to add default dimstyle.");
    return false;
  }
  model.m_settings.SetCurrentDimensionStyleId(parent_dimstyle->Id());

  // Add a text object to the model.
  ON_Text* text0 = new ON_Text();
  if (text0->Create(string, parent_dimstyle, plane))
  {
    ON_3dmObjectAttributes* attributes = Internal_CreateManagedAttributes(0, nullptr);
    model.AddManagedModelGeometryComponent(text0, attributes);
  }
  else
  {
    delete text0;
    ON_ERROR("Failed to create text object.");
    return false;
  }

  // Create a dimension style that overrides the default
  const ON_DimStyle* child_dimstyle = nullptr;
  {
    ON_DimStyle dimstyle = parent_dimstyle->CreateOverrideCandidate();
    dimstyle.SetFieldOverride(ON_DimStyle::field::TextHeight, true);
    dimstyle.SetTextHeight(height);
    ON_ModelComponentReference mcr = model.AddModelComponent(dimstyle, true);
    child_dimstyle = ON_DimStyle::FromModelComponentRef(mcr, nullptr);
  }
  if (nullptr == child_dimstyle)
  {
    ON_ERROR("Failed to add child dimstyle.");
    return false;
  }

  plane.SetOrigin(ON_3dPoint(0.0, height + 1.0, 0.0));
  ON_Text* text1 = new ON_Text();
  if (text1->Create(string, child_dimstyle, plane))
  {
    ON_3dmObjectAttributes* attributes = Internal_CreateManagedAttributes(0, nullptr);
    attributes->SetName(L"some name", true);
    attributes->SetColorSource(ON::color_from_object);
    attributes->m_color.SetRGB(255, 0, 0);
    model.AddManagedModelGeometryComponent(text1, attributes);
  }
  else
  {
    delete text1;
    return false;
  }

  return Internal_WriteExampleModel(model, filename, error_log);
}

– Dale

Hi @dale,

Thank-you, this is exactly what I was looking for!

-Luke