|
|
/*------------------------------------------------------------------------------
|
|
|
* Copyright (c) 2023 by Bai Bing (seread@163.com)
|
|
|
* See COPYING file for copying and redistribution conditions.
|
|
|
*
|
|
|
* Alians IT Studio.
|
|
|
*----------------------------------------------------------------------------*/
|
|
|
#include <algorithm>
|
|
|
#include <chrono>
|
|
|
#include <cstdlib>
|
|
|
#include <execution>
|
|
|
#include <filesystem>
|
|
|
#include <functional>
|
|
|
#include <fstream>
|
|
|
#include <iostream>
|
|
|
#include <list>
|
|
|
#include <map>
|
|
|
#include <memory>
|
|
|
#include <random>
|
|
|
#include <regex>
|
|
|
#include <set>
|
|
|
#include <stdexcept>
|
|
|
#include <thread>
|
|
|
#include <vector>
|
|
|
#include <SurfaceGrid.h>
|
|
|
#include <Windows.h>
|
|
|
#include "params.h"
|
|
|
#include "version.h"
|
|
|
#include "SurfaceGridWrapper.h"
|
|
|
#include "utils/pystring.h"
|
|
|
|
|
|
void parse_args(int argc, char **argv, ais::Settings &settings)
|
|
|
{
|
|
|
// parse params
|
|
|
char c;
|
|
|
int optIndex = 0;
|
|
|
|
|
|
std::set<std::string> onParams = {"on", "1", "true", "yes"};
|
|
|
|
|
|
while (-1 != (c = ais::getopt_long_2(argc, argv, ais::shortopts, ais::longopts, &optIndex, &ais::optarg2)))
|
|
|
{
|
|
|
switch (c)
|
|
|
{
|
|
|
case 's':
|
|
|
settings.randomsFilename = ais::optarg2;
|
|
|
break;
|
|
|
case 't':
|
|
|
settings.concernPointsFilename = ais::optarg2;
|
|
|
break;
|
|
|
case 'c':
|
|
|
{
|
|
|
int count = atoi(ais::optarg2);
|
|
|
// only use mock random points when specified this option
|
|
|
settings.useMockRandoms = true;
|
|
|
settings.mockRandomCount = count ? count : 200; // default is 200
|
|
|
break;
|
|
|
}
|
|
|
case 'd':
|
|
|
{
|
|
|
std::string strArea = ais::optarg2;
|
|
|
std::vector<std::string> vec = pystring::split(strArea, ",");
|
|
|
if (vec.size() >= 4)
|
|
|
{
|
|
|
settings.area.xMin = std::atof(vec[0].c_str());
|
|
|
settings.area.yMin = std::atof(vec[1].c_str());
|
|
|
settings.area.xMax = std::atof(vec[2].c_str());
|
|
|
settings.area.yMax = std::atof(vec[3].c_str());
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case 'b':
|
|
|
settings.breaklinesFilename = ais::optarg2;
|
|
|
break;
|
|
|
case 'a':
|
|
|
settings.faultsFilename = ais::optarg2;
|
|
|
break;
|
|
|
case 'x':
|
|
|
settings.xCount = atoi(ais::optarg2);
|
|
|
break;
|
|
|
case 'y':
|
|
|
settings.yCount = atoi(ais::optarg2);
|
|
|
break;
|
|
|
case 'X':
|
|
|
settings.targetXGridSize = atof(ais::optarg2);
|
|
|
break;
|
|
|
case 'Y':
|
|
|
settings.targetYGridSize = atof(ais::optarg2);
|
|
|
break;
|
|
|
case 'i':
|
|
|
settings.maxIteration = atoi(ais::optarg2);
|
|
|
break;
|
|
|
case 'r':
|
|
|
settings.residual = atof(ais::optarg2);
|
|
|
break;
|
|
|
case 'f':
|
|
|
settings.fillValue = atof(ais::optarg2);
|
|
|
break;
|
|
|
case 'e':
|
|
|
settings.estimateFactor = atoi(ais::optarg2);
|
|
|
break;
|
|
|
case 'n':
|
|
|
settings.contourStep = atof(ais::optarg2);
|
|
|
break;
|
|
|
case 'u':
|
|
|
settings.contourMarkStep = atoi(ais::optarg2);
|
|
|
break;
|
|
|
case 'g':
|
|
|
settings.insertTimes = atoi(ais::optarg2);
|
|
|
break;
|
|
|
case 'p':
|
|
|
settings.smoothTimes = atoi(ais::optarg2);
|
|
|
break;
|
|
|
case 'w':
|
|
|
{
|
|
|
// corner weight should between 4~256
|
|
|
int v = atoi(ais::optarg2);
|
|
|
if (v < 4)
|
|
|
v = 4;
|
|
|
if (v > 256)
|
|
|
v = 256;
|
|
|
settings.cornerWeight = v;
|
|
|
break;
|
|
|
}
|
|
|
case 'm':
|
|
|
{
|
|
|
std::string value = ais::optarg2;
|
|
|
value = ais::tolower(value);
|
|
|
settings.useMultiThread = onParams.find(value.c_str()) != onParams.end();
|
|
|
break;
|
|
|
}
|
|
|
case 'o':
|
|
|
{
|
|
|
settings.outputFilename = ais::optarg2;
|
|
|
if (settings.outputFilename.empty())
|
|
|
settings.outputFilename = "output.grd";
|
|
|
break;
|
|
|
}
|
|
|
case 'l':
|
|
|
{
|
|
|
// 0 add fault point with out any constrict, default is 0
|
|
|
// 1-4 add fault point with different constrict level, 1-less 4-more
|
|
|
auto faultEdgeLevel = (ais::optarg2 != NULL) ? atoi(ais::optarg2) : 0;
|
|
|
|
|
|
if (faultEdgeLevel < 0 || faultEdgeLevel > 4)
|
|
|
{
|
|
|
std::cout << "Invalid param, the fault edge level must between 0 and 4, default is 0" << std::endl;
|
|
|
exit(-1);
|
|
|
}
|
|
|
|
|
|
settings.faultEdgeLevel = faultEdgeLevel;
|
|
|
break;
|
|
|
}
|
|
|
case '?':
|
|
|
case 'h':
|
|
|
ais::usage(argv[0]);
|
|
|
exit(EXIT_SUCCESS);
|
|
|
case 'v':
|
|
|
std::cout << ais::VERSION << std::endl;
|
|
|
exit(EXIT_SUCCESS);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static std::vector<std::string> WideArgsToNarrow(int wargc, LPWSTR* wargv)
|
|
|
{
|
|
|
std::vector<std::string> result;
|
|
|
|
|
|
for (int i = 0; i < wargc; i++)
|
|
|
{
|
|
|
result.push_back(WstringToString(wargv[i]));
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
static std::vector<char *> VectorToArgv(const std::vector<std::string> &argv)
|
|
|
{
|
|
|
std::vector<char *> argvPointers;
|
|
|
|
|
|
for (auto &arg : argv)
|
|
|
{
|
|
|
argvPointers.push_back(const_cast<char *>(arg.c_str()));
|
|
|
}
|
|
|
|
|
|
return argvPointers;
|
|
|
}
|
|
|
|
|
|
int WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow)
|
|
|
{
|
|
|
ais::Settings settings;
|
|
|
|
|
|
// MFC <20><><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD>ͳ<EFBFBD><CDB3> main <20><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF>ַ<EFBFBD><D6B7><EFBFBD>
|
|
|
// <20><><EFBFBD><EFBFBD> parse_args <20><>Ҫ<EFBFBD><D2AA>ͳ<EFBFBD><CDB3> int argc, char **argv <20><>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
|
|
|
int wargc = 0;
|
|
|
LPWSTR *wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
|
|
|
std::vector<std::string> narrowArgs = WideArgsToNarrow(wargc, wargv);
|
|
|
std::vector<char *> argvPointers = VectorToArgv(narrowArgs);
|
|
|
|
|
|
int argc = static_cast<int>(argvPointers.size());
|
|
|
char **argv = argvPointers.data();
|
|
|
|
|
|
parse_args(argc, argv, settings);
|
|
|
|
|
|
std::wstring sourcePointFile = StringToWstring(settings.randomsFilename);
|
|
|
std::wstring faultFile = StringToWstring(settings.faultsFilename);
|
|
|
std::wstring borderFile = StringToWstring(settings.breaklinesFilename);
|
|
|
size_t xNodeCount = settings.xCount;
|
|
|
int maxIteration = settings.maxIteration;
|
|
|
double residual = settings.residual;
|
|
|
double fillValue = settings.fillValue;
|
|
|
int faultEdgeLevel = settings.faultEdgeLevel;
|
|
|
std::wstring outputFile = StringToWstring(settings.outputFilename);
|
|
|
int estimateFactor = settings.estimateFactor;
|
|
|
double cornerWeight = settings.cornerWeight;
|
|
|
double contourStep = settings.contourStep;
|
|
|
int contourMarkStep = settings.contourMarkStep;
|
|
|
int insertTimes = settings.insertTimes;
|
|
|
int smoothTimes = settings.smoothTimes;
|
|
|
double xMin = settings.area.xMin;
|
|
|
double yMin = settings.area.yMin;
|
|
|
double xMax = settings.area.xMax;
|
|
|
double yMax = settings.area.yMax;
|
|
|
|
|
|
if (BuildMinCurvatureGrid3Impl(sourcePointFile.c_str(),
|
|
|
faultFile.c_str(),
|
|
|
borderFile.c_str(),
|
|
|
xNodeCount,
|
|
|
maxIteration,
|
|
|
residual,
|
|
|
fillValue,
|
|
|
faultEdgeLevel,
|
|
|
outputFile.c_str(),
|
|
|
estimateFactor,
|
|
|
cornerWeight,
|
|
|
contourStep,
|
|
|
contourMarkStep,
|
|
|
insertTimes,
|
|
|
smoothTimes,
|
|
|
xMin,
|
|
|
yMin,
|
|
|
xMax,
|
|
|
yMax))
|
|
|
{
|
|
|
return EXIT_SUCCESS;
|
|
|
}
|
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
} |