12 #ifndef BEMBEL_SRC_GEOMETRY_GEOMETRYIGS_HPP_ 
   13 #define BEMBEL_SRC_GEOMETRY_GEOMETRYIGS_HPP_ 
   27   std::vector<int> patch_lines;
 
   30     std::cerr << 
"File " << file_name << 
" doesn't exist!";
 
   37     std::cerr << 
"Format of the file not supported! I assume that character 72 " 
   38                  "denotes the section";
 
   42   while (row[72] != 
'D') {
 
   44     assert(!file.eof() && 
"End of file should not be found here!");
 
   48   while (row[72] != 
'P') {
 
   49     std::stringstream iss;
 
   51     std::vector<int> info1, info2;
 
   54       info1.push_back(std::stoi(word));
 
   56     assert(info1[0] == 128 && 
"Entry type must be NURBS surface!");
 
   63       info2.push_back(std::stoi(word));
 
   67     patch_lines.push_back(info2[3]);
 
   68     assert(!file.eof() && 
"End of file should not be found here!");
 
   72   std::vector<Patch> out;
 
   73   out.reserve(patch_lines.size());
 
   74   const int number_of_patches = patch_lines.size();
 
   75   for (
auto i = 0; i < number_of_patches; ++i) {
 
   76     std::stringstream iss;
 
   78     std::vector<double> data;
 
   79     for (
auto j = 0; j < patch_lines[i]; ++j) {
 
   81       std::string raw_data = row.substr(0, 64);
 
   82       raw_data.erase(std::remove(raw_data.begin(), raw_data.end(), 
' '),
 
   86       while (std::getline(iss, word, 
',')) {
 
   87         data.push_back(atof(word.c_str()));
 
   94     const int K1 = data[1];
 
   95     const int K2 = data[2];
 
   96     const int M1 = data[3];
 
   97     const int M2 = data[4];
 
   99     const int N1 = 1 + K1 - M1;
 
  100     const int N2 = 1 + K2 - M2;
 
  101     const int A = N1 + 2 * M1;
 
  102     const int B = N2 + 2 * M2;
 
  103     const int C = (1 + K1) * (1 + K2);
 
  106     data.erase(data.begin(), data.begin() + 10);
 
  109     std::vector<double> tempknt1(data.begin(), data.begin() + A + 1);
 
  110     std::vector<double> tempknt2(data.begin() + A + 1,
 
  111                                  data.begin() + A + B + 2);
 
  113     const int M = K2 + 1;
 
  114     const int N = K1 + 1;
 
  116     Eigen::MatrixXd weights(M, N);
 
  117     auto it_weights = data.begin() + A + B + 2;
 
  118     for (
auto entry = it_weights; entry != it_weights + C; ++entry) {
 
  119       int index = entry - it_weights;
 
  120       weights((
int)index / N, index % N) = *entry;
 
  123     Eigen::MatrixXd x_coordinates(M, N);
 
  124     Eigen::MatrixXd y_coordinates(M, N);
 
  125     Eigen::MatrixXd z_coordinates(M, N);
 
  126     auto it_points = data.begin() + A + B + C + 2;
 
  127     for (
auto entry = it_points; entry != it_points + 3 * C; entry += 3) {
 
  128       int index = (int)(entry - it_points) / 3;
 
  129       x_coordinates((
int)index / N, index % N) = *entry;
 
  130       y_coordinates((
int)index / N, index % N) = *(entry + 1);
 
  131       z_coordinates((
int)index / N, index % N) = *(entry + 2);
 
  135     x_coordinates = x_coordinates.cwiseProduct(weights);
 
  136     y_coordinates = y_coordinates.cwiseProduct(weights);
 
  137     z_coordinates = z_coordinates.cwiseProduct(weights);
 
  139     std::vector<Eigen::MatrixXd> tmp = {x_coordinates, y_coordinates,
 
  140                                         z_coordinates, weights};
 
  143     tempPatch.
init_Patch(tmp, tempknt1, tempknt2);
 
  144     out.push_back(tempPatch);
 
  159                   const std::vector<std::string>& section,
 
  160                   const char section_char) {
 
  161   std::ofstream file(file_name, std::ios::app);
 
  162   for (
auto it = section.begin(); it != section.end(); ++it) {
 
  163     const int index = std::distance(section.begin(), it);
 
  164     file << std::left << std::setw(72) << *it << section_char << std::right
 
  165          << std::setw(7) << index + 1 << 
"\n";
 
  182                           const std::vector<std::string>& section,
 
  183                           const int patch_idx, 
const int start_count) {
 
  184   std::ofstream file(file_name, std::ios::app);
 
  185   int last_line = start_count;
 
  186   for (
auto it = section.begin(); it != section.end(); ++it) {
 
  187     file << std::left << std::setw(64) << *it
 
  188          << std::right << std::setw(8) << patch_idx << 
"P" 
  189          << std::right << std::setw(7) << last_line << 
"\n";
 
  205 std::vector<std::string> 
makeSection(std::vector<std::string> data,
 
  206                                      const int linewidth = 72) {
 
  207   std::vector<std::string> out;
 
  208   out.reserve(data.size());
 
  210   std::string line = 
"";
 
  211   const int number_of_entries = data.size();
 
  212   for (
auto i = 0; i < number_of_entries; ++i) {
 
  213     std::string item = data[i];
 
  214     if (i < number_of_entries - 1)
 
  219     const int line_length = line.length() + item.length();
 
  220     if (line_length > linewidth) {
 
  237   std::vector<std::string> section(4);
 
  239   section[1] = 
"IGES obtained from Bembel.";
 
  240   section[2] = 
"See <http://www.bembel.eu>";
 
  254   std::ostringstream stm;
 
  255   stm << std::setprecision(precision) << d;
 
  266   std::vector<std::string> out(24);
 
  267   std::time_t now = std::time(
nullptr);
 
  269   std::tm* localTime = std::localtime(&now);
 
  271   std::strftime(dateString, 
sizeof(dateString), 
"%Y-%m-%d", localTime);
 
  283   out[5] = 
"writeIGSFile";
 
  295   out[11] = 
"Nurbs from Bembel";
 
  307   out[17] = dateString;
 
  309   out[18] = 
"0.000001";
 
  313   out[20] = 
"Maximilian Nolte";
 
  315   out[21] = 
"CEM - TU Darmstadt";
 
  321   std::vector<std::string> section = 
makeSection(out);
 
  324   return section.size();
 
  337                     std::vector<int> number_of_lines) {
 
  338   assert(start_idx.size() == number_of_lines.size());
 
  340   std::ofstream fid(file_name, std::ios::app);
 
  341   int tot_number_of_lines = 0;
 
  342   const int number_of_patches = start_idx.size();
 
  343   for (
auto i = 0; i < number_of_patches; ++i) {
 
  344     fid << std::setw(8) << 
"128" 
  345         << std::setw(8) << start_idx[i]
 
  354         << std::setw(7) << (i + 1) * 2 - 1<< 
"\n";
 
  356     fid << std::setw(8) << 
"128" 
  359         << std::setw(8) << number_of_lines[i]
 
  361         << std::setw(8) << 
" " 
  362         << std::setw(8) << 
" " 
  363         << std::setw(8) << 
" " 
  366         << std::setw(7) << (i + 1) * 2 << 
"\n";
 
  368     tot_number_of_lines += 2;
 
  370   return tot_number_of_lines;
 
  386                                         const int precision) {
 
  387   const int degree_x = patch.polynomial_degree_x_;
 
  388   const int degree_y = patch.polynomial_degree_y_;
 
  390   assert(patch.unique_knots_x_.size() == 2 &&
 
  391          "We can not handle internal knots");
 
  392   assert(patch.unique_knots_y_.size() == 2 &&
 
  393          "We can not handle internal knots");
 
  395   std::vector<double> knots_x(2 * degree_x, 0);
 
  396   for (
auto i = 0; i <= degree_x; ++i) knots_x[degree_x + i] = 1;
 
  397   std::vector<double> knots_y(2 * degree_y, 0);
 
  398   for (
auto i = 0; i <= degree_y; ++i) knots_y[degree_y + i] = 1;
 
  400   const std::array<double, 2> span_x = {0, 1};
 
  401   const std::array<double, 2> span_y = {0, 1};
 
  403   const int number_of_points_x = knots_x.size() - degree_x;
 
  404   const int number_of_points_y = knots_y.size() - degree_y;
 
  406   const int size = patch.
data_.size() / 4;
 
  407   std::vector<double> weights(size);
 
  408   std::vector<double> coordinates_x(size);
 
  409   std::vector<double> coordinates_y(size);
 
  410   std::vector<double> coordinates_z(size);
 
  413   for (
auto i = 0; i < size; ++i) {
 
  414     const int rowIndex = i % number_of_points_y;
 
  415     const int colIndex = i / number_of_points_y;
 
  418     const int j = rowIndex * number_of_points_x + colIndex;
 
  420     double weight = patch.
data_[i * 4 + 3];
 
  422     coordinates_x[j] = patch.
data_[i * 4] / weight;
 
  423     coordinates_y[j] = patch.
data_[i * 4 + 1] / weight;
 
  424     coordinates_z[j] = patch.
data_[i * 4 + 2] / weight;
 
  427   const int number_of_data_entries = 16;
 
  428   const int size_data =
 
  429       number_of_data_entries + 4 * size + knots_x.size() + knots_y.size();
 
  430   std::vector<std::string> patch_data(size_data);
 
  432   patch_data[0] = 
"128";
 
  433   patch_data[1] = std::to_string(number_of_points_x - 1);
 
  434   patch_data[2] = std::to_string(number_of_points_y - 1);
 
  435   patch_data[3] = std::to_string(degree_x - 1);
 
  436   patch_data[4] = std::to_string(degree_y - 1);
 
  443   for (
auto i = 0; i < knots_x.size(); ++i) {
 
  447   const int idx_knots_y = 10 + knots_x.size();
 
  448   for (
auto i = 0; i < knots_y.size(); ++i) {
 
  452   const int idx_weights = 10 + knots_x.size() + knots_y.size();
 
  453   for (
auto i = 0; i < size; ++i) {
 
  456     patch_data[idx_weights + size + i * 3] =
 
  458     patch_data[idx_weights + size + i * 3 + 1] =
 
  460     patch_data[idx_weights + size + i * 3 + 2] =
 
  463   patch_data[idx_weights + 4 * size] = std::to_string(span_x[0]);
 
  464   patch_data[idx_weights + 4 * size + 1] = std::to_string(span_x[1]);
 
  465   patch_data[idx_weights + 4 * size + 2] = std::to_string(span_y[0]);
 
  466   patch_data[idx_weights + 4 * size + 3] = std::to_string(span_y[1]);
 
  467   patch_data[idx_weights + 4 * size + 4] = 
"0";
 
  468   patch_data[idx_weights + 4 * size + 5] = 
"0";
 
  481 void writeIGSFile(
const std::vector<Patch>& geometry, std::string file_name,
 
  482                   const int precision = 6) {
 
  483   std::ofstream out(file_name);
 
  488   const int number_of_patches = geometry.size();
 
  489   std::vector<int> start_idx(number_of_patches);
 
  490   std::vector<int> end_idx(number_of_patches);
 
  491   std::vector<std::vector<std::string>> patch_sections(number_of_patches);
 
  493   for (
auto i = 0; i < number_of_patches; ++i) {
 
  494     const std::vector<std::string> patch_data =
 
  498     start_idx[i] = start_line;
 
  499     start_line += patch_sections[i].size();
 
  500     end_idx[i] = patch_sections[i].size();
 
  502   const int size_directory = 
writeDirectory(file_name, start_idx, end_idx);
 
  505   int size_parameter = 0;
 
  506   for (
auto it = patch_sections.begin(); it != patch_sections.end(); ++it) {
 
  507     const int i = std::distance(patch_sections.begin(), it);
 
  510     first_line = last_idx;
 
  511     size_parameter += (*it).size();
 
  515   std::stringstream last_section;
 
  516   last_section << std::setw(7) << 4 << 
"S" 
  517                << std::setw(7) << size_global << 
"G" 
  518                << std::setw(7) << size_directory << 
"D" 
  519                << std::setw(7) << size_parameter << 
"P";
 
  522   std::ofstream file(file_name, std::ios::app);
 
  523   file << std::left << std::setw(72) << last_section.str()
 
  525        << std::right << std::setw(7) << 1 << 
"\n";
 
void init_Patch(const std::vector< Eigen::Matrix< double, -1, -1 >> &xyzw, const std::vector< double > &x_knots, const std::vector< double > &y_knots)
init
std::vector< double > data_
getter
int writeDirectory(std::string file_name, std::vector< int > start_idx, std::vector< int > number_of_lines)
Write the IGES Directory section into the given file.
int writeParameterSection(std::string file_name, const std::vector< std::string > §ion, const int patch_idx, const int start_count)
This function writes a the parameter section of the IGES file.
void writeIGSHeader(std::string file_name)
Write the IGES header into the given file.
void writeSection(std::string file_name, const std::vector< std::string > §ion, const char section_char)
This function writes a given section to the specified file.
std::vector< Patch > LoadGeometryFileIGS(const std::string &file_name) noexcept
loads geometry from IGES file. Note that the direction of the normals must be consistent.
std::vector< std::string > makeSection(std::vector< std::string > data, const int linewidth=72)
Transform a vector of Data in a vector of lines with a specific length.
std::vector< std::string > writePatchData(const Patch &patch, const int precision)
This Function writes the patch from Bembel into a vector which can be written into an IGES file.
void writeIGSFile(const std::vector< Patch > &geometry, std::string file_name, const int precision=6)
Writes Geometry into an IGES file format.
int writeGlobalSection(std::string file_name)
Write the IGES Global section into the given file.
Routines for the evalutation of pointwise errors.
std::string double_to_string(double d, const int precision)
Convert a double to a string with given precision.