From 3b09eedb3e2dce812fc213d96846a89104db8d78 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Tue, 27 Jan 2026 13:02:12 -0800 Subject: [PATCH] Fix VRML submodel scaling for PCBnew exports When loading VRML files exported by PCBnew with Inline nodes, submodels were incorrectly scaled. The parent file correctly disabled unit conversion after detecting a top-level scale transform, but inline submodels were loaded as separate WRL2BASE instances that defaulted to legacy unit conversion mode. Propagate the parent's unit conversion setting to inline submodels so they use the same scaling behavior as the main VRML file. Fixes https://gitlab.com/kicad/code/kicad/-/issues/19091 --- plugins/3d/vrml/v2/vrml2_base.cpp | 8 ++++++-- plugins/3d/vrml/vrml.cpp | 9 +++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/plugins/3d/vrml/v2/vrml2_base.cpp b/plugins/3d/vrml/v2/vrml2_base.cpp index d892fc4c0d..f0a81ed73a 100644 --- a/plugins/3d/vrml/v2/vrml2_base.cpp +++ b/plugins/3d/vrml/v2/vrml2_base.cpp @@ -47,7 +47,7 @@ #include "plugins/3dapi/ifsg_all.h" -SCENEGRAPH* LoadVRML( const wxString& aFileName, bool useInline ); +SCENEGRAPH* LoadVRML( const wxString& aFileName, bool useInline, bool applyUnitConversion ); WRL2BASE::WRL2BASE() : WRL2NODE() @@ -148,7 +148,11 @@ SGNODE* WRL2BASE::GetInlineData( const std::string& aName ) return nullptr; } - SCENEGRAPH* sp = LoadVRML( fn.GetFullPath(), false ); + // Load the inline model with the same unit conversion setting as the parent. + // This ensures that submodels referenced via Inline{} nodes in PCBnew-exported VRML + // files (which have top-level scale and disabled unit conversion) are also loaded + // without unit conversion. + SCENEGRAPH* sp = LoadVRML( fn.GetFullPath(), false, m_applyUnitConversion ); if( nullptr == sp ) { diff --git a/plugins/3d/vrml/vrml.cpp b/plugins/3d/vrml/vrml.cpp index 97723f5548..3ef2f56c5a 100644 --- a/plugins/3d/vrml/vrml.cpp +++ b/plugins/3d/vrml/vrml.cpp @@ -167,7 +167,7 @@ private: }; -SCENEGRAPH* LoadVRML( const wxString& aFileName, bool useInline ) +SCENEGRAPH* LoadVRML( const wxString& aFileName, bool useInline, bool applyUnitConversion ) { FILE_LINE_READER* modelFile = nullptr; SCENEGRAPH* scene = nullptr; @@ -278,6 +278,11 @@ SCENEGRAPH* LoadVRML( const wxString& aFileName, bool useInline ) // to prevent infinite recursion when loading referenced VRML files) bp->SetEnableInline( useInline ); + // Set unit conversion mode. For top-level files, this defaults to true (legacy mode) + // and will be disabled if a top-level scale transform is detected. For inline submodels, + // this inherits the parent's setting. + bp->SetApplyUnitConversion( applyUnitConversion ); + if( !bp->Read( proc ) ) { wxLogTrace( traceVrmlPlugin, wxT( " * [INFO] load failed" ) ); @@ -347,7 +352,7 @@ SCENEGRAPH* Load( char const* aFileName ) if( ext == wxT( "x3d" ) || ext == wxT( "X3D" ) ) scene = LoadX3D( fname ); else - scene = LoadVRML( fname, true ); + scene = LoadVRML( fname, true, true ); return scene; }