OBJ Importing and Displaying

ok, apologies up front: I'm still figuring out OCCT and I'm probably being stupid...

I'm trying to import and display an OBJ file, but failing at the first hurdle:

Q1.
-----
Do I use:
1. XDE
2. RWObj::ReadFile()
3. RWObj_Reader class?

(using 7.8, aiming for latest-and-greatest support)

Q2.
-----

I've got somewhere with RWObj::ReadFile() but it reads it in as Poly_Triangulation. Are there any standard routines which will either allow me to display this, or convert it into a BRep/Topo shape (to display it)? Or, is it a case of walking the datastructure and re-creating?

Thought I'd take a look at the FreeCAD implementation, but alas (apart from it being python), it makes a dogs-dinner of my OBJ files, so I'm not inclined to follow that particular path!

cheers

Mat

simon messi's picture

Dear Mat :
I've used this function in conjunction with QT to read files in the past.
For example:
{
BRep_Builder builder;
QString filepath = QFileDialog::getOpenFileName();
QByteArray byteArray = filepath.toLatin1();
const char* cString = byteArray.constData();
Standard_CString fileName = cString;
Handle(Poly_Triangulation) triangulation = RWObj::ReadFile(fileName);
if (!triangulation.IsNull())
{
TopoDS_Face face;
builder.MakeFace(face, triangulation);
Handle(AIS_Shape) aisShape = new AIS_Shape(face);
myContext->Display(aisShape, AIS_Shaded, 0, false);
}
But it is just a simple example ,it made whole

gkv311 n's picture

If objective is to display OBJ model with materials, than you may use RWObj_CafReader to read OBJ file and XCAFPrs_AISObject to display it 3D Viewer. Here is a sample for reading STEP file - you'll need replacing STEPCAFControl_Reader with RWObj_CafReader and use SetDocument() and Perform() methods.

Mat Maher's picture

Thank you both for your quick replies. Not quite there yet, but I think you were both right...

I tried the easy way first (Simons). This loaded my model on first attempt!! But, it took doing this to find that rotation and scaling are completely to-cock. Hence a more comprehensive solution is needed (gkv's). I'm currently working through this, but will post the results when I get something going...

Mat

Mat Maher's picture

ok, I'll try to reply again, this time using language which doesn't flag me for moderation :)

Thanks for both for the replies - you are both right. First example code got me up the running instantly - which immediately showed I had a scale and rotation issue with the .OBJ Importing - which pushed me to the bigger implementation. Took a little playing around, but I've got something up and running using this code:

//-----------------------------------------------------------------------------

//! Open OBJ file.
bool CBlah::ImportOBJ (const TCollection_AsciiString& theFilePath)
{
    // create an empty XCAF document
    createXCAFApp();
    newDocument();

    // read and translate STEP file into XCAF document
    RWObj_CafReader aReader;
    aReader.SetDocument(myXdeDoc);
    aReader.Perform(theFilePath, Message_ProgressRange());

    TDF_Label mainLabel = myXdeDoc->Main();
    Handle(XCAFDoc_ShapeTool) myShapeTool = XCAFDoc_DocumentTool::ShapeTool(mainLabel);
    Handle(XCAFDoc_ColorTool) myColors = XCAFDoc_DocumentTool::ColorTool(mainLabel);
    Handle(XCAFDoc_MaterialTool) myMaterial = XCAFDoc_DocumentTool::MaterialTool (mainLabel);

    TDF_LabelSequence FreeShape;
    myShapeTool->GetFreeShapes(FreeShape);

    //rotate and scale OBJ to correct for Y-up and m not mm scale
    gp_Trsf trsf;
    trsf.SetRotation(gp_Quaternion(0.7071, 0, 0, 0.7071));
    trsf.SetScaleFactor(1000);

    int Roots = FreeShape.Length();
    for (int i = 1; i <= Roots; i++)
    {
        TDF_Label label = FreeShape.Value(i);
        Handle(XCAFPrs_AISObject) displayedShape = new XCAFPrs_AISObject(label);
        displayedShape->SetLocalTransformation(trsf);
        myContext->Display(displayedShape, true);
    }
    return true;
}
//-----------------------------------------------------------------------

So, progressing well. The next hurdles start to get interesting:
1. Material is being loaded using this function, but not displayed - any ideas?
(I know its being loaded because it complains when the file paths are missing)
2. To solve the rotation problem I want to auto-detect the coordinate system by measuring the object and detecting the longest edge. We're starting to swerve a little off-topic here, but do you know any way to extract bounding-box dimensions from an AIS or Topo shape? Once again, my thoughts are about manually calculating from points, but it feels like something there is a secret function for (if only I knew where to look :))

cheers

Mat

gkv311 n's picture
  1. Material is being loaded using this function, but not displayed - any ideas? (I know its being loaded because it complains when the file paths are missing)

Check the .mtl file - it should be places nearby to .obj, and associated texture files should be also accessible (note that some software may generate unusable .mtl files referring to image files with inaccessible paths - e.g. absolute paths within some another computer).

  1. any way to extract bounding-box dimensions from an AIS or Topo shape?
TDF_Label theLabel = ...; // prs->GetLabel();

TopoDS_Shape aShape;
XCAFDoc_ShapeTool::GetShape(theLabel, aShape);

Bnd_Box aBox;
BRepBndLib::Add(aShape, aBox);

if (!aBox.IsVoid()) {
  gp_XYZ aDims = aBox.CornerMax().XYZ() - aBox.CornerMin().XYZ();
}
Mat Maher's picture

Aha, another magic function which does exactly what I need!

Still no luck with the materials - definitely being loaded because it complains if the texture files aren't there. I'll keep on plugging - not entirely convinced its not my view in the wrong mode!