1 /*
2 XLiFE++ is an extended library of finite elements written in C++
3     Copyright (C) 2014  Lunéville, Eric; Kielbasiewicz, Nicolas; Lafranche, Yvon; Nguyen, Manh-Ha; Chambeyron, Colin
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
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 
17 /*!
18   \file geometries3D.cpp
19   \authors N. Kielbasiewicz, Y. Lafranche
20   \since 18 oct 2012
21   \date 30 jul 2015
22 
23   \brief This file contains the implementation of methods of Volume class and Polyhedron and Ellipsoid classes
24   defined in geometries3D.hpp
25 */
26 
27 #include "geometries2D.hpp"
28 #include "geometries3D.hpp"
29 #include "geometries_utils.hpp"
30 
31 namespace xlifepp
32 {
33 
34 //===========================================================
35 //
36 // Volume and child classes member functions
37 //
38 //===========================================================
39 
40 //! default volume is inside bounding box [0,1]^3
Volume()41 Volume::Volume()
42   : Geometry(BoundingBox(0.,1.,0.,1.,0.,1.), 3) {}
43 
buildParam(const Parameter & p)44 void Volume::buildParam(const Parameter& p)
45 {
46   trace_p->push("Volume::buildParam");
47   ParameterKey key=p.key();
48 
49   switch(key)
50     {
51       case _pk_side_names:
52         {
53           if(p.type()==_string) { sideNames_.resize(1,p.get_s()); }
54           else if(p.type()==_stringVector) { sideNames_=p.get_sv(); }
55           else { error("param_badtype",words("value",p.type()),words("param key",key)); }
56           break;
57         }
58       default: Geometry::buildParam(p); break;
59     }
60   trace_p->pop();
61 }
62 
buildDefaultParam(ParameterKey key)63 void Volume::buildDefaultParam(ParameterKey key)
64 {
65   trace_p->push("Volume::buildDefaultParam");
66   switch(key)
67     {
68       case _pk_side_names: sideNames_.resize(0); break;
69       default: Geometry::buildDefaultParam(key); break;
70     }
71   trace_p->pop();
72 }
73 
getParamsKeys()74 std::set<ParameterKey> Volume::getParamsKeys()
75 {
76   std::set<ParameterKey> params=Geometry::getParamsKeys();
77   params.insert(_pk_side_names);
78   return params;
79 }
80 
81 //! default polyhedron is tetrahedron (0,0,0) (1,0,0) (0,1,0) (0,0,1)
Polyhedron()82 Polyhedron::Polyhedron() : Volume()
83 {
84   p_.resize(4);
85   p_[0] = Point(0.,0.,0.);
86   p_[1] = Point(1.,0.,0.);
87   p_[2] = Point(0.,1.,0.);
88   p_[3] = Point(0.,0.,1.);
89   faces_.resize(4);
90   faces_[0] = new Triangle(p_[0], p_[1], p_[2]);
91   faces_[1] = new Triangle(p_[0], p_[1], p_[3]);
92   faces_[2] = new Triangle(p_[1], p_[2], p_[3]);
93   faces_[3] = new Triangle(p_[2], p_[0], p_[3]);
94   shape_=_polyhedron;
95   computeMB();
96 }
97 
buildP()98 void Polyhedron::buildP()
99 {
100   for(number_t i=0; i < faces_.size(); ++i)
101     {
102       boundingBox+=faces_[i]->boundingBox;
103       for(number_t j=0; j < faces_[i]->p().size(); ++j)
104         {
105           int_t foundId=-1;
106           for(number_t k=0; k < p_.size(); ++k)
107             {
108               if(p_[k] == faces_[i]->p(j+1)) { foundId=j; }
109             }
110           if(foundId == -1) { p_.push_back(faces_[i]->p(j+1)); }
111         }
112     }
113 }
114 
build(const std::vector<Parameter> & ps)115 void Polyhedron::build(const std::vector<Parameter>& ps)
116 {
117   trace_p->push("Polyhedron::build");
118   shape_=_polyhedron;
119   std::set<ParameterKey> params=getParamsKeys(), usedParams;
120   // managing params
121   for(number_t i=0; i < ps.size(); ++i)
122     {
123       ParameterKey key=ps[i].key();
124       buildParam(ps[i]);
125       if(params.find(key) != params.end()) { params.erase(key); }
126       else
127         {
128           if(usedParams.find(key) == usedParams.end())
129             { error("geom_unexpected_param_key", words("param key",key), words("shape",_polyhedron)); }
130           else { warning("param_already_used", words("param key",key)); }
131         }
132       usedParams.insert(key);
133     }
134 
135   // faces has to be set (no default values)
136   if(params.find(_pk_faces) != params.end()) { error("param_missing","faces"); }
137 
138   std::set<ParameterKey>::const_iterator it_p;
139   for(it_p=params.begin(); it_p != params.end(); ++it_p) { buildDefaultParam(*it_p); }
140 
141   buildP();
142 
143   computeMB();
144   trace_p->pop();
145 }
146 
buildParam(const Parameter & p)147 void Polyhedron::buildParam(const Parameter& p)
148 {
149   trace_p->push("Polyhedron::buildParam");
150   ParameterKey key=p.key();
151   switch(key)
152     {
153       case _pk_faces:
154         {
155           switch(p.type())
156             {
157               case _pointer:
158                 {
159                   const std::vector<Polygon>& faces = *reinterpret_cast<const std::vector<Polygon>*>(p.get_p());
160                   faces_.resize(faces.size());
161                   for(number_t i=0; i < faces_.size(); ++i) { faces_[i]=faces[i].clonePG(); }
162                   break;
163                 }
164               default: error("param_badtype",words("value",p.type()),words("param key",key));
165             }
166           break;
167         }
168       default: Volume::buildParam(p); break;
169     }
170   trace_p->pop();
171 }
172 
buildDefaultParam(ParameterKey key)173 void Polyhedron::buildDefaultParam(ParameterKey key)
174 {
175   Volume::buildDefaultParam(key);
176 }
177 
getParamsKeys()178 std::set<ParameterKey> Polyhedron::getParamsKeys()
179 {
180   std::set<ParameterKey> params=Volume::getParamsKeys();
181   params.insert(_pk_faces);
182   return params;
183 }
184 
Polyhedron(const Parameter & p1)185 Polyhedron::Polyhedron(const Parameter& p1) : Volume()
186 {
187   std::vector<Parameter> ps(1,p1);
188   build(ps);
189 }
190 
Polyhedron(const Parameter & p1,const Parameter & p2)191 Polyhedron::Polyhedron(const Parameter& p1, const Parameter& p2) : Volume()
192 {
193   std::vector<Parameter> ps(2);
194   ps[0]=p1; ps[1]=p2;
195   build(ps);
196 }
197 
Polyhedron(const Polyhedron & ph)198 Polyhedron::Polyhedron(const Polyhedron& ph) : Volume(ph)
199 {
200   p_=ph.p_;
201   n_=ph.n_;
202   h_=ph.h_;
203   faces_.resize(ph.faces_.size());
204   for(number_t i=0; i < faces_.size(); ++i)
205     {
206       faces_[i]=ph.faces_[i]->clonePG();
207     }
208 }
209 
asString() const210 string_t Polyhedron::asString() const
211 {
212   string_t s("Polyhedron (");
213   s += tostring(faces_.size()) + " faces )";
214   return s;
215 }
216 
boundNodes() const217 std::vector<const Point*> Polyhedron::boundNodes() const
218 {
219   std::vector<const Point*> nodes(p_.size());
220   for(number_t i=0; i < p_.size(); ++i) { nodes[i]=&p_[i]; }
221   return nodes;
222 }
223 
nodes()224 std::vector<Point*> Polyhedron::nodes()
225 {
226   std::vector<Point*> nodes(p_.size());
227   for(number_t i=0; i < p_.size(); ++i) { nodes[i]=&p_[i]; }
228   return nodes;
229 }
230 
nodes() const231 std::vector<const Point*> Polyhedron::nodes() const
232 {
233   std::vector<const Point*> nodes(p_.size());
234   for(number_t i=0; i < p_.size(); ++i) { nodes[i]=&p_[i]; }
235   return nodes;
236 }
237 
curves() const238 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Polyhedron::curves() const
239 {
240   std::vector<std::pair<ShapeType,std::vector<const Point*> > > curves, curves2;
241 
242   for(number_t i=0; i < faces_.size(); ++i)
243     {
244       for(number_t j=0; j < faces_[i]->curves().size(); ++j)
245         {
246           curves2=faces_[i]->curves();
247           if(findBorder(curves2[j], curves) == -1)
248             {
249               curves.push_back(curves2[j]);
250             }
251         }
252     }
253   return curves;
254 }
255 
surfs() const256 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Polyhedron::surfs() const
257 {
258   std::vector<std::pair<ShapeType,std::vector<const Point*> > > surfs(faces_.size());
259   for(number_t i=0; i < faces_.size(); ++i)
260     {
261       surfs[i]=faces_[i]->surfs()[0];
262     }
263   return surfs;
264 }
265 
266 //! collect in a list all canonical geometry's with name n
collect(const string_t & n,std::list<Geometry * > & geoms) const267 void Polyhedron::collect(const string_t& n, std::list<Geometry*>& geoms) const
268 {
269   if(domName_==n) geoms.push_back(const_cast<Geometry*>(static_cast<const Geometry*>(this)));
270   //loop on sides
271   std::vector<Polygon*>::const_iterator its=faces_.begin();
272   for(; its!=faces_.end(); ++its)
273     {
274       if((*its)->domName()==n) geoms.push_back((*its)->clone()); //create geometry related to side by cloning
275     }
276 }
277 
278 //! default tetrahedron is tetrahedron (0,0,0) (1,0,0) (0,1,0) (0,0,1)
Tetrahedron()279 Tetrahedron::Tetrahedron() : Polyhedron()
280 {
281   n_.resize(6,2);
282   shape_=_tetrahedron;
283   computeMB();
284   setFaces();
285 }
286 
build(const std::vector<Parameter> & ps)287 void Tetrahedron::build(const std::vector<Parameter>& ps)
288 {
289   trace_p->push("Tetrahedron::build");
290   shape_=_tetrahedron;
291   std::set<ParameterKey> params=getParamsKeys(), usedParams;
292   // _faces key is replaced by _v1, _v2 and _v3
293   params.erase(_pk_faces);
294 
295   p_.resize(4);
296   // managing params
297   for(number_t i=0; i < ps.size(); ++i)
298     {
299       ParameterKey key=ps[i].key();
300       buildParam(ps[i]);
301       if(params.find(key) != params.end()) { params.erase(key); }
302       else
303         {
304           if(usedParams.find(key) == usedParams.end())
305             { error("geom_unexpected_param_key", words("param key",key), words("shape",_tetrahedron)); }
306           else { warning("param_already_used", words("param key",key)); }
307         }
308       usedParams.insert(key);
309       // user must use nnodes or hsteps, not both
310       if(key==_pk_hsteps && usedParams.find(_pk_nnodes) != usedParams.end())
311         { error("param_conflict", words("param key",key), words("param key",_pk_nnodes)); }
312       if(key==_pk_nnodes && usedParams.find(_pk_hsteps) != usedParams.end())
313         { error("param_conflict", words("param key",key), words("param key",_pk_hsteps)); }
314     }
315 
316   // if hsteps is not used, nnodes is used instead and there is no default value
317   if(params.find(_pk_hsteps) != params.end()) { params.erase(_pk_hsteps); }
318 
319   // (v1,v2,v3,v4) has to be set (no default values)
320   if(params.find(_pk_v1) != params.end()) { error("param_missing","v1"); }
321   if(params.find(_pk_v2) != params.end()) { error("param_missing","v2"); }
322   if(params.find(_pk_v3) != params.end()) { error("param_missing","v3"); }
323   if(params.find(_pk_v4) != params.end()) { error("param_missing","v4"); }
324 
325   std::set<ParameterKey>::const_iterator it_p;
326   for(it_p=params.begin(); it_p != params.end(); ++it_p) { buildDefaultParam(*it_p); }
327 
328   // checking nnodes and hsteps size
329   if(n_.size() != 0)
330     {
331       if(n_.size() == 1) { number_t n0=n_[0]; n_.resize(6,n0); }
332       else if(n_.size() != 6) {error("bad_size","nnodes",6,n_.size()); }
333     }
334   if(h_.size() != 0)
335     {
336       if(h_.size() == 1) { real_t h0=h_[0]; h_.resize(4,h0); }
337       else if(h_.size() != 4) {error("bad_size","hsteps",4,h_.size()); }
338     }
339 
340   boundingBox=BoundingBox(p_[0], p_[1], p_[2], p_[3]);
341   computeMB();
342   setFaces();
343   trace_p->pop();
344 }
345 
setFaces()346 void Tetrahedron::setFaces()
347 {
348   faces_.resize(4);
349   std::vector<number_t> ns(4,2);  // ns is set to 2
350   if(sideNames_.size()>=4)
351     {
352       faces_[0] = new Triangle(p_[0], p_[1], p_[2], ns, sideNames_[0]);
353       faces_[1] = new Triangle(p_[0], p_[1], p_[3], ns, sideNames_[1]);
354       faces_[2] = new Triangle(p_[1], p_[2], p_[3], ns, sideNames_[2]);
355       faces_[3] = new Triangle(p_[2], p_[0], p_[3], ns, sideNames_[3]);
356     }
357   else
358     {
359       string_t sn="";
360       if(sideNames_.size()>=1) sn=sideNames_[0];
361       faces_[0] = new Triangle(p_[0], p_[1], p_[2], ns, sn);
362       faces_[1] = new Triangle(p_[0], p_[1], p_[3], ns, sn);
363       faces_[2] = new Triangle(p_[1], p_[2], p_[3], ns, sn);
364       faces_[3] = new Triangle(p_[2], p_[0], p_[3], ns, sn);
365     }
366 }
367 
measure() const368 real_t Tetrahedron::measure() const
369 {
370   real_t h;
371   Point P=projectionOnStraightLine(p_[2], p_[0], p_[1], h);
372   real_t area=0.5*(p_[0].distance(p_[1])) * h;
373   P=projectionOnTriangle(p_[3], p_[0], p_[1], p_[2], h);
374   return area*h/3.;
375 }
376 
buildParam(const Parameter & p)377 void Tetrahedron::buildParam(const Parameter& p)
378 {
379   trace_p->push("Tetrahedron::buildParam");
380   ParameterKey key=p.key();
381   switch(key)
382     {
383       case _pk_v1:
384         {
385           switch(p.type())
386             {
387               case _pt: p_[0]=p.get_pt(); break;
388               case _integer: p_[0]=Point(real_t(p.get_i())); break;
389               case _real: p_[0]=Point(p.get_r()); break;
390               default: error("param_badtype",words("value",p.type()),words("param key",key));
391             }
392           break;
393         }
394       case _pk_v2:
395         {
396           switch(p.type())
397             {
398               case _pt: p_[1]=p.get_pt(); break;
399               case _integer: p_[1]=Point(real_t(p.get_i())); break;
400               case _real: p_[1]=Point(p.get_r()); break;
401               default: error("param_badtype",words("value",p.type()),words("param key",key));
402             }
403           break;
404         }
405       case _pk_v3:
406         {
407           switch(p.type())
408             {
409               case _pt: p_[2]=p.get_pt(); break;
410               case _integer: p_[2]=Point(real_t(p.get_i())); break;
411               case _real: p_[2]=Point(p.get_r()); break;
412               default: error("param_badtype",words("value",p.type()),words("param key",key));
413             }
414           break;
415         }
416       case _pk_v4:
417         {
418           switch(p.type())
419             {
420               case _pt: p_[3]=p.get_pt(); break;
421               case _integer: p_[3]=Point(real_t(p.get_i())); break;
422               case _real: p_[3]=Point(p.get_r()); break;
423               default: error("param_badtype",words("value",p.type()),words("param key",key));
424             }
425           break;
426         }
427       case _pk_nnodes:
428         {
429           switch(p.type())
430             {
431               case _integerVector:
432                 {
433                   std::vector<number_t> n=p.get_nv();
434                   n_.resize(n.size());
435                   for(number_t i=0; i < n.size(); ++i) { n_[i] = n[i] > 2 ? n[i] : 2; }
436                   break;
437                 }
438               case _integer: n_=std::vector<number_t>(1,p.get_n() > 2 ? p.get_n() : 2); break;
439               default: error("param_badtype",words("value",p.type()),words("param key",key));
440             }
441           break;
442         }
443       case _pk_hsteps:
444         {
445           switch(p.type())
446             {
447               case _realVector: h_=p.get_rv(); break;
448               case _integer: h_=std::vector<real_t>(1,real_t(p.get_i())); break;
449               case _real: h_=std::vector<real_t>(1,p.get_r()); break;
450               default: error("param_badtype",words("value",p.type()),words("param key",key));
451             }
452           break;
453         }
454       default: Polyhedron::buildParam(p); break;
455     }
456   trace_p->pop();
457 }
458 
buildDefaultParam(ParameterKey key)459 void Tetrahedron::buildDefaultParam(ParameterKey key)
460 {
461   trace_p->push("Tetrahedron::buildDefaultParam");
462   switch(key)
463     {
464       case _pk_nnodes: n_=std::vector<number_t>(6,2); break;
465       default: Polyhedron::buildDefaultParam(key); break;
466     }
467   trace_p->pop();
468 }
469 
getParamsKeys()470 std::set<ParameterKey> Tetrahedron::getParamsKeys()
471 {
472   std::set<ParameterKey> params=Polyhedron::getParamsKeys();
473   params.insert(_pk_v1);
474   params.insert(_pk_v2);
475   params.insert(_pk_v3);
476   params.insert(_pk_v4);
477   params.insert(_pk_nnodes);
478   params.insert(_pk_hsteps);
479   return params;
480 }
481 
Tetrahedron(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4)482 Tetrahedron::Tetrahedron(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4) : Polyhedron()
483 {
484   std::vector<Parameter> ps(4);
485   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4;
486   build(ps);
487 }
488 
Tetrahedron(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5)489 Tetrahedron::Tetrahedron(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5)
490   : Polyhedron()
491 {
492   std::vector<Parameter> ps(5);
493   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5;
494   build(ps);
495 }
496 
Tetrahedron(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6)497 Tetrahedron::Tetrahedron(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
498                          const Parameter& p6) : Polyhedron()
499 {
500   std::vector<Parameter> ps(6);
501   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6;
502   build(ps);
503 }
504 
Tetrahedron(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7)505 Tetrahedron::Tetrahedron(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
506                          const Parameter& p6, const Parameter& p7) : Polyhedron()
507 {
508   std::vector<Parameter> ps(7);
509   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7;
510   build(ps);
511 }
512 
asString() const513 string_t Tetrahedron::asString() const
514 {
515   string_t s("Tetrahedron (");
516   s += p_[0].toString() +", " + p_[1].toString() + ", " + p_[2].toString() + ", " + p_[3].toString() + ")";
517   return s;
518 }
519 
curves() const520 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Tetrahedron::curves() const
521 {
522   std::vector<std::pair<ShapeType,std::vector<const Point*> > > curves(6);
523   std::vector<const Point*> vertices(2);
524   vertices[0]=&p_[0]; vertices[1]=&p_[1];
525   curves[0]=std::make_pair(_segment, vertices);
526   vertices[0]=&p_[1]; vertices[1]=&p_[2];
527   curves[1]=std::make_pair(_segment, vertices);
528   vertices[0]=&p_[2]; vertices[1]=&p_[0];
529   curves[2]=std::make_pair(_segment, vertices);
530   vertices[0]=&p_[0]; vertices[1]=&p_[3];
531   curves[3]=std::make_pair(_segment, vertices);
532   vertices[0]=&p_[1]; vertices[1]=&p_[3];
533   curves[4]=std::make_pair(_segment, vertices);
534   vertices[0]=&p_[2]; vertices[1]=&p_[3];
535   curves[5]=std::make_pair(_segment, vertices);
536 
537   return curves;
538 }
539 
surfs() const540 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Tetrahedron::surfs() const
541 {
542   std::vector<std::pair<ShapeType,std::vector<const Point*> > > surfs(4);
543   std::vector<const Point*> vertices(3);
544   vertices[0]=&p_[0]; vertices[1]=&p_[1]; vertices[2]=&p_[2];
545   surfs[0]=std::make_pair(_triangle, vertices);
546   vertices[0]=&p_[0]; vertices[1]=&p_[1]; vertices[2]=&p_[3];
547   surfs[1]=std::make_pair(_triangle, vertices);
548   vertices[0]=&p_[1]; vertices[1]=&p_[2]; vertices[2]=&p_[3];
549   surfs[2]=std::make_pair(_triangle, vertices);
550   vertices[0]=&p_[2]; vertices[1]=&p_[0]; vertices[2]=&p_[3];
551   surfs[3]=std::make_pair(_triangle, vertices);
552 
553   return surfs;
554 }
555 
Hexahedron()556 Hexahedron::Hexahedron() : Polyhedron()
557 {
558   p_.resize(8);
559   p_[0]=Point(0.,0.,0.);
560   p_[1]=Point(1.,0.,0.);
561   p_[2]=Point(1.,1.,0.);
562   p_[3]=Point(0.,1.,0.);
563   p_[4]=Point(0.,0.,1.);
564   p_[5]=Point(1.,0.,1.);
565   p_[6]=Point(1.,1.,1.);
566   p_[7]=Point(0.,1.,1.);
567   n_.resize(12,2);
568   shape_=_hexahedron;
569   computeMB();
570   setFaces();
571 }
572 
build(const std::vector<Parameter> & ps)573 void Hexahedron::build(const std::vector<Parameter>& ps)
574 {
575   trace_p->push("Hexahedron::build");
576   shape_=_hexahedron;
577   std::set<ParameterKey> params=getParamsKeys(), usedParams;
578   // _faces key is replaced by _v1, _v2, _v3, _v4, _v5, _v6, _v7 and _v8
579   params.erase(_pk_faces);
580 
581   p_.resize(8);
582   // managing params
583   for(number_t i=0; i < ps.size(); ++i)
584     {
585       ParameterKey key=ps[i].key();
586       buildParam(ps[i]);
587       if(params.find(key) != params.end()) { params.erase(key); }
588       else
589         {
590           if(usedParams.find(key) == usedParams.end())
591             { error("geom_unexpected_param_key", words("param key",key), words("shape",_hexahedron)); }
592           else { warning("param_already_used", words("param key",key)); }
593         }
594       usedParams.insert(key);
595       // user must use nnodes or hsteps, not both
596       if(key==_pk_hsteps && usedParams.find(_pk_nnodes) != usedParams.end())
597         { error("param_conflict", words("param key",key), words("param key",_pk_nnodes)); }
598       if(key==_pk_nnodes && usedParams.find(_pk_hsteps) != usedParams.end())
599         { error("param_conflict", words("param key",key), words("param key",_pk_hsteps)); }
600     }
601 
602   // if hsteps is not used, nnodes is used instead and there is no default value
603   if(params.find(_pk_hsteps) != params.end()) { params.erase(_pk_hsteps); }
604 
605   // (v1,v2,v3,v4) has to be set (no default values)
606   if(params.find(_pk_v1) != params.end()) { error("param_missing","v1"); }
607   if(params.find(_pk_v2) != params.end()) { error("param_missing","v2"); }
608   if(params.find(_pk_v3) != params.end()) { error("param_missing","v3"); }
609   if(params.find(_pk_v4) != params.end()) { error("param_missing","v4"); }
610   if(params.find(_pk_v5) != params.end()) { error("param_missing","v5"); }
611   if(params.find(_pk_v6) != params.end()) { error("param_missing","v6"); }
612   if(params.find(_pk_v7) != params.end()) { error("param_missing","v7"); }
613   if(params.find(_pk_v8) != params.end()) { error("param_missing","v8"); }
614 
615   std::set<ParameterKey>::const_iterator it_p;
616   for(it_p=params.begin(); it_p != params.end(); ++it_p) { buildDefaultParam(*it_p); }
617 
618   // checking nnodes and hsteps size
619   if(n_.size() != 0)
620     {
621       if(n_.size() == 1) { number_t n0=n_[0]; n_.resize(12,n0); }
622       else if(n_.size() != 12) {error("bad_size","nnodes",12,n_.size()); }
623     }
624   if(h_.size() != 0)
625     {
626       if(h_.size() == 1) { real_t h0=h_[0]; h_.resize(8,h0); }
627       else if(h_.size() != 8) {error("bad_size","hsteps",8,h_.size()); }
628     }
629 
630   boundingBox=BoundingBox(p_[0], p_[1], p_[4], p_[4]);
631   computeMB();
632   setFaces();
633   trace_p->pop();
634 }
635 
buildParam(const Parameter & p)636 void Hexahedron::buildParam(const Parameter& p)
637 {
638   trace_p->push("Hexahedron::buildParam");
639   ParameterKey key=p.key();
640   switch(key)
641     {
642       case _pk_v1:
643         {
644           switch(p.type())
645             {
646               case _pt: p_[0]=p.get_pt(); break;
647               case _integer: p_[0]=Point(real_t(p.get_i())); break;
648               case _real: p_[0]=Point(p.get_r()); break;
649               default: error("param_badtype",words("value",p.type()),words("param key",key));
650             }
651           break;
652         }
653       case _pk_v2:
654         {
655           switch(p.type())
656             {
657               case _pt: p_[1]=p.get_pt(); break;
658               case _integer: p_[1]=Point(real_t(p.get_i())); break;
659               case _real: p_[1]=Point(p.get_r()); break;
660               default: error("param_badtype",words("value",p.type()),words("param key",key));
661             }
662           break;
663         }
664       case _pk_v3:
665         {
666           switch(p.type())
667             {
668               case _pt: p_[2]=p.get_pt(); break;
669               case _integer: p_[2]=Point(real_t(p.get_i())); break;
670               case _real: p_[2]=Point(p.get_r()); break;
671               default: error("param_badtype",words("value",p.type()),words("param key",key));
672             }
673           break;
674         }
675       case _pk_v4:
676         {
677           switch(p.type())
678             {
679               case _pt: p_[3]=p.get_pt(); break;
680               case _integer: p_[3]=Point(real_t(p.get_i())); break;
681               case _real: p_[3]=Point(p.get_r()); break;
682               default: error("param_badtype",words("value",p.type()),words("param key",key));
683             }
684           break;
685         }
686       case _pk_v5:
687         {
688           switch(p.type())
689             {
690               case _pt: p_[4]=p.get_pt(); break;
691               case _integer: p_[4]=Point(real_t(p.get_i())); break;
692               case _real: p_[4]=Point(p.get_r()); break;
693               default: error("param_badtype",words("value",p.type()),words("param key",key));
694             }
695           break;
696         }
697       case _pk_v6:
698         {
699           switch(p.type())
700             {
701               case _pt: p_[5]=p.get_pt(); break;
702               case _integer: p_[5]=Point(real_t(p.get_i())); break;
703               case _real: p_[5]=Point(p.get_r()); break;
704               default: error("param_badtype",words("value",p.type()),words("param key",key));
705             }
706           break;
707         }
708       case _pk_v7:
709         {
710           switch(p.type())
711             {
712               case _pt: p_[6]=p.get_pt(); break;
713               case _integer: p_[6]=Point(real_t(p.get_i())); break;
714               case _real: p_[6]=Point(p.get_r()); break;
715               default: error("param_badtype",words("value",p.type()),words("param key",key));
716             }
717           break;
718         }
719       case _pk_v8:
720         {
721           switch(p.type())
722             {
723               case _pt: p_[7]=p.get_pt(); break;
724               case _integer: p_[7]=Point(real_t(p.get_i())); break;
725               case _real: p_[7]=Point(p.get_r()); break;
726               default: error("param_badtype",words("value",p.type()),words("param key",key));
727             }
728           break;
729         }
730       case _pk_nnodes:
731         {
732           switch(p.type())
733             {
734               case _integerVector:
735                 {
736                   std::vector<number_t> n=p.get_nv();
737                   n_.resize(n.size());
738                   for(number_t i=0; i < n.size(); ++i) { n_[i] = n[i] > 2 ? n[i] : 2; }
739                   break;
740                 }
741               case _integer: n_=std::vector<number_t>(1,p.get_n()); break;
742               default: error("param_badtype",words("value",p.type()),words("param key",key));
743             }
744           break;
745         }
746       case _pk_hsteps:
747         {
748           switch(p.type())
749             {
750               case _realVector: h_=p.get_rv(); break;
751               case _integer: h_=std::vector<real_t>(1,real_t(p.get_i())); break;
752               case _real: h_=std::vector<real_t>(1,p.get_r()); break;
753               default: error("param_badtype",words("value",p.type()),words("param key",key));
754             }
755           break;
756         }
757       default: Polyhedron::buildParam(p); break;
758     }
759   trace_p->pop();
760 }
761 
setFaces()762 void Hexahedron::setFaces()
763 {
764   faces_.resize(6);
765   std::vector<number_t> ns(4,2);  // ns is set to 2
766   if(sideNames_.size()>=6)
767     {
768       faces_[0] = new Quadrangle(p_[0], p_[1], p_[2], p_[4], ns, sideNames_[0]);
769       faces_[1] = new Quadrangle(p_[4], p_[5], p_[6], p_[7], ns, sideNames_[1]);
770       faces_[2] = new Quadrangle(p_[0], p_[1], p_[5], p_[4], ns, sideNames_[2]);
771       faces_[3] = new Quadrangle(p_[3], p_[2], p_[6], p_[7], ns, sideNames_[3]);
772       faces_[4] = new Quadrangle(p_[0], p_[3], p_[7], p_[4], ns, sideNames_[4]);
773       faces_[5] = new Quadrangle(p_[1], p_[2], p_[6], p_[5], ns, sideNames_[5]);
774     }
775   else
776     {
777       string_t sn="";
778       if(sideNames_.size()>0) sn=sideNames_[0];
779       faces_[0] = new Quadrangle(p_[0], p_[1], p_[2], p_[4], ns, sn);
780       faces_[1] = new Quadrangle(p_[4], p_[5], p_[6], p_[7], ns, sn);
781       faces_[2] = new Quadrangle(p_[0], p_[1], p_[5], p_[4], ns, sn);
782       faces_[3] = new Quadrangle(p_[3], p_[2], p_[6], p_[7], ns, sn);
783       faces_[4] = new Quadrangle(p_[0], p_[3], p_[7], p_[4], ns, sn);
784       faces_[5] = new Quadrangle(p_[1], p_[2], p_[6], p_[5], ns, sn);
785     }
786 }
787 
buildDefaultParam(ParameterKey key)788 void Hexahedron::buildDefaultParam(ParameterKey key)
789 {
790   trace_p->push("Hexahedron::buildDefaultParam");
791   switch(key)
792     {
793       case _pk_nnodes: n_=std::vector<number_t>(12,2); break;
794       default: Polyhedron::buildDefaultParam(key); break;
795     }
796   trace_p->pop();
797 }
798 
getParamsKeys()799 std::set<ParameterKey> Hexahedron::getParamsKeys()
800 {
801   std::set<ParameterKey> params=Polyhedron::getParamsKeys();
802   params.insert(_pk_v1);
803   params.insert(_pk_v2);
804   params.insert(_pk_v3);
805   params.insert(_pk_v4);
806   params.insert(_pk_v5);
807   params.insert(_pk_v6);
808   params.insert(_pk_v7);
809   params.insert(_pk_v8);
810   params.insert(_pk_nnodes);
811   params.insert(_pk_hsteps);
812   return params;
813 }
814 
Hexahedron(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7,const Parameter & p8)815 Hexahedron::Hexahedron(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
816                        const Parameter& p6, const Parameter& p7, const Parameter& p8) : Polyhedron()
817 {
818   std::vector<Parameter> ps(8);
819   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7; ps[7]=p8;
820   build(ps);
821 }
822 
Hexahedron(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7,const Parameter & p8,const Parameter & p9)823 Hexahedron::Hexahedron(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
824                        const Parameter& p6, const Parameter& p7, const Parameter& p8, const Parameter& p9) : Polyhedron()
825 {
826   std::vector<Parameter> ps(9);
827   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7; ps[7]=p8; ps[8]=p9;
828   build(ps);
829 }
830 
Hexahedron(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7,const Parameter & p8,const Parameter & p9,const Parameter & p10)831 Hexahedron::Hexahedron(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
832                        const Parameter& p6, const Parameter& p7, const Parameter& p8, const Parameter& p9, const Parameter& p10)
833   : Polyhedron()
834 {
835   std::vector<Parameter> ps(10);
836   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7; ps[7]=p8; ps[8]=p9; ps[9]=p10;
837   build(ps);
838 }
839 
Hexahedron(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7,const Parameter & p8,const Parameter & p9,const Parameter & p10,const Parameter & p11)840 Hexahedron::Hexahedron(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
841                        const Parameter& p6, const Parameter& p7, const Parameter& p8, const Parameter& p9, const Parameter& p10,
842                        const Parameter& p11) : Polyhedron()
843 {
844   std::vector<Parameter> ps(11);
845   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7; ps[7]=p8; ps[8]=p9; ps[9]=p10; ps[10]=p11;
846   build(ps);
847 }
848 
asString() const849 string_t Hexahedron::asString() const
850 {
851   string_t s("Hexahedron (");
852   s += p_[0].toString() +", " + p_[1].toString() + ", " + p_[2].toString() + ", " + p_[3].toString();
853   s += p_[4].toString() +", " + p_[5].toString() + ", " + p_[6].toString() + ", " + p_[7].toString() + ")";
854   return s;
855 }
856 
curves() const857 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Hexahedron::curves() const
858 {
859   std::vector<std::pair<ShapeType,std::vector<const Point*> > > curves(12);
860   std::vector<const Point*> vertices(2);
861   vertices[0]=&p_[0]; vertices[1]=&p_[1];
862   curves[0]=std::make_pair(_segment, vertices);
863   vertices[0]=&p_[1]; vertices[1]=&p_[2];
864   curves[1]=std::make_pair(_segment, vertices);
865   vertices[0]=&p_[2]; vertices[1]=&p_[3];
866   curves[2]=std::make_pair(_segment, vertices);
867   vertices[0]=&p_[3]; vertices[1]=&p_[0];
868   curves[3]=std::make_pair(_segment, vertices);
869   vertices[0]=&p_[4]; vertices[1]=&p_[5];
870   curves[4]=std::make_pair(_segment, vertices);
871   vertices[0]=&p_[5]; vertices[1]=&p_[6];
872   curves[5]=std::make_pair(_segment, vertices);
873   vertices[0]=&p_[6]; vertices[1]=&p_[7];
874   curves[6]=std::make_pair(_segment, vertices);
875   vertices[0]=&p_[7]; vertices[1]=&p_[4];
876   curves[7]=std::make_pair(_segment, vertices);
877   vertices[0]=&p_[0]; vertices[1]=&p_[4];
878   curves[8]=std::make_pair(_segment, vertices);
879   vertices[0]=&p_[1]; vertices[1]=&p_[5];
880   curves[9]=std::make_pair(_segment, vertices);
881   vertices[0]=&p_[2]; vertices[1]=&p_[6];
882   curves[10]=std::make_pair(_segment, vertices);
883   vertices[0]=&p_[3]; vertices[1]=&p_[7];
884   curves[11]=std::make_pair(_segment, vertices);
885 
886   return curves;
887 }
888 
surfs() const889 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Hexahedron::surfs() const
890 {
891   std::vector<std::pair<ShapeType,std::vector<const Point*> > > surfs(6);
892   std::vector<const Point*> vertices(4);
893   vertices[0]=&p_[0]; vertices[1]=&p_[1]; vertices[2]=&p_[2]; vertices[3]=&p_[3];
894   surfs[0]=std::make_pair(_quadrangle, vertices);
895   vertices[0]=&p_[4]; vertices[1]=&p_[5]; vertices[2]=&p_[6]; vertices[3]=&p_[7];
896   surfs[1]=std::make_pair(_quadrangle, vertices);
897   vertices[0]=&p_[0]; vertices[1]=&p_[1]; vertices[2]=&p_[5]; vertices[3]=&p_[4];
898   surfs[2]=std::make_pair(_quadrangle, vertices);
899   vertices[0]=&p_[2]; vertices[1]=&p_[3]; vertices[2]=&p_[7]; vertices[3]=&p_[6];
900   surfs[3]=std::make_pair(_quadrangle, vertices);
901   vertices[0]=&p_[3]; vertices[1]=&p_[0]; vertices[2]=&p_[4]; vertices[3]=&p_[7];
902   surfs[4]=std::make_pair(_quadrangle, vertices);
903   vertices[0]=&p_[1]; vertices[1]=&p_[2]; vertices[2]=&p_[6]; vertices[3]=&p_[5];
904   surfs[5]=std::make_pair(_quadrangle, vertices);
905 
906   return surfs;
907 }
908 
Parallelepiped()909 Parallelepiped::Parallelepiped() : Hexahedron()
910 {
911   shape_=_parallelepiped;
912   computeMB();
913 }
914 
build(const std::vector<Parameter> & ps)915 void Parallelepiped::build(const std::vector<Parameter>& ps)
916 {
917   trace_p->push("Parallelepiped::build");
918   shape_=_parallelepiped;
919   std::set<ParameterKey> params=getParamsKeys(), usedParams;
920   // _faces key is replaced by _v1, _v2, _v4 and _v5
921   params.erase(_pk_faces);
922   // _v3, _v6, _v7, _v8 are disabled
923   params.erase(_pk_v3);
924   params.erase(_pk_v6);
925   params.erase(_pk_v7);
926   params.erase(_pk_v8);
927 
928   p_.resize(8);
929   // managing params
930   for(number_t i=0; i < ps.size(); ++i)
931     {
932       ParameterKey key=ps[i].key();
933       buildParam(ps[i]);
934       if(params.find(key) != params.end()) { params.erase(key); }
935       else
936         {
937           if(usedParams.find(key) == usedParams.end())
938             { error("geom_unexpected_param_key", words("param key",key), words("shape",_parallelepiped)); }
939           else { warning("param_already_used", words("param key",key)); }
940         }
941       usedParams.insert(key);
942       // user must use nnodes or hsteps, not both
943       if(key==_pk_hsteps && usedParams.find(_pk_nnodes) != usedParams.end())
944         { error("param_conflict", words("param key",key), words("param key",_pk_nnodes)); }
945       if(key==_pk_nnodes && usedParams.find(_pk_hsteps) != usedParams.end())
946         { error("param_conflict", words("param key",key), words("param key",_pk_hsteps)); }
947     }
948 
949   // if hsteps is not used, nnodes is used instead and there is no default value
950   if(params.find(_pk_hsteps) != params.end()) { params.erase(_pk_hsteps); }
951 
952   // (v1,v2,v4,v5) has to be set (no default values)
953   if(params.find(_pk_v1) != params.end()) { error("param_missing","v1"); }
954   if(params.find(_pk_v2) != params.end()) { error("param_missing","v2"); }
955   if(params.find(_pk_v4) != params.end()) { error("param_missing","v4"); }
956   if(params.find(_pk_v5) != params.end()) { error("param_missing","v5"); }
957 
958   // p_ is not fully built
959   p_[2]=p_[1]+p_[3]-p_[0];
960   p_[5]=p_[1]+p_[4]-p_[0];
961   p_[6]=p_[2]+p_[4]-p_[0];
962   p_[7]=p_[3]+p_[4]-p_[0];
963 
964   std::set<ParameterKey>::const_iterator it_p;
965   for(it_p=params.begin(); it_p != params.end(); ++it_p) { buildDefaultParam(*it_p); }
966 
967   // checking nnodes and hsteps size
968   if(n_.size() != 0)
969     {
970       if(n_.size() == 1) { number_t n0=n_[0]; n_.resize(12,n0); }
971       else if(n_.size() == 3)
972         {
973           number_t n0=n_[0], n1=n_[1], n2=n_[2];
974           n_.clear();
975           n_.resize(12, n0);
976           n_[1]=n1;
977           n_[3]=n1;
978           n_[5]=n1;
979           n_[7]=n1;
980           for(number_t i=8; i < 12; ++i) { n_[i]=n2; }
981         }
982       else if(n_.size() != 12) {error("bad_size","nnodes",12,n_.size()); }
983     }
984   if(h_.size() != 0)
985     {
986       if(h_.size() == 1) { real_t h0=h_[0]; h_.resize(8,h0); }
987       else if(h_.size() != 8) {error("bad_size","hsteps",8,h_.size()); }
988     }
989 
990   boundingBox=BoundingBox(p_[0], p_[1], p_[3], p_[4]);
991   computeMB();
992   setFaces();
993   trace_p->pop();
994 }
995 
setFaces()996 void Parallelepiped::setFaces()
997 {
998   faces_.resize(6);
999   if(sideNames_.size()>=6)
1000     {
1001       faces_[0] = new Parallelogram(_v1=p_[0], _v2=p_[1], _v4=p_[4], _nnodes=2, _domain_name=sideNames_[0]);
1002       faces_[1] = new Parallelogram(_v1=p_[4], _v2=p_[5], _v4=p_[7], _nnodes=2, _domain_name=sideNames_[1]);
1003       faces_[2] = new Parallelogram(_v1=p_[0], _v2=p_[1], _v4=p_[4], _nnodes=2, _domain_name=sideNames_[2]);
1004       faces_[3] = new Parallelogram(_v1=p_[3], _v2=p_[2], _v4=p_[7], _nnodes=2, _domain_name=sideNames_[3]);
1005       faces_[4] = new Parallelogram(_v1=p_[0], _v2=p_[3], _v4=p_[4], _nnodes=2, _domain_name=sideNames_[4]);
1006       faces_[5] = new Parallelogram(_v1=p_[1], _v2=p_[2], _v4=p_[5], _nnodes=2, _domain_name=sideNames_[5]);
1007     }
1008   else
1009     {
1010       string_t sn="";
1011       if(sideNames_.size()>=1) sn=sideNames_[0];
1012       faces_[0] = new Parallelogram(_v1=p_[0], _v2=p_[1], _v4=p_[4], _nnodes=2, _domain_name=sn);
1013       faces_[1] = new Parallelogram(_v1=p_[4], _v2=p_[5], _v4=p_[7], _nnodes=2, _domain_name=sn);
1014       faces_[2] = new Parallelogram(_v1=p_[0], _v2=p_[1], _v4=p_[4], _nnodes=2, _domain_name=sn);
1015       faces_[3] = new Parallelogram(_v1=p_[3], _v2=p_[2], _v4=p_[7], _nnodes=2, _domain_name=sn);
1016       faces_[4] = new Parallelogram(_v1=p_[0], _v2=p_[3], _v4=p_[4], _nnodes=2, _domain_name=sn);
1017       faces_[5] = new Parallelogram(_v1=p_[1], _v2=p_[2], _v4=p_[5], _nnodes=2, _domain_name=sn);
1018     }
1019 }
1020 
buildParam(const Parameter & p)1021 void Parallelepiped::buildParam(const Parameter& p)
1022 {
1023   Hexahedron::buildParam(p);
1024 }
1025 
buildDefaultParam(ParameterKey key)1026 void Parallelepiped::buildDefaultParam(ParameterKey key)
1027 {
1028   Hexahedron::buildDefaultParam(key);
1029 }
1030 
getParamsKeys()1031 std::set<ParameterKey> Parallelepiped::getParamsKeys()
1032 {
1033   std::set<ParameterKey> params=Hexahedron::getParamsKeys();
1034   return params;
1035 }
1036 
Parallelepiped(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4)1037 Parallelepiped::Parallelepiped(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4) : Hexahedron()
1038 {
1039   std::vector<Parameter> ps(4);
1040   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4;
1041   build(ps);
1042 }
1043 
Parallelepiped(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5)1044 Parallelepiped::Parallelepiped(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5)
1045   : Hexahedron()
1046 {
1047   std::vector<Parameter> ps(5);
1048   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5;
1049   build(ps);
1050 }
1051 
Parallelepiped(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6)1052 Parallelepiped::Parallelepiped(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
1053                                const Parameter& p6) : Hexahedron()
1054 {
1055   std::vector<Parameter> ps(6);
1056   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6;
1057   build(ps);
1058 }
1059 
Parallelepiped(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7)1060 Parallelepiped::Parallelepiped(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
1061                                const Parameter& p6, const Parameter& p7) : Hexahedron()
1062 {
1063   std::vector<Parameter> ps(7);
1064   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7;
1065   build(ps);
1066 }
1067 
asString() const1068 string_t Parallelepiped::asString() const
1069 {
1070   string_t s("Parallelepiped (");
1071   s += p_[0].toString() +", " + p_[1].toString() + ", " + p_[3].toString() + ", " + p_[4].toString() + ")";
1072   return s;
1073 }
1074 
surfs() const1075 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Parallelepiped::surfs() const
1076 {
1077   std::vector<std::pair<ShapeType,std::vector<const Point*> > > surfs(6);
1078   std::vector<const Point*> vertices(4);
1079   vertices[0]=&p_[0]; vertices[1]=&p_[1]; vertices[2]=&p_[2]; vertices[3]=&p_[3];
1080   surfs[0]=std::make_pair(_parallelogram, vertices);
1081   vertices[0]=&p_[4]; vertices[1]=&p_[5]; vertices[2]=&p_[6]; vertices[3]=&p_[7];
1082   surfs[1]=std::make_pair(_parallelogram, vertices);
1083   vertices[0]=&p_[0]; vertices[1]=&p_[1]; vertices[2]=&p_[5]; vertices[3]=&p_[4];
1084   surfs[2]=std::make_pair(_parallelogram, vertices);
1085   vertices[0]=&p_[2]; vertices[1]=&p_[3]; vertices[2]=&p_[7]; vertices[3]=&p_[6];
1086   surfs[3]=std::make_pair(_parallelogram, vertices);
1087   vertices[0]=&p_[3]; vertices[1]=&p_[0]; vertices[2]=&p_[4]; vertices[3]=&p_[7];
1088   surfs[4]=std::make_pair(_parallelogram, vertices);
1089   vertices[0]=&p_[1]; vertices[1]=&p_[2]; vertices[2]=&p_[6]; vertices[3]=&p_[5];
1090   surfs[5]=std::make_pair(_parallelogram, vertices);
1091 
1092   return surfs;
1093 }
1094 
measure() const1095 real_t Parallelepiped::measure() const
1096 {
1097   real_t h;
1098   Point P=projectionOnStraightLine(p_[2], p_[0], p_[1], h);
1099   real_t area=(p_[0].distance(p_[1])) * h;
1100   P=projectionOnTriangle(p_[4], p_[0], p_[1], p_[2], h);
1101   return area*h;
1102 }
1103 
Cuboid()1104 Cuboid::Cuboid() : Parallelepiped(), center_(Point(0.5,0.5,0.5)), origin_(Point(0.,0.,0.)), isCenter_(false), isOrigin_(false),
1105   xlength_(1.), ylength_(1.), zlength_(1.), xmin_(0.), xmax_(1.), ymin_(0.), ymax_(1.), zmin_(0.), zmax_(1.),
1106   isBounds_(false)
1107 {
1108   shape_=_cuboid;
1109   computeMB();
1110 }
1111 
buildP()1112 void Cuboid::buildP()
1113 {
1114   if(isBounds_)
1115     {
1116       p_[0]=Point(xmin_,ymin_,zmin_);
1117       p_[1]=Point(xmax_,ymin_,zmin_);
1118       p_[2]=Point(xmax_,ymax_,zmin_);
1119       p_[3]=Point(xmin_,ymax_,zmin_);
1120       p_[4]=Point(xmin_,ymin_,zmax_);
1121       p_[5]=Point(xmax_,ymin_,zmax_);
1122       p_[6]=Point(xmax_,ymax_,zmax_);
1123       p_[7]=Point(xmin_,ymax_,zmax_);
1124       origin_=p_[0];
1125       center_=(p_[0]+p_[6])/2.;
1126       xlength_=xmax_-xmin_;
1127       ylength_=ymax_-ymin_;
1128       zlength_=zmax_-zmin_;
1129     }
1130   else if(isCenter_)
1131     {
1132       Point shift0(-xlength_/2., -ylength_/2., -zlength_/2.);
1133       p_[0]=center_+shift0;
1134       Point shift1(xlength_/2., -ylength_/2., -zlength_/2.);
1135       p_[1]=center_+shift1;
1136       Point shift2(xlength_/2., ylength_/2., -zlength_/2.);
1137       p_[2]=center_+shift2;
1138       Point shift3(-xlength_/2., ylength_/2., -zlength_/2.);
1139       p_[3]=center_+shift3;
1140       Point shift4(-xlength_/2., -ylength_/2., zlength_/2.);
1141       p_[4]=center_+shift4;
1142       Point shift5(xlength_/2., -ylength_/2., zlength_/2.);
1143       p_[5]=center_+shift5;
1144       Point shift6(xlength_/2., ylength_/2., zlength_/2.);
1145       p_[6]=center_+shift6;
1146       Point shift7(-xlength_/2., ylength_/2., zlength_/2.);
1147       p_[7]=center_+shift7;
1148       origin_=p_[0];
1149       xmin_=xmax_=ymin_=ymax_=zmin_=zmax_=0.;
1150     }
1151   else if(isOrigin_)
1152     {
1153       p_[0]=origin_;
1154       Point shift1(xlength_,0.,0.);
1155       p_[1]=origin_+shift1;
1156       Point shift2(xlength_, ylength_, 0.);
1157       p_[2]=origin_+shift2;
1158       Point shift3(0., ylength_, 0.);
1159       p_[3]=origin_+shift3;
1160       Point shift4(0., 0., zlength_);
1161       p_[4]=origin_+shift4;
1162       Point shift5(xlength_, 0., zlength_);
1163       p_[5]=origin_+shift5;
1164       Point shift6(xlength_, ylength_, zlength_);
1165       p_[6]=origin_+shift6;
1166       Point shift7(0., ylength_, zlength_);
1167       p_[7]=origin_+shift7;
1168       center_=(p_[0]+p_[6])/2.;
1169       xmin_=xmax_=ymin_=ymax_=zmin_=zmax_=0.;
1170     }
1171   else // vertices keys are used so p_[2] is not defined
1172     {
1173       p_[2]=p_[1]+p_[3]-p_[0];
1174       p_[5]=p_[1]+p_[4]-p_[0];
1175       p_[6]=p_[2]+p_[4]-p_[0];
1176       p_[7]=p_[3]+p_[4]-p_[0];
1177       origin_=p_[0];
1178       center_=(p_[0]+p_[6])/2.;
1179       xlength_=p_[0].distance(p_[1]);
1180       ylength_=p_[0].distance(p_[3]);
1181       zlength_=p_[0].distance(p_[4]);
1182       xmin_=xmax_=ymin_=ymax_=zmin_=zmax_=0.;
1183       if(dot(p_[3]-p_[0],p_[1]-p_[0]) > theTolerance ||
1184           dot(p_[4]-p_[0],p_[1]-p_[0]) > theTolerance ||
1185           dot(p_[4]-p_[0],p_[3]-p_[0]) > theTolerance) { error("geometry_incoherent_points", words("shape",_cuboid)); }
1186     }
1187 }
1188 
build(const std::vector<Parameter> & ps)1189 void Cuboid::build(const std::vector<Parameter>& ps)
1190 {
1191   trace_p->push("Cuboid::build");
1192   shape_=_cuboid;
1193   std::set<ParameterKey> params=getParamsKeys(), usedParams;
1194   // _faces key is replaced by (_v1,_v2,_v4,_v5), (_center|_origin, _xlength, _ylength, _zlength)
1195   // or (_xmin, _xmax, _ymin, _ymax, _zmin, _zmax)
1196   params.erase(_pk_faces);
1197   // _v3, _v6, _v7, _v8 are disabled
1198   params.erase(_pk_v3);
1199   params.erase(_pk_v6);
1200   params.erase(_pk_v7);
1201   params.erase(_pk_v8);
1202 
1203   p_.resize(8);
1204   // managing params
1205   for(number_t i=0; i < ps.size(); ++i)
1206     {
1207       ParameterKey key=ps[i].key();
1208       buildParam(ps[i]);
1209       if(params.find(key) != params.end()) { params.erase(key); }
1210       else
1211         {
1212           if(usedParams.find(key) == usedParams.end())
1213             { error("geom_unexpected_param_key", words("param key",key), words("shape",_cuboid)); }
1214           else { warning("param_already_used", words("param key",key)); }
1215         }
1216       usedParams.insert(key);
1217 
1218       // user must use nnodes or hsteps, not both
1219       if(key==_pk_hsteps && usedParams.find(_pk_nnodes) != usedParams.end())
1220         { error("param_conflict", words("param key",key), words("param key",_pk_nnodes)); }
1221       if(key==_pk_nnodes && usedParams.find(_pk_hsteps) != usedParams.end())
1222         { error("param_conflict", words("param key",key), words("param key",_pk_hsteps)); }
1223       // user must use only one of the following combination: (v1,v2,v4,v5), (xmin,xmax,ymin,ymax,zmin,zmax),
1224       // (center,xlength,ylength,zlength), (origin,xlength,ylength,zlength)
1225       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_xmin) != usedParams.end())
1226         { error("param_conflict", words("param key",key), words("param key",_pk_xmin)); }
1227       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_xmax) != usedParams.end())
1228         { error("param_conflict", words("param key",key), words("param key",_pk_xmax)); }
1229       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_ymin) != usedParams.end())
1230         { error("param_conflict", words("param key",key), words("param key",_pk_ymin)); }
1231       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_ymax) != usedParams.end())
1232         { error("param_conflict", words("param key",key), words("param key",_pk_ymax)); }
1233       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_zmin) != usedParams.end())
1234         { error("param_conflict", words("param key",key), words("param key",_pk_zmin)); }
1235       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_zmax) != usedParams.end())
1236         { error("param_conflict", words("param key",key), words("param key",_pk_zmax)); }
1237       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_center) != usedParams.end())
1238         { error("param_conflict", words("param key",key), words("param key",_pk_center)); }
1239       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_origin) != usedParams.end())
1240         { error("param_conflict", words("param key",key), words("param key",_pk_origin)); }
1241       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_xlength) != usedParams.end())
1242         { error("param_conflict", words("param key",key), words("param key",_pk_xlength)); }
1243       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_ylength) != usedParams.end())
1244         { error("param_conflict", words("param key",key), words("param key",_pk_ylength)); }
1245       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_zlength) != usedParams.end())
1246         { error("param_conflict", words("param key",key), words("param key",_pk_zlength)); }
1247       if((key==_pk_xmin || key==_pk_xmax || key==_pk_ymin || key==_pk_ymax || key==_pk_zmin || key==_pk_zmax) &&
1248           usedParams.find(_pk_v1) != usedParams.end())
1249         { error("param_conflict", words("param key",key), words("param key",_pk_v1)); }
1250       if((key==_pk_xmin || key==_pk_xmax || key==_pk_ymin || key==_pk_ymax || key==_pk_zmin || key==_pk_zmax) &&
1251           usedParams.find(_pk_v2) != usedParams.end())
1252         { error("param_conflict", words("param key",key), words("param key",_pk_v2)); }
1253       if((key==_pk_xmin || key==_pk_xmax || key==_pk_ymin || key==_pk_ymax || key==_pk_zmin || key==_pk_zmax) &&
1254           usedParams.find(_pk_v4) != usedParams.end())
1255         { error("param_conflict", words("param key",key), words("param key",_pk_v4)); }
1256       if((key==_pk_xmin || key==_pk_xmax || key==_pk_ymin || key==_pk_ymax || key==_pk_zmin || key==_pk_zmax) &&
1257           usedParams.find(_pk_v5) != usedParams.end())
1258         { error("param_conflict", words("param key",key), words("param key",_pk_v5)); }
1259       if((key==_pk_xmin || key==_pk_xmax || key==_pk_ymin || key==_pk_ymax || key==_pk_zmin || key==_pk_zmax) &&
1260           usedParams.find(_pk_center) != usedParams.end())
1261         { error("param_conflict", words("param key",key), words("param key",_pk_center)); }
1262       if((key==_pk_xmin || key==_pk_xmax || key==_pk_ymin || key==_pk_ymax || key==_pk_zmin || key==_pk_zmax) &&
1263           usedParams.find(_pk_origin) != usedParams.end())
1264         { error("param_conflict", words("param key",key), words("param key",_pk_origin)); }
1265       if((key==_pk_xmin || key==_pk_xmax || key==_pk_ymin || key==_pk_ymax || key==_pk_zmin || key==_pk_zmax) &&
1266           usedParams.find(_pk_xlength) != usedParams.end())
1267         { error("param_conflict", words("param key",key), words("param key",_pk_xlength)); }
1268       if((key==_pk_xmin || key==_pk_xmax || key==_pk_ymin || key==_pk_ymax || key==_pk_zmin || key==_pk_zmax) &&
1269           usedParams.find(_pk_ylength) != usedParams.end())
1270         { error("param_conflict", words("param key",key), words("param key",_pk_ylength)); }
1271       if((key==_pk_xmin || key==_pk_xmax || key==_pk_ymin || key==_pk_ymax || key==_pk_zmin || key==_pk_zmax) &&
1272           usedParams.find(_pk_zlength) != usedParams.end())
1273         { error("param_conflict", words("param key",key), words("param key",_pk_zlength)); }
1274       if(key==_pk_center && usedParams.find(_pk_origin) != usedParams.end())
1275         { error("param_conflict", words("param key",key), words("param key",_pk_origin)); }
1276       if(key==_pk_origin && usedParams.find(_pk_center) != usedParams.end())
1277         { error("param_conflict", words("param key",key), words("param key",_pk_center)); }
1278       if((key==_pk_center || key==_pk_origin || key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) &&
1279           usedParams.find(_pk_v1) != usedParams.end())
1280         { error("param_conflict", words("param key",key), words("param key",_pk_v1)); }
1281       if((key==_pk_center || key==_pk_origin || key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) &&
1282           usedParams.find(_pk_v2) != usedParams.end())
1283         { error("param_conflict", words("param key",key), words("param key",_pk_v2)); }
1284       if((key==_pk_center || key==_pk_origin || key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) &&
1285           usedParams.find(_pk_v4) != usedParams.end())
1286         { error("param_conflict", words("param key",key), words("param key",_pk_v4)); }
1287       if((key==_pk_center || key==_pk_origin || key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) &&
1288           usedParams.find(_pk_v5) != usedParams.end())
1289         { error("param_conflict", words("param key",key), words("param key",_pk_v5)); }
1290       if((key==_pk_center || key==_pk_origin || key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) &&
1291           usedParams.find(_pk_xmin) != usedParams.end())
1292         { error("param_conflict", words("param key",key), words("param key",_pk_xmin)); }
1293       if((key==_pk_center || key==_pk_origin || key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) &&
1294           usedParams.find(_pk_xmax) != usedParams.end())
1295         { error("param_conflict", words("param key",key), words("param key",_pk_xmax)); }
1296       if((key==_pk_center || key==_pk_origin || key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) &&
1297           usedParams.find(_pk_ymin) != usedParams.end())
1298         { error("param_conflict", words("param key",key), words("param key",_pk_ymin)); }
1299       if((key==_pk_center || key==_pk_origin || key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) &&
1300           usedParams.find(_pk_ymax) != usedParams.end())
1301         { error("param_conflict", words("param key",key), words("param key",_pk_ymax)); }
1302       if((key==_pk_center || key==_pk_origin || key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) &&
1303           usedParams.find(_pk_zmin) != usedParams.end())
1304         { error("param_conflict", words("param key",key), words("param key",_pk_zmin)); }
1305       if((key==_pk_center || key==_pk_origin || key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) &&
1306           usedParams.find(_pk_zmax) != usedParams.end())
1307         { error("param_conflict", words("param key",key), words("param key",_pk_zmax)); }
1308     }
1309 
1310   // if hsteps is not used, nnodes is used instead and there is no default value
1311   if(params.find(_pk_hsteps) != params.end()) { params.erase(_pk_hsteps); }
1312 
1313   // (v1,v2,v4) or (xmin,xmax,ymin,ymax) or (center,xlength,ylength) has to be set (no default values)
1314   if(params.find(_pk_v1) == params.end() && params.find(_pk_v2) != params.end()) { error("param_missing","v2"); }
1315   if(params.find(_pk_v1) == params.end() && params.find(_pk_v4) != params.end()) { error("param_missing","v4"); }
1316   if(params.find(_pk_v1) == params.end() && params.find(_pk_v5) != params.end()) { error("param_missing","v5"); }
1317   if(params.find(_pk_v2) == params.end() && params.find(_pk_v1) != params.end()) { error("param_missing","v1"); }
1318   if(params.find(_pk_v2) == params.end() && params.find(_pk_v4) != params.end()) { error("param_missing","v4"); }
1319   if(params.find(_pk_v2) == params.end() && params.find(_pk_v5) != params.end()) { error("param_missing","v5"); }
1320   if(params.find(_pk_v4) == params.end() && params.find(_pk_v1) != params.end()) { error("param_missing","v1"); }
1321   if(params.find(_pk_v4) == params.end() && params.find(_pk_v2) != params.end()) { error("param_missing","v2"); }
1322   if(params.find(_pk_v4) == params.end() && params.find(_pk_v5) != params.end()) { error("param_missing","v5"); }
1323   if(params.find(_pk_v5) == params.end() && params.find(_pk_v1) != params.end()) { error("param_missing","v1"); }
1324   if(params.find(_pk_v5) == params.end() && params.find(_pk_v2) != params.end()) { error("param_missing","v2"); }
1325   if(params.find(_pk_v5) == params.end() && params.find(_pk_v4) != params.end()) { error("param_missing","v4"); }
1326   if(params.find(_pk_xmin) == params.end() && params.find(_pk_xmax) != params.end()) { error("param_missing","xmax"); }
1327   if(params.find(_pk_xmin) == params.end() && params.find(_pk_ymin) != params.end()) { error("param_missing","ymin"); }
1328   if(params.find(_pk_xmin) == params.end() && params.find(_pk_ymax) != params.end()) { error("param_missing","ymax"); }
1329   if(params.find(_pk_xmin) == params.end() && params.find(_pk_zmin) != params.end()) { error("param_missing","zmin"); }
1330   if(params.find(_pk_xmin) == params.end() && params.find(_pk_zmax) != params.end()) { error("param_missing","zmax"); }
1331   if(params.find(_pk_xmax) == params.end() && params.find(_pk_xmin) != params.end()) { error("param_missing","xmin"); }
1332   if(params.find(_pk_xmax) == params.end() && params.find(_pk_ymin) != params.end()) { error("param_missing","ymin"); }
1333   if(params.find(_pk_xmax) == params.end() && params.find(_pk_ymax) != params.end()) { error("param_missing","ymax"); }
1334   if(params.find(_pk_xmax) == params.end() && params.find(_pk_zmin) != params.end()) { error("param_missing","zmin"); }
1335   if(params.find(_pk_xmax) == params.end() && params.find(_pk_zmax) != params.end()) { error("param_missing","zmax"); }
1336   if(params.find(_pk_ymin) == params.end() && params.find(_pk_xmin) != params.end()) { error("param_missing","xmin"); }
1337   if(params.find(_pk_ymin) == params.end() && params.find(_pk_xmax) != params.end()) { error("param_missing","xmax"); }
1338   if(params.find(_pk_ymin) == params.end() && params.find(_pk_ymax) != params.end()) { error("param_missing","ymax"); }
1339   if(params.find(_pk_ymin) == params.end() && params.find(_pk_zmin) != params.end()) { error("param_missing","zmin"); }
1340   if(params.find(_pk_ymin) == params.end() && params.find(_pk_zmax) != params.end()) { error("param_missing","zmax"); }
1341   if(params.find(_pk_ymax) == params.end() && params.find(_pk_xmin) != params.end()) { error("param_missing","xmin"); }
1342   if(params.find(_pk_ymax) == params.end() && params.find(_pk_xmax) != params.end()) { error("param_missing","xmax"); }
1343   if(params.find(_pk_ymax) == params.end() && params.find(_pk_ymin) != params.end()) { error("param_missing","ymin"); }
1344   if(params.find(_pk_ymax) == params.end() && params.find(_pk_zmin) != params.end()) { error("param_missing","zmin"); }
1345   if(params.find(_pk_ymax) == params.end() && params.find(_pk_zmax) != params.end()) { error("param_missing","zmax"); }
1346   if(params.find(_pk_zmin) == params.end() && params.find(_pk_xmin) != params.end()) { error("param_missing","xmin"); }
1347   if(params.find(_pk_zmin) == params.end() && params.find(_pk_xmax) != params.end()) { error("param_missing","xmax"); }
1348   if(params.find(_pk_zmin) == params.end() && params.find(_pk_ymin) != params.end()) { error("param_missing","ymin"); }
1349   if(params.find(_pk_zmin) == params.end() && params.find(_pk_ymax) != params.end()) { error("param_missing","ymax"); }
1350   if(params.find(_pk_zmin) == params.end() && params.find(_pk_zmax) != params.end()) { error("param_missing","zmax"); }
1351   if(params.find(_pk_zmax) == params.end() && params.find(_pk_xmin) != params.end()) { error("param_missing","xmin"); }
1352   if(params.find(_pk_zmax) == params.end() && params.find(_pk_xmax) != params.end()) { error("param_missing","xmax"); }
1353   if(params.find(_pk_zmax) == params.end() && params.find(_pk_ymin) != params.end()) { error("param_missing","ymin"); }
1354   if(params.find(_pk_zmax) == params.end() && params.find(_pk_ymax) != params.end()) { error("param_missing","ymax"); }
1355   if(params.find(_pk_zmax) == params.end() && params.find(_pk_zmin) != params.end()) { error("param_missing","zmin"); }
1356   if((params.find(_pk_center) == params.end() || params.find(_pk_origin) == params.end()) && params.find(_pk_xlength) != params.end())
1357     { error("param_missing","xlength"); }
1358   if((params.find(_pk_center) == params.end() || params.find(_pk_origin) == params.end()) && params.find(_pk_ylength) != params.end())
1359     { error("param_missing","ylength"); }
1360   if((params.find(_pk_center) == params.end() || params.find(_pk_origin) == params.end()) && params.find(_pk_zlength) != params.end())
1361     { error("param_missing","zlength"); }
1362   if(params.find(_pk_xlength) == params.end() && params.find(_pk_ylength) != params.end()) { error("param_missing","ylength"); }
1363   if(params.find(_pk_xlength) == params.end() && params.find(_pk_zlength) != params.end()) { error("param_missing","zlength"); }
1364   if(params.find(_pk_ylength) == params.end() && params.find(_pk_xlength) != params.end()) { error("param_missing","xlength"); }
1365   if(params.find(_pk_ylength) == params.end() && params.find(_pk_zlength) != params.end()) { error("param_missing","zlength"); }
1366   if(params.find(_pk_zlength) == params.end() && params.find(_pk_xlength) != params.end()) { error("param_missing","xlength"); }
1367   if(params.find(_pk_zlength) == params.end() && params.find(_pk_ylength) != params.end()) { error("param_missing","ylength"); }
1368   if(params.find(_pk_xlength) == params.end() && params.find(_pk_center) != params.end() && params.find(_pk_origin) != params.end())
1369     { error("param_missing","center or origin"); }
1370   isCenter_=true;
1371   isOrigin_=true;
1372   isBounds_=true;
1373   // now, we clean unwanted keys
1374   if(params.find(_pk_xlength) != params.end())
1375     { params.erase(_pk_xlength); params.erase(_pk_ylength);  params.erase(_pk_zlength); }
1376   if(params.find(_pk_center) != params.end()) { params.erase(_pk_center); isCenter_=false; }
1377   if(params.find(_pk_origin) != params.end()) { params.erase(_pk_origin); isOrigin_=false; }
1378   if(params.find(_pk_xmin) != params.end())
1379     {
1380       params.erase(_pk_xmin); params.erase(_pk_xmax);
1381       params.erase(_pk_ymin); params.erase(_pk_ymax);
1382       params.erase(_pk_zmin); params.erase(_pk_zmax);
1383       isBounds_=false;
1384     }
1385   if(params.find(_pk_v1) != params.end()) { params.erase(_pk_v1); params.erase(_pk_v2); params.erase(_pk_v4); params.erase(_pk_v5); }
1386 
1387   // p_ is not (fully) built so we do
1388   buildP();
1389 
1390   std::set<ParameterKey>::const_iterator it_p;
1391   for(it_p=params.begin(); it_p != params.end(); ++it_p) { buildDefaultParam(*it_p); }
1392 
1393   // checking nnodes and hsteps size
1394   if(n_.size() != 0)
1395     {
1396       if(n_.size() == 1) { number_t n0=n_[0]; n_.resize(12,n0); }
1397       else if(n_.size() == 3)
1398         {
1399           number_t n0=n_[0], n1=n_[1], n2=n_[2];
1400           n_.clear();
1401           n_.resize(12, n0);
1402           n_[1]=n1;
1403           n_[3]=n1;
1404           n_[5]=n1;
1405           n_[7]=n1;
1406           for(number_t i=8; i < 12; ++i) { n_[i]=n2; }
1407         }
1408       else if(n_.size() != 12) {error("bad_size","nnodes",12,n_.size()); }
1409     }
1410   if(h_.size() != 0)
1411     {
1412       if(h_.size() == 1) { real_t h0=h_[0]; h_.resize(8,h0); }
1413       else if(h_.size() != 8) {error("bad_size","hsteps",8,h_.size()); }
1414     }
1415   boundingBox=BoundingBox(p_[0], p_[1], p_[3], p_[4]);
1416   computeMB();
1417   setFaces();
1418   trace_p->pop();
1419 }
1420 
setFaces()1421 void Cuboid::setFaces()
1422 {
1423   faces_.resize(6);
1424   if(sideNames_.size()>=6)
1425     {
1426       faces_[0] = new Rectangle(_v1=p_[0], _v2=p_[1], _v4=p_[4], _nnodes=2, _domain_name=sideNames_[0]);
1427       faces_[1] = new Rectangle(_v1=p_[4], _v2=p_[5], _v4=p_[7], _nnodes=2, _domain_name=sideNames_[1]);
1428       faces_[2] = new Rectangle(_v1=p_[0], _v2=p_[1], _v4=p_[4], _nnodes=2, _domain_name=sideNames_[2]);
1429       faces_[3] = new Rectangle(_v1=p_[3], _v2=p_[2], _v4=p_[7], _nnodes=2, _domain_name=sideNames_[3]);
1430       faces_[4] = new Rectangle(_v1=p_[0], _v2=p_[3], _v4=p_[4], _nnodes=2, _domain_name=sideNames_[4]);
1431       faces_[5] = new Rectangle(_v1=p_[1], _v2=p_[2], _v4=p_[5], _nnodes=2, _domain_name=sideNames_[5]);
1432     }
1433   else
1434     {
1435       string_t sn="";
1436       if(sideNames_.size()>=1) sn=sideNames_[0];
1437       faces_[0] = new Rectangle(_v1=p_[0], _v2=p_[1], _v4=p_[4], _nnodes=2, _domain_name=sn);
1438       faces_[1] = new Rectangle(_v1=p_[4], _v2=p_[5], _v4=p_[7], _nnodes=2, _domain_name=sn);
1439       faces_[2] = new Rectangle(_v1=p_[0], _v2=p_[1], _v4=p_[4], _nnodes=2, _domain_name=sn);
1440       faces_[3] = new Rectangle(_v1=p_[3], _v2=p_[2], _v4=p_[7], _nnodes=2, _domain_name=sn);
1441       faces_[4] = new Rectangle(_v1=p_[0], _v2=p_[3], _v4=p_[4], _nnodes=2, _domain_name=sn);
1442       faces_[5] = new Rectangle(_v1=p_[1], _v2=p_[2], _v4=p_[5], _nnodes=2, _domain_name=sn);
1443     }
1444 }
1445 
1446 
buildParam(const Parameter & p)1447 void Cuboid::buildParam(const Parameter& p)
1448 {
1449   trace_p->push("Cuboid::buildParam");
1450   ParameterKey key=p.key();
1451   switch(key)
1452     {
1453       case _pk_center:
1454         {
1455           switch(p.type())
1456             {
1457               case _pt: center_=p.get_pt(); break;
1458               case _integer: center_=Point(real_t(p.get_i())); break;
1459               case _real: center_=Point(p.get_r()); break;
1460               default: error("param_badtype",words("value",p.type()),words("param key",key));
1461             }
1462           break;
1463         }
1464       case _pk_origin:
1465         {
1466           switch(p.type())
1467             {
1468               case _pt: origin_=p.get_pt(); break;
1469               case _integer: origin_=Point(real_t(p.get_i())); break;
1470               case _real: origin_=Point(p.get_r()); break;
1471               default: error("param_badtype",words("value",p.type()),words("param key",key));
1472             }
1473           break;
1474         }
1475       case _pk_xlength:
1476         {
1477           switch(p.type())
1478             {
1479               case _integer: xlength_=real_t(p.get_n()); break;
1480               case _real: xlength_=p.get_r(); break;
1481               default: error("param_badtype",words("value",p.type()),words("param key",key));
1482             }
1483           break;
1484         }
1485       case _pk_ylength:
1486         {
1487           switch(p.type())
1488             {
1489               case _integer: ylength_=real_t(p.get_n()); break;
1490               case _real: ylength_=p.get_r(); break;
1491               default: error("param_badtype",words("value",p.type()),words("param key",key));
1492             }
1493           break;
1494         }
1495       case _pk_zlength:
1496         {
1497           switch(p.type())
1498             {
1499               case _integer: zlength_=real_t(p.get_n()); break;
1500               case _real: zlength_=p.get_r(); break;
1501               default: error("param_badtype",words("value",p.type()),words("param key",key));
1502             }
1503           break;
1504         }
1505       case _pk_xmin:
1506         {
1507           switch(p.type())
1508             {
1509               case _integer: xmin_=real_t(p.get_i()); break;
1510               case _real: xmin_=p.get_r(); break;
1511               default: error("param_badtype",words("value",p.type()),words("param key",key));
1512             }
1513           break;
1514         }
1515       case _pk_xmax:
1516         {
1517           switch(p.type())
1518             {
1519               case _integer: xmax_=real_t(p.get_i()); break;
1520               case _real: xmax_=p.get_r(); break;
1521               default: error("param_badtype",words("value",p.type()),words("param key",key));
1522             }
1523           break;
1524         }
1525       case _pk_ymin:
1526         {
1527           switch(p.type())
1528             {
1529               case _integer: ymin_=real_t(p.get_i()); break;
1530               case _real: ymin_=p.get_r(); break;
1531               default: error("param_badtype",words("value",p.type()),words("param key",key));
1532             }
1533           break;
1534         }
1535       case _pk_ymax:
1536         {
1537           switch(p.type())
1538             {
1539               case _integer: ymax_=real_t(p.get_i()); break;
1540               case _real: ymax_=p.get_r(); break;
1541               default: error("param_badtype",words("value",p.type()),words("param key",key));
1542             }
1543           break;
1544         }
1545       case _pk_zmin:
1546         {
1547           switch(p.type())
1548             {
1549               case _integer: zmin_=real_t(p.get_i()); break;
1550               case _real: zmin_=p.get_r(); break;
1551               default: error("param_badtype",words("value",p.type()),words("param key",key));
1552             }
1553           break;
1554         }
1555       case _pk_zmax:
1556         {
1557           switch(p.type())
1558             {
1559               case _integer: zmax_=real_t(p.get_i()); break;
1560               case _real: zmax_=p.get_r(); break;
1561               default: error("param_badtype",words("value",p.type()),words("param key",key));
1562             }
1563           break;
1564         }
1565       default: Parallelepiped::buildParam(p); break;
1566     }
1567   trace_p->pop();
1568 }
1569 
buildDefaultParam(ParameterKey key)1570 void Cuboid::buildDefaultParam(ParameterKey key)
1571 {
1572   Parallelepiped::buildDefaultParam(key);
1573 }
1574 
getParamsKeys()1575 std::set<ParameterKey> Cuboid::getParamsKeys()
1576 {
1577   std::set<ParameterKey> params=Parallelepiped::getParamsKeys();
1578   params.insert(_pk_center);
1579   params.insert(_pk_origin);
1580   params.insert(_pk_xlength);
1581   params.insert(_pk_ylength);
1582   params.insert(_pk_zlength);
1583   params.insert(_pk_xmin);
1584   params.insert(_pk_xmax);
1585   params.insert(_pk_ymin);
1586   params.insert(_pk_ymax);
1587   params.insert(_pk_zmin);
1588   params.insert(_pk_zmax);
1589   return params;
1590 }
1591 
Cuboid(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4)1592 Cuboid::Cuboid(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4) : Parallelepiped()
1593 {
1594   std::vector<Parameter> ps(4);
1595   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4;
1596   build(ps);
1597 }
1598 
Cuboid(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5)1599 Cuboid::Cuboid(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5)
1600   : Parallelepiped()
1601 {
1602   std::vector<Parameter> ps(5);
1603   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5;
1604   build(ps);
1605 }
1606 
Cuboid(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6)1607 Cuboid::Cuboid(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
1608                const Parameter& p6) : Parallelepiped()
1609 {
1610   std::vector<Parameter> ps(6);
1611   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6;
1612   build(ps);
1613 }
1614 
Cuboid(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7)1615 Cuboid::Cuboid(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
1616                const Parameter& p6, const Parameter& p7) : Parallelepiped()
1617 {
1618   std::vector<Parameter> ps(7);
1619   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7;
1620   build(ps);
1621 }
1622 
Cuboid(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7,const Parameter & p8)1623 Cuboid::Cuboid(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
1624                const Parameter& p6, const Parameter& p7, const Parameter& p8) : Parallelepiped()
1625 {
1626   std::vector<Parameter> ps(8);
1627   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7; ps[7]=p8;
1628   build(ps);
1629 }
1630 
Cuboid(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7,const Parameter & p8,const Parameter & p9)1631 Cuboid::Cuboid(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
1632                const Parameter& p6, const Parameter& p7, const Parameter& p8, const Parameter& p9) : Parallelepiped()
1633 {
1634   std::vector<Parameter> ps(9);
1635   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7; ps[7]=p8; ps[8]=p9;
1636   build(ps);
1637 }
1638 
Cuboid(const Cuboid & c)1639 Cuboid::Cuboid(const Cuboid& c) : Parallelepiped(c), center_(c.center_), origin_(c.origin_), isCenter_(c.isCenter_),
1640   isOrigin_(c.isOrigin_), xlength_(c.xlength_), ylength_(c.ylength_), zlength_(c.zlength_),
1641   xmin_(c.xmin_), xmax_(c.xmax_), ymin_(c.ymin_), ymax_(c.ymax_), zmin_(c.zmin_), zmax_(c.zmax_),
1642   isBounds_(c.isBounds_)
1643 {}
1644 
asString() const1645 string_t Cuboid::asString() const
1646 {
1647   string_t s("Cuboid (");
1648   s += p_[0].toString() +", " + p_[1].toString() + ", " + p_[3].toString() + ", " + p_[4].toString() + ")";
1649   return s;
1650 }
1651 
surfs() const1652 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Cuboid::surfs() const
1653 {
1654   std::vector<std::pair<ShapeType,std::vector<const Point*> > > surfs(6);
1655   std::vector<const Point*> vertices(4);
1656   vertices[0]=&p_[0]; vertices[1]=&p_[1]; vertices[2]=&p_[2]; vertices[3]=&p_[3];
1657   surfs[0]=std::make_pair(_rectangle, vertices);
1658   vertices[0]=&p_[4]; vertices[1]=&p_[5]; vertices[2]=&p_[6]; vertices[3]=&p_[7];
1659   surfs[1]=std::make_pair(_rectangle, vertices);
1660   vertices[0]=&p_[0]; vertices[1]=&p_[1]; vertices[2]=&p_[5]; vertices[3]=&p_[4];
1661   surfs[2]=std::make_pair(_rectangle, vertices);
1662   vertices[0]=&p_[2]; vertices[1]=&p_[3]; vertices[2]=&p_[7]; vertices[3]=&p_[6];
1663   surfs[3]=std::make_pair(_rectangle, vertices);
1664   vertices[0]=&p_[3]; vertices[1]=&p_[0]; vertices[2]=&p_[4]; vertices[3]=&p_[7];
1665   surfs[4]=std::make_pair(_rectangle, vertices);
1666   vertices[0]=&p_[1]; vertices[1]=&p_[2]; vertices[2]=&p_[6]; vertices[3]=&p_[5];
1667   surfs[5]=std::make_pair(_rectangle, vertices);
1668 
1669   return surfs;
1670 }
1671 
Cube()1672 Cube::Cube() : Cuboid(), nboctants_(8)
1673 { shape_=_cube; }
1674 
buildP()1675 void Cube::buildP()
1676 {
1677   if(isCenter_)
1678     {
1679       Point shift0(-xlength_/2., -ylength_/2., -zlength_/2.);
1680       p_[0]=center_+shift0;
1681       Point shift1(xlength_/2., -ylength_/2., -zlength_/2.);
1682       p_[1]=center_+shift1;
1683       Point shift2(xlength_/2., ylength_/2., -zlength_/2.);
1684       p_[2]=center_+shift2;
1685       Point shift3(-xlength_/2., ylength_/2., -zlength_/2.);
1686       p_[3]=center_+shift3;
1687       Point shift4(-xlength_/2., -ylength_/2., zlength_/2.);
1688       p_[4]=center_+shift4;
1689       Point shift5(xlength_/2., -ylength_/2., zlength_/2.);
1690       p_[5]=center_+shift5;
1691       Point shift6(xlength_/2., ylength_/2., zlength_/2.);
1692       p_[6]=center_+shift6;
1693       Point shift7(-xlength_/2., ylength_/2., zlength_/2.);
1694       p_[7]=center_+shift7;
1695       origin_=p_[0];
1696     }
1697   else if(isOrigin_)
1698     {
1699       p_[0]=origin_;
1700       Point shift1(xlength_, 0., 0.);
1701       p_[1]=origin_+shift1;
1702       Point shift2(xlength_, ylength_, 0.);
1703       p_[2]=origin_+shift2;
1704       Point shift3(0., ylength_, 0.);
1705       p_[3]=origin_+shift3;
1706       Point shift4(0., 0., zlength_);
1707       p_[4]=origin_+shift4;
1708       Point shift5(xlength_, 0., zlength_);
1709       p_[5]=origin_+shift5;
1710       Point shift6(xlength_, ylength_, zlength_);
1711       p_[6]=origin_+shift6;
1712       Point shift7(0., ylength_, zlength_);
1713       p_[7]=origin_+shift7;
1714       center_=(p_[0]+p_[6])/2.;
1715     }
1716   else // vertices keys are used so p_[2] is not defined
1717     {
1718       p_[2]=p_[1]+p_[3]-p_[0];
1719       p_[5]=p_[1]+p_[4]-p_[0];
1720       p_[6]=p_[2]+p_[4]-p_[0];
1721       p_[7]=p_[3]+p_[4]-p_[0];
1722       origin_=p_[0];
1723       center_=(p_[0]+p_[6])/2.;
1724       xlength_=p_[0].distance(p_[1]);
1725       ylength_=p_[0].distance(p_[3]);
1726       zlength_=p_[0].distance(p_[4]);
1727       if(dot(p_[3]-p_[0],p_[1]-p_[0]) > theTolerance ||
1728           dot(p_[4]-p_[0],p_[1]-p_[0]) > theTolerance ||
1729           dot(p_[4]-p_[0],p_[3]-p_[0]) > theTolerance) { error("geometry_incoherent_points", words("shape",_cube)); }
1730     }
1731 }
1732 
build(const std::vector<Parameter> & ps)1733 void Cube::build(const std::vector<Parameter>& ps)
1734 {
1735   trace_p->push("Cube::build");
1736   shape_=_cube;
1737   std::set<ParameterKey> params=getParamsKeys(), usedParams;
1738   // _facces key is replaced by (_v1,_v2,_v4), (_center|_origin, _xlength, _ylength) or (_xmin, _xmax, _ymin, _ymax)
1739   params.erase(_pk_faces);
1740   // _v3, _v6, _v7, _v8, _xlength, _ylength, _zlength, _xmin, _xmax, _ymin, _ymax, _zmin and _zmax are disabled
1741   params.erase(_pk_v3);
1742   params.erase(_pk_v6);
1743   params.erase(_pk_v7);
1744   params.erase(_pk_v8);
1745   params.erase(_pk_xlength);
1746   params.erase(_pk_ylength);
1747   params.erase(_pk_zlength);
1748   params.erase(_pk_xmin);
1749   params.erase(_pk_xmax);
1750   params.erase(_pk_ymin);
1751   params.erase(_pk_ymax);
1752   params.erase(_pk_zmin);
1753   params.erase(_pk_zmax);
1754 
1755   p_.resize(8);
1756   // managing params
1757   for(number_t i=0; i < ps.size(); ++i)
1758     {
1759       ParameterKey key=ps[i].key();
1760       buildParam(ps[i]);
1761       if(params.find(key) != params.end()) { params.erase(key); }
1762       else
1763         {
1764           if(usedParams.find(key) == usedParams.end())
1765             { error("geom_unexpected_param_key", words("param key",key), words("shape",_cube)); }
1766           else { warning("param_already_used", words("param key",key)); }
1767         }
1768       usedParams.insert(key);
1769       // user must use nnodes or hsteps, not both
1770       if(key==_pk_hsteps && usedParams.find(_pk_nnodes) != usedParams.end())
1771         { error("param_conflict", words("param key",key), words("param key",_pk_nnodes)); }
1772       if(key==_pk_nnodes && usedParams.find(_pk_hsteps) != usedParams.end())
1773         { error("param_conflict", words("param key",key), words("param key",_pk_hsteps)); }
1774       // user must use only one of the following combination: (v1,v2,v4), (center,length) or (origin,length)
1775       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_center) != usedParams.end())
1776         { error("param_conflict", words("param key",key), words("param key",_pk_center)); }
1777       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_origin) != usedParams.end())
1778         { error("param_conflict", words("param key",key), words("param key",_pk_origin)); }
1779       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v4 || key==_pk_v5) && usedParams.find(_pk_length) != usedParams.end())
1780         { error("param_conflict", words("param key",key), words("param key",_pk_length)); }
1781       if(key==_pk_center && usedParams.find(_pk_origin) != usedParams.end())
1782         { error("param_conflict", words("param key",key), words("param key",_pk_origin)); }
1783       if(key==_pk_origin && usedParams.find(_pk_center) != usedParams.end())
1784         { error("param_conflict", words("param key",key), words("param key",_pk_center)); }
1785       if((key==_pk_center || key==_pk_origin || key==_pk_length) && usedParams.find(_pk_v1) != usedParams.end())
1786         { error("param_conflict", words("param key",key), words("param key",_pk_v1)); }
1787       if((key==_pk_center || key==_pk_origin || key==_pk_length) && usedParams.find(_pk_v2) != usedParams.end())
1788         { error("param_conflict", words("param key",key), words("param key",_pk_v2)); }
1789       if((key==_pk_center || key==_pk_origin || key==_pk_length) && usedParams.find(_pk_v4) != usedParams.end())
1790         { error("param_conflict", words("param key",key), words("param key",_pk_v4)); }
1791       if((key==_pk_center || key==_pk_origin || key==_pk_length) && usedParams.find(_pk_v5) != usedParams.end())
1792         { error("param_conflict", words("param key",key), words("param key",_pk_v5)); }
1793     }
1794 
1795   // if hsteps is not used, nnodes is used instead and there is no default value
1796   if(params.find(_pk_hsteps) != params.end()) { params.erase(_pk_hsteps); }
1797 
1798   // (v1,v2,v4) or (xmin,xmax,ymin,ymax) or (center,xlength,ylength) has to be set (no default values)
1799   if(params.find(_pk_v1) == params.end() && params.find(_pk_v2) != params.end()) { error("param_missing","v2"); }
1800   if(params.find(_pk_v1) == params.end() && params.find(_pk_v4) != params.end()) { error("param_missing","v4"); }
1801   if(params.find(_pk_v2) == params.end() && params.find(_pk_v1) != params.end()) { error("param_missing","v1"); }
1802   if(params.find(_pk_v2) == params.end() && params.find(_pk_v4) != params.end()) { error("param_missing","v4"); }
1803   if(params.find(_pk_v4) == params.end() && params.find(_pk_v1) != params.end()) { error("param_missing","v1"); }
1804   if(params.find(_pk_v4) == params.end() && params.find(_pk_v2) != params.end()) { error("param_missing","v2"); }
1805   if((params.find(_pk_center) == params.end() || params.find(_pk_origin) == params.end()) && params.find(_pk_length) != params.end())
1806     { error("param_missing","length"); }
1807   if(params.find(_pk_length) == params.end() && params.find(_pk_center) != params.end() && params.find(_pk_origin) != params.end())
1808     { error("param_missing","center or origin"); }
1809   isCenter_=true;
1810   isOrigin_=true;
1811   // now, we clean unwanted keys
1812   if(params.find(_pk_length) != params.end()) { params.erase(_pk_length); }
1813   if(params.find(_pk_center) != params.end()) { params.erase(_pk_center); isCenter_=false; }
1814   if(params.find(_pk_origin) != params.end()) { params.erase(_pk_origin); isOrigin_=false; }
1815   if(params.find(_pk_v1) != params.end()) { params.erase(_pk_v1); params.erase(_pk_v2); params.erase(_pk_v4); params.erase(_pk_v5); }
1816 
1817   // p_ is not (fully) built so we do
1818   buildP();
1819   if(std::abs(p_[0].distance(p_[1])-p_[0].distance(p_[3])) > theTolerance ||
1820       std::abs(p_[0].distance(p_[1])-p_[0].distance(p_[4])) > theTolerance ||
1821       std::abs(p_[0].distance(p_[3])-p_[0].distance(p_[4])) > theTolerance)
1822     { error("geometry_incoherent_points", words("shape",_cube)); }
1823 
1824   std::set<ParameterKey>::const_iterator it_p;
1825   for(it_p=params.begin(); it_p != params.end(); ++it_p) { buildDefaultParam(*it_p); }
1826 
1827   // checking nnodes and hsteps size
1828   if(n_.size() != 0)
1829     {
1830       if(n_.size() == 1) { number_t n0=n_[0]; n_.resize(12,n0); }
1831       else if(n_.size() == 3)
1832         {
1833           number_t n0=n_[0], n1=n_[1], n2=n_[2];
1834           n_.clear();
1835           n_.resize(12, n0);
1836           n_[1]=n1;
1837           n_[3]=n1;
1838           n_[5]=n1;
1839           n_[7]=n1;
1840           for(number_t i=8; i < 12; ++i) { n_[i]=n2; }
1841         }
1842       else if(n_.size() != 12) {error("bad_size","nnodes",12,n_.size()); }
1843     }
1844   if(h_.size() != 0)
1845     {
1846       if(h_.size() == 1) { real_t h0=h_[0]; h_.resize(8,h0); }
1847       else if(h_.size() != 8) {error("bad_size","hsteps",8,h_.size()); }
1848     }
1849 
1850   boundingBox=BoundingBox(p_[0], p_[1], p_[3], p_[4]);
1851   computeMB();
1852   setFaces();
1853   trace_p->pop();
1854 }
1855 
setFaces()1856 void Cube::setFaces()
1857 {
1858   faces_.resize(6);
1859   if(sideNames_.size()>=6)
1860     {
1861       faces_[0] = new Square(_v1=p_[0], _v2=p_[1], _v4=p_[4], _nnodes=2, _domain_name=sideNames_[0]);
1862       faces_[1] = new Square(_v1=p_[4], _v2=p_[5], _v4=p_[7], _nnodes=2, _domain_name=sideNames_[1]);
1863       faces_[2] = new Square(_v1=p_[0], _v2=p_[1], _v4=p_[4], _nnodes=2, _domain_name=sideNames_[2]);
1864       faces_[3] = new Square(_v1=p_[3], _v2=p_[2], _v4=p_[7], _nnodes=2, _domain_name=sideNames_[3]);
1865       faces_[4] = new Square(_v1=p_[0], _v2=p_[3], _v4=p_[4], _nnodes=2, _domain_name=sideNames_[4]);
1866       faces_[5] = new Square(_v1=p_[1], _v2=p_[2], _v4=p_[5], _nnodes=2, _domain_name=sideNames_[5]);
1867     }
1868   else
1869     {
1870       string_t sn="";
1871       if(sideNames_.size()>=1) sn=sideNames_[0];
1872       faces_[0] = new Square(_v1=p_[0], _v2=p_[1], _v4=p_[4], _nnodes=2, _domain_name=sn);
1873       faces_[1] = new Square(_v1=p_[4], _v2=p_[5], _v4=p_[7], _nnodes=2, _domain_name=sn);
1874       faces_[2] = new Square(_v1=p_[0], _v2=p_[1], _v4=p_[4], _nnodes=2, _domain_name=sn);
1875       faces_[3] = new Square(_v1=p_[3], _v2=p_[2], _v4=p_[7], _nnodes=2, _domain_name=sn);
1876       faces_[4] = new Square(_v1=p_[0], _v2=p_[3], _v4=p_[4], _nnodes=2, _domain_name=sn);
1877       faces_[5] = new Square(_v1=p_[1], _v2=p_[2], _v4=p_[5], _nnodes=2, _domain_name=sn);
1878     }
1879 }
1880 
buildParam(const Parameter & p)1881 void Cube::buildParam(const Parameter& p)
1882 {
1883   trace_p->push("Cube::buildParam");
1884   ParameterKey key=p.key();
1885   switch(key)
1886     {
1887       case _pk_length:
1888         {
1889           switch(p.type())
1890             {
1891               case _integer: xlength_=ylength_=zlength_=real_t(p.get_n()); break;
1892               case _real: xlength_=ylength_=zlength_=p.get_r(); break;
1893               default: error("param_badtype",words("value",p.type()),words("param key",key));
1894             }
1895           break;
1896         }
1897       case _pk_nboctants:
1898         {
1899           switch(p.type())
1900             {
1901               case _integer: nboctants_ = p.get_n(); break;
1902               default: error("param_badtype",words("value",p.type()),words("param key",key));
1903             }
1904           break;
1905         }
1906       default: Cuboid::buildParam(p); break;
1907     }
1908   trace_p->pop();
1909 }
1910 
buildDefaultParam(ParameterKey key)1911 void Cube::buildDefaultParam(ParameterKey key)
1912 {
1913   trace_p->push("Cube::buildDefaultParam");
1914   switch(key)
1915     {
1916       case _pk_nboctants: nboctants_=8; break;
1917       default: Cuboid::buildDefaultParam(key); break;
1918     }
1919   trace_p->pop();
1920 }
1921 
getParamsKeys()1922 std::set<ParameterKey> Cube::getParamsKeys()
1923 {
1924   std::set<ParameterKey> params=Cuboid::getParamsKeys();
1925   params.insert(_pk_length);
1926   params.insert(_pk_nboctants);
1927   return params;
1928 }
1929 
Cube(const Parameter & p1,const Parameter & p2)1930 Cube::Cube(const Parameter& p1, const Parameter& p2) : Cuboid()
1931 {
1932   std::vector<Parameter> ps(2);
1933   ps[0]=p1; ps[1]=p2;
1934   build(ps);
1935 }
1936 
Cube(const Parameter & p1,const Parameter & p2,const Parameter & p3)1937 Cube::Cube(const Parameter& p1, const Parameter& p2, const Parameter& p3) : Cuboid()
1938 {
1939   std::vector<Parameter> ps(3);
1940   ps[0]=p1; ps[1]=p2; ps[2]=p3;
1941   build(ps);
1942 }
1943 
Cube(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4)1944 Cube::Cube(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4) : Cuboid()
1945 {
1946   std::vector<Parameter> ps(4);
1947   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4;
1948   build(ps);
1949 }
1950 
Cube(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5)1951 Cube::Cube(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5) : Cuboid()
1952 {
1953   std::vector<Parameter> ps(5);
1954   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5;
1955   build(ps);
1956 }
1957 
Cube(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6)1958 Cube::Cube(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
1959            const Parameter& p6) : Cuboid()
1960 {
1961   std::vector<Parameter> ps(6);
1962   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6;
1963   build(ps);
1964 }
1965 
Cube(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7)1966 Cube::Cube(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
1967            const Parameter& p6, const Parameter& p7) : Cuboid()
1968 {
1969   std::vector<Parameter> ps(7);
1970   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7;
1971   build(ps);
1972 }
1973 
Cube(const Cube & c)1974 Cube::Cube(const Cube& c) : Cuboid(c), nboctants_(c.nboctants_)
1975 {}
1976 
nbSubdiv() const1977 number_t Cube::nbSubdiv() const
1978 {
1979   number_t n0=n(1);
1980   for(number_t i=1; i < 12; ++i) { if(n(i+1) > n0) { n0=n(i+1); } }
1981   return static_cast<number_t>(theTolerance+std::log(n0-1)/std::log(2));
1982 }
1983 
1984 //! Format Cube as string : "center = (.,.,.), edge length = L"
asString() const1985 string_t Cube::asString() const
1986 {
1987   string_t s("Cube (");
1988   s += p_[0].toString() +", " + p_[1].toString() + ", " + p_[3].toString() + ", " + p_[4].toString() + ")";
1989   return s;
1990 }
1991 
surfs() const1992 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Cube::surfs() const
1993 {
1994   std::vector<std::pair<ShapeType,std::vector<const Point*> > > surfs(6);
1995   std::vector<const Point*> vertices(4);
1996   vertices[0]=&p_[0]; vertices[1]=&p_[1]; vertices[2]=&p_[2]; vertices[3]=&p_[3];
1997   surfs[0]=std::make_pair(_square, vertices);
1998   vertices[0]=&p_[4]; vertices[1]=&p_[5]; vertices[2]=&p_[6]; vertices[3]=&p_[7];
1999   surfs[1]=std::make_pair(_square, vertices);
2000   vertices[0]=&p_[0]; vertices[1]=&p_[1]; vertices[2]=&p_[5]; vertices[3]=&p_[4];
2001   surfs[2]=std::make_pair(_square, vertices);
2002   vertices[0]=&p_[2]; vertices[1]=&p_[3]; vertices[2]=&p_[7]; vertices[3]=&p_[6];
2003   surfs[3]=std::make_pair(_square, vertices);
2004   vertices[0]=&p_[3]; vertices[1]=&p_[0]; vertices[2]=&p_[4]; vertices[3]=&p_[7];
2005   surfs[4]=std::make_pair(_square, vertices);
2006   vertices[0]=&p_[1]; vertices[1]=&p_[2]; vertices[2]=&p_[6]; vertices[3]=&p_[5];
2007   surfs[5]=std::make_pair(_square, vertices);
2008 
2009   return surfs;
2010 }
2011 
2012 //! default ellipsoid is sphere of center (0,0,0) and radius 1
Ellipsoid()2013 Ellipsoid::Ellipsoid() : Volume(), center_(Point(0.,0.,0.)), p1_(Point(1.,0.,0.)), p2_(Point(0.,1.,0.)), p3_(Point(-1.,0.,0.)),
2014   p4_(Point(0.,-1.,0.)), p5_(Point(0.,0.,-1.)), p6_(Point(0.,0.,1.)), xlength_(1.), ylength_(1.), zlength_(1.),
2015   isAxis_(false), n1_(2), n2_(2), n3_(2), n4_(2), n5_(2), n6_(2), n7_(2), n8_(2), n9_(2), n10_(2), n11_(2),
2016   n12_(2), nboctants_(8), type_(1)
2017 {
2018   shape_=_ellipsoid;
2019   computeMB();
2020 }
2021 
buildP()2022 void Ellipsoid::buildP()
2023 {
2024   if(isAxis_)
2025     {
2026       Point shift1(xlength_/2., 0., 0.);
2027       p1_=center_+shift1;
2028       Point shift2(0., ylength_/2., 0.);
2029       p2_=center_+shift2;
2030       Point shift3(-xlength_/2., 0., 0.);
2031       p3_=center_+shift3;
2032       Point shift4(0., -ylength_/2., 0.);
2033       p4_=center_+shift4;
2034       Point shift5(0., 0., -zlength_/2.);
2035       p5_=center_+shift5;
2036       Point shift6(0., 0., zlength_/2.);
2037       p6_=center_+shift6;
2038     }
2039   else // vertices keys are used so p3_ and p4_ are not defined
2040     {
2041       p3_=2.*center_-p1_;
2042       p4_=2.*center_-p2_;
2043       p5_=2.*center_-p6_;
2044       xlength_=2.*center_.distance(p1_);
2045       ylength_=2.*center_.distance(p2_);
2046       zlength_=2.*center_.distance(p6_);
2047       if(dot(p2_-center_,p1_-center_) > theTolerance ||
2048           dot(p6_-center_,p1_-center_) > theTolerance ||
2049           dot(p6_-center_,p2_-center_) > theTolerance) { error("geometry_incoherent_points", words("shape",shape_)); }
2050     }
2051 }
2052 
build(const std::vector<Parameter> & ps)2053 void Ellipsoid::build(const std::vector<Parameter>& ps)
2054 {
2055   trace_p->push("Ellipsoid::build");
2056   shape_=_ellipsoid;
2057   std::set<ParameterKey> params=getParamsKeys(), usedParams;
2058 
2059   // managing params
2060   for(number_t i=0; i < ps.size(); ++i)
2061     {
2062       ParameterKey key=ps[i].key();
2063       buildParam(ps[i]);
2064       if(params.find(key) != params.end()) { params.erase(key); }
2065       else
2066         {
2067           if(usedParams.find(key) == usedParams.end())
2068             { error("geom_unexpected_param_key", words("param key",key), words("shape",_ellipsoid)); }
2069           else { warning("param_already_used", words("param key",key)); }
2070         }
2071       usedParams.insert(key);
2072       // user must use nnodes or hsteps, not both
2073       if(key==_pk_hsteps && usedParams.find(_pk_nnodes) != usedParams.end())
2074         { error("param_conflict", words("param key",key), words("param key",_pk_nnodes)); }
2075       if(key==_pk_nnodes && usedParams.find(_pk_hsteps) != usedParams.end())
2076         { error("param_conflict", words("param key",key), words("param key",_pk_hsteps)); }
2077       // user must use only one of the following combination: (center,v1,v2) or (center,xlength,ylength)
2078       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v6) && usedParams.find(_pk_xlength) != usedParams.end())
2079         { error("param_conflict", words("param key",key), words("param key",_pk_xlength)); }
2080       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v6) && usedParams.find(_pk_ylength) != usedParams.end())
2081         { error("param_conflict", words("param key",key), words("param key",_pk_ylength)); }
2082       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v6) && usedParams.find(_pk_zlength) != usedParams.end())
2083         { error("param_conflict", words("param key",key), words("param key",_pk_zlength)); }
2084       if((key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) && usedParams.find(_pk_v1) != usedParams.end())
2085         { error("param_conflict", words("param key",key), words("param key",_pk_v1)); }
2086       if((key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) && usedParams.find(_pk_v2) != usedParams.end())
2087         { error("param_conflict", words("param key",key), words("param key",_pk_v2)); }
2088       if((key==_pk_xlength || key==_pk_ylength || key==_pk_zlength) && usedParams.find(_pk_v6) != usedParams.end())
2089         { error("param_conflict", words("param key",key), words("param key",_pk_v6)); }
2090     }
2091 
2092   // if hsteps is not used, nnodes is used instead and there is no default value
2093   if(params.find(_pk_hsteps) != params.end()) { params.erase(_pk_hsteps); }
2094 
2095   // (center,v1,v2,v6) or (center,xlength,ylength,zlength) has to be set (no default values)
2096   if(params.find(_pk_center) != params.end()) { error("param_missing","center"); }
2097   if(params.find(_pk_v1) == params.end() && params.find(_pk_v2) != params.end()) { error("param_missing","v2"); }
2098   if(params.find(_pk_v1) == params.end() && params.find(_pk_v6) != params.end()) { error("param_missing","v6"); }
2099   if(params.find(_pk_v2) == params.end() && params.find(_pk_v1) != params.end()) { error("param_missing","v1"); }
2100   if(params.find(_pk_v2) == params.end() && params.find(_pk_v6) != params.end()) { error("param_missing","v6"); }
2101   if(params.find(_pk_v6) == params.end() && params.find(_pk_v1) != params.end()) { error("param_missing","v1"); }
2102   if(params.find(_pk_v6) == params.end() && params.find(_pk_v2) != params.end()) { error("param_missing","v2"); }
2103   if(params.find(_pk_xlength) == params.end() && params.find(_pk_ylength) != params.end()) { error("param_missing","ylength"); }
2104   if(params.find(_pk_xlength) == params.end() && params.find(_pk_zlength) != params.end()) { error("param_missing","zlength"); }
2105   if(params.find(_pk_ylength) == params.end() && params.find(_pk_xlength) != params.end()) { error("param_missing","xlength"); }
2106   if(params.find(_pk_ylength) == params.end() && params.find(_pk_zlength) != params.end()) { error("param_missing","zlength"); }
2107   if(params.find(_pk_zlength) == params.end() && params.find(_pk_xlength) != params.end()) { error("param_missing","xlength"); }
2108   if(params.find(_pk_zlength) == params.end() && params.find(_pk_ylength) != params.end()) { error("param_missing","ylength"); }
2109 
2110   isAxis_=true;
2111   // now, we clean unwanted keys
2112   if(params.find(_pk_xlength) != params.end())
2113     { params.erase(_pk_xlength); params.erase(_pk_ylength); params.erase(_pk_zlength); isAxis_=false; }
2114   if(params.find(_pk_v1) != params.end()) { params.erase(_pk_v1); params.erase(_pk_v2); params.erase(_pk_v6); }
2115   // p_ is not (fully) built so we do
2116   buildP();
2117 
2118   std::set<ParameterKey>::const_iterator it_p;
2119   for(it_p=params.begin(); it_p != params.end(); ++it_p) { buildDefaultParam(*it_p); }
2120 
2121   // checking hsteps size
2122   if(h_.size() != 0)
2123     {
2124       if(h_.size() == 1) { real_t h0=h_[0]; h_.resize(6,h0); }
2125       else if(h_.size() != 6) {error("bad_size","hsteps",6,h_.size()); }
2126     }
2127 
2128   boundingBox=BoundingBox(4.*center_-p1_-p2_-p6_, 2.*center_+p1_-p2_-p6_, 2.*center_+p2_-p1_-p6_, 2.*center_+p6_-p1_-p2_);
2129   computeMB();
2130   trace_p->pop();
2131 }
2132 
buildParam(const Parameter & p)2133 void Ellipsoid::buildParam(const Parameter& p)
2134 {
2135   trace_p->push("Ellipsoid::buildParam");
2136   ParameterKey key=p.key();
2137   switch(key)
2138     {
2139       case _pk_center:
2140         {
2141           switch(p.type())
2142             {
2143               case _pt: center_=p.get_pt(); break;
2144               case _integer: center_=Point(real_t(p.get_i())); break;
2145               case _real: center_=Point(p.get_r()); break;
2146               default: error("param_badtype",words("value",p.type()),words("param key",key));
2147             }
2148           break;
2149         }
2150       case _pk_v1:
2151         {
2152           switch(p.type())
2153             {
2154               case _pt: p1_=p.get_pt(); break;
2155               case _integer: p1_=Point(real_t(p.get_i())); break;
2156               case _real: p1_=Point(p.get_r()); break;
2157               default: error("param_badtype",words("value",p.type()),words("param key",key));
2158             }
2159           break;
2160         }
2161       case _pk_v2:
2162         {
2163           switch(p.type())
2164             {
2165               case _pt: p2_=p.get_pt(); break;
2166               case _integer: p2_=Point(real_t(p.get_i())); break;
2167               case _real: p2_=Point(p.get_r()); break;
2168               default: error("param_badtype",words("value",p.type()),words("param key",key));
2169             }
2170           break;
2171         }
2172       case _pk_v6:
2173         {
2174           switch(p.type())
2175             {
2176               case _pt: p6_=p.get_pt(); break;
2177               case _integer: p6_=Point(real_t(p.get_i())); break;
2178               case _real: p6_=Point(p.get_r()); break;
2179               default: error("param_badtype",words("value",p.type()),words("param key",key));
2180             }
2181           break;
2182         }
2183       case _pk_xlength:
2184         {
2185           switch(p.type())
2186             {
2187               case _integer: xlength_=real_t(p.get_n()); break;
2188               case _real: xlength_=p.get_r(); break;
2189               default: error("param_badtype",words("value",p.type()),words("param key",key));
2190             }
2191           break;
2192         }
2193       case _pk_ylength:
2194         {
2195           switch(p.type())
2196             {
2197               case _integer: ylength_=real_t(p.get_n()); break;
2198               case _real: ylength_=p.get_r(); break;
2199               default: error("param_badtype",words("value",p.type()),words("param key",key));
2200             }
2201           break;
2202         }
2203       case _pk_zlength:
2204         {
2205           switch(p.type())
2206             {
2207               case _integer: zlength_=real_t(p.get_n()); break;
2208               case _real: zlength_=p.get_r(); break;
2209               default: error("param_badtype",words("value",p.type()),words("param key",key));
2210             }
2211           break;
2212         }
2213       case _pk_type:
2214         {
2215           switch(p.type())
2216             {
2217               case _integer: type_=dimen_t(p.get_n()); break;
2218               default: error("param_badtype",words("value",p.type()),words("param key",key));
2219             }
2220           break;
2221         }
2222       case _pk_nnodes:
2223         {
2224           switch(p.type())
2225             {
2226               case _integerVector:
2227                 {
2228                   std::vector<number_t> n=p.get_nv();
2229                   if(n.size() == 1) { n1_=n2_=n3_=n4_=n5_=n6_=n7_=n8_=n9_=n10_=n11_=n12_=n[0] > 2 ? n[0] : 2; }
2230                   else if(n.size() == 3)
2231                     {
2232                       n1_=n2_=n3_=n4_=n[0] > 2 ? n[0] : 2;
2233                       n5_=n6_=n7_=n8_=n[1] > 2 ? n[1] : 2;
2234                       n9_=n10_=n11_=n12_=n[2] > 2 ? n[2] : 2;
2235                     }
2236                   else if(n.size() != 12) { error("bad_size","nnodes",12,n.size()); }
2237                   else
2238                     {
2239                       n1_=n[0] > 2 ? n[0] : 2;
2240                       n2_=n[1] > 2 ? n[1] : 2;
2241                       n3_=n[2] > 2 ? n[2] : 2;
2242                       n4_=n[3] > 2 ? n[3] : 2;
2243                       n5_=n[4] > 2 ? n[4] : 2;
2244                       n6_=n[5] > 2 ? n[5] : 2;
2245                       n7_=n[6] > 2 ? n[6] : 2;
2246                       n8_=n[7] > 2 ? n[7] : 2;
2247                       n9_=n[8] > 2 ? n[8] : 2;
2248                       n10_=n[9] > 2 ? n[9] : 2;
2249                       n11_=n[10] > 2 ? n[10] : 2;
2250                       n12_=n[11] > 2 ? n[11] : 2;
2251                     }
2252                   break;
2253                 }
2254               case _integer: n1_=n2_=n3_=n4_=n5_=n6_=n7_=n8_=n9_=n10_=n11_=n12_=p.get_n() > 2 ? p.get_n() : 2; break;
2255               default: error("param_badtype",words("value",p.type()),words("param key",key));
2256             }
2257           break;
2258         }
2259       case _pk_hsteps:
2260         {
2261           switch(p.type())
2262             {
2263               case _realVector: h_=p.get_rv(); break;
2264               case _integer: h_=std::vector<real_t>(1,real_t(p.get_n())); break;
2265               case _real: h_=std::vector<real_t>(1,p.get_r()); break;
2266               default: error("param_badtype",words("value",p.type()),words("param key",key));
2267             }
2268           break;
2269         }
2270       case _pk_nboctants:
2271         {
2272           switch(p.type())
2273             {
2274               //case _integer: nboctants_=p.get_d(); break;
2275               case _integer: nboctants_ = p.get_n(); break;
2276               default: error("param_badtype",words("value",p.type()),words("param key",key));
2277             }
2278           break;
2279         }
2280       default: Volume::buildParam(p); break;
2281     }
2282   trace_p->pop();
2283 }
2284 
buildDefaultParam(ParameterKey key)2285 void Ellipsoid::buildDefaultParam(ParameterKey key)
2286 {
2287   trace_p->push("Ellipsoid::buildDefaultParam");
2288   switch(key)
2289     {
2290       case _pk_nnodes: n1_=n2_=n3_=n4_=n5_=n6_=n7_=n8_=n9_=n10_=n11_=n12_=2; break;
2291       case _pk_type: type_=1; break;
2292       case _pk_nboctants: nboctants_=0; break;
2293       default: Volume::buildDefaultParam(key); break;
2294     }
2295   trace_p->pop();
2296 }
2297 
getParamsKeys()2298 std::set<ParameterKey> Ellipsoid::getParamsKeys()
2299 {
2300   std::set<ParameterKey> params=Volume::getParamsKeys();
2301   params.insert(_pk_center);
2302   params.insert(_pk_v1);
2303   params.insert(_pk_v2);
2304   params.insert(_pk_v6);
2305   params.insert(_pk_xlength);
2306   params.insert(_pk_ylength);
2307   params.insert(_pk_zlength);
2308   params.insert(_pk_nnodes);
2309   params.insert(_pk_hsteps);
2310   params.insert(_pk_nboctants);
2311   params.insert(_pk_type);
2312   return params;
2313 }
2314 
Ellipsoid(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4)2315 Ellipsoid::Ellipsoid(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4) : Volume()
2316 {
2317   std::vector<Parameter> ps(4);
2318   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4;
2319   build(ps);
2320 }
2321 
Ellipsoid(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5)2322 Ellipsoid::Ellipsoid(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5)
2323   : Volume()
2324 {
2325   std::vector<Parameter> ps(5);
2326   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5;
2327   build(ps);
2328 }
2329 
Ellipsoid(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6)2330 Ellipsoid::Ellipsoid(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
2331                      const Parameter& p6) : Volume()
2332 {
2333   std::vector<Parameter> ps(6);
2334   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6;
2335   build(ps);
2336 }
2337 
Ellipsoid(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7)2338 Ellipsoid::Ellipsoid(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
2339                      const Parameter& p6, const Parameter& p7) : Volume()
2340 {
2341   std::vector<Parameter> ps(7);
2342   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7;
2343   build(ps);
2344 }
2345 
Ellipsoid(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7,const Parameter & p8)2346 Ellipsoid::Ellipsoid(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
2347                      const Parameter& p6, const Parameter& p7, const Parameter& p8) : Volume()
2348 {
2349   std::vector<Parameter> ps(8);
2350   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7; ps[7]=p8;
2351   build(ps);
2352 }
2353 
Ellipsoid(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7,const Parameter & p8,const Parameter & p9)2354 Ellipsoid::Ellipsoid(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
2355                      const Parameter& p6, const Parameter& p7, const Parameter& p8, const Parameter& p9) : Volume()
2356 {
2357   std::vector<Parameter> ps(9);
2358   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7; ps[7]=p8; ps[8]=p9;
2359   build(ps);
2360 }
2361 
Ellipsoid(const Ellipsoid & e)2362 Ellipsoid::Ellipsoid(const Ellipsoid& e) : Volume(e), center_(e.center_), p1_(e.p1_), p2_(e.p2_), p3_(e.p3_), p4_(e.p4_), p5_(e.p5_),
2363   p6_(e.p6_), xlength_(e.xlength_), ylength_(e.ylength_), zlength_(e.zlength_),
2364   isAxis_(e.isAxis_), n1_(e.n1_), n2_(e.n2_), n3_(e.n3_), n4_(e.n4_), n5_(e.n5_), n6_(e.n6_),
2365   n7_(e.n7_), n8_(e.n8_), n9_(e.n9_), n10_(e.n10_), n11_(e.n11_), n12_(e.n12_), h_(e.h_),
2366   nboctants_(e.nboctants_), type_(e.type_)
2367 {}
2368 
nbSubdiv() const2369 number_t Ellipsoid::nbSubdiv() const
2370 {
2371   number_t n=n1_;
2372   if(n2_ > n) { n=n2_; }
2373   if(n3_ > n) { n=n3_; }
2374   if(n4_ > n) { n=n4_; }
2375   if(n5_ > n) { n=n5_; }
2376   if(n6_ > n) { n=n6_; }
2377   if(n7_ > n) { n=n7_; }
2378   if(n8_ > n) { n=n8_; }
2379   if(n9_ > n) { n=n9_; }
2380   if(n10_ > n) { n=n10_; }
2381   if(n11_ > n) { n=n11_; }
2382   if(n12_ > n) { n=n12_; }
2383   return static_cast<number_t>(theTolerance+std::log(n-1)/std::log(2));
2384 }
2385 
asString() const2386 string_t Ellipsoid::asString() const
2387 {
2388   string_t s("Ellipsoid (center = ");
2389   s += center_.toString() +", ";
2390   s += "1st apogee = " + p1_.toString() + ", 2nd apogee = " + p2_.toString() + ", 3rd apogee = " + p6_.toString() + ")";
2391   return s;
2392 }
2393 
boundNodes() const2394 std::vector<const Point*> Ellipsoid::boundNodes() const
2395 {
2396   std::vector<const Point*> nodes(6);
2397   nodes[0]=&p1_; nodes[1]=&p2_; nodes[2]=&p3_; nodes[3]=&p4_; nodes[4]=&p5_; nodes[5]=&p6_;
2398   return nodes;
2399 }
2400 
nodes()2401 std::vector<Point*> Ellipsoid::nodes()
2402 {
2403   std::vector<Point*> nodes(7);
2404   nodes[0]=&center_; nodes[1]=&p1_; nodes[2]=&p2_; nodes[3]=&p3_; nodes[4]=&p4_; nodes[5]=&p5_; nodes[6]=&p6_;
2405   return nodes;
2406 }
2407 
nodes() const2408 std::vector<const Point*> Ellipsoid::nodes() const
2409 {
2410   std::vector<const Point*> nodes(7);
2411   nodes[0]=&center_; nodes[1]=&p1_; nodes[2]=&p2_; nodes[3]=&p3_; nodes[4]=&p4_; nodes[5]=&p5_; nodes[6]=&p6_;
2412   return nodes;
2413 }
2414 
curves() const2415 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Ellipsoid::curves() const
2416 {
2417   std::vector<std::pair<ShapeType,std::vector<const Point*> > > curves(12);
2418   std::vector<const Point*> vertices(2);
2419   vertices[0]=&p1_; vertices[1]=&p2_;
2420   curves[0]=std::make_pair(_ellArc,vertices);
2421   vertices[0]=&p2_; vertices[1]=&p3_;
2422   curves[1]=std::make_pair(_ellArc,vertices);
2423   vertices[0]=&p3_; vertices[1]=&p4_;
2424   curves[2]=std::make_pair(_ellArc,vertices);
2425   vertices[0]=&p4_; vertices[1]=&p1_;
2426   curves[3]=std::make_pair(_ellArc,vertices);
2427   vertices[0]=&p1_; vertices[1]=&p6_;
2428   curves[4]=std::make_pair(_ellArc,vertices);
2429   vertices[0]=&p6_; vertices[1]=&p3_;
2430   curves[5]=std::make_pair(_ellArc,vertices);
2431   vertices[0]=&p3_; vertices[1]=&p5_;
2432   curves[6]=std::make_pair(_ellArc,vertices);
2433   vertices[0]=&p5_; vertices[1]=&p1_;
2434   curves[7]=std::make_pair(_ellArc,vertices);
2435   vertices[0]=&p2_; vertices[1]=&p6_;
2436   curves[8]=std::make_pair(_ellArc,vertices);
2437   vertices[0]=&p6_; vertices[1]=&p4_;
2438   curves[9]=std::make_pair(_ellArc,vertices);
2439   vertices[0]=&p4_; vertices[1]=&p5_;
2440   curves[10]=std::make_pair(_ellArc,vertices);
2441   vertices[0]=&p5_; vertices[1]=&p2_;
2442   curves[11]=std::make_pair(_ellArc,vertices);
2443   return curves;
2444 }
2445 
surfs() const2446 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Ellipsoid::surfs() const
2447 {
2448   std::vector<std::pair<ShapeType,std::vector<const Point*> > > surfs(8);
2449   std::vector<const Point*> vertices(3);
2450   vertices[0]=&p1_; vertices[1]=&p2_; vertices[2]=&p6_;
2451   surfs[0]=std::make_pair(_ellipsoidPart,vertices);
2452   vertices[0]=&p1_; vertices[1]=&p2_; vertices[2]=&p5_;
2453   surfs[1]=std::make_pair(_ellipsoidPart,vertices);
2454   vertices[0]=&p3_; vertices[1]=&p2_; vertices[2]=&p6_;
2455   surfs[2]=std::make_pair(_ellipsoidPart,vertices);
2456   vertices[0]=&p3_; vertices[1]=&p2_; vertices[2]=&p5_;
2457   surfs[3]=std::make_pair(_ellipsoidPart,vertices);
2458   vertices[0]=&p1_; vertices[1]=&p4_; vertices[2]=&p6_;
2459   surfs[4]=std::make_pair(_ellipsoidPart,vertices);
2460   vertices[0]=&p1_; vertices[1]=&p4_; vertices[2]=&p5_;
2461   surfs[5]=std::make_pair(_ellipsoidPart,vertices);
2462   vertices[0]=&p3_; vertices[1]=&p4_; vertices[2]=&p6_;
2463   surfs[6]=std::make_pair(_ellipsoidPart,vertices);
2464   vertices[0]=&p3_; vertices[1]=&p4_; vertices[2]=&p5_;
2465   surfs[7]=std::make_pair(_ellipsoidPart,vertices);
2466   return surfs;
2467 }
2468 
measure() const2469 real_t Ellipsoid::measure() const
2470 {
2471   number_t nboct=nboctants_;
2472   if (nboctants_ == 0) { nboct=8; }
2473   return pi_*xlength_*ylength_*zlength_/46.*nboct;
2474 }
2475 
2476 //! default is ball of center (0,0,0) and radius 1
Ball()2477 Ball::Ball() : Ellipsoid()
2478 { shape_ = _ball; }
2479 
build(const std::vector<Parameter> & ps)2480 void Ball::build(const std::vector<Parameter>& ps)
2481 {
2482   trace_p->push("Ball::build");
2483   shape_=_ball;
2484   std::set<ParameterKey> params=getParamsKeys(), usedParams;
2485   // xlength, ylength and zlength are replaced by radius
2486   params.erase(_pk_xlength);
2487   params.erase(_pk_ylength);
2488   params.erase(_pk_zlength);
2489 
2490   // managing params
2491   for(number_t i=0; i < ps.size(); ++i)
2492     {
2493       ParameterKey key=ps[i].key();
2494       buildParam(ps[i]);
2495       if(params.find(key) != params.end()) { params.erase(key); }
2496       else
2497         {
2498           if(usedParams.find(key) == usedParams.end())
2499             { error("geom_unexpected_param_key", words("param key",key), words("shape",_ball)); }
2500           else { warning("param_already_used", words("param key",key)); }
2501         }
2502       usedParams.insert(key);
2503       // user must use nnodes or hsteps, not both
2504       if(key==_pk_hsteps && usedParams.find(_pk_nnodes) != usedParams.end())
2505         { error("param_conflict", words("param key",key), words("param key",_pk_nnodes)); }
2506       if(key==_pk_nnodes && usedParams.find(_pk_hsteps) != usedParams.end())
2507         { error("param_conflict", words("param key",key), words("param key",_pk_hsteps)); }
2508       // user must use only one of the following combination: (center,v1,v2) or (center,xlength,ylength)
2509       if((key==_pk_v1 || key==_pk_v2 || key==_pk_v6) && usedParams.find(_pk_radius) != usedParams.end())
2510         { error("param_conflict", words("param key",key), words("param key",_pk_radius)); }
2511       if((key==_pk_radius) && usedParams.find(_pk_v1) != usedParams.end())
2512         { error("param_conflict", words("param key",key), words("param key",_pk_v1)); }
2513       if((key==_pk_radius) && usedParams.find(_pk_v2) != usedParams.end())
2514         { error("param_conflict", words("param key",key), words("param key",_pk_v2)); }
2515       if((key==_pk_radius) && usedParams.find(_pk_v6) != usedParams.end())
2516         { error("param_conflict", words("param key",key), words("param key",_pk_v6)); }
2517     }
2518 
2519   // if hsteps is not used, nnodes is used instead and there is no default value
2520   if(params.find(_pk_hsteps) != params.end()) { params.erase(_pk_hsteps); }
2521 
2522   // (center,v1,v2) or (center,xlength,ylength) has to be set (no default values)
2523   if(params.find(_pk_center) != params.end()) { error("param_missing","center"); }
2524   if(params.find(_pk_v1) == params.end() && params.find(_pk_v2) != params.end()) { error("param_missing","v2"); }
2525   if(params.find(_pk_v1) == params.end() && params.find(_pk_v6) != params.end()) { error("param_missing","v6"); }
2526   if(params.find(_pk_v2) == params.end() && params.find(_pk_v1) != params.end()) { error("param_missing","v1"); }
2527   if(params.find(_pk_v2) == params.end() && params.find(_pk_v6) != params.end()) { error("param_missing","v6"); }
2528   if(params.find(_pk_v6) == params.end() && params.find(_pk_v1) != params.end()) { error("param_missing","v1"); }
2529   if(params.find(_pk_v6) == params.end() && params.find(_pk_v2) != params.end()) { error("param_missing","v2"); }
2530 
2531   isAxis_=true;
2532   // now, we clean unwanted keys
2533   if(params.find(_pk_radius) != params.end()) { params.erase(_pk_radius); isAxis_=false; }
2534   if(params.find(_pk_v1) != params.end()) { params.erase(_pk_v1); params.erase(_pk_v2); params.erase(_pk_v6); }
2535 
2536   // p_ is not (fully) built so we do
2537   buildP();
2538 
2539   std::set<ParameterKey>::const_iterator it_p;
2540   for(it_p=params.begin(); it_p != params.end(); ++it_p) { buildDefaultParam(*it_p); }
2541 
2542   if((std::abs(center_.distance(p1_) - center_.distance(p2_)) > theTolerance) ||
2543       (std::abs(center_.distance(p1_) - center_.distance(p6_)) > theTolerance) ||
2544       (std::abs(center_.distance(p2_) - center_.distance(p6_)) > theTolerance))
2545     { error("geometry_incoherent_points", words("shape",_ball)); }
2546 
2547   // checking hsteps size
2548   if(h_.size() != 0)
2549     {
2550       if(h_.size() == 1) { real_t h0=h_[0]; h_.resize(6,h0); }
2551       else if(h_.size() != 6) {error("bad_size","hsteps",6,h_.size()); }
2552     }
2553 
2554   boundingBox=BoundingBox(4.*center_-p1_-p2_-p6_, 2.*center_+p1_-p2_-p6_, 2.*center_+p2_-p1_-p6_, 2.*center_+p6_-p1_-p2_);
2555   computeMB();
2556   trace_p->pop();
2557 }
2558 
buildParam(const Parameter & p)2559 void Ball::buildParam(const Parameter& p)
2560 {
2561   trace_p->push("Ball::buildParam");
2562   ParameterKey key=p.key();
2563   switch(key)
2564     {
2565       case _pk_radius:
2566         {
2567           switch(p.type())
2568             {
2569               case _integer: xlength_=ylength_=zlength_=real_t(p.get_i())*2.; break;
2570               case _real: xlength_=ylength_=zlength_=p.get_r()*2.; break;
2571               default: error("param_badtype",words("value",p.type()),words("param key",key));
2572             }
2573           break;
2574         }
2575       default: Ellipsoid::buildParam(p); break;
2576     }
2577   trace_p->pop();
2578 }
2579 
buildDefaultParam(ParameterKey key)2580 void Ball::buildDefaultParam(ParameterKey key)
2581 {
2582   Ellipsoid::buildDefaultParam(key);
2583 }
2584 
getParamsKeys()2585 std::set<ParameterKey> Ball::getParamsKeys()
2586 {
2587   std::set<ParameterKey> params=Ellipsoid::getParamsKeys();
2588   params.insert(_pk_radius);
2589   return params;
2590 }
2591 
Ball(const Parameter & p1,const Parameter & p2)2592 Ball::Ball(const Parameter& p1, const Parameter& p2) : Ellipsoid()
2593 {
2594   std::vector<Parameter> ps(2);
2595   ps[0]=p1; ps[1]=p2;
2596   build(ps);
2597 }
2598 
Ball(const Parameter & p1,const Parameter & p2,const Parameter & p3)2599 Ball::Ball(const Parameter& p1, const Parameter& p2, const Parameter& p3) : Ellipsoid()
2600 {
2601   std::vector<Parameter> ps(3);
2602   ps[0]=p1; ps[1]=p2; ps[2]=p3;
2603   build(ps);
2604 }
2605 
Ball(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4)2606 Ball::Ball(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4) : Ellipsoid()
2607 {
2608   std::vector<Parameter> ps(4);
2609   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4;
2610   build(ps);
2611 }
2612 
Ball(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5)2613 Ball::Ball(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5) : Ellipsoid()
2614 {
2615   std::vector<Parameter> ps(5);
2616   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5;
2617   build(ps);
2618 }
2619 
Ball(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6)2620 Ball::Ball(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
2621            const Parameter& p6) : Ellipsoid()
2622 {
2623   std::vector<Parameter> ps(6);
2624   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6;
2625   build(ps);
2626 }
2627 
Ball(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7)2628 Ball::Ball(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
2629            const Parameter& p6, const Parameter& p7) : Ellipsoid()
2630 {
2631   std::vector<Parameter> ps(7);
2632   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7;
2633   build(ps);
2634 }
2635 
Ball(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7,const Parameter & p8)2636 Ball::Ball(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
2637            const Parameter& p6, const Parameter& p7, const Parameter& p8) : Ellipsoid()
2638 {
2639   std::vector<Parameter> ps(8);
2640   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7; ps[7]=p8;
2641   build(ps);
2642 }
2643 
Ball(const Parameter & p1,const Parameter & p2,const Parameter & p3,const Parameter & p4,const Parameter & p5,const Parameter & p6,const Parameter & p7,const Parameter & p8,const Parameter & p9)2644 Ball::Ball(const Parameter& p1, const Parameter& p2, const Parameter& p3, const Parameter& p4, const Parameter& p5,
2645            const Parameter& p6, const Parameter& p7, const Parameter& p8, const Parameter& p9) : Ellipsoid()
2646 {
2647   std::vector<Parameter> ps(9);
2648   ps[0]=p1; ps[1]=p2; ps[2]=p3; ps[3]=p4; ps[4]=p5; ps[5]=p6; ps[6]=p7; ps[7]=p8; ps[8]=p9;
2649   build(ps);
2650 }
2651 
Ball(const Ball & b)2652 Ball::Ball(const Ball& b) : Ellipsoid(b) {}
2653 
2654 //! Format Ball as string : "Ball (center = (.,.,.), radius = R)"
asString() const2655 string_t Ball::asString() const
2656 {
2657   string_t s("Ball (center = ");
2658   s += center_.toString() +", ";
2659   s += "1st point = " + p1_.toString() + ", 2nd point = " + p2_.toString() + ", 3rd point = " + p6_.toString() + ")";
2660   return s;
2661 }
2662 
curves() const2663 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Ball::curves() const
2664 {
2665   std::vector<std::pair<ShapeType,std::vector<const Point*> > > curves(12);
2666   std::vector<const Point*> vertices(2);
2667   vertices[0]=&p1_; vertices[1]=&p2_;
2668   curves[0]=std::make_pair(_circArc,vertices);
2669   vertices[0]=&p2_; vertices[1]=&p3_;
2670   curves[1]=std::make_pair(_circArc,vertices);
2671   vertices[0]=&p3_; vertices[1]=&p4_;
2672   curves[2]=std::make_pair(_circArc,vertices);
2673   vertices[0]=&p4_; vertices[1]=&p1_;
2674   curves[3]=std::make_pair(_circArc,vertices);
2675   vertices[0]=&p1_; vertices[1]=&p6_;
2676   curves[4]=std::make_pair(_circArc,vertices);
2677   vertices[0]=&p6_; vertices[1]=&p3_;
2678   curves[5]=std::make_pair(_circArc,vertices);
2679   vertices[0]=&p3_; vertices[1]=&p5_;
2680   curves[6]=std::make_pair(_circArc,vertices);
2681   vertices[0]=&p5_; vertices[1]=&p1_;
2682   curves[7]=std::make_pair(_circArc,vertices);
2683   vertices[0]=&p2_; vertices[1]=&p6_;
2684   curves[8]=std::make_pair(_circArc,vertices);
2685   vertices[0]=&p6_; vertices[1]=&p4_;
2686   curves[9]=std::make_pair(_circArc,vertices);
2687   vertices[0]=&p4_; vertices[1]=&p5_;
2688   curves[10]=std::make_pair(_circArc,vertices);
2689   vertices[0]=&p5_; vertices[1]=&p2_;
2690   curves[11]=std::make_pair(_circArc,vertices);
2691   return curves;
2692 }
2693 
surfs() const2694 std::vector<std::pair<ShapeType,std::vector<const Point*> > > Ball::surfs() const
2695 {
2696   std::vector<std::pair<ShapeType,std::vector<const Point*> > > curves(8);
2697   std::vector<const Point*> vertices(3);
2698   vertices[0]=&p1_; vertices[1]=&p2_; vertices[2]=&p6_;
2699   curves[0]=std::make_pair(_spherePart,vertices);
2700   vertices[0]=&p1_; vertices[1]=&p2_; vertices[2]=&p5_;
2701   curves[1]=std::make_pair(_spherePart,vertices);
2702   vertices[0]=&p3_; vertices[1]=&p2_; vertices[2]=&p6_;
2703   curves[2]=std::make_pair(_spherePart,vertices);
2704   vertices[0]=&p3_; vertices[1]=&p2_; vertices[2]=&p5_;
2705   curves[3]=std::make_pair(_spherePart,vertices);
2706   vertices[0]=&p1_; vertices[1]=&p4_; vertices[2]=&p6_;
2707   curves[4]=std::make_pair(_spherePart,vertices);
2708   vertices[0]=&p1_; vertices[1]=&p4_; vertices[2]=&p5_;
2709   curves[5]=std::make_pair(_spherePart,vertices);
2710   vertices[0]=&p3_; vertices[1]=&p4_; vertices[2]=&p6_;
2711   curves[6]=std::make_pair(_spherePart,vertices);
2712   vertices[0]=&p3_; vertices[1]=&p4_; vertices[2]=&p5_;
2713   curves[7]=std::make_pair(_spherePart,vertices);
2714   return curves;
2715 }
2716 
2717 } // end of namespace xlifepp
2718