root/cgm/geom/BoundingBoxTool.cpp

Revision 1040, 13.6 kB (checked in by tautges, 2 years ago)

Version 10.2 of cgm.

Line 
1 //- Class: BoundingBoxTool
2 //- Description: Class for bounding boxes (primarily for "tight" bounding boxes)
3 //- Owner: Steve Storm
4 //- Created: 06-October-2000
5
6 #include "CubitBox.hpp"
7 #include "Body.hpp"
8 #include "RefVolume.hpp"
9 #include "RefFace.hpp"
10 #include "RefEdge.hpp"
11 #include "RefVertex.hpp"
12 #include "RefGroup.hpp"
13
14 #include "BoundingBoxTool.hpp"
15 #include "AnalyticGeometryTool.hpp"
16 #include "GMem.hpp"
17
18 #include "GeometryQueryEngine.hpp"
19
20 #include "DLIList.hpp"
21
22 #include "SettingHandler.hpp"
23
24 CubitBoolean BoundingBoxTool::useTriangles = CUBIT_TRUE;
25 CubitBoolean BoundingBoxTool::useCurves = CUBIT_FALSE;
26 CubitBoolean BoundingBoxTool::useVertices = CUBIT_FALSE;
27
28 BoundingBoxTool::BoundingBoxTool()
29 {}
30
31 // Destructor
32 BoundingBoxTool::~BoundingBoxTool()
33 {}
34
35 CubitStatus 
36 BoundingBoxTool::get_tight_bounding_box( DLIList<RefEntity*> &ref_entity_list,
37                                          CubitVector &center,
38                                          CubitVector axes[3],
39                                          CubitVector &extension,
40                                          double ang_facet_tol,
41                                          double abs_facet_tol )
42 {
43    DLIList<CubitVector*> vec_list;
44
45    // Expand out groups in the list
46    DLIList<RefEntity*> ref_entity_list_expanded = ref_entity_list;
47    expand_groups_in_list( ref_entity_list_expanded );
48
49    // Get the facet points from all the objects in the list
50    append_ref_entity_points( ref_entity_list_expanded, vec_list, ang_facet_tol, abs_facet_tol );
51    
52    // Get the smallest box that fits around the points making up the facetted geometry
53    AnalyticGeometryTool::instance()->get_tight_bounding_box( vec_list, center,
54                                                              axes, extension );
55
56    // Free memory
57    for( int i=0; i<vec_list.size(); i++ )
58    {
59       CubitVector* cubit_vector_ptr =
60          vec_list.get_and_step();
61       delete cubit_vector_ptr;
62    }
63    
64    return CUBIT_SUCCESS;
65 }
66
67 CubitStatus 
68 BoundingBoxTool::get_axis_bounding_box( DLIList<RefEntity*> &ref_entity_list,
69                                         CubitVector &center,
70                                         CubitVector axes[3],
71                                         CubitVector &extension )
72 {
73    CubitBoolean bounding_box_found = CUBIT_FALSE;
74    CubitBox bounding_box;
75
76    // Expand out groups in the list
77    DLIList<RefEntity*> ref_entity_list_expanded = ref_entity_list;
78    expand_groups_in_list( ref_entity_list_expanded );
79
80    ref_entity_list_expanded.reset();
81    for( int i = ref_entity_list_expanded.size(); i>0; i-- )
82    {
83       RefEntity* ref_entity_ptr = ref_entity_list_expanded.get_and_step();
84       if( bounding_box_found == CUBIT_FALSE )
85       {
86          bounding_box = ref_entity_ptr->bounding_box();
87          bounding_box_found = CUBIT_TRUE;
88       }
89       else {
90          bounding_box |= ref_entity_ptr->bounding_box();
91       }     
92    }
93
94    axes[0].set( 1.0, 0.0, 0.0 );
95    axes[1].set( 0.0, 1.0, 0.0 );
96    axes[2].set( 0.0, 0.0, 1.0 );
97    
98    if( bounding_box_found )
99    {
100       extension.set( bounding_box.x_range()/2.0, bounding_box.y_range()/2.0,
101          bounding_box.z_range()/2.0 );
102       center = bounding_box.center();
103    }
104    else
105    {
106       extension.set( 0.0, 0.0, 0.0 );
107       center.set( 0.0, 0.0, 0.0 );
108    }
109
110    return CUBIT_SUCCESS;   
111 }
112
113 CubitStatus 
114 BoundingBoxTool::append_ref_entity_points( DLIList<RefEntity*> &ref_entity_list,
115                                            DLIList<CubitVector*> &vec_list,
116                                            double ang_facet_tol, double abs_facet_tol )
117 {
118    DLIList<Body*> body_list;
119    CAST_LIST( ref_entity_list, body_list, Body );
120    if( body_list.size() )
121       append_body_points( body_list, vec_list, ang_facet_tol, abs_facet_tol );
122
123    DLIList<RefVolume*> vol_list;
124    CAST_LIST( ref_entity_list, vol_list, RefVolume );
125    if( vol_list.size() )
126       append_volume_points( vol_list, vec_list, ang_facet_tol, abs_facet_tol );
127
128    DLIList<RefFace*> surface_list;
129    CAST_LIST( ref_entity_list, surface_list, RefFace );
130    if( surface_list.size() )
131       append_surface_points( surface_list, vec_list, ang_facet_tol, abs_facet_tol );
132
133    DLIList<RefEdge*> curve_list;
134    CAST_LIST( ref_entity_list, curve_list, RefEdge );
135    if( curve_list.size() )
136       append_curve_points( curve_list, vec_list );
137
138    DLIList<RefVertex*> vertex_list;
139    CAST_LIST( ref_entity_list, vertex_list, RefVertex );
140    if( vertex_list.size() )
141       append_vertex_points( vertex_list, vec_list );
142
143    return CUBIT_SUCCESS;
144 }
145
146 CubitStatus 
147 BoundingBoxTool::append_body_points( DLIList<Body*> &body_list,
148                                      DLIList<CubitVector*> &vec_list,
149                                      double ang_tol, double abs_tol )
150 {
151    int i;
152    Body *body_ptr;
153    DLIList<RefFace*> ref_face_list;
154
155    body_list.reset();
156    for( i=0; i<body_list.size(); i++ )
157    {
158       body_ptr = body_list.get_and_step();
159
160       DLIList<RefFace*> ref_face_list_tmp;
161       body_ptr->ref_faces( ref_face_list_tmp );
162
163       ref_face_list.merge_unique( ref_face_list_tmp );
164    }
165
166    append_surface_points( ref_face_list, vec_list, ang_tol, abs_tol);
167    
168    return CUBIT_SUCCESS;
169 }
170
171 CubitStatus 
172 BoundingBoxTool::append_volume_points( DLIList<RefVolume*> &vol_list,
173                                        DLIList<CubitVector*> &vec_list,
174                                        double ang_tol, double abs_tol )
175 {
176    int i;
177    RefVolume *vol_ptr;
178    DLIList<RefFace*> ref_face_list;
179
180    vol_list.reset();
181    for( i=0; i<vol_list.size(); i++ )
182    {
183       vol_ptr = vol_list.get_and_step();
184
185       DLIList<RefFace*> ref_face_list_tmp;
186       vol_ptr->ref_faces( ref_face_list_tmp );
187
188       ref_face_list.merge_unique( ref_face_list_tmp );
189    }
190
191    append_surface_points( ref_face_list, vec_list, ang_tol, abs_tol);
192    
193    return CUBIT_SUCCESS;
194 }
195
196 CubitStatus 
197 BoundingBoxTool::append_surface_points( DLIList<RefFace*> &ref_face_list,
198                                         DLIList<CubitVector*> &vec_list,
199                                         double ang_tol, double abs_tol)
200 {
201    int i;
202    RefFace *ref_face_ptr;
203    DLIList<RefEdge*> ref_edge_list;
204    DLIList<RefVertex*> ref_vertex_list;
205    
206    ref_face_list.reset();
207    for( i=0; i<ref_face_list.size(); i++ )
208    {
209       ref_face_ptr = ref_face_list.get_and_step();
210
211       if( useTriangles == CUBIT_TRUE )
212       {
213          int num_tri, num_pnt, num_facet;
214          GMem *g_mem = new GMem;
215      
216          ref_face_ptr->get_graphics( *g_mem, (int)ang_tol, abs_tol );
217          num_pnt = g_mem->pointListCount;
218          num_facet = g_mem->fListCount;
219          num_tri = num_facet / 4;
220
221          GPoint* point_list = g_mem->point_list();
222          int num_pnts = g_mem->point_list_size();
223          int y;
224          for( y=0; y<num_pnts; y++ )
225          {
226             CubitVector* cubit_vector_ptr = new CubitVector(
227                point_list[y].x, point_list[y].y, point_list[y].z );
228             vec_list.append( cubit_vector_ptr );
229          }
230          delete g_mem;
231       }
232      
233       if( useCurves == CUBIT_TRUE )
234       {
235          // Grab the curves from the surface
236          DLIList<RefEdge*> ref_edge_list_tmp;
237          ref_face_ptr->ref_edges( ref_edge_list_tmp );
238          ref_edge_list.merge_unique( ref_edge_list_tmp );
239       }
240
241       // Only need vertices if both surfaces and curves are false
242       if( useTriangles == CUBIT_FALSE && useCurves == CUBIT_FALSE &&
243          useVertices == CUBIT_TRUE )
244       {
245          // Grab the vertices from the surface
246          DLIList<RefVertex*> ref_vertex_list_tmp;
247          ref_face_ptr->ref_vertices( ref_vertex_list_tmp );
248          ref_vertex_list.merge_unique( ref_vertex_list_tmp );
249       }
250    }
251
252    if( useCurves == CUBIT_TRUE )
253       append_curve_points( ref_edge_list, vec_list );
254
255    if( useTriangles == CUBIT_FALSE && useCurves == CUBIT_FALSE &&
256        useVertices == CUBIT_TRUE )
257        append_vertex_points( ref_vertex_list, vec_list );
258
259    return CUBIT_SUCCESS;
260 }
261
262 CubitStatus 
263 BoundingBoxTool::append_curve_points( DLIList<RefEdge*> &ref_edge_list,
264                                       DLIList<CubitVector*> &vec_list )
265 {
266    // First grab all the vertices and append their coordinates to vec_list.
267    // Then do the curves, but just put inside points in.  This avoids duplicate
268    // points at the vertices.
269
270    int i;
271    RefEdge *ref_edge_ptr;
272    DLIList<RefVertex*> ref_vertex_list;
273    ref_edge_list.reset();
274    for( i=0; i<ref_edge_list.size(); i++ )
275    {
276       ref_edge_ptr = ref_edge_list.get_and_step();
277       DLIList<RefVertex*> ref_vertex_list_temp;
278       ref_edge_ptr->ref_vertices( ref_vertex_list_temp );
279       ref_vertex_list.merge_unique( ref_vertex_list_temp );
280    }
281    append_vertex_points( ref_vertex_list, vec_list );
282
283    // Now add the *inside* curve points
284
285    int j, num_pnts;
286    ref_edge_list.reset();
287    for( i=0; i<ref_edge_list.size(); i++ )
288    {
289       ref_edge_ptr = ref_edge_list.get_and_step();
290       GMem *g_mem = new GMem;
291      
292       ref_edge_ptr->get_graphics( *g_mem );
293       num_pnts = g_mem->pointListCount;
294
295       GPoint* point_list = g_mem->point_list();
296
297       for( j=1; j<num_pnts-1; j++ )
298       {
299          CubitVector* cubit_vector_ptr = new CubitVector(
300             point_list[j].x, point_list[j].y, point_list[j].z );
301          vec_list.append( cubit_vector_ptr );
302       }
303       delete g_mem;
304    }
305
306    return CUBIT_SUCCESS;
307 }
308
309 CubitStatus 
310 BoundingBoxTool::append_vertex_points( DLIList<RefVertex*> &ref_vertex_list,
311                                        DLIList<CubitVector*> &vec_list )
312 {
313    int i;
314    RefVertex *ref_vertex_ptr;
315    ref_vertex_list.reset();
316    for( i=0; i<ref_vertex_list.size(); i++ )
317    {
318       ref_vertex_ptr = ref_vertex_list.get_and_step();
319       CubitVector coords = ref_vertex_ptr->coordinates();
320       CubitVector* cubit_vector_ptr = new CubitVector( coords );
321       vec_list.append( cubit_vector_ptr );
322    }
323    return CUBIT_SUCCESS;
324 }
325
326
327 CubitStatus 
328 BoundingBoxTool::get_corner_points( CubitVector &center,
329                                     CubitVector axes[3],
330                                     CubitVector &extension,
331                                     CubitVector& p1, CubitVector& p2,
332                                     CubitVector& p3, CubitVector& p4,
333                                     CubitVector& p5, CubitVector& p6,
334                                     CubitVector& p7, CubitVector& p8)
335 {
336    double x = extension.x(); double y = extension.y(); double z = extension.z();
337
338    // Front, Bottom, Left
339    center.next_point( -axes[0], x, p1 ); p1.next_point( -axes[1], y, p1 );
340    p1.next_point( axes[2], z, p1 );
341    
342    // Front, Top, Left
343    center.next_point( -axes[0], x, p2 ); p2.next_point( axes[1], y, p2 );
344    p2.next_point( axes[2], z, p2 );
345    
346    // Front, Top, Right
347    center.next_point( axes[0], x, p3 ); p3.next_point( axes[1], y, p3 );
348    p3.next_point( axes[2], z, p3 );
349    
350    // Front, Bottom, Right
351    center.next_point( axes[0], x, p4 ); p4.next_point( -axes[1], y, p4 );
352    p4.next_point( axes[2], z, p4 );
353    
354    // Back, Bottom, Left
355    center.next_point( -axes[0], x, p5 ); p5.next_point( -axes[1], y, p5 );
356    p5.next_point( -axes[2], z, p5 );
357    
358    // Back, Top, Left
359    center.next_point( -axes[0], x, p6 ); p6.next_point( axes[1], y, p6 );
360    p6.next_point( -axes[2], z, p6 );
361    
362    // Back, Top, Right
363    center.next_point( axes[0], x, p7 ); p7.next_point( axes[1], y, p7 );
364    p7.next_point( -axes[2], z, p7 );
365    
366    // Back, Bottom, Right
367    center.next_point( axes[0], x, p8 ); p8.next_point( -axes[1], y, p8 );
368    p8.next_point( -axes[2], z, p8 );
369
370    return CUBIT_SUCCESS;
371 }
372
373
374 //Initialize all settings in this class
375 void BoundingBoxTool::initialize_settings()
376 {
377
378   SettingHandler::instance()->add_setting("Tight Surface",
379                                           BoundingBoxTool::set_use_triangles_setting,
380                                           BoundingBoxTool::get_use_triangles_setting );
381
382   SettingHandler::instance()->add_setting("Tight Curve",
383                                           BoundingBoxTool::set_use_curves_setting,
384                                           BoundingBoxTool::get_use_curves_setting);
385    
386   SettingHandler::instance()->add_setting("Tight Vertex",
387                                          BoundingBoxTool::set_use_vertices_setting,
388                                          BoundingBoxTool::get_use_vertices_setting); 
389
390
391 }
392
393
394
395 CubitBoolean 
396 BoundingBoxTool::expand_groups_in_list( DLIList<RefEntity*> &ref_entity_list )
397 {
398    CubitBoolean group_found = CUBIT_FALSE;
399    // just have to step through original entity_list, not the expanded list
400    for (int i = ref_entity_list.size(); i>0; i--) 
401    {
402       RefEntity *entity = ref_entity_list.get();
403       RefGroup *group = CAST_TO( entity, RefGroup );     
404       if ( group )
405       {
406          ref_entity_list.remove();
407          group->expand_group( ref_entity_list );
408          group_found = CUBIT_TRUE;
409       }
410       else
411          ref_entity_list.step();
412    }
413    return group_found;
414 }
415
416
417 int BoundingBoxTool::get_use_triangles_setting()
418 {return useTriangles;}
419
420 void BoundingBoxTool::set_use_triangles_setting( int val )
421 {useTriangles = (val) ? CUBIT_TRUE : CUBIT_FALSE;}
422
423 int BoundingBoxTool::get_use_curves_setting()
424 {return useCurves;}
425
426 void BoundingBoxTool::set_use_curves_setting( int val )
427 {useCurves = (val) ? CUBIT_TRUE : CUBIT_FALSE;}
428
429 int BoundingBoxTool::get_use_vertices_setting()
430 {return useVertices;}
431
432 void BoundingBoxTool::set_use_vertices_setting( int val )
433 {useVertices = (val) ? CUBIT_TRUE : CUBIT_FALSE;}
434
435
436 CubitBoolean BoundingBoxTool::get_use_triangles()
437 {return useTriangles;}
438
439 void BoundingBoxTool::set_use_triangles( CubitBoolean val )
440 {useTriangles=val;}
441
442 CubitBoolean BoundingBoxTool::get_use_curves()
443 {return useCurves;}
444
445 void BoundingBoxTool::set_use_curves( CubitBoolean val )
446 {useCurves=val;}
447
448 CubitBoolean BoundingBoxTool::get_use_vertices()
449 {return useVertices;}
450
451 void BoundingBoxTool::set_use_vertices( CubitBoolean val )
452 {useVertices=val;}
453
454
Note: See TracBrowser for help on using the browser.