STEPCAFControl_Writer无法导出面等子形状的名称与颜色数据
STEP文件导出时面颜色无法生效的问题解决
问题描述
我在处理STEP文件的导入与再导出工作,需要修改模型外观(颜色与材质)。目前Compound和Solid的颜色信息可以正常导出,但Face的颜色无法导出。已确认导出前Face对应的TDF_Label已包含颜色信息,以下是添加面颜色的导出代码,预期每个面都带有红色,但未实现:
void ShapeNode::Export(std::string fileName) { Handle (XCAFApp_Application) app = XCAFApp_Application::GetApplication(); // Create a new XDE document Handle (TDocStd_Document) doc; app->NewDocument("MDTV-XCAF", doc); // Access the shape, color, and material tools Handle (XCAFDoc_ShapeTool) shapeTool = XCAFDoc_DocumentTool::ShapeTool(doc->Main()); Handle (XCAFDoc_ColorTool) colorTool = XCAFDoc_DocumentTool::ColorTool(doc->Main()); Handle (XCAFDoc_MaterialTool) materialTool = XCAFDoc_DocumentTool::MaterialTool(doc->Main()); // Add the root shape to the document TDF_Label shapeLabel = shapeTool->AddShape(shape); // Set the name using TDataStd_Name attribute TDataStd_Name::Set(shapeLabel, name.c_str()); if (material.GetName() != "") { std::vector<double> color; if (material.GetAttribute(color, "Color")) { Quantity_Color col(color[0], color[1], color[2], Quantity_TOC_RGB); // Set the color colorTool->SetColor(shapeLabel, col, XCAFDoc_ColorGen); } Handle (TCollection_HAsciiString) matName = new TCollection_HAsciiString(material.GetName().c_str()); Handle (TCollection_HAsciiString) matDes = new TCollection_HAsciiString(material.GetName().c_str()); double density = 0.0; if (material.GetAttribute(density, "Density")) { TDF_Label matLabel = materialTool->AddMaterial(matName, matDes, density, matDes, matDes); materialTool->SetMaterial(shapeLabel, matLabel); } } for (TopExp_Explorer itf(shape, TopAbs_FACE); itf.More(); itf.Next()) { TopoDS_Face face = TopoDS::Face(itf.Current()); Quantity_Color color; if (!colorTool->SetColor(face, color, XCAFDoc_ColorSurf)) { TDF_Label faceLabel; if (!shapeTool->FindSubShape(shapeLabel, face, faceLabel)) { faceLabel = shapeTool->AddSubShape(shapeLabel, face); } colorTool->SetColor(faceLabel, Quantity_Color(1, 0, 0, Quantity_TOC_RGB), XCAFDoc_ColorSurf); } } // Write to STEP file STEPCAFControl_Writer writer; writer.Transfer(doc, STEPControl_AsIs); if (writer.Write(fileName.c_str()) != IFSelect_RetDone) { std::cout << "Failed to write STEP file." << std::endl; } }
问题分析
- 颜色设置逻辑错误:
colorTool->SetColor(face, color, XCAFDoc_ColorSurf)是读取面颜色的接口,返回值表示是否读取成功,而非设置成功。原代码的判断逻辑完全颠倒,导致仅在读取不到颜色时才尝试设置,不符合需求。 - 导出器配置缺失:默认情况下
STEPCAFControl_Writer可能未启用子形状(如Face)的颜色导出,需要显式开启颜色导出模式。 - 子形状可见性未设置:添加的面子形状若未标记为可见,可能在导出时被过滤。
修正后的代码
void ShapeNode::Export(std::string fileName) { Handle(XCAFApp_Application) app = XCAFApp_Application::GetApplication(); // 创建新的XDE文档 Handle(TDocStd_Document) doc; app->NewDocument("MDTV-XCAF", doc); // 获取形状、颜色、材质工具 Handle(XCAFDoc_ShapeTool) shapeTool = XCAFDoc_DocumentTool::ShapeTool(doc->Main()); Handle(XCAFDoc_ColorTool) colorTool = XCAFDoc_DocumentTool::ColorTool(doc->Main()); Handle(XCAFDoc_MaterialTool) materialTool = XCAFDoc_DocumentTool::MaterialTool(doc->Main()); // 将根形状添加到文档 TDF_Label shapeLabel = shapeTool->AddShape(shape); // 设置形状名称 TDataStd_Name::Set(shapeLabel, name.c_str()); // 处理材质和全局颜色 if (!material.GetName().empty()) { std::vector<double> color; if (material.GetAttribute(color, "Color")) { Quantity_Color col(color[0], color[1], color[2], Quantity_TOC_RGB); colorTool->SetColor(shapeLabel, col, XCAFDoc_ColorGen); } Handle(TCollection_HAsciiString) matName = new TCollection_HAsciiString(material.GetName().c_str()); Handle(TCollection_HAsciiString) matDes = new TCollection_HAsciiString(material.GetName().c_str()); double density = 0.0; if (material.GetAttribute(density, "Density")) { TDF_Label matLabel = materialTool->AddMaterial(matName, matDes, density, matDes, matDes); materialTool->SetMaterial(shapeLabel, matLabel); } } // 遍历所有面并设置颜色 for (TopExp_Explorer itf(shape, TopAbs_FACE); itf.More(); itf.Next()) { TopoDS_Face face = TopoDS::Face(itf.Current()); TDF_Label faceLabel; // 查找或注册面子形状 if (!shapeTool->FindSubShape(shapeLabel, face, faceLabel)) { faceLabel = shapeTool->AddSubShape(shapeLabel, face); // 标记子形状可见,避免导出时被忽略 shapeTool->SetVisibility(faceLabel, Standard_True); } // 给面设置表面颜色(红色) colorTool->SetColor(faceLabel, Quantity_Color(1, 0, 0, Quantity_TOC_RGB), XCAFDoc_ColorSurf); } // 配置STEP导出器,启用颜色和材质导出 STEPCAFControl_Writer writer; writer.SetColorMode(Standard_True); writer.SetMaterialMode(Standard_True); // 传输文档到STEP格式 if (!writer.Transfer(doc, STEPControl_AsIs)) { std::cout << "Failed to transfer document to STEP." << std::endl; return; } // 写入STEP文件 if (writer.Write(fileName.c_str()) != IFSelect_RetDone) { std::cout << "Failed to write STEP file." << std::endl; } }
关键修改点
- 移除了错误的颜色读取判断逻辑,直接查找/注册面子形状并设置颜色。
- 添加子形状可见性标记,确保导出时面不会被过滤。
- 显式开启
STEPCAFControl_Writer的颜色导出模式,支持子形状颜色导出。 - 优化代码格式,修复原代码中的字符串转义问题。
内容的提问来源于stack exchange,提问作者Sumil Sood
相关产品推荐
相关产品推荐

