43const std::vector<wxString>& stepExtensions()
45 static const std::vector<wxString> exts = {
46 wxS(
"step" ), wxS(
"stp" ), wxS(
"stpz" ),
47 wxS(
"step.gz" ), wxS(
"stp.gz" ),
48 wxS(
"iges" ), wxS(
"igs" )
57const std::vector<wxString>& dottedStepExtensions()
59 static const std::vector<wxString> dotted = []
61 std::vector<wxString>
result;
62 result.reserve( stepExtensions().size() );
64 for(
const wxString& ext : stepExtensions() )
65 result.push_back( wxS(
"." ) + ext );
74bool hasStepExtension(
const wxString& aPath )
76 const wxString lower = aPath.Lower();
78 for(
const wxString& dotted : dottedStepExtensions() )
80 if( lower.length() > dotted.length()
81 && lower.Right( dotted.length() ) == dotted )
94wxString normalizeStem(
const wxString& aName )
96 wxString stem = aName;
98 static const wxString stripList[] = {
99 wxS(
".step.gz" ), wxS(
".stp.gz" ),
100 wxS(
".wrl" ), wxS(
".wrz" ),
101 wxS(
".step" ), wxS(
".stp" ), wxS(
".stpz" ),
102 wxS(
".iges" ), wxS(
".igs" )
105 for(
const wxString& ext : stripList )
107 if( stem.length() > ext.length()
108 && stem.Right( ext.length() ).Lower() == ext )
110 stem = stem.Left( stem.length() - ext.length() );
117 stem.Replace( wxS(
"-" ), wxS(
"_" ) );
118 stem.Replace( wxS(
" " ), wxS(
"_" ) );
124wxString parentDirName(
const wxString& aPath )
126 wxFileName fn( aPath );
127 const wxArrayString& dirs = fn.GetDirs();
129 return dirs.empty() ? wxString() : dirs.Last();
136std::vector<wxString> gatherScanDirs(
const wxString& aProjectPath,
139 std::vector<wxString>
result;
140 std::unordered_set<wxString> seen;
142 auto addDir = [&](
const wxString& aDir )
147 wxFileName norm( aDir, wxEmptyString );
148 norm.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS );
149 const wxString key = norm.GetPath().Lower();
151 if( !seen.insert( key ).second )
154 if( wxDir::Exists( norm.GetPath() ) )
155 result.push_back( norm.GetPath() );
160 if(
const std::list<SEARCH_PATH>* paths = aResolver->
GetPaths() )
163 addDir( sp.m_Pathexp );
167 if( !aProjectPath.IsEmpty() )
169 wxFileName prj3D( aProjectPath, wxEmptyString );
170 prj3D.AppendDir( wxS(
"3dshapes" ) );
171 addDir( prj3D.GetPath() );
176 for(
const wxString& dir : common->m_Extra3DSearchDirs )
188 const wxString ext = aFilename.AfterLast(
'.' ).Lower();
190 return ext == wxS(
"wrl" ) || ext == wxS(
"wrz" );
198 for(
const wxString& dir : gatherScanDirs( aProjectPath, aResolver ) )
203 for(
const wxString& file : files )
205 if( !hasStepExtension( file ) )
208 const wxString stem = normalizeStem( wxFileName( file ).GetFullName() );
222 return wxEmptyString;
224 const wxString stem = normalizeStem( wxFileName( aMissingWrl ).GetFullName() );
227 return wxEmptyString;
231 if( it ==
m_byStem.end() || it->second.empty() )
232 return wxEmptyString;
234 const wxString wrlParent = parentDirName( aMissingWrl );
236 if( !wrlParent.IsEmpty() )
238 for(
const wxString& candidate : it->second )
240 if( parentDirName( candidate ).CmpNoCase( wrlParent ) == 0 )
245 return it->second.front();
void CollectFilesLoopSafe(const wxString &aRoot, wxArrayString &aFiles, const wxString &aFileSpec, int aFlags)
Recursively collect every file under aRoot, deduplicating subdirectories by their resolved path.
wxString result
Test unit parsing edge cases and error handling.