1 // This is gel/vtol/vtol_block.cxx
2 #include <iostream>
3 #include <vector>
4 #include "vtol_block.h"
5 //:
6 // \file
7 
8 #include <vtol/vtol_edge.h>
9 #include <vtol/vtol_two_chain.h>
10 #include <vtol/vtol_macros.h>
11 #include <vtol/vtol_list_functions.h>
12 #ifdef _MSC_VER
13 #  include "vcl_msvc_warnings.h"
14 #endif
15 #include <cassert>
16 
17 //***************************************************************************
18 // Initialization
19 //***************************************************************************
20 
link_inferior(const vtol_two_chain_sptr & inf)21 void vtol_block::link_inferior(const vtol_two_chain_sptr& inf)
22 {
23   vtol_topology_object::link_inferior(inf->cast_to_topology_object());
24 }
25 
unlink_inferior(const vtol_two_chain_sptr & inf)26 void vtol_block::unlink_inferior(const vtol_two_chain_sptr& inf)
27 {
28   vtol_topology_object::unlink_inferior(inf->cast_to_topology_object());
29 }
30 
31 //---------------------------------------------------------------------------
32 //: Constructor from a two-chain (inferior)
33 //---------------------------------------------------------------------------
vtol_block(vtol_two_chain_sptr const & faceloop)34 vtol_block::vtol_block(vtol_two_chain_sptr const& faceloop)
35 {
36   link_inferior(faceloop);
37 }
38 
39 //---------------------------------------------------------------------------
40 //: Constructor from a list of two-chains.
41 // The first two-chain is the outside boundary.
42 // The remaining two-chains are considered holes inside the outside volume.
43 //---------------------------------------------------------------------------
vtol_block(two_chain_list const & faceloops)44 vtol_block::vtol_block(two_chain_list const& faceloops)
45 {
46   if (!faceloops.empty()) {
47     link_inferior(faceloops.front());
48   }
49 
50   vtol_two_chain_sptr twoch=get_boundary_cycle();
51 
52   if (twoch)
53     for (unsigned int i=1;i<faceloops.size();++i)
54       twoch->link_chain_inferior(faceloops[i]);
55 }
56 
57 //---------------------------------------------------------------------------
58 //: Constructor from a list of faces
59 //---------------------------------------------------------------------------
vtol_block(face_list const & new_face_list)60 vtol_block::vtol_block(face_list const& new_face_list)
61 {
62   link_inferior(new vtol_two_chain(new_face_list));
63 }
64 
65 //---------------------------------------------------------------------------
66 //: Pseudo-copy constructor. Deep copy.
67 //---------------------------------------------------------------------------
vtol_block(vtol_block_sptr const & other)68 vtol_block::vtol_block(vtol_block_sptr const& other)
69 {
70   edge_list edgs;    other->edges(edgs);
71   vertex_list verts; other->vertices(verts);
72 
73   topology_list newedges(edgs.size());
74   topology_list newverts(verts.size());
75 
76   int i=0;
77   for (auto vi=verts.begin();vi!=verts.end();++vi,++i)
78   {
79     vtol_vertex_sptr v= *vi;
80     newverts[i]=v->clone()->cast_to_topology_object();
81     v->set_id(i);
82   }
83 
84   int j=0;
85   for (auto ei=edgs.begin();ei!=edgs.end();++ei,++j)
86   {
87     vtol_edge_sptr e = *ei;
88 
89     newedges[j]=newverts[e->v1()->get_id()]->cast_to_vertex()->new_edge(
90                               newverts[e->v2()->get_id()]->cast_to_vertex())->cast_to_topology_object();
91 
92     e->set_id(j);
93   }
94 
95   const topology_list *old2chains = other->inferiors();
96 
97   topology_list::const_iterator tci;
98   for (tci=old2chains->begin();tci != old2chains->end();tci++)
99   {
100     vtol_two_chain_sptr new2ch=(*tci)->cast_to_two_chain()->copy_with_arrays(newverts,newedges);
101     assert(*new2ch == *(*tci));
102     link_inferior(new2ch);
103   }
104 }
105 
106 //---------------------------------------------------------------------------
107 // Destructor
108 //---------------------------------------------------------------------------
~vtol_block()109 vtol_block::~vtol_block()
110 {
111   unlink_all_inferiors();
112 }
113 
114 //---------------------------------------------------------------------------
115 //: Clone `this': creation of a new object and initialization
116 // See Prototype pattern
117 //---------------------------------------------------------------------------
clone() const118 vsol_spatial_object_2d* vtol_block::clone() const
119 {
120   return new vtol_block(vtol_block_sptr(const_cast<vtol_block*>(this)));
121 }
122 
123 //: outside boundary vertices
124 
outside_boundary_vertices()125 vertex_list *vtol_block::outside_boundary_vertices()
126 {
127   auto *result=new vertex_list();
128   std::vector<vtol_vertex *> *ptr_list=outside_boundary_compute_vertices();
129 
130   // copy the lists
131   std::vector<vtol_vertex*>::iterator i;
132   for (i=ptr_list->begin();i!=ptr_list->end();++i)
133     result->push_back(*i);
134   delete ptr_list;
135 
136   return result;
137 }
138 
outside_boundary_compute_vertices()139 std::vector<vtol_vertex *> *vtol_block::outside_boundary_compute_vertices()
140 {
141   OUTSIDE_BOUNDARY(vtol_vertex,two_chain,compute_vertices);
142 }
143 
144 //: get vertex list
145 
compute_vertices()146 std::vector<vtol_vertex *> *vtol_block::compute_vertices()
147 {
148   SEL_INF(vtol_vertex,compute_vertices);
149 }
150 
151 //: get outside boundary zero chains
152 
outside_boundary_zero_chains()153 zero_chain_list *vtol_block::outside_boundary_zero_chains()
154 {
155   auto *result=new zero_chain_list();
156   std::vector<vtol_zero_chain *> *ptr_list=outside_boundary_compute_zero_chains();
157 
158   // copy the lists
159   std::vector<vtol_zero_chain*>::iterator i;
160   for (i=ptr_list->begin();i!=ptr_list->end();++i)
161     result->push_back(*i);
162   delete ptr_list;
163 
164   return result;
165 }
166 
167 
168 std::vector<vtol_zero_chain *> *
outside_boundary_compute_zero_chains()169 vtol_block::outside_boundary_compute_zero_chains()
170 {
171   OUTSIDE_BOUNDARY(vtol_zero_chain,two_chain,compute_zero_chains);
172 }
173 
174 //: get zero chains
175 
compute_zero_chains()176 std::vector<vtol_zero_chain *> *vtol_block::compute_zero_chains()
177 {
178  SEL_INF(vtol_zero_chain,compute_zero_chains);
179 }
180 
181 //: outside boundary edges
182 
outside_boundary_edges()183 edge_list *vtol_block::outside_boundary_edges()
184 {
185   auto *result=new edge_list();
186   std::vector<vtol_edge *> *ptr_list=outside_boundary_compute_edges();
187 
188   // copy the lists
189   std::vector<vtol_edge*>::iterator i;
190   for (i=ptr_list->begin();i!=ptr_list->end();++i)
191     result->push_back(*i);
192   delete ptr_list;
193 
194   return result;
195 }
196 
197 //: outside boundary edges
198 
outside_boundary_compute_edges()199 std::vector<vtol_edge *> *vtol_block::outside_boundary_compute_edges()
200 {
201   OUTSIDE_BOUNDARY(vtol_edge,two_chain,compute_edges);
202 }
203 
204 //: get edges
compute_edges()205 std::vector<vtol_edge *> *vtol_block::compute_edges()
206 {
207   SEL_INF(vtol_edge,compute_edges);
208 }
209 
210 //: get outside boundary one chains
211 
outside_boundary_one_chains()212 one_chain_list *vtol_block::outside_boundary_one_chains()
213 {
214   auto *result=new one_chain_list;
215   std::vector<vtol_one_chain *> *ptr_list=outside_boundary_compute_one_chains();
216 
217   std::vector<vtol_one_chain*>::iterator i;
218   for (i=ptr_list->begin();i!=ptr_list->end();++i)
219     result->push_back(*i);
220   delete ptr_list;
221 
222   return result;
223 }
224 
225 //: get outside boundary one chains
226 
227 std::vector<vtol_one_chain *> *
outside_boundary_compute_one_chains()228 vtol_block::outside_boundary_compute_one_chains()
229 {
230   OUTSIDE_BOUNDARY(vtol_one_chain,two_chain,compute_one_chains);
231 }
232 
233 //: get the one chains
compute_one_chains()234 std::vector<vtol_one_chain *> *vtol_block::compute_one_chains()
235 {
236   SEL_INF(vtol_one_chain,compute_one_chains);
237 }
238 
239 //: get the outside boundary faces
240 
outside_boundary_faces()241 face_list *vtol_block::outside_boundary_faces()
242 {
243   auto *result=new face_list();
244   std::vector<vtol_face *> *ptr_list=outside_boundary_compute_faces();
245 
246   std::vector<vtol_face*>::iterator i;
247   for (i=ptr_list->begin();i!=ptr_list->end();++i)
248     result->push_back(*i);
249   delete ptr_list;
250 
251   return result;
252 }
253 
254 //: get the outside boundary faces
255 
outside_boundary_compute_faces()256 std::vector<vtol_face *> *vtol_block::outside_boundary_compute_faces()
257 {
258   OUTSIDE_BOUNDARY(vtol_face,two_chain,compute_faces);
259 }
260 
261 //: get the faces
compute_faces()262 std::vector<vtol_face *> *vtol_block::compute_faces()
263 {
264   SEL_INF(vtol_face,compute_faces);
265 }
266 
267 //: get the outside boundary two chains
268 
outside_boundary_two_chains()269 two_chain_list *vtol_block::outside_boundary_two_chains()
270 {
271   auto *result=new two_chain_list();
272   std::vector<vtol_two_chain *> *ptr_list=outside_boundary_compute_two_chains();
273 
274   std::vector<vtol_two_chain*>::iterator i;
275   for (i=ptr_list->begin();i!=ptr_list->end();++i)
276     result->push_back(*i);
277   delete ptr_list;
278 
279   return result;
280 }
281 
282 //: get the outside boundary two chains
283 
284 std::vector<vtol_two_chain *> *
outside_boundary_compute_two_chains()285 vtol_block::outside_boundary_compute_two_chains()
286 {
287   OUTSIDE_BOUNDARY(vtol_two_chain,two_chain,compute_two_chains);
288 }
289 
290 //: get the two chains
291 
compute_two_chains()292 std::vector<vtol_two_chain *> *vtol_block::compute_two_chains()
293 {
294   SEL_INF(vtol_two_chain,compute_two_chains);
295 }
296 
297 //: get blocks
compute_blocks()298 std::vector<vtol_block *> *vtol_block::compute_blocks()
299 {
300   LIST_SELF(vtol_block);
301 }
302 
303 
304 // ******************************************************
305 //
306 //    Operators Functions
307 //
308 
309 // This is hardly an equality test...but we`ll leave it for now....pav
310 // June 1992.
311 
operator ==(const vtol_block & other) const312 bool vtol_block::operator==(const vtol_block &other) const
313 {
314   if (this==&other)
315     return true;
316 
317   if (numinf()!=other.numinf())
318     return false;
319 
320   auto bi1=inferiors()->begin();
321   auto bi2=other.inferiors()->begin();
322   for (; bi1!=inferiors()->end(); ++bi1,++bi2)
323   {
324     vtol_two_chain_sptr twoch1=(*bi1)->cast_to_two_chain();
325     vtol_two_chain_sptr twoch2=(*bi2)->cast_to_two_chain();
326 
327     if (!(*twoch1 == *twoch2))
328       return false;
329   }
330 
331   return true;
332 }
333 
334 //: spatial object equality
335 
operator ==(const vsol_spatial_object_2d & obj) const336 bool vtol_block::operator==(const vsol_spatial_object_2d& obj) const
337 {
338   return
339    obj.cast_to_topology_object() &&
340    obj.cast_to_topology_object()->cast_to_block() &&
341    *this == *obj.cast_to_topology_object()->cast_to_block();
342 }
343 
344 //: get a hole cycle
hole_cycles() const345 two_chain_list *vtol_block::hole_cycles() const
346 {
347   auto *result=new two_chain_list;
348 
349   topology_list::const_iterator ti;
350   for (ti=inferiors_.begin();ti!=inferiors_.end();++ti)
351   {
352     two_chain_list *templist=(*ti)->cast_to_two_chain()->inferior_two_chains();
353     for (auto & ii : *templist)
354       result->push_back(ii);
355     delete templist;
356   }
357   return result;
358 }
359 
360 //: get the boundary cycle
get_boundary_cycle()361 vtol_two_chain_sptr vtol_block::get_boundary_cycle()
362 {
363   return (!inferiors_.empty()) ? inferiors_[0]->cast_to_two_chain() : nullptr;
364 }
365 
366 //: add a hole cycle
367 
add_hole_cycle(vtol_two_chain_sptr new_hole)368 bool vtol_block::add_hole_cycle(vtol_two_chain_sptr new_hole)
369 {
370   vtol_two_chain_sptr twoch=get_boundary_cycle();
371   if (! twoch) return false;
372   twoch->link_chain_inferior(new_hole);
373   return true;
374 }
375 
376 // ******************************************************
377 //
378 //    Print Functions
379 //
380 
381 
382 //: print data
383 
print(std::ostream & strm) const384 void vtol_block::print(std::ostream &strm) const
385 {
386   strm<<"<vtol_block "<<inferiors()->size()<<"  "<<(void const*)this<<">\n";
387 }
388 
describe(std::ostream & strm,int blanking) const389 void vtol_block::describe(std::ostream &strm,
390                           int blanking) const
391 {
392   for (int i=0; i<blanking; ++i) strm << ' ';
393   print(strm);
394   describe_inferiors(strm,blanking);
395   describe_superiors(strm,blanking);
396 }
397