Как импортировать STEP файлы с OpenCascade и отображать с coin3d с правильными цветами?

я пытаюсь импортировать файлы STEP с помощью OpenCascade и отображать их на экране с помощью библиотеки Coin3d, совместимой с Open Inventor. К сожалению, я всегда получаю либо работающие цвета, либо правильную геометрию, когда правильно расположенные детали с правильными цветами, кажется, не работают.

Handle(XCAFDoc_ShapeTool) Assembly;
Assembly = XCAFDoc_DocumentTool::ShapeTool(scene->document->Main());

STEPCAFControl_Reader stepReader;
stepReader.SetColorMode(true);
stepReader.SetNameMode(true);
stepReader.SetLayerMode(true);
const auto stepStat = stepReader.ReadFile(fn.c_str());
if(stepStat != IFSelect_ReturnStatus::IFSelect_RetDone) {
return false;
}

stepReader.Transfer(scene->document);

TDF_LabelSequence frshapes;
Assembly->GetShapes(frshapes);

if (frshapes.Length() == 0) {
return false;
} else if (frshapes.Length() == 1) {
TopoDS_Shape shape = Assembly->GetShape(frshapes.Value(1));
loadShape(scene, shape, noPerVertexNormals, qualityNormals);
} else {
for (Standard_Integer i=1; i<frshapes.Length(); i++) {
TopoDS_Shape S = Assembly->GetShape(frshapes.Value(i));

TDF_Label aLabel = Assembly->FindShape(S, Standard_False);
if ( (!aLabel.IsNull()) && (Assembly->IsShape(aLabel)) ) {
if (Assembly->IsFree(aLabel) ) {
loadShape(scene, S, noPerVertexNormals, qualityNormals);
}
}
}
}

Я также попытался создать составную фигуру на случай, если существует более 1 фигуры, как я нашел ее на форуме OpenCascade, но без разницы.

В общем, простые файлы STEP, найденные в сетевом импорте штрафа (я предполагаю, что они имеют только одну деталь), но более сложные многоэлементные объекты, экспортируемые из твердых работ, поставляются либо с правильной геометрией, либо с правильными цветами, но никогда с обоими.

Проблемная часть здесь:

if (Assembly->IsFree(aLabel) ) {
loadShape(scene, S, noPerVertexNormals, qualityNormals);                }

Если я использую IsFree (aLabel), вся геометрия верна, но цвета почти не импортируются.

Если я отрицаю это, используя if (! Assembly-> IsFree (aLabel)) … импортированная геометрия повсюду, повернута, преобразована, но с правильными цветами.

Если я удаляю if if полностью, обе ситуации активны, он импортирует все дважды, один раз с правильным гео, без цветов, и второй раз, где-то переведенный и повернутый, с правильными цветами.

Я думал, что цветные объекты, переведенные / повернутые, могут просто иметь информацию о перемещении / повороте, которая игнорируется там, где они преобразуются, но когда я выводлю информацию о преобразованиях фигур (), расположение и поворот равны 0.

Вот остаток кода, фактически преобразующий импортированные фигуры в объекты многоугольника для отображения:

void loadShape(const std::shared_ptr<Scene> &scene, const TopoDS_Shape &shape, bool noPerVertexNormals, bool qualityNormals)
{
TopExp_Explorer ex;

Handle(XCAFDoc_ColorTool) Colors;

Colors = XCAFDoc_DocumentTool::ColorTool(scene->document->Main());

SceneShape * so = new SceneShape;
so->setShape(shape);

// this is all zero
gp_XYZ aggi = shape.Location().Transformation().TranslationPart();
std::cout << aggi.X() << "," << aggi.Y() << "," << aggi.Z() << std::endl;
gp_Quaternion aggiaggi = shape.Location().Transformation().GetRotation();
std::cout << aggiaggi.X() << "," << aggiaggi.Y() << "," << aggiaggi.Z() << "," << aggiaggi.W() << std::endl << std::endl;

BRepMesh_IncrementalMesh bMesh(so->shape(), 1 /* ? */,Standard_False, 0.5, Standard_True);

SoMaterial *fallBackMat = new SoMaterial;
fallBackMat->ref();
fallBackMat->diffuseColor.setValue(0.64f, 0.64f, 0.64f);

Quantity_Color fbColor;
if (Colors->GetColor(so->shape(), XCAFDoc_ColorGen, fbColor) || Colors->GetColor(so->shape(), XCAFDoc_ColorSurf, fbColor) || Colors->GetColor(so->shape(), XCAFDoc_ColorCurv, fbColor)) {
fallBackMat->diffuseColor.setValue(static_cast<float>(fbColor.Red()), static_cast<float>(fbColor.Green()), static_cast<float>(fbColor.Blue()));
}

so->root()->addChild(fallBackMat);

SoMaterial *selectionMat = new SoMaterial;
selectionMat->emissiveColor.setValue(.9f, .9f, .6f);

int i = 1;
for (ex.Init(so->shape(), TopAbs_FACE); ex.More(); ex.Next(),i++) {
const TopoDS_Face& aFace = TopoDS::Face(ex.Current());

ObjectPart *part = new ObjectPart;
part->setFace(aFace);

selectionMat->ref();

part->selectedRoot()->addChild(selectionMat);

Quantity_Color color;
if (
Colors->GetColor(aFace, XCAFDoc_ColorGen, color) ||
Colors->GetColor(aFace, XCAFDoc_ColorSurf, color) ||
Colors->GetColor(aFace, XCAFDoc_ColorCurv, color)
) {

SoMaterial *myMaterial = new SoMaterial;
myMaterial->ref();
myMaterial->diffuseColor.setValue(static_cast<float>(color.Red()), static_cast<float>(color.Green()), static_cast<float>(color.Blue()));
part->unselectedRoot()->addChild(myMaterial);
} else {
fallBackMat->ref();
part->unselectedRoot()->addChild(fallBackMat);
}

Standard_Integer nbNodesInFace,nbTriInFace;
SbVec3f* vertices=0;
SbVec3f* vertexnormals=0;
int32_t* cons=0;

// this subroutine is taken from FreeCAD which can import the models correctly, so i assume it is not the problem
transferToArray(aFace, &vertices, &vertexnormals, &cons, nbNodesInFace, nbTriInFace, noPerVertexNormals, qualityNormals);

if (!vertices)
continue;

part->selectedRoot()->addChild(part->selectedPolygonRoot());
part->unselectedRoot()->addChild(part->unselectedPolygonRoot());

if (!noPerVertexNormals) {
SoNormal * norm = new SoNormal;
norm->vector.setValues(0, nbNodesInFace, vertexnormals);

part->selectedPolygonRoot()->addChild(norm);
part->unselectedPolygonRoot()->addChild(norm);

SoNormalBinding * normb = new SoNormalBinding;
normb->value = SoNormalBinding::PER_VERTEX_INDEXED;
part->selectedPolygonRoot()->addChild(normb);
part->unselectedPolygonRoot()->addChild(normb);
}

SoCoordinate3 * coords = new SoCoordinate3;
coords->point.setValues(0,nbNodesInFace, vertices);

part->selectedPolygonRoot()->addChild(coords);
part->unselectedPolygonRoot()->addChild(coords);

SoIndexedFaceSet * faceset = new SoIndexedFaceSet;
faceset->coordIndex.setValues(0,4*nbTriInFace,(const int32_t*) cons);
faceset->setUserData((void *) part);

part->selectedPolygonRoot()->addChild(faceset);
part->unselectedPolygonRoot()->addChild(faceset);

so->addPart(part);

delete [] vertexnormals;
delete [] vertices;
delete [] cons;
}

scene->addShape(so);
}

Что я делаю неправильно? Почему объекты удваиваются?

4

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …