Unable to import an OBJ model with an associated MTL material file

I want to load an OBJ model with an MTL material, so I included the necessary headers:

#include <RWObj_Material.hxx>
#include <RWObj_MtlReader.hxx>

But when I declare the variable:

NCollection_DataMap<TCollection_AsciiString, RWObj_Material> aMaterials;

RWObj_MtlReader aMtlReader(aMaterials);

The compiler gives an error:

Error        LNK2019 Unresolved external symbol "public: __cdecl RWObj_MtlReader::~RWObj_MtlReader(void)" (??1RWObj_MtlReader@@QEAA@XZ), referenced in the function main.    opencascadeLoadObjTest

This is not the only error, but it is enough to illustrate the issue. It seems that the corresponding destructor is not linked, so the compilation fails. I have added a link to TKRWMesh.lib, but it still doesn't work. I suspect that some functions may not be correctly exported in TKRWMesh, but I do not know how to fix it. I am using version 7.7.0, and 7.8.0 has the same issue. I would like to know if there is any method to help me resolve this issue. Thank you.

Dmitrii Pasukhin's picture

Hello, you need to link any TK that are used to. This satting should be on your application side. OBJ needs TKService for example. 7.8 OBJ moved from TKRWMesh to TKDEOBJ

Best regards, Dmitrii.

Xposeder's picture

Hello, thank you for your response. I have linked all the libraries that can be linked, and I have tested both versions 7.7 and 7.8, still got the error. Let me demonstrate how to trigger this issue:

  1. Create a new blank C++ project in Visual Studio.
  2. In the project's configuration properties, under VC++ Directories -> Include Directories, add C:\occt-vc143-64\inc. In the Library Directories, add C:\occt-vc143-64\win64\vc14\lib.
  3. Under Linker -> Input, Additional Dependencies, add all the libraries。Most of the libraries may not be needed, but I think it should be permissible to reference all the libraries.: TKBinXCAF.lib TKBin.lib TKBinL.lib TKBinTObj.lib TKBO.lib TKBool.lib TKBRep.lib TKCAF.lib TKCDF.lib TKD3DHost.lib TKD3DHostTest.lib TKDCAF.lib TKDE.lib TKDECascade.lib TKDEGLTF.lib TKDEIGES.lib TKDEOBJ.lib TKDEPLY.lib TKDESTEP.lib TKDESTL.lib TKDEVRML.lib TKDFBrowser.lib TKDraw.lib TKernel.lib TKFeat.lib TKFillet.lib TKG2d.lib TKG3d.lib TKGeomAlgo.lib TKGeomBase.lib TKHLR.lib TKIVtk.lib TKIVtkDraw.lib TKLCAF.lib TKMath.lib TKMesh.lib TKMeshVS.lib TKMessageModel.lib TKMessageView.lib TKOffset.lib TKOpenGl.lib TKOpenGles.lib TKOpenGlesTest.lib TKOpenGlTest.lib TKPrim.lib TKQADraw.lib TKRWMesh.lib TKService.lib TKShapeView.lib TKShHealing.lib TKStd.lib TKStdL.lib TKTInspector.lib TKTInspectorAPI.lib TKTObj.lib TKTObjDRAW.lib TKToolsDraw.lib TKTopAlgo.lib TKTopTest.lib TKTreeModel.lib TKV3d.lib TKVCAF.lib TKView.lib TKViewerTest.lib TKVInspector.lib TKXCAF.lib TKXDEDRAW.lib TKXMesh.lib TKXml.lib TKXmlL.lib TKXmlTObj.lib TKXmlXCAF.lib TKXSBase.lib TKXSDRAW.lib TKXSDRAWDE.lib TKXSDRAWGLTF.lib TKXSDRAWIGES.lib TKXSDRAWOBJ.lib TKXSDRAWPLY.lib TKXSDRAWSTEP.lib TKXSDRAWSTL.lib TKXSDRAWVRML.lib
  4. Then create a new main.cpp in the project and add the following code:

    #include <RWObj_Material.hxx>
    #include <RWObj_MtlReader.hxx>
    int main() {
       NCollection_DataMap<TCollection_AsciiString, RWObj_Material> aMaterials;
    
       RWObj_MtlReader aMtlReader(aMaterials);
       return 1;
    }
    
  5. After compiling, you will encounter an unresolved external command error. It's worth mentioning that this error occurs only when I include and call mtlReader, and I'm not quite clear why this is happening.
gkv311 n's picture

Classes like RWObj_MtlReader have been considered as internal details for RWObj_Reader and RWObj_CafReader, hence they lack some Standard_EXPORT attributes (by mistake or by intention).

Any reason for using RWObj_MtlReader directly? RWObj_Reader will read MTL file referred by OBJ file on its own, if it is properly specified.

Xposeder's picture

Hi, thank you, I think this is the reason. After reading the official documentation, I mistakenly thought that I needed to manually read and load the MTL file, which is why I called RWObj_MtlReader. So I guess the problem should be solved, and I will directly use RWObj_Reader to read the MTL file.

Xposeder's picture

Hi, how can I specify the MTL when reading the OBJ file? I didn't see how to specify it in the documentation, and I think I may have missed something. Is there any example code for reference?

gkv311 n's picture

Take a look into OBJ format description. It should be specified in OBJ file via mtllib statement.

Xposeder's picture

Thank you! I successfully displayed the OBJ model with materials using the following code:

myViewer->myContext->SetDisplayMode(displayedShape, AIS_Shaded, false);
myViewer->myContext->Display(displayedShape, false);