Points&Forces (survey)
Software tools facilitating the task of surveying architecture
a_block.cxx
Go to the documentation of this file.
1 /*
2 Copyright 2010-2018 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 "a_block.h"
17 
18 #include "config.h"
19 
20 //---------------------------------------------------------------------------
22 {
23  pos_ = new a_twist();
24  material_ = new a_material;
25  material_->density(1.);
26  material_auto_ = true;
27  exit_face_ = -1;
28  g_ = new a_point(0.,0.,-9.81);
29 }
30 //---------------------------------------------------------------------------
32 {
33  this->clear();
34  delete pos_;
35 }
36 //---------------------------------------------------------------------------
38 {
39  for(std::vector<a_point *>::iterator it = vertices_.begin(); it != vertices_.end(); ++it) (*it)->clear();
40  for(std::vector<a_face *>::iterator it = faces_.begin(); it != faces_.end(); ++it) (*it)->clear();
41  vertices_.clear();
42  faces_.clear();
43 }
44 //: exit_face_(-1), a_wrench_()
45 //---------------------------------------------------------------------------
46 const std::string a_block::help()
47 {
48  std::ostringstream o;
49  o << "*********" << std::endl;
50  o << "a_block:" << std::endl;
51  o << "*********" << std::endl;
52  o << "This class is used to model the blocks of a 'a_structure' (see a_structure_help for more information)" << std::endl;
53  o << "This is a virtual class, it cannot be used directly, see a_block_... for usable classes" << std::endl;
54  o << "Commands:" << std::endl;
55  o << "--------" << std::endl;
56  o << "clear: clear the block object" << std::endl;
57  o << "deepcopy 'b': make a completely independant copy of block 'b'" << std::endl;
58  o << "g 'val': sets value of the acceleration of gravity to 'val'" << std::endl;
59  o << "g: gets value of gravity" << std::endl;
60  o << "c: gets centre of mass in world coordinates" << std::endl;
61  o << "cl: get centre of mass in local coordinates" << std::endl;
62  o << "name: gets class name" << std::endl;
63  o << "m: gets mass" << std::endl;
64  o << "Ws: gets scalar value of weight" << std::endl;
65  o << "W: gets weight (returns a wrench, see a_wrench_help)" << std::endl;
66  o << "fe: gets external force on block (returns a wrench)" << std::endl;
67  o << "ft: gets total force on block (returns a wrench)" << std::endl;
68  o << "potential: gets potential energy" << std::endl;
69  o << "nextblock: block connected (return 0 if end or problem)" << std::endl;
70  o << "clearinternal: clear all the internal face forces" << std::endl;
71  o << "clearexternal: clear all the external face forces" << std::endl;
72  o << "clearall: clear all the forces on faces" << std::endl;
73  o << "material 'material': link a material" << std::endl;
74  o << "material: gets material" << std::endl;
75  o << "nv: gets number of vertices" << std::endl;
76  o << "nvt: gets number of vertices (not only the reference vertices)" << std::endl;
77  o << "ni: gets number of faces" << std::endl;
78  o << "nit: gets number of faces (not only the reference faces)" << std::endl;
79  o << "av 'a_point': add a vertex" << std::endl;
80  o << "ai 'a_face': add a face" << std::endl;
81  o << "v 'ref': gets vertex 'ref' (starts from 0)" << std::endl;
82  o << "v3d 'ref': gets vertex 'ref' (world coordinate, 3D)" << std::endl;
83  o << "i 'ref': gets face 'ref'" << std::endl;
84  o << "pos: gets position handle (a a_twist, see a_twist_help)" << std::endl;
85  o << "in: gets insides faces" << std::endl;
86  o << "out: gets outside faces" << std::endl;
87  o << "exit 'ref': set exit face" << std::endl;
88  o << "exit: gets exit face" << std::endl;
89  o << "entrance 'ref': set exit face specifying where the force enters" << std::endl;
90  o << "criteria: set resistance criteria" << std::endl;
91  o << "ok: check whether forces on face are acceptable" << std::endl;
92  o << "penalty: gets penalty value used for optimization" << std::endl;
93  o << "writeb 'file': write block in blender format" << std::endl;
94  o << "writeg 'file': write block in brlcad format" << std::endl;
95  o << "trianglecloud 'a_trianglecloud': write block in a 'a_trianglecloud' object (points&forces)" << std::endl;
96  return o.str();
97 }
98 //---------------------------------------------------------------------------
99 void a_block::copy(const a_block& b)
100 {
101  for (int i=0; i<b.nv(); i++)
102  this->av(b.v(i));
103  material_ = b.material();
104  g_ = b.g();
105  material_auto_ = false;
106  pos_ = new a_twist();
107  //no faces is copied
108 }
109 //---------------------------------------------------------------------------
111 {
112  for (int i=0; i<b.nv(); i++)
113  {
114  a_point * v = new a_point(*(b.v(i)));
115  this->av(v);
116  }
117  g_ = b.g();
118  material_ = new a_material(*(b.material()));
119  material_auto_ = true;
120  pos_ = new a_twist();
121  //no faces is copied
122 }
123 //---------------------------------------------------------------------------
124 void a_block::material(a_material * material)
125 {
126  if (material_auto_)
127  {
128  delete material_;
129  material_auto_ = false;
130  }
132 }
133 //---------------------------------------------------------------------------
134 a_point * a_block::v(const int i)
135 {
136  if ((i>=0)&&(i<vertices_.size()))
137  return vertices_[i];
138  return 0;
139 }
140 //---------------------------------------------------------------------------
141 a_point * a_block::v(const int i) const
142 {
143  if ((i>=0)&&(i<vertices_.size()))
144  return vertices_[i];
145  return 0;
146 }
147 //---------------------------------------------------------------------------
148 a_face * a_block::i(const int i)
149 {
150  if ((i>=0)&&(i<faces_.size()))
151  return faces_[i];
152  return 0;
153 }
154 //---------------------------------------------------------------------------
155 a_face * a_block::i(const int i) const
156 {
157  if ((i>=0)&&(i<faces_.size()))
158  return faces_[i];
159  return 0;
160 }
161 //---------------------------------------------------------------------------
162 a_point a_block::c() const
163 {
164  return (*pos_)*this->cl();
165 }
166 //---------------------------------------------------------------------------
167 double a_block::m() const
168 {
169  return this->V()*this->material()->density();
170 }
171 //---------------------------------------------------------------------------
172 double a_block::Ws() const
173 {
174  double g = this->g()->norm();
175  return g*this->m();
176 }
177 //---------------------------------------------------------------------------
179 {
180  a_point c = this->c();
181  a_point g = *this->g();
182  double m = this->m();
183  return a_wrench(c,g*m);
184 }
185 //---------------------------------------------------------------------------
187 {
188  a_wrench w;
189  for (int i=0; i<faces_.size(); i++)
190  {
191  a_face * f = faces_[i];
192  if (f->out())
193  {
194  w += f->f();
195  }
196  }
197  return w;
198 }
199 //---------------------------------------------------------------------------
201 {
202  a_wrench w1 = this->W();
203  a_wrench w2 = this->fe();
204  return w1+w2;
205 }
206 //---------------------------------------------------------------------------
207 a_wrench a_block::W(const a_block& be) const
208 {
209  if (this==&be)
210  return this->W();
211  a_block * nb = this->nextblock();
212  if (nb==0)
213  throw a_block::no_block_error();
214  a_wrench w2 = nb->W(be);
215  return w2+this->W();
216 }
217 //---------------------------------------------------------------------------
218 a_wrench a_block::ft(const a_block& be) const
219 {
220  if (this==&be)
221  return this->ft();
222  a_block * nb = this->nextblock();
223  if (nb==0)
224  throw a_block::no_block_error();
225  a_wrench w2 = nb->ft(be);
226  return w2+this->ft();
227 }
228 //---------------------------------------------------------------------------
230 {
231  int ri = this->exit();
232  if (ri==-1)
233  return 0;
234  a_face * f = this->i(ri);
235  a_face * f2 = f->lface();
236  if (f2==0)
237  return 0;
238  a_block * b2 = f2->block();
239  //get reference of face
240  int r2 = f2->rf();
241  //set the exit face of the next block
242  b2->entrance(r2);
243  return b2;
244 }
245 //---------------------------------------------------------------------------
246 double a_block::potential() const
247 {
248  a_point c = this->c();
249  a_point n = -this->g()->normalise();
250  return this->Ws()*(c*n);
251 }
252 //---------------------------------------------------------------------------
254 {
255  for (int i=0; i<faces_.size(); i++)
256  {
257  a_face * f = faces_[i];
258  if (f->in())
259  f->clear();
260  }
261 }
262 //---------------------------------------------------------------------------
264 {
265  for (int i=0; i<faces_.size(); i++)
266  {
267  a_face * f = faces_[i];
268  if (f->out())
269  f->clear();
270  }
271 }
272 //---------------------------------------------------------------------------
274 {
275  for (int i=0; i<faces_.size(); i++)
276  {
277  a_face * f = faces_[i];
278  f->clear();
279  }
280 }
281 //---------------------------------------------------------------------------
283 {
284  for (int i=0; i<faces_.size(); i++)
286 }
287 //---------------------------------------------------------------------------
288 bool a_block::ok() const
289 {
290  for (int i=0; i<faces_.size(); i++)
291  {
292  if (!faces_[i]->ok())
293  return false;
294  }
295  return true;
296 }
297 //---------------------------------------------------------------------------
298 double a_block::penalty() const
299 {
300  double val = 0.;
301  for (int i=0; i<faces_.size(); i++)
302  {
303  double v = faces_[i]->penalty();
304  if (v>val)
305  val = v;
306  }
307  return val;
308 }
309 //---------------------------------------------------------------------------
311 {
312  a_wrench * exit = new a_wrench;
313  int ri = -1;
314  //compute summ of forces from faces
315  for (int i=0; i<ni(); i++)
316  {
317  a_face * f = this->i(i);
318  if (f->exit())
319  ri = i;
320  else
321  *exit -= f->f();
322  }
323  //add weight
324  *exit -= this->W();
325  if (ri != -1)
326  {
327  //get exit face
328  a_face * f = this->i(ri);
329  //assign force to the exit face
330  f->f(exit);
331  //get connected face
332  a_face * f2 = f->lface();
333  //if there is a connect face
334  if (f2 != 0)
335  {
336  //prepare next block
337  //assign opposite of force to connected face
338  a_wrench * exit2 = new a_wrench;
339  *exit2 = *exit;
340  *exit2 *= -1.;
341  f2->f(exit2);
342  //get connected block
343  a_block * b2 = f2->block();
344  //get reference of face
345  int r2 = f2->rf();
346  //set the exit face of the next block
347  b2->entrance(r2);
348  return b2;
349  }
350  return 0;
351  }
352  return 0;
353 }
354 //---------------------------------------------------------------------------
355 void a_block::place(const int fi, a_block * block, const int fe, double u, double v)
356 {
357  a_face * fip = this->i(fi);
358  a_point ci = fip->c();
359  a_face * fep = block->i(fe);
360  a_point nxi = fip->nx();
361  a_point nxe = -fep->nx();
362  a_point nyi = fip->ny();
363  a_point nye = -fep->ny();
364  double ax = angle(nxi,nxe);
365  double ay = angle(nyi,nye);
366  a_point pt = fep->c()+u*nxe+v*nye;
367  a_point d = pt-ci;
368  pos_->translate(d);
369  pos_->rotate(pt,nye,ax);
370 // pos_->rotate(pt,nxe,ay);
371 }
372 //---------------------------------------------------------------------------
373 std::vector<int> a_block::in() const
374 {
375  std::vector<int> list;
376  for (int i=0; i<ni(); i++)
377  {
378  a_face * f = this->i(i);
379  if (f->in())
380  list.push_back(i);
381  }
382  return list;
383 }
384 //---------------------------------------------------------------------------
385 std::vector<int> a_block::out() const
386 {
387  std::vector<int> list;
388  for (int i=0; i<ni(); i++)
389  {
390  a_face * f = this->i(i);
391  if (f->out())
392  list.push_back(i);
393  }
394  return list;
395 }
396 //---------------------------------------------------------------------------
397 void a_block::exit(int ref)
398 {
399  for (int i=0; i<this->ni(); i++)
400  {
401  if (i == ref)
402  faces_[i]->exit(true);
403  else
404  faces_[i]->exit(false);
405  }
406  exit_face_ = ref;
407 }
408 //---------------------------------------------------------------------------
409 int a_block::entrance(int val)
410 {
411  a_face * in = this->i(val);
412  in->exit(false);
413  //number of inside faces
414  int nc = 0;
415  int ref;
416  for (int i=0; i<this->ni(); i++)
417  {
418  //do not count entrance face
419  if (i != val)
420  {
421  a_face * f = this->i(i);
422  //if inside face, possible exit
423  if (f->in())
424  {
425  nc++;
426  ref = i;
427  }
428  }
429  }
430  //if more than one possible exit, stop
431  if (nc>1)
432  return -2;
433  //no candidate -> probably the last block
434  else if (nc==0)
435  {
436  //check whether there is already an exit face specified
437  //that should be the case
438  if (exit_face_ != -1)
439  return 0;
440  //last block will not be computed
441  return -1;
442  }
443  //if nc==1 set exit face
444  exit_face_ = ref;
445  faces_[ref]->exit(true);
446  return 0;
447 }
448 //---------------------------------------------------------------------------
449 void a_block::read(std::istream &in)
450 {
451  std::string name;
452  in >> name;
453  if (name != this->name())
454  throw compatibility_error();
455  int nv;
456  in >> nv;
457  for (int i=0; i<nv; i++)
458  {
459  a_point * vertex = new a_point;
460  in >> *vertex;
461  this->av(vertex);
462  }
463  in >> g_;
464  //type of face will depend of type of block... this part will be read in children of a_block
465  int ni;
466  in >> ni;
467  for (int i=0; i<ni; i++)
468  {
469  }
470  in >> *pos_;
471 }
472 //---------------------------------------------------------------------------
473 void a_block::write(std::ostream &o) const
474 {
475  o << this->name() << std::endl;
476  int nv = this->nv();
477  o << nv << std::endl;
478  for (int i=0; i<nv; i++)
479  o << this->v(i) << std::endl;
480  o << this->g() << std::endl;
481  int ni = this->ni();
482  o << ni << std::endl;
483  for (int i=0; i<ni; i++)
484  this->i(i)->write(o);
485  o << *(this->pos()) << std::endl;
486 }
487 //---------------------------------------------------------------------------
488 void a_block::writeverts(std::ostream &o) const
489 {
490  int nv = this->nvt();
491  for (int i=0; i<nv; i++)
492  o << this->v3d(i) << std::endl;
493 }
494 //*****************************************************************************
495 //-operator>>----------------------------------------------------------------
496 std::istream& operator>> (std::istream& in, a_block& b)
497 {
498  b.read(in);
499  return in;
500 }
501 //-operator<<----------------------------------------------------------------
502 std::ostream& operator<< (std::ostream& o, const a_block& b)
503 {
504  b.write(o);
505  return o;
506 }
507 
std::ostream & operator<<(std::ostream &o, const a_block &b)
Definition: a_block.cxx:502
std::istream & operator>>(std::istream &in, a_block &b)
Definition: a_block.cxx:496
a_block * compute()
compute the exit force from all the forces on the block, return next block or 0 if last one or proble...
Definition: a_block.cxx:310
static const std::string help()
get information about the class
Definition: a_block.cxx:46
double potential() const
potential energy
Definition: a_block.cxx:246
virtual void copy(const a_block &)
Definition: a_block.cxx:99
int entrance(int ref)
set exit face specifying where the force enters
Definition: a_block.cxx:409
int exit_face_
Definition: a_block.h:145
void clearinternal()
clear all the internal face forces
Definition: a_block.cxx:253
a_wrench W() const
weight wrench in world coordinate
Definition: a_block.cxx:178
a_point * g() const
get gravity
Definition: a_block.h:40
virtual void write(std::ostream &o) const
Definition: a_block.cxx:473
void av(a_point *vertex)
add a vertex
Definition: a_block.h:87
a_wrench fe() const
external force on block in world coordinate
Definition: a_block.cxx:186
void material(a_material *material)
link a material
Definition: a_block.cxx:124
virtual ~a_block()
Definition: a_block.cxx:31
void place(const int fi, a_block *block, const int fe, double u, double v)
place a face of the block on the face of another block
Definition: a_block.cxx:355
void writeverts(std::ostream &o) const
Definition: a_block.cxx:488
std::vector< int > in() const
return inside faces
Definition: a_block.cxx:373
void g(a_point *g)
set gravity
Definition: a_block.h:38
void clearall()
clear all the forces on faces
Definition: a_block.cxx:273
a_twist * pos_
Definition: a_block.h:146
std::vector< a_point * > vertices_
Definition: a_block.h:141
double penalty() const
penalty value used for optimization
Definition: a_block.cxx:298
a_wrench ft() const
total force on block in world coordinate
Definition: a_block.cxx:200
a_point c() const
centre of mass (in world coordinate)
Definition: a_block.cxx:162
virtual std::string name() const
Definition: a_block.h:47
a_face * i(const int i)
get pointer to face
Definition: a_block.cxx:148
bool ok() const
check if forces on face are acceptable
Definition: a_block.cxx:288
void criteria(a_fcriteria *criteria)
set resistance criteria
Definition: a_block.cxx:282
virtual a_point v3d(const int i) const =0
get vertex (world coordinate, 3D)
int ni() const
get number of faces
Definition: a_block.h:83
a_twist * pos() const
get pointer to position handle
Definition: a_block.h:101
std::vector< a_face * > faces_
Definition: a_block.h:142
a_block()
Definition: a_block.cxx:21
void clearexternal()
clear all the external face forces
Definition: a_block.cxx:263
a_material * material_
Definition: a_block.h:143
a_point * v(const int i)
get pointer to vertex
Definition: a_block.cxx:134
virtual a_point cl() const =0
centre of mass (in local system)
int exit() const
get exit face
Definition: a_block.h:111
a_point * g_
Definition: a_block.h:147
virtual void deepcopy(const a_block &)
Definition: a_block.cxx:110
bool material_auto_
Definition: a_block.h:144
virtual int nvt() const =0
get number of vertices (not only the reference vertices)
virtual void read(std::istream &i)
input/output
Definition: a_block.cxx:449
int nv() const
get number of vertices
Definition: a_block.h:79
double m() const
mass
Definition: a_block.cxx:167
void clear()
Definition: a_block.cxx:37
std::vector< int > out() const
return outside faces
Definition: a_block.cxx:385
virtual double V() const =0
volume of the block
a_material * material() const
get pointer to material
Definition: a_block.h:77
double Ws() const
weight
Definition: a_block.cxx:172
a_block * nextblock() const
block connected (return 0 if end or problem)
Definition: a_block.cxx:229
Definition: a_face.h:33
virtual a_point nx() const =0
direction of face (in world coordinate)
bool in() const
face is connected to other faces, inside the structure
Definition: a_face.h:159
virtual void clear()
set force to 0
Definition: a_face.cxx:48
void lface(a_face *f)
set connected face
Definition: a_face.h:153
a_point c() const
centre of mass (in world coordinate)
Definition: a_face.cxx:311
void exit(bool exit)
set as an exit face
Definition: a_face.h:72
int rf() const
get face reference in connected block
Definition: a_face.h:47
virtual void write(std::ostream &o) const
Definition: a_face.cxx:505
void f(const a_wrench &f)
set force on the face
Definition: a_face.h:133
virtual a_point ny() const =0
normal to the vertices of the block (in world coordinate)
bool out() const
face is not connected to other faces, on the boudary
Definition: a_face.h:161
a_block * block()
get block
Definition: a_face.h:49
void density(const double density)
Definition: a_material.h:33
a twist class
Definition: a_twist.h:31
void rotate(const a_point &pt, const a_point &dir, double v)
Definition: a_twist.cxx:209
void translate(const a_point &d)
iterative transformation
Definition: a_twist.cxx:151
a wrench class
Definition: a_wrench.h:30