diff --git a/common/advanced_config.cpp b/common/advanced_config.cpp index 8761d5ec80..d1c24e8210 100644 --- a/common/advanced_config.cpp +++ b/common/advanced_config.cpp @@ -105,6 +105,8 @@ static const wxChar EnableEeschemaPrintCairo[] = wxT( "EnableEeschemaPrintCairo" static const wxChar DisambiguationTime[] = wxT( "DisambiguationTime" ); static const wxChar PcbSelectionVisibilityRatio[] = wxT( "PcbSelectionVisibilityRatio" ); static const wxChar MinimumSegmentLength[] = wxT( "MinimumSegmentLength" ); +static const wxChar OcePluginLinearDeflection[] = wxT( "OcePluginLinearDeflection" ); +static const wxChar OcePluginAngularDeflection[] = wxT( "OcePluginAngularDeflection" ); } // namespace KEYS @@ -250,6 +252,9 @@ ADVANCED_CFG::ADVANCED_CFG() m_MinimumSegmentLength = 50; + m_OcePluginLinearDeflection = 0.14; + m_OcePluginAngularDeflection = 30; + loadFromConfigFile(); } @@ -449,6 +454,14 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg ) &m_MinimumSegmentLength, m_MinimumSegmentLength, 10, 1000 ) ); + configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::OcePluginLinearDeflection, + &m_OcePluginLinearDeflection, + m_OcePluginLinearDeflection, 0.01, 1.0 ) ); + + configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::OcePluginAngularDeflection, + &m_OcePluginAngularDeflection, + m_OcePluginAngularDeflection, 0.01, 360.0 ) ); + // Special case for trace mask setting...we just grab them and set them immediately // Because we even use wxLogTrace inside of advanced config wxString traceMasks; diff --git a/include/advanced_config.h b/include/advanced_config.h index aa4922a27b..f0bed19e69 100644 --- a/include/advanced_config.h +++ b/include/advanced_config.h @@ -518,6 +518,33 @@ public: */ int m_MinimumSegmentLength; + /** + * OCE (STEP/IGES) 3D Plugin Tesselation Linear Deflection + * + * Linear deflection determines the maximum distance between the original geometry + * and the tessellated representation, measured in millimeters (mm), influencing + * the precision of flat surfaces. + * + * Setting name: "OcePluginLinearDeflection" + * Valid values: 0.01 to 1.0 + * Default value: 0.14 + */ + double m_OcePluginLinearDeflection; + + /** + * OCE (STEP/IGES) 3D Plugin Tesselation Angular Deflection + * + * Angular deflection specifies the maximum deviation angle (in degrees) between + * the normals of adjacent facets in the tessellated model. Lower values result + * in smoother curved surfaces by creating more facets to closely approximate + * the curve. + * + * Setting name: "OcePluginAngularDeflection" + * Valid values: 0.1 to 180 + * Default value: 30 + */ + double m_OcePluginAngularDeflection; + ///@} diff --git a/plugins/3d/oce/CMakeLists.txt b/plugins/3d/oce/CMakeLists.txt index a6f198c4ea..b8a2694980 100644 --- a/plugins/3d/oce/CMakeLists.txt +++ b/plugins/3d/oce/CMakeLists.txt @@ -17,7 +17,7 @@ add_library( s3d_plugin_oce MODULE loadmodel.cpp ) -target_link_libraries( s3d_plugin_oce kicad_3dsg ${OCC_LIBRARIES} ${wxWidgets_LIBRARIES} ZLIB::ZLIB ) +target_link_libraries( s3d_plugin_oce kicad_3dsg common ${OCC_LIBRARIES} ${wxWidgets_LIBRARIES} ZLIB::ZLIB ) target_include_directories( s3d_plugin_oce PRIVATE $<TARGET_PROPERTY:gzip-hpp,INTERFACE_INCLUDE_DIRECTORIES> diff --git a/plugins/3d/oce/loadmodel.cpp b/plugins/3d/oce/loadmodel.cpp index da0d01f639..ef09c0df28 100644 --- a/plugins/3d/oce/loadmodel.cpp +++ b/plugins/3d/oce/loadmodel.cpp @@ -40,6 +40,7 @@ #include <wx/wfstream.h> #include <wx/zipstrm.h> +#include <advanced_config.h> #include <decompress.hpp> #include <TDocStd_Document.hxx> @@ -88,15 +89,6 @@ #define MASK_OCE wxT( "PLUGIN_OCE" ) #define MASK_OCE_EXTRA wxT( "PLUGIN_OCE_EXTRA" ) -// precision for mesh creation; 0.07 should be good enough for ECAD viewing -#define USER_PREC (0.14) - -// angular deflection for meshing -// 10 deg (36 faces per circle) = 0.17453293 -// 20 deg (18 faces per circle) = 0.34906585 -// 30 deg (12 faces per circle) = 0.52359878 -#define USER_ANGLE (0.52359878) - typedef std::map<std::size_t, SGNODE*> COLORMAP; typedef std::map<std::string, SGNODE*> FACEMAP; typedef std::map<std::string, std::vector<SGNODE*>> NODEMAP; @@ -588,8 +580,8 @@ bool readSTEP( Handle(TDocStd_Document)& m_doc, const char* fname ) if( !Interface_Static::SetIVal( "read.precision.mode", 1 ) ) return false; - // Set the shape conversion precision to USER_PREC (default 0.0001 has too many triangles) - if( !Interface_Static::SetRVal( "read.precision.val", USER_PREC ) ) + // Set the shape conversion precision (default 0.0001 has too many triangles) + if( !Interface_Static::SetRVal( "read.precision.val", ADVANCED_CFG::GetCfg().m_OcePluginLinearDeflection ) ) return false; // set other translation options @@ -1139,13 +1131,15 @@ bool processFace( const TopoDS_Face& face, DATA& data, SGNODE* parent, std::vect TopLoc_Location loc; Standard_Boolean isTessellate (Standard_False); Handle( Poly_Triangulation ) triangulation = BRep_Tool::Triangulation( face, loc ); + const double linDeflection = ADVANCED_CFG::GetCfg().m_OcePluginLinearDeflection; - if( triangulation.IsNull() || triangulation->Deflection() > USER_PREC + Precision::Confusion() ) + if( triangulation.IsNull() || triangulation->Deflection() > linDeflection + Precision::Confusion() ) isTessellate = Standard_True; if( isTessellate ) { - BRepMesh_IncrementalMesh IM(face, USER_PREC, Standard_False, USER_ANGLE ); + BRepMesh_IncrementalMesh IM(face, linDeflection, Standard_False, + glm::radians(ADVANCED_CFG::GetCfg().m_OcePluginAngularDeflection) ); triangulation = BRep_Tool::Triangulation( face, loc ); }