From 8fd12d8b7e20d0bb9db2ba4b4f10890a554ca1c9 Mon Sep 17 00:00:00 2001 From: Alex Shvartzkop <dudesuchamazing@gmail.com> Date: Thu, 16 May 2024 21:57:44 +0300 Subject: [PATCH] Allow reading VRML models for glTF export. Note that some VRML 2.0 models fill fail until our patches are integrated into OCCT 7.9.0. --- cmake/FindOCC.cmake | 1 + pcbnew/exporters/step/step_pcb_model.cpp | 73 +++++++++++++++++++++++- pcbnew/exporters/step/step_pcb_model.h | 5 +- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/cmake/FindOCC.cmake b/cmake/FindOCC.cmake index bcd99682f6..f2726248be 100644 --- a/cmake/FindOCC.cmake +++ b/cmake/FindOCC.cmake @@ -86,6 +86,7 @@ set( OCC_LIBS_POST_78 TKDEGLTF TKDESTEP TKDESTL + TKDEVRML ) set(OCC_TYPE "OpenCASCADE Standard Edition") diff --git a/pcbnew/exporters/step/step_pcb_model.cpp b/pcbnew/exporters/step/step_pcb_model.cpp index 5c9402ab44..22caf772da 100644 --- a/pcbnew/exporters/step/step_pcb_model.cpp +++ b/pcbnew/exporters/step/step_pcb_model.cpp @@ -118,6 +118,7 @@ #include <GC_MakeCircle.hxx> #include <RWGltf_CafWriter.hxx> +#include <VrmlAPI_CafReader.hxx> #include <macros.h> @@ -592,6 +593,46 @@ static Standard_Boolean rescaleShapes( const TDF_Label& theLabel, const gp_XYZ& } +// Sets names in assembly to <aPrefix> (<old name>), or to <aPrefix> +static Standard_Boolean prefixNames( const TDF_Label& aLabel, + const TCollection_ExtendedString& aPrefix ) +{ + Handle( KI_XCAFDoc_AssemblyGraph ) aG = new KI_XCAFDoc_AssemblyGraph( aLabel ); + + if( aG.IsNull() ) + { + Message::SendFail( "Couldn't create assembly graph." ); + return Standard_False; + } + + Standard_Boolean anIsDone = Standard_True; + + for( Standard_Integer idx = 1; idx <= aG->NbNodes(); idx++ ) + { + const TDF_Label& lbl = aG->GetNode( idx ); + Handle( TDataStd_Name ) nameHandle; + + if( lbl.FindAttribute( TDataStd_Name::GetID(), nameHandle ) ) + { + TCollection_ExtendedString name; + + name += aPrefix; + name += " ("; + name += nameHandle->Get(); + name += ")"; + + TDataStd_Name::Set( lbl, name ); + } + else + { + TDataStd_Name::Set( lbl, aPrefix ); + } + } + + return anIsDone; +} + + STEP_PCB_MODEL::STEP_PCB_MODEL( const wxString& aPcbName ) { m_app = XCAFApp_Application::GetApplication(); @@ -2436,7 +2477,22 @@ bool STEP_PCB_MODEL::getModelLabel( const std::string& aFileNameUTF8, VECTOR3D a } } - return false; // No replacement model found + // VRML models only work when exporting to glTF + // Also OCCT < 7.9.0 fail to load most VRML 2.0 models because of Switch nodes + if( readVRML( doc, aFileNameUTF8.c_str() ) ) + { + Handle( XCAFDoc_ShapeTool ) shapeTool = + XCAFDoc_DocumentTool::ShapeTool( doc->Main() ); + + prefixNames( shapeTool->Label(), + TCollection_ExtendedString( baseName.c_str().AsChar() ) ); + } + else + { + ReportMessage( wxString::Format( wxT( "readVRML() failed on filename '%s'.\n" ), + fileName ) ); + return false; + } } else // Substitution is not allowed { @@ -2624,6 +2680,21 @@ bool STEP_PCB_MODEL::readSTEP( Handle( TDocStd_Document )& doc, const char* fnam } +bool STEP_PCB_MODEL::readVRML( Handle( TDocStd_Document ) & doc, const char* fname ) +{ + VrmlAPI_CafReader reader; + RWMesh_CoordinateSystemConverter conv; + conv.SetInputLengthUnit( 2.54 ); + reader.SetCoordinateSystemConverter( conv ); + reader.SetDocument( doc ); + + if( !reader.Perform( TCollection_AsciiString( fname ), Message_ProgressRange() ) ) + return false; + + return true; +} + + TDF_Label STEP_PCB_MODEL::transferModel( Handle( TDocStd_Document ) & source, Handle( TDocStd_Document ) & dest, VECTOR3D aScale ) { diff --git a/pcbnew/exporters/step/step_pcb_model.h b/pcbnew/exporters/step/step_pcb_model.h index c140602f36..91828684e3 100644 --- a/pcbnew/exporters/step/step_pcb_model.h +++ b/pcbnew/exporters/step/step_pcb_model.h @@ -223,8 +223,9 @@ private: bool getModelLocation( bool aBottom, VECTOR2D aPosition, double aRotation, VECTOR3D aOffset, VECTOR3D aOrientation, TopLoc_Location& aLocation ); - bool readIGES( Handle( TDocStd_Document )& m_doc, const char* fname ); - bool readSTEP( Handle( TDocStd_Document )& m_doc, const char* fname ); + bool readIGES( Handle( TDocStd_Document ) & aDoc, const char* aFname ); + bool readSTEP( Handle( TDocStd_Document ) & aDoc, const char* aFname ); + bool readVRML( Handle( TDocStd_Document ) & aDoc, const char* aFname ); TDF_Label transferModel( Handle( TDocStd_Document )& source, Handle( TDocStd_Document ) & dest, VECTOR3D aScale );