Manifold Geometry // Многообразная Геометрия

Ошибки

Подписаться на эту рубрику по RSS

Известные грабли

Цветная геометрия XDE

"The use of color on a model does not mean you’re weak or trying to be artistic, or a closet marketing monkey. It means you’re visually organized. It means you have a system and can identify parts quickly, at sight. Color can be used in models to help you quickly and visually identify different types of geometry in parts and assemblies. You can even use colors in multibody models to help you identify faces that will eventually go into creating a particular body or area of the model. Visualization techniques can save you a lot of time, and if you standardize techniques across your organization, that savings will really accumulate." (source)

В предыдущей заметке мы говорили о том, как прочитать файл STEP с метаданными в OpenCascade. Напомним, что структурой хранения данных для сборок и всей сопутствующей информации является OCAF, а точнее, его специализация XDE (eXtended Data Exchange). После того как содержимое обменного формата прочитано в структуры XDE, возникает необходимость получать из этих структур геометрию и атрибуты. Ниже приведен кусок кода, который выводит на экран все прочитанные из обменного файла (STEP, IGES) цвета и ассоциированные с ними метки деталей («геометрию»).

//-----------------------------------------------------------------------------
  
void DumpShapesForTreeNode(const Handle(TDataStd_TreeNode)& TN,
                           Standard_OStream&                out)
{
  // Iterate over the list of direct children for the color. These children
  // are the labels of parts and instances by design
  for ( TDataStd_ChildNodeIterator tnit(TN, false); tnit.More(); tnit.Next() )
  {
    const Handle(TDataStd_TreeNode)& TN_child = tnit.Value();
    
    // Get label of the part or instance
    TDF_Label labOfPartOrInstance = TN_child->Label();
    
    // Get entry for dump
    TCollection_AsciiString entryOfPartOrInstance;
    TDF_Tool::Entry(labOfPartOrInstance, entryOfPartOrInstance);
    //
    out << "	" << entryOfPartOrInstance.ToCString() << "
";
  }
}
  
//-----------------------------------------------------------------------------
  
TCollection_AsciiString ColorTypeName(const XCAFDoc_ColorType colorType)
{
  TCollection_AsciiString name;
  switch ( colorType )
  {
    case XCAFDoc_ColorSurf: name = "Surface color";        break;
    case XCAFDoc_ColorCurv: name = "Curve color";          break;
    case XCAFDoc_ColorGen:  name = "Generic color";        break;
    default:                name = "Undefined color type"; break;
  }
  return name;
}
  
//-----------------------------------------------------------------------------
  
void DumpColorType(const XCAFDoc_ColorType colorType,
                   Standard_OStream&       out)
{
  TCollection_AsciiString colorInfo;
  
  // Dump color name and components
  colorInfo += " / ";
  colorInfo += ColorTypeName(colorType);
  
  // Output
  out << colorInfo;
}
  
//-----------------------------------------------------------------------------
  
//! Dumps colors and shapes associated with colors.
//! param[in]  XDE document.
//! param[out] out output stream.
void DumpColoredShapes(const Handle(TDocStd_Document)& doc, Standard_OStream& out)
{
  out << "===========================================
";
  out << "Colored shapes
";
  out << "===========================================
";
  
  Handle(XCAFDoc_ColorTool) colorTool = XCAFDoc_DocumentTool::ColorTool( doc->Main() );
  
  // Get all colors
  TDF_LabelSequence colorLabels;
  colorTool->GetColors(colorLabels);
  //
  for ( TDF_LabelSequence::Iterator cit(colorLabels); cit.More(); cit.Next() )
  {
    const TDF_Label& colorLabel = cit.Value();
    TCollection_AsciiString colorInfo;
    
    // Get color name
    Handle(TDataStd_Name) nameAttr;
    if ( !colorLabel.FindAttribute(TDataStd_Name::GetID(), nameAttr) )
      colorInfo = "Undefined color name";
    else
      colorInfo = nameAttr->Get();
    
    // Get visibility
    if ( !colorTool->IsVisible(colorLabel) )
      colorInfo += " / Invisible";
    
    // Output
    out << colorInfo;
    
    // Dump color type
    Handle(TDataStd_TreeNode) TNSurf, TNCurve, TNGen;
    if ( colorLabel.FindAttribute( XCAFDoc::ColorRefGUID(XCAFDoc_ColorSurf), TNSurf ) )
      DumpColorType(XCAFDoc_ColorSurf, out);
    if ( colorLabel.FindAttribute( XCAFDoc::ColorRefGUID(XCAFDoc_ColorCurv), TNCurve ) )
      DumpColorType(XCAFDoc_ColorCurv, out);
    if ( colorLabel.FindAttribute( XCAFDoc::ColorRefGUID(XCAFDoc_ColorGen), TNGen ) )
      DumpColorType(XCAFDoc_ColorGen, out);
    //
    out << "
";
    
    // Dump shapes
    if ( !TNSurf.IsNull() )
      DumpShapesForTreeNode(TNSurf, out);
    if ( !TNCurve.IsNull() )
      DumpShapesForTreeNode(TNCurve, out);
    if ( !TNGen.IsNull() )
      DumpShapesForTreeNode(TNGen, out);
  }
}

Вот пример вызова:

DumpColoredShapes(doc, std::cout);

Переменная doc имеет тип TDocStd_Document. Это OCAF-документ, в который было прочитано содержимое обменного файла. Для тестового файла, содержащего цвета граней и ребер (см. картинку выше), будет выведена следующая информация:


Искушенного программиста, наверное, смутит неповоротливость и сложность заявленного выше механизма фильтрации данных. Заметил ли читатель, насколько органичнее для решения подобных задач смотрится База Данных и верный слуга ее SQL?