Points&Forces (survey)
Software tools facilitating the task of surveying architecture
rib0.cxx
Go to the documentation of this file.
1 /*
2  Copyright 2002-2011 Pierre SMARS (smars@yuntech.edu.tw)
3  This program is free software: you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation, either version 2 of the License, or
6  (at your option) any later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16 #include <fstream>
17 #include <iostream>
18 #include <vector>
19 #include <math.h>
20 #include <sstream>
21 #include <stdlib.h>
22 
23 #include "a_point.h"
24 
25 #include "SimpleOpt.h"
26 
27 enum { OPT_HELP, OPT_DIR };
28 
29 CSimpleOpt::SOption g_rgOptions[] = {
30  { OPT_DIR,_T("-d"), SO_MULTI },
31  { OPT_HELP,_T("-?"), SO_NONE },
32  { OPT_HELP,_T("-h"), SO_NONE },
33  { OPT_HELP,_T("--help"), SO_NONE },
34  SO_END_OF_OPTIONS
35 };
36 //---------------------------------------------------------------------------
37 int error(int val)
38 {
39  std::cerr << "rib0:" << std::endl;
40  std::cerr << " extrude a profile along a path" << std::endl;
41  std::cerr << "syntax: rib0 path_file profile_file [-?|-h|--help] [-d nx ny nz|--dir nx ny nz] > output_file" << std::endl;
42  std::cerr << " path_file : '.pt' file:" << std::endl;
43  std::cerr << " n_pt" << std::endl;
44  std::cerr << " x1 y1 z1" << std::endl;
45  std::cerr << " x2 y2 z2" << std::endl;
46  std::cerr << " ..." << std::endl;
47  std::cerr << " profile_file: '.pt2' file:" << std::endl;
48  std::cerr << " n_pt" << std::endl;
49  std::cerr << " x1 y1" << std::endl;
50  std::cerr << " x2 y2" << std::endl;
51  std::cerr << " ..." << std::endl;
52  std::cerr << " -d: 3D direction of the x axis of the profile_file" << std::endl;
53  std::cerr << "author: P.Smars, 2001-2008" << std::endl;
54  std::cerr << "version: 2008-04-30" << std::endl;
55  return val;
56 }
57 //---------------------------------------------------------------------------
58 std::vector<a_point *> path;
59 //---------------------------------------------------------------------------
60 a_point dir(int i, int l)
61 {
62  a_point d;
63  int imin = i;
64  int imax = i;
65  if (imin>0)
66  imin -= 1;
67  if (imax<l-1)
68  imax += 1;
69  return (*path[imax]-*path[imin]).normalise();
70 }
71 //---------------------------------------------------------------------------
72 a_point normal(int i, int l)
73 {
74  const a_point vertical(0,0,1);
75  a_point d;
76  const double cosv_lim = 0.95;
77  bool changed;
78  double cosv;
79  int imin = i;
80  int imax = i;
81  do
82  {
83  changed = false;
84  if (imin>0)
85  {
86  changed = true;
87  imin -= 1;
88  }
89  if (imax<l-1)
90  {
91  changed = true;
92  imax += 1;
93  }
94  d = (*path[imax]-*path[imin]).normalise();
95  cosv = fabs(d*vertical);
96  } while ((cosv>cosv_lim)&&changed);
97  if (!changed)
98  {
99  std::cerr << "the path is nearly vertical" << std::endl;
100  std::cerr << "you should define the direction of the normal to the structure with the -d option" << std::endl;
101  std::cerr << "(this is also the 3D direction of the x axis of the profile file)" << std::endl;
102  exit(-2);
103  }
104  return (cross(vertical,d)).normalise();
105 }
106 //---------------------------------------------------------------------------
107 int main( int argc, char *argv[] )
108 {
109  a_point u;
110  bool without_normal = true;
111  CSimpleOpt args(argc, argv, g_rgOptions);
112  while (args.Next())
113  {
114  if (args.LastError() == SO_SUCCESS)
115  {
116  if (args.OptionId() == OPT_HELP)
117  return error(0);
118  else if (args.OptionId() == OPT_DIR)
119  {
120  char ** arg0 = args.MultiArg(3);
121  if (!arg0)
122  {
123  std::cerr << "the number of arguments is not correct" << std::endl;
124  return error(-2);
125  }
126  double x[3];
127  for (int i = 0; i < 3; i++)
128  {
129  std::istringstream in(arg0[i]);
130  in >> x[i];
131  }
132  u.set(x[0],x[1],x[2]);
133  u.normalise();
134  if (u.norm()==0.) return error(-2);
135  without_normal = false;
136  } else
137  return error(-1);
138  // handle option, using OptionId(), OptionText() and OptionArg()
139  } else {
140  std::cerr << "Invalid argument: " << args.OptionText() << std::endl;
141  return error(args.LastError());
142  // handle error, one of: SO_OPT_INVALID, SO_OPT_MULTIPLE,
143  // SO_ARG_INVALID, SO_ARG_INVALID_TYPE, SO_ARG_MISSING
144  }
145  }
146  if (args.FileCount() != 2) return error(-3);
147 
148  std::ifstream f_path(args.File(0));
149  if (!f_path) {std::cerr << "file '" << args.File(1) << "' does not exist" << std::endl; return error(-4);}
150  std::ifstream f_temp(args.File(1));
151  if (!f_temp) {std::cerr << "file '" << args.File(0) << "' does not exist" << std::endl; return error(-5);}
152  //read the path
153  int n_path;
154  a_point * pt;
155  f_path >> n_path;
156  path.resize(n_path);
157  for (int k = 0; k < n_path; k++)
158  {
159  double x,y,z;
160  f_path >> x >> y >> z;
161  pt = new a_point(x,y,z);
162  path[k] =pt;
163  }
164  f_path.close();
165 
166  //read the profile
167  int n_temp;
168  f_temp >> n_temp;
169  std::vector<a_point *> temp(n_temp);
170  for (int k = 0; k < n_temp; k++)
171  {
172  double x,y;
173  f_temp >> x >> y;
174  pt = new a_point(x,y,0);
175  temp[k] = pt;
176  }
177  f_temp.close();
178 
179  a_point vertical(0,0,1);
180  std::cout << n_path*n_temp << std::endl;
181  for (int k = 0; k < n_path; k++)
182  {
183  a_point pt0 = *path[k];
184  a_point dt = dir(k,n_path); //find the average direction at that point
185  if (without_normal)
186  u = normal(k,n_path); //average normal to the plane of the structure at that point
187  a_point v = (cross(dt,u)).normalise();
188  for (int m = 0; m < n_temp; m++)
189  {
190  a_point point0 = *temp[m];
191  a_point pointn = pt0;
192  pointn += (point0.x())*u;
193  pointn += (point0.y())*v;
194  std::cout << pointn << std::endl;
195  }
196  }
197  std::cout << (n_path-1)*(n_temp-1)*2 << std::endl;
198  for (int k = 0; k < n_path-1; k++)
199  {
200  for (int m = 0; m < n_temp-1; m++)
201  {
202  int i1 = k*n_temp+m;
203  int i2 = i1+1;
204  int j1 = i1+n_temp;
205  int j2 = j1+1;
206  std::cout << i1 << "\t" << j2 << "\t" << j1 << std::endl;
207  std::cout << i1 << "\t" << i2 << "\t" << j2 << std::endl;
208  }
209  }
210  return 0;
211 }
e_point cross(e_point &a, e_point &b)
Definition: e_point.cxx:105
double v(const uint32_t step, const uint32_t n)
Definition: generate.cxx:42
std::istringstream in
Definition: ply2tri.cxx:32
int main(int argc, char *argv[])
Definition: rib0.cxx:107
a_point normal(int i, int l)
Definition: rib0.cxx:72
int error(int val)
Definition: rib0.cxx:37
CSimpleOpt::SOption g_rgOptions[]
Definition: rib0.cxx:29
@ OPT_DIR
Definition: rib0.cxx:27
@ OPT_HELP
Definition: rib0.cxx:27
std::vector< a_point * > path
Definition: rib0.cxx:58
a_point dir(int i, int l)
Definition: rib0.cxx:60
Definition: stlb2stla.cxx:21