Annotation examples


#1

The annotation class is different from the v5 Annotation2 class. I am trying to get my head around the new classes including the dimension classes… seems difficult.

Some example files showing the optimal way of reading / creating annotations and dimensions with v6, would be really helpful. What happens when OpenNURBS reads previous version of the annotation/dimensions.

Thanks in advance.


(Dale Fugier) #2

Hi @rajeev,

The annotation classes have been overhauled in Rhino 6.

http://developer.rhino3d.com/guides/cpp/annotation-objects/

OpenNURBS will correctly convert annotations, written in V5, to the new annotation objects available in V6.

Reading annotations should not be too difficult. Here is a starting point you can use:

ONX_Model model;...
...
ONX_ModelComponentIterator it(model, ON_ModelComponent::Type::ModelGeometry);
const ON_ModelComponent* model_component = nullptr;
for (model_component = it.FirstComponent(); nullptr != model_component; model_component = it.NextComponent())
{
  const ON_Annotation* annotation = ON_Annotation::Cast(model_component);
  if (nullptr != annotation)
  {
    const ON_ModelComponentReference& model_component_ref = model.DimensionStyleFromId(annotation->DimensionStyleId());
    const ON_DimStyle* dim_style = ON_DimStyle::Cast(model_component_ref.ModelComponent());
    if (nullptr != dim_style)
    {
      switch (annotation->Type())
      {
      // Text
      case ON::AnnotationType::Text:
      {
        const ON_Text* text = ON_Text::Cast(annotation);
        if (nullptr != text)
        {
          // TODO...
        }
      }
      break;
      // Linear dimensions
      case ON::AnnotationType::Aligned:
      {
        const ON_DimLinear* dim_linear = ON_DimLinear::Cast(annotation);
        if (nullptr != dim_linear)
        {
          // TODO...
        }
      }
      break;
      // Etc...
      }
    }
  }
}

If you want assistance porting the creation of V5 annotations to V6, just forward me your old code.

Thanks,

– Dale


#3

Hi @dale,

Thank you so much. Please find the sample code snippet below. I am guessing that annotation and dimensions are geometry objects and should be added to the ONX_Model by AddManagedModelGeometryComponent method?

I am not able to figure out the replacement for SetPoint methods in the v5 dimension/annotation class

############## old code below

			    ON_LinearDimension2* dim = new ON_LinearDimension2();				
				double x1, y1, z1, x2, y2, z2, off;
				//get the above variables from external api in CM
				x1 *= 10; y1 *= 10; z1 *= 10;
				x2 *= 10; y2 *= 10; z2 *= 10;
				off *= 10;
				ON_3dPoint start = ON_3dPoint(x1,y1,z1); 
				ON_3dPoint end = ON_3dPoint(x2,y2,z2);
				ON_3dPoint z3 = ON_3dPoint(x2 + 10, y2 + 10, z2 + 10);
				if (start.x == end.x && start.z == end.z)
				{
					z3.x = x2+10; z3.y = y2; z3.z = z2;
				}
				else if (start.y == end.y && start.z == end.z)
				{
					z3.x = x2; z3.y = y2+10; z3.z = z2;
				}
				else if (start.x == end.x && start.y == end.y)
				{
					z3.x = x2; z3.y = y2; z3.z = z2+10;
				}
				const double dist = start.DistanceTo(end);
				ON_Plane pln = ON_Plane(start,end,z3);
				dim->SetPlane(pln);
				dim->SetPoint(0, ON_2dPoint(0,0));
				dim->SetPoint(1, ON_2dPoint(0,off));
				dim->SetPoint(2, ON_2dPoint(dist,0));
				dim->SetPoint(3, ON_2dPoint(dist,off));
				dim->SetType(ON::dtDimAligned);
				dim->SetTextValue(L"<>");
				ON_TextLog errlog;
				if(dim->IsValid(&errlog))
				{
					ONX_Model_Object &mo = model.m_object_table.AppendNew();
					mo.m_object = dim;
					mo.m_bDeleteObject = true;
					mo.m_attributes.m_layer_index = from_external_api;
					dim = 0;
				}
				delete dim;

############ end code


(Dale Fugier) #4

Hi @rajeev,

I have not tested this. But this should work.

static bool Internal_AddDimLinear(
  ONX_Model& model,
  ON_3dPoint point0,
  ON_3dPoint point1,
  ON_3dPoint line_point,
  ON_3dVector plane_normal,
  const ON_DimStyle* dim_style,
  const ON_3dmObjectAttributes* attributes
)
{
  if (nullptr == dim_style)
  {
    const ON_ModelComponentReference& dim_style_ref = model.CurrentDimensionStyle();
    dim_style = ON_DimStyle::Cast(dim_style_ref.ModelComponent());
  }

  if (nullptr == dim_style)
    return false;

  const ON_UUID parent_id
    = dim_style->ParentIdIsNotNil()
    ? dim_style->ParentId()
    : dim_style->Id();

  const ON_ModelComponentReference& parent_dim_style_ref = model.DimensionStyleFromId(parent_id);
  const ON_DimStyle* parent_dim_style = ON_DimStyle::Cast(parent_dim_style_ref.ModelComponent());
  if (nullptr == parent_dim_style)
    return false;

  ON_DimLinear dim_linear;
  if (nullptr == ON_DimLinear::CreateAligned(point0, point1, line_point, plane_normal, parent_dim_style->Id(), &dim_linear))
    return false;

  if (dim_style->ContentHash() != parent_dim_style->ContentHash())
  {
    ON_DimStyle* override_style = new ON_DimStyle(*dim_style);
    override_style->SetParentId(parent_dim_style->Id());
    override_style->ClearId();
    override_style->ClearName();
    override_style->OverrideFieldsWithDifferentValues(*dim_style, *parent_dim_style);
    if (override_style->HasOverrides())
      dim_linear.SetOverrideDimensionStyle(override_style);
    else
      delete override_style;
  }

  if (nullptr == attributes)
    attributes = &ON_3dmObjectAttributes::DefaultAttributes;

  // 'model' will copy input and manage this memory
  const ON_ModelComponentReference& geometry_ref = model.AddModelGeometryComponent(&dim_linear, attributes);
  return !geometry_ref.IsEmpty();
}

– Dale


#5

Thank you dale. It was really helpful in understanding the new concepts.


#6

Hi @dale,

How is the Diameter Dimension implemented. I am not able to find a DimDiameter class…
Should the ON_DimRadial() class be used instead? Or is it ON_LinearDimension().

Thanks


(Dale Fugier) #7

Hi @rajeev,

To creae a diameter dimension, use ON_DimRadial.

– Dale