root/cgm/trunk/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
24CubitBoolean BoundingBoxTool::useTriangles = CUBIT_TRUE;
25CubitBoolean BoundingBoxTool::useCurves = CUBIT_FALSE;
26CubitBoolean BoundingBoxTool::useVertices = CUBIT_FALSE;
27
28BoundingBoxTool::BoundingBoxTool()
29{}
30
31// Destructor
32BoundingBoxTool::~BoundingBoxTool()
33{}
34
35CubitStatus
36BoundingBoxTool::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
67CubitStatus
68BoundingBoxTool::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
113CubitStatus
114BoundingBoxTool::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
146CubitStatus
147BoundingBoxTool::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
171CubitStatus
172BoundingBoxTool::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
196CubitStatus
197BoundingBoxTool::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
262CubitStatus
263BoundingBoxTool::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
309CubitStatus
310BoundingBoxTool::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
327CubitStatus
328BoundingBoxTool::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
375void 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
395CubitBoolean
396BoundingBoxTool::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
417int BoundingBoxTool::get_use_triangles_setting()
418{return useTriangles;}
419
420void BoundingBoxTool::set_use_triangles_setting( int val )
421{useTriangles = (val) ? CUBIT_TRUE : CUBIT_FALSE;}
422
423int BoundingBoxTool::get_use_curves_setting()
424{return useCurves;}
425
426void BoundingBoxTool::set_use_curves_setting( int val )
427{useCurves = (val) ? CUBIT_TRUE : CUBIT_FALSE;}
428
429int BoundingBoxTool::get_use_vertices_setting()
430{return useVertices;}
431
432void BoundingBoxTool::set_use_vertices_setting( int val )
433{useVertices = (val) ? CUBIT_TRUE : CUBIT_FALSE;}
434
435
436CubitBoolean BoundingBoxTool::get_use_triangles()
437{return useTriangles;}
438
439void BoundingBoxTool::set_use_triangles( CubitBoolean val )
440{useTriangles=val;}
441
442CubitBoolean BoundingBoxTool::get_use_curves()
443{return useCurves;}
444
445void BoundingBoxTool::set_use_curves( CubitBoolean val )
446{useCurves=val;}
447
448CubitBoolean BoundingBoxTool::get_use_vertices()
449{return useVertices;}
450
451void BoundingBoxTool::set_use_vertices( CubitBoolean val )
452{useVertices=val;}
453
Note: See TracBrowser for help on using the browser.