OpenCascade を使用して STEP ファイルをインポートし、Open Inventor 互換の coin3d ライブラリを使用して画面に表示しようとしています。残念ながら、私は常に色が機能しているか、ジオメトリが正しいかのいずれかになります。正しい色でパーツを正しく配置しても機能しないようです。
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);
}
}
}
}
OpenCascadeフォーラムで見つけたように、複数の形状がある場合に備えて複合形状を作成しようとしましたが、違いはありません。
一般に、ネットで見つかった単純な STEP ファイルは正常にインポートされますが (パーツが 1 つしかないと仮定します)、ソリッド作品からエクスポートされたより複雑な複数パーツのオブジェクトは、正しいジオメトリまたは正しい色のいずれかで提供されますが、両方が提供されることはありません。
問題の部分はここにあります:
if (Assembly->IsFree(aLabel) ) {
loadShape(scene, S, noPerVertexNormals, qualityNormals); }
IsFree(aLabel) を使用すると、すべてのジオメトリが正しくなりますが、インポートされる色はほとんどありません。
if (!Assembly->IsFree(aLabel) ) を使用してそれを否定すると、インポートされたジオメトリはいたるところにあり、回転、変換されますが、正しい色になります。
ifを完全に削除すると、両方の状況がアクティブになり、すべてが二重にインポートされます.1回目は正しいジオで色なし、2回目はどこかで翻訳および回転され、正しい色でインポートされます.
私の考えでは、変換された/回転した色のオブジェクトには、変換された場所で無視される変換/回転情報があるかもしれませんが、形状の Transformation() 情報を出力すると、場所と回転はすべて 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);
}
私は何を間違っていますか?オブジェクトが 2 倍になっているのはなぜですか?