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