Branch data Line data Source code
1 : : //-------------------------------------------------------------------------
2 : : // Filename : RefVolume.cpp
3 : : //
4 : : // Purpose : This file contains the implementation of the class
5 : : // RefVolume.
6 : : //
7 : : // Special Notes :
8 : : //
9 : : // Creator :
10 : : //
11 : : // Creation Date :
12 : : //
13 : : // Owner :
14 : : //-------------------------------------------------------------------------
15 : :
16 : : #include <stdio.h>
17 : : #include <string.h>
18 : : #include <math.h>
19 : : #include <assert.h>
20 : :
21 : : #include "CubitDefines.h"
22 : : #include "CubitMessage.hpp"
23 : : #include "CubitBox.hpp"
24 : :
25 : : #include "Body.hpp"
26 : : #include "RefVolume.hpp"
27 : : #include "RefFace.hpp"
28 : : #include "RefEdge.hpp"
29 : : #include "RefVertex.hpp"
30 : : #include "CoVolume.hpp"
31 : : #include "Shell.hpp"
32 : :
33 : : // tools
34 : : #include "RefEntityFactory.hpp"
35 : : #include "GeometryQueryTool.hpp"
36 : : #include "ModelQueryEngine.hpp"
37 : :
38 : : // lists
39 : : #include "DLIList.hpp"
40 : :
41 : : #include "Lump.hpp"
42 : :
43 : : //-------------------------------------------------------------------------
44 : : // Purpose : Constructor with a pointer to a Lump
45 : : //
46 : : // Special Notes :
47 : : //
48 : : // Creator : Xuchen Liu
49 : : //
50 : : // Creation Date : 07/11/96
51 : : //-------------------------------------------------------------------------
52 : 5692 : RefVolume::RefVolume(Lump* lumpPtr)
53 : : {
54 : : // Set the GeometryEntity pointer
55 [ + - ]: 2846 : if (lumpPtr != NULL)
56 : : {
57 [ + - ]: 2846 : set_geometry_entity_ptr(lumpPtr) ;
58 : :
59 : : // Commented-out code from Phil Tuchinsky for FUTURE meshing
60 : : // from a surface mesh with no solid model.
61 : : //
62 : : // hasGeometry = CUBIT_TRUE;
63 : : //
64 : : // initialize the surface mesh entity lists exactly once
65 : : // nodes_boundary ( surfaceNodes );
66 : : // edges_inclusive ( surfaceEdges );
67 : : // faces_inclusive ( surfaceFaces );
68 : : }
69 : : else
70 : : {
71 [ # # ][ # # ]: 0 : PRINT_ERROR("In the RefVolume(Lump*) constructor\n");
[ # # ][ # # ]
72 [ # # ][ # # ]: 0 : PRINT_ERROR(" Input Lump pointer is NULL\n");
[ # # ][ # # ]
73 : 0 : assert(CUBIT_FALSE);
74 : : }
75 : :
76 : : // Initialize the member data
77 [ + - ]: 2846 : initialize();
78 : 2846 : }
79 : :
80 : : //-------------------------------------------------------------------------
81 : : // Purpose : The destructor.
82 : : //
83 : : // Special Notes :
84 : : //
85 : : // Creator : Raikanta Sahu
86 : : //
87 : : // Creation Date : 10/22/96
88 : : //-------------------------------------------------------------------------
89 : 5037 : RefVolume::~RefVolume()
90 : : {
91 [ - + ]: 3358 : }
92 : :
93 : : //-------------------------------------------------------------------------
94 : : // Purpose : Return a pointer to the Lump associated with a volume.
95 : : //
96 : : // Special Notes :
97 : : //
98 : : // Creator : Xuechen Liu
99 : : //
100 : : // Creation Date : 08/02/96
101 : : //-------------------------------------------------------------------------
102 : :
103 : 358 : Lump* RefVolume::get_lump_ptr()
104 : : {
105 [ - + ]: 358 : return CAST_TO(get_geometry_entity_ptr(), Lump);
106 : : }
107 : :
108 : 0 : Lump const* RefVolume::get_lump_ptr() const
109 : : {
110 [ # # ]: 0 : return CAST_TO(get_geometry_entity_ptr(), Lump);
111 : : }
112 : :
113 : : //-------------------------------------------------------------------------
114 : : // Purpose : Get parent Body
115 : : //
116 : : // Special Notes :
117 : : //
118 : : // Creator : Jason Kraftcheck
119 : : //
120 : : // Creation Date : 02/11/03
121 : : //-------------------------------------------------------------------------
122 : 0 : Body* RefVolume::get_body_ptr()
123 : : {
124 : 0 : SenseEntity* co_volume_ptr = get_first_sense_entity_ptr();
125 : :
126 [ # # ]: 0 : if (!co_volume_ptr // no covolume
127 [ # # ][ # # ]: 0 : || co_volume_ptr->next_on_bte() ) // multiple covolumes )
128 : : {
129 [ # # ]: 0 : PRINT_ERROR("%s:%d RefVolume %d has other than one parent CoVolume.\n"
130 : : "This is a BUG -- please report it.\n",
131 [ # # ]: 0 : __FILE__, __LINE__, id() );
132 : 0 : return 0;
133 : : }
134 : :
135 [ # # ]: 0 : return dynamic_cast<Body*>(co_volume_ptr->get_grouping_entity_ptr());
136 : : }
137 : :
138 : 0 : int RefVolume::genus()
139 : : {
140 : : int i;
141 [ # # ]: 0 : DLIList<RefFace*> faces;
142 [ # # ]: 0 : ref_faces(faces);
143 : 0 : int gs = 0;
144 [ # # ][ # # ]: 0 : for (i = faces.size(); i > 0; i--)
145 [ # # ][ # # ]: 0 : gs += faces.get_and_step()->genus();
146 : :
147 [ # # ][ # # ]: 0 : return 1 - (num_ref_vertices() - num_ref_edges() + faces.size() - gs)/2;
[ # # ][ # # ]
148 : : }
149 : :
150 : 0 : CubitVector RefVolume::center_point()
151 : : {
152 [ # # ]: 0 : return bounding_box().center();
153 : : }
154 : :
155 : 1261 : int RefVolume::dimension() const
156 : : {
157 : 1261 : return 3;
158 : : }
159 : :
160 : 0 : CubitStatus RefVolume::mass_properties( CubitVector ¢roid, double &volume )
161 : : {
162 [ # # ]: 0 : DLIList<Body*> bodies;
163 [ # # ]: 0 : this->bodies( bodies );
164 [ # # ][ # # ]: 0 : if( bodies.get()->is_sheet_body() )
[ # # ]
165 : : {
166 [ # # ]: 0 : centroid.set(0,0,0);
167 : 0 : volume = 0;
168 : 0 : return CUBIT_SUCCESS;
169 : : }
170 : : else
171 : : {
172 [ # # ]: 0 : Lump *lump = get_lump_ptr();
173 [ # # ]: 0 : return lump->mass_properties( centroid, volume );
174 [ # # ]: 0 : }
175 : : }
176 : :
177 : 0 : CubitStatus RefVolume::mass_properties( CubitVector principal_axes[3],
178 : : CubitVector &principal_moments,
179 : : CubitVector ¢roid,
180 : : double &volume )
181 : : {
182 [ # # ]: 0 : DLIList<Body*> bodies;
183 [ # # ]: 0 : this->bodies( bodies );
184 [ # # ][ # # ]: 0 : if( bodies.get()->is_sheet_body() )
[ # # ]
185 : : {
186 [ # # ]: 0 : centroid.set(0,0,0);
187 : 0 : volume = 0;
188 : 0 : return CUBIT_SUCCESS;
189 : : }
190 : : else
191 : : {
192 [ # # ]: 0 : Lump *lump = get_lump_ptr();
193 [ # # ]: 0 : return lump->mass_properties( principal_axes, principal_moments, centroid, volume );
194 [ # # ]: 0 : }
195 : : }
196 : :
197 : 0 : CubitString RefVolume::measure_label()
198 : : {
199 : 0 : return "volume";
200 : : }
201 : :
202 : : // Draws each surface in the volume
203 : : /*
204 : : void RefVolume::draw_my_faces ( int color )
205 : : {
206 : : DLIList<RefFace*> ref_face_list;
207 : : int i;
208 : :
209 : : if (color == CUBIT_DEFAULT_COLOR_INDEX)
210 : : color = this->color();
211 : : ref_faces ( ref_face_list );
212 : : ref_face_list.reset();
213 : : for (i = 0; i < ref_face_list.size(); i++ )
214 : : ref_face_list.get_and_step()->draw(color);
215 : : }
216 : : */
217 : :
218 : : //-------------------------------------------------------------------------
219 : : // Purpose : Initializes member data
220 : : //
221 : : // Special Notes :
222 : : //
223 : : // Creator : Malcolm J. Panthaki
224 : : //
225 : : // Creation Date : 10/07/96
226 : : //-------------------------------------------------------------------------
227 : 2846 : void RefVolume::initialize()
228 : : {
229 : : // Set the Entity and Block IDs for this new RefVolume
230 : 2846 : GeometryEntity* geom_ptr = get_geometry_entity_ptr();
231 : 2846 : int saved_id = geom_ptr->get_saved_id();
232 [ - + ][ # # ]: 2846 : if ( !saved_id || RefEntityFactory::instance()->get_ref_volume(saved_id) )
[ + - ]
233 : : {
234 : 2846 : saved_id = RefEntityFactory::instance()->next_ref_volume_id();
235 : 2846 : geom_ptr->set_saved_id(saved_id);
236 : : }
237 : 2846 : entityId = saved_id;
238 : :
239 : : // read and initialize attributes
240 : 2846 : auto_read_cubit_attrib();
241 : 2846 : auto_actuate_cubit_attrib();
242 : :
243 : : // Assign a default entity name
244 : 2846 : assign_default_name();
245 : 2846 : }
246 : :
247 : : // unmark this face, and
248 : : // recursively unmark all other marked faces sharing an edge with this face.
249 : 0 : void unmark_component( RefFace *face )
250 : : {
251 [ # # ][ # # ]: 0 : assert( face->marked() );
252 [ # # ]: 0 : face->marked( CUBIT_FALSE );
253 [ # # ]: 0 : DLIList<RefEdge*> edges;
254 [ # # ]: 0 : face->ref_edges( edges );
255 [ # # ][ # # ]: 0 : DLIList<RefFace*> edge_faces;
256 : : RefEdge *edge;
257 [ # # ][ # # ]: 0 : for ( int e = edges.size(); e--; )
258 : : {
259 [ # # ]: 0 : edge = edges.get_and_step();
260 [ # # ]: 0 : edge_faces.clean_out();
261 [ # # ]: 0 : edge->ref_faces( edge_faces );
262 [ # # ][ # # ]: 0 : for ( int f = edge_faces.size(); f--; )
263 : : {
264 [ # # ]: 0 : face = edge_faces.get_and_step();
265 [ # # ][ # # ]: 0 : if ( face->marked() )
266 [ # # ]: 0 : unmark_component( face );
267 : : }
268 [ # # ]: 0 : }
269 : 0 : }
270 : :
271 : 0 : int RefVolume::num_boundary_components()
272 : : {
273 : : // get all the surfaces
274 : : // march from one to the next, using shared-ref_edge connectivity
275 : :
276 : 0 : int num_components = 0;
277 [ # # ]: 0 : DLIList<RefFace*> face_list;
278 [ # # ]: 0 : ref_faces( face_list );
279 : :
280 : : // mark them as belonging to this volume and not seen yet.
281 : : int i;
282 : : RefFace *face;
283 [ # # ][ # # ]: 0 : for( i = face_list.size(); i--; )
284 : : {
285 [ # # ]: 0 : face = face_list.get_and_step();
286 [ # # ]: 0 : face->marked( CUBIT_FALSE );
287 : : }
288 : :
289 [ # # ][ # # ]: 0 : for ( i = face_list.size(); i--; )
290 : : {
291 [ # # ]: 0 : face = face_list.get_and_step();
292 [ # # ][ # # ]: 0 : assert( !face->marked() );
293 [ # # ]: 0 : face->marked( CUBIT_TRUE );
294 : : }
295 : :
296 [ # # ][ # # ]: 0 : for ( i = face_list.size(); i--; )
297 : : {
298 [ # # ]: 0 : face = face_list.get_and_step();
299 [ # # ][ # # ]: 0 : if ( face->marked() )
300 : : {
301 : 0 : num_components++;
302 [ # # ]: 0 : unmark_component( face );
303 : : }
304 : : }
305 [ # # ]: 0 : return num_components;
306 : : }
307 : :
308 : 0 : CubitBoolean RefVolume::about_spatially_equal(
309 : : RefVolume* ref_vol_ptr_2,double tolerance_factor)
310 : : {
311 : : // Get rid of the trivial case...
312 [ # # ]: 0 : if( this == ref_vol_ptr_2)
313 : : {
314 : 0 : return CUBIT_TRUE;
315 : : }
316 : :
317 [ # # ][ # # ]: 0 : DLIList<RefEdge*> ref_edge_list_1, ref_edge_list_2;
[ # # ]
318 [ # # ]: 0 : this->ref_edges( ref_edge_list_1 );
319 [ # # ]: 0 : ref_vol_ptr_2->ref_edges( ref_edge_list_2 );
320 : :
321 : : //compare the size of the two lists.
322 [ # # ][ # # ]: 0 : if ( ref_edge_list_1.size() != ref_edge_list_2.size() )
[ # # ]
323 : 0 : return CUBIT_FALSE;
324 : :
325 [ # # ][ # # ]: 0 : DLIList<RefFace*> ref_face_list_1, ref_face_list_2;
[ # # ][ # # ]
326 [ # # ]: 0 : this->ref_faces( ref_face_list_1 );
327 [ # # ]: 0 : ref_vol_ptr_2->ref_faces( ref_face_list_2 );
328 : :
329 : : //compare the size of the two lists.
330 [ # # ][ # # ]: 0 : if ( ref_face_list_1.size() != ref_face_list_2.size() )
[ # # ]
331 : 0 : return CUBIT_FALSE;
332 : :
333 : :
334 : : //This compare precedure does the following :
335 : : // 1. Test the bounding boxes of the 2 volumes for equality;
336 : :
337 [ # # ][ # # ]: 0 : CubitBox box_1 = this->bounding_box();
338 [ # # ][ # # ]: 0 : CubitBox box_2 = ref_vol_ptr_2->bounding_box();
339 : :
340 : 0 : CubitBoolean passes_b_box = CUBIT_FALSE;
341 : :
342 : : // This test checks to see that the min and max vectors of the
343 : : // bounding boxes are within 10% of the length of the bbox diagonal.
344 : : // Note that this assumes the default values of resabs=1e-6 and
345 : : // tolerance_factor=500
346 : :
347 : : CubitVector tol_vect(
348 [ # # ][ # # ]: 0 : CUBIT_MIN(box_1.x_range(), box_2.x_range()),
349 [ # # ][ # # ]: 0 : CUBIT_MIN(box_1.y_range(), box_2.y_range()),
350 [ # # ][ # # ]: 0 : CUBIT_MIN(box_1.z_range(), box_2.z_range()) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
351 [ # # ]: 0 : tol_vect *= 200.0 * tolerance_factor * GEOMETRY_RESABS;
352 [ # # ][ # # ]: 0 : if( tol_vect.x() < GEOMETRY_RESABS )
353 [ # # ]: 0 : tol_vect.x(GEOMETRY_RESABS);
354 [ # # ][ # # ]: 0 : if( tol_vect.y() < GEOMETRY_RESABS )
355 [ # # ]: 0 : tol_vect.y(GEOMETRY_RESABS);
356 [ # # ][ # # ]: 0 : if( tol_vect.z() < GEOMETRY_RESABS )
357 [ # # ]: 0 : tol_vect.z(GEOMETRY_RESABS);
358 : :
359 [ # # ][ # # ]: 0 : if((fabs(box_1.minimum().x() - box_2.minimum().x()) < tol_vect.x()) &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # ]
360 [ # # ][ # # ]: 0 : (fabs(box_1.maximum().x() - box_2.maximum().x()) < tol_vect.x()) &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
361 [ # # ][ # # ]: 0 : (fabs(box_1.minimum().y() - box_2.minimum().y()) < tol_vect.y()) &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
362 [ # # ][ # # ]: 0 : (fabs(box_1.maximum().y() - box_2.maximum().y()) < tol_vect.y()) &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
363 [ # # ][ # # ]: 0 : (fabs(box_1.minimum().z() - box_2.minimum().z()) < tol_vect.z()) &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
364 [ # # ][ # # ]: 0 : (fabs(box_1.maximum().z() - box_2.maximum().z()) < tol_vect.z()))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
365 : : {
366 : 0 : passes_b_box = CUBIT_TRUE;
367 : : }
368 : :
369 [ # # ]: 0 : return passes_b_box;
370 : : }
371 : :
372 : : //-------------------------------------------------------------------------
373 : : // Purpose : Check if all shells are sheets
374 : : //
375 : : // Special Notes :
376 : : //
377 : : // Creator : Jason Kraftcheck
378 : : //
379 : : // Creation Date : 01/15/04
380 : : //-------------------------------------------------------------------------
381 : 55 : CubitBoolean RefVolume::is_sheet()
382 : : {
383 [ + - ]: 55 : DLIList<Shell*> shells;
384 [ + - ]: 55 : this->shells(shells);
385 [ + - ][ + + ]: 88 : while (shells.size())
386 [ + - ][ + - ]: 55 : if (!shells.pop()->is_sheet())
[ + + ]
387 : 22 : return CUBIT_FALSE;
388 [ + - ]: 55 : return CUBIT_TRUE;
389 : : }
390 : :
391 : 0 : int RefVolume::validate()
392 : : {
393 : : //- This function determines whether the entity is valid.
394 : : //- Several types of checks can be done,
395 : 0 : int error = 0;
396 : :
397 : : // Perform general RefEntity checks (measure > 0)
398 : 0 : error += RefEntity::validate();
399 : :
400 : : // Pass through to surface and add in its validation
401 : 0 : Lump *lump = this->get_lump_ptr();
402 : :
403 : : // check surface ptr
404 [ # # ]: 0 : if (lump != NULL) {
405 : : // Check underlying surface
406 [ # # ]: 0 : DLIList <TopologyEntity*> bad_entities;
407 [ # # ][ # # ]: 0 : error += lump->validate(entity_name(), bad_entities);
[ # # ][ # # ]
408 : : } else {
409 [ # # ][ # # ]: 0 : PRINT_WARNING("\tWARNING: Null underlying volume for %s, (%s %d)\n",
[ # # ][ # # ]
410 [ # # ]: 0 : entity_name().c_str(), class_name(), id());
411 : 0 : error++;
412 : : }
413 : 0 : return error;
414 : : }
415 : :
416 : 0 : void RefVolume::get_parent_ref_entities(DLIList<RefEntity*>& entity_list)
417 : : {
418 : :
419 : : // First get the type of RefEntity that is a child of "this" one
420 [ # # ]: 0 : DagType parent_type = get_parent_ref_entity_type();;
421 : :
422 [ # # ]: 0 : DLIList<TopologyEntity*> tempList ;
423 : :
424 : : CubitStatus result = ModelQueryEngine::instance()->
425 [ # # ][ # # ]: 0 : query_model( *this, parent_type, tempList );
426 [ # # ]: 0 : if (result == CUBIT_FAILURE)
427 : : {
428 [ # # ][ # # ]: 0 : PRINT_ERROR("In RefEntity::get_parent_ref_entities\n");
[ # # ][ # # ]
429 [ # # ][ # # ]: 0 : PRINT_ERROR(" Query failed for unknown reason.\n");
[ # # ][ # # ]
430 : 0 : return;
431 : : }
432 : :
433 [ # # ]: 0 : entity_list.clean_out();
434 [ # # ][ # # ]: 0 : for(int i=0; i<tempList.size(); i++)
[ # # ][ # # ]
435 : : {
436 [ # # ][ # # ]: 0 : entity_list.append(static_cast<ParentType*>(tempList[i]));
[ # # ]
437 : 0 : }
438 [ + - ][ + - ]: 6540 : }
|