Branch data Line data Source code
1 : : //-------------------------------------------------------------------------
2 : : // Filename : FacetShell.cpp
3 : : //
4 : : // Purpose :
5 : : //
6 : : // Special Notes :
7 : : //
8 : : // Creator : David White
9 : : //
10 : : // Creation Date : 7/18/2000
11 : : //
12 : : //-------------------------------------------------------------------------
13 : :
14 : : // ********** BEGIN STANDARD INCLUDES **********
15 : : #include <stddef.h>
16 : : // ********** END STANDARD INCLUDES **********
17 : :
18 : : // ********** BEGIN CUBIT INCLUDES **********
19 : : #include "CastTo.hpp"
20 : : #include "CubitUtil.hpp"
21 : :
22 : : #include "FacetQueryEngine.hpp"
23 : : #include "FacetShell.hpp"
24 : : #include "ShellSM.hpp"
25 : : #include "Lump.hpp"
26 : : #include "Surface.hpp"
27 : :
28 : : #include "FacetBody.hpp"
29 : : #include "FacetLump.hpp"
30 : : #include "FacetSurface.hpp"
31 : : #include "FacetLoop.hpp"
32 : : #include "FacetCoEdge.hpp"
33 : : #include "FacetCurve.hpp"
34 : : #include "FacetPoint.hpp"
35 : : #include "FacetEvalTool.hpp"
36 : : #include "CubitPoint.hpp"
37 : : #include "CubitFacetEdge.hpp"
38 : : #include "GfxDebug.hpp"
39 : :
40 : : // ********** END CUBIT INCLUDES **********
41 : :
42 : : // ********** BEGIN STATIC DECLARATIONS **********
43 : : // ********** END STATIC DECLARATIONS **********
44 : :
45 : : // ********** BEGIN PUBLIC FUNCTIONS **********
46 : :
47 : : //-------------------------------------------------------------------------
48 : : // Purpose : A constructor with a pointer to a SHELL.
49 : : //
50 : : // Special Notes :
51 : : //
52 : : //-------------------------------------------------------------------------
53 : 77 : FacetShell::FacetShell(Lump* my_lump,
54 [ + - ]: 77 : DLIList<Surface*> &my_surfs )
55 : : {
56 : 77 : myLump = my_lump;
57 [ + - ]: 77 : mySurfs += my_surfs;
58 : 77 : }
59 : :
60 : : //-------------------------------------------------------------------------
61 : : // Purpose : A constructor with list of surfaces.
62 : : //
63 : : // Special Notes : For use with save/restore
64 : : //
65 : : //-------------------------------------------------------------------------
66 [ + - ]: 44 : FacetShell::FacetShell( DLIList<Surface*> &my_surfs )
67 : : {
68 : 22 : myLump = NULL;
69 [ + - ]: 22 : mySurfs += my_surfs;
70 : 22 : }
71 : : //-------------------------------------------------------------------------
72 : : // Purpose : The destructor.
73 : : //
74 : : // Special Notes :
75 : : //
76 : : //-------------------------------------------------------------------------
77 [ # # ]: 0 : FacetShell::~FacetShell()
78 [ # # ]: 0 : {}
79 : :
80 : :
81 : : //-------------------------------------------------------------------------
82 : : // Purpose : Get geometry modeling engine: FacetQueryEngine
83 : : //
84 : : // Special Notes :
85 : : //
86 : : //-------------------------------------------------------------------------
87 : : GeometryQueryEngine*
88 : 0 : FacetShell::get_geometry_query_engine() const
89 : : {
90 : 0 : return FacetQueryEngine::instance();
91 : : }
92 : :
93 : 0 : void FacetShell::append_simple_attribute_virt(const CubitSimpleAttrib&)
94 : : {
95 : 0 : }
96 : 0 : void FacetShell::remove_simple_attribute_virt(const CubitSimpleAttrib& )
97 : : {
98 : 0 : }
99 : 0 : void FacetShell::remove_all_simple_attribute_virt()
100 : : {
101 : 0 : }
102 : 0 : CubitStatus FacetShell::get_simple_attribute(DLIList<CubitSimpleAttrib>&)
103 : : {
104 : 0 : return CUBIT_FAILURE;
105 : : }
106 : 0 : CubitStatus FacetShell::get_simple_attribute(const CubitString&,
107 : : DLIList<CubitSimpleAttrib>&)
108 : 0 : { return CUBIT_FAILURE; }
109 : :
110 : : /*
111 : : void FacetShell::bodysms(DLIList<BodySM*> &bodies)
112 : : {
113 : : if (myLump)
114 : : myLump->bodysms(bodies);
115 : : }
116 : :
117 : : void FacetShell::lumps(DLIList<Lump*> &lumps)
118 : : {
119 : : lumps.append_unique(myLump);
120 : : }
121 : :
122 : : void FacetShell::shellsms(DLIList<ShellSM*> &shellsms)
123 : : {
124 : : shellsms.append_unique(this);
125 : : }
126 : :
127 : : void FacetShell::surfaces(DLIList<Surface*> &surfaces)
128 : : {
129 : : int ii;
130 : : for ( ii = mySurfs.size(); ii > 0; ii-- )
131 : : {
132 : : surfaces.append_unique(mySurfs.get_and_step());
133 : : }
134 : : }
135 : :
136 : : void FacetShell::loopsms(DLIList<LoopSM*> &loopsms)
137 : : {
138 : : int ii;
139 : : for ( ii = mySurfs.size(); ii > 0; ii-- )
140 : : {
141 : : mySurfs.get_and_step()->loopsms(loopsms);
142 : : }
143 : : }
144 : :
145 : : void FacetShell::curves(DLIList<Curve*> &curves)
146 : : {
147 : : int ii;
148 : : for ( ii = mySurfs.size(); ii > 0; ii-- )
149 : : {
150 : : mySurfs.get_and_step()->curves(curves);
151 : : }
152 : : }
153 : :
154 : : void FacetShell::coedgesms(DLIList<CoEdgeSM*> &coedgesms)
155 : : {
156 : : int ii;
157 : : for ( ii = mySurfs.size(); ii > 0; ii-- )
158 : : {
159 : : mySurfs.get_and_step()->coedgesms(coedgesms);
160 : : }
161 : : }
162 : :
163 : : void FacetShell::points(DLIList<Point*> &points)
164 : : {
165 : : int ii;
166 : : for ( ii = mySurfs.size(); ii > 0; ii-- )
167 : : {
168 : : mySurfs.get_and_step()->points(points);
169 : : }
170 : : }
171 : : */
172 : :
173 : 99 : void FacetShell::add_lump(Lump* lump_ptr)
174 : : {
175 [ - + ]: 99 : assert(NULL == myLump);
176 : 99 : myLump = lump_ptr;
177 : 99 : }
178 : :
179 : :
180 : : //-------------------------------------------------------------------------
181 : : // Purpose : Query solid modeler topology
182 : : //
183 : : // Special Notes :
184 : : //
185 : : // Creator : Jason Kraftcheck
186 : : //
187 : : // Creation Date :
188 : : //-------------------------------------------------------------------------
189 : 0 : void FacetShell::get_parents_virt( DLIList<TopologyBridge*>& parents )
190 [ # # ]: 0 : { parents.append(myLump); }
191 : 352 : void FacetShell::get_children_virt( DLIList<TopologyBridge*>& children )
192 [ + - ][ + + ]: 2343 : { CAST_LIST_TO_PARENT( mySurfs, children ); }
193 : :
194 : :
195 : 0 : void FacetShell::get_lumps( DLIList<FacetLump*>& result_list )
196 : : {
197 [ # # ]: 0 : FacetLump* lump = dynamic_cast<FacetLump*>(myLump);
198 [ # # ]: 0 : if (lump)
199 [ # # ]: 0 : result_list.append(lump);
200 : 0 : }
201 : :
202 : 154 : void FacetShell::get_surfaces( DLIList<FacetSurface*>& result_list )
203 : : {
204 : 154 : mySurfs.reset();
205 [ + + ]: 836 : for ( int i = 0; i < mySurfs.size(); i++ )
206 [ + - ][ - + ]: 682 : if ( FacetSurface* surf = dynamic_cast<FacetSurface*>(mySurfs.next(i)) )
[ + - ]
207 [ + - ]: 682 : result_list.append_unique(surf);
208 : 154 : }
209 : :
210 : :
211 : 0 : void FacetShell::get_coedges( DLIList<FacetCoEdge*>& result_list )
212 : : {
213 [ # # ]: 0 : DLIList<FacetSurface*> surface_list;
214 [ # # ]: 0 : get_surfaces( surface_list );
215 [ # # ]: 0 : surface_list.reset();
216 [ # # ][ # # ]: 0 : for ( int i = 0; i < surface_list.size(); i++ )
217 [ # # ][ # # ]: 0 : surface_list.next(i)->get_coedges( result_list );
[ # # ]
218 : 0 : }
219 : :
220 : 0 : void FacetShell::get_curves( DLIList<FacetCurve*>& result_list )
221 : : {
222 [ # # ]: 0 : DLIList<FacetCoEdge*> coedge_list;
223 [ # # ]: 0 : get_coedges( coedge_list );
224 [ # # ]: 0 : coedge_list.reset();
225 [ # # ][ # # ]: 0 : for ( int i = coedge_list.size(); i--; )
226 : : {
227 [ # # ]: 0 : FacetCoEdge* coedge = coedge_list.get_and_step();
228 [ # # ][ # # ]: 0 : FacetCurve* curve = dynamic_cast<FacetCurve*>(coedge->curve());
229 [ # # ]: 0 : if (curve)
230 [ # # ]: 0 : result_list.append_unique(curve);
231 [ # # ]: 0 : }
232 : 0 : }
233 : :
234 : : //-------------------------------------------------------------------------
235 : : // Purpose : Disconnect input surfaces from "this" shell
236 : : //
237 : : // Special Notes :
238 : : //
239 : : // Creator : Corey Ernst
240 : : //
241 : : // Creation Date : 08/31/04
242 : : //-------------------------------------------------------------------------
243 : 0 : void FacetShell::disconnect_surfaces( DLIList<FacetSurface*> &surfs_to_disconnect )
244 : : {
245 [ # # ]: 0 : for (int i = surfs_to_disconnect.size(); i--; )
246 : : {
247 : 0 : FacetSurface* surface = surfs_to_disconnect.get_and_step();
248 [ # # ][ # # ]: 0 : if( mySurfs.move_to( dynamic_cast<Surface*>(surface) ) )
249 : 0 : mySurfs.change_to(NULL);
250 : :
251 [ # # ]: 0 : if (surface)
252 : 0 : surface->remove_shell(this);
253 : : }
254 [ # # ]: 0 : mySurfs.remove_all_with_value( NULL );
255 : 0 : }
256 : :
257 : :
258 : : //-------------------------------------------------------------------------
259 : : // Purpose : Tear down topology
260 : : //
261 : : // Special Notes :
262 : : //
263 : : // Creator : Jason Kraftcheck
264 : : //
265 : : // Creation Date : 09/29/03
266 : : //-------------------------------------------------------------------------
267 : 0 : void FacetShell::disconnect_all_surfaces()
268 : : {
269 : 0 : mySurfs.reset();
270 [ # # ]: 0 : for (int i = mySurfs.size(); i--; )
271 : : {
272 : 0 : Surface* sm_ptr = mySurfs.get_and_step();
273 [ # # ]: 0 : FacetSurface* surface = dynamic_cast<FacetSurface*>(sm_ptr);
274 [ # # ]: 0 : if (surface)
275 : 0 : surface->remove_shell(this);
276 : : }
277 : 0 : mySurfs.clean_out();
278 : 0 : }
279 : :
280 : : //-------------------------------------------------------------------------
281 : : // Purpose : Flip surface-use sense
282 : : //
283 : : // Special Notes :
284 : : //
285 : : // Creator : Jason Kraftcheck
286 : : //
287 : : // Creation Date : 05/26/04
288 : : //-------------------------------------------------------------------------
289 : 0 : void FacetShell::reverse()
290 : : {
291 [ # # ]: 0 : for (int i = mySurfs.size(); i--; )
292 : : {
293 [ # # ]: 0 : FacetSurface* surf = dynamic_cast<FacetSurface*>(mySurfs.next(i));
294 : 0 : CubitSense sense = surf->get_shell_sense( this );
295 [ # # ]: 0 : assert( CUBIT_UNKNOWN != sense );
296 : 0 : surf->set_shell_sense( this, CubitUtil::opposite_sense( sense ) );
297 : : }
298 : 0 : }
299 : :
300 : : //-------------------------------------------------------------------------
301 : : // Purpose : Actually flip the underlying surfaces
302 : : //
303 : : // Special Notes :
304 : : //
305 : : // Creator : Michael Brewer
306 : : //
307 : : // Creation Date : 03/22/05
308 : : //-------------------------------------------------------------------------
309 : 0 : void FacetShell::reverse_surfaces()
310 : : {
311 [ # # ]: 0 : for (int i = mySurfs.size(); i--; )
312 : : {
313 [ # # ]: 0 : FacetSurface* surf = dynamic_cast<FacetSurface*>(mySurfs.next(i));
314 : 0 : surf->reverse_sense();
315 : : }
316 : 0 : }
317 : : //-------------------------------------------------------------------------
318 : : // Purpose : Determines if point is contained within shell
319 : : //
320 : : // Special Notes : If the shell is a void, it contains all points it doesn't enclose
321 : : //
322 : : // Creator : Corey Ernst
323 : : //
324 : : // Creation Date : 09/01/04
325 : : //-------------------------------------------------------------------------
326 : 0 : CubitPointContainment FacetShell::point_containment(
327 : : const CubitVector &input_point,
328 : : double tolerance )
329 : : {
330 : : //just to avoid crashes, make sure we have surfaces in this list.
331 [ # # ][ # # ]: 0 : if(mySurfs.size() < 1){
332 : 0 : return CUBIT_PNT_OUTSIDE;
333 : : }
334 [ # # ][ # # ]: 0 : CubitVector closest_location, point = input_point;
335 [ # # ][ # # ]: 0 : FacetSurface *closest_surf = dynamic_cast<FacetSurface*>(mySurfs.get_and_step());
336 : : FacetSurface *tmp_surf;
337 [ # # ][ # # ]: 0 : closest_surf->closest_point_trimmed( point, closest_location );
338 [ # # ]: 0 : double shortest_dist = point.distance_between( closest_location );
339 : :
340 : : int i;
341 : : //Look through all this shell's surfaces to find the closest
342 : : //surface to input_point
343 : :
344 [ # # ][ # # ]: 0 : for(i=mySurfs.size()-1; i--;)
345 : : {
346 [ # # ]: 0 : CubitVector tmp_closest_location;
347 [ # # ][ # # ]: 0 : tmp_surf = dynamic_cast<FacetSurface*>(mySurfs.get_and_step());
348 [ # # ][ # # ]: 0 : tmp_surf->closest_point_trimmed( point, tmp_closest_location );
349 : :
350 [ # # ]: 0 : double tmp_shortest_dist = point.distance_between( tmp_closest_location );
351 [ # # ]: 0 : if( tmp_shortest_dist < shortest_dist )
352 : : {
353 [ # # ]: 0 : closest_location = tmp_closest_location;
354 : 0 : closest_surf = tmp_surf;
355 : 0 : shortest_dist = tmp_shortest_dist;
356 : : }
357 : : }
358 : :
359 [ # # ]: 0 : if( tolerance < 0 )
360 : 0 : tolerance = GEOMETRY_RESABS;
361 : :
362 : : //determine if it's on the surface, inside or outside
363 [ # # ]: 0 : if( shortest_dist <= tolerance )
364 : 0 : return CUBIT_PNT_BOUNDARY;
365 : :
366 : : //find the closest facet on that surface to input_point
367 [ # # ][ # # ]: 0 : CubitFacet *closest_facet = closest_surf->get_eval_tool()->closest_facet( closest_location );
368 : :
369 : : //get the coordinates of the closest point
370 : 0 : CubitPoint *pt1 = NULL;
371 : 0 : CubitPoint *pt2 = NULL;
372 [ # # ]: 0 : closest_facet->closest_point_trimmed( point, closest_location, pt1, pt2 );
373 : :
374 [ # # ]: 0 : CubitVector normal;
375 : 0 : CubitPoint *on_point = NULL;
376 : : //case 1: point is closest to an edge of the facet
377 [ # # ][ # # ]: 0 : if( pt1 || pt2 )
378 : : {
379 : : //only returned one, so the it is closest to a node
380 [ # # ]: 0 : if(!pt2){
381 : 0 : on_point = pt1;
382 : : }
383 [ # # ]: 0 : else if(!pt1){
384 : 0 : on_point = pt2;
385 : : }
386 : : else{//double-check that we are not closest to a single node
387 : :
388 [ # # ][ # # ]: 0 : if((pt1->coordinates().distance_between(closest_location)) <= tolerance )
[ # # ]
389 : 0 : on_point = pt1;
390 [ # # ][ # # ]: 0 : else if((pt2->coordinates().distance_between(closest_location)) <= tolerance )
[ # # ]
391 : 0 : on_point = pt2;
392 : : }
393 : :
394 [ # # ]: 0 : if( on_point )
395 : : {
396 : : //get all facets that share this point
397 [ # # ]: 0 : DLIList<CubitFacet*> facets_sharing_point;
398 [ # # ]: 0 : on_point->facets( facets_sharing_point );
399 : :
400 [ # # ][ # # ]: 0 : for(i=facets_sharing_point.size(); i--; )
401 [ # # ][ # # ]: 0 : normal += facets_sharing_point.get_and_step()->normal();
[ # # ]
402 : :
403 : : //average the normals of all these facets
404 [ # # ][ # # ]: 0 : normal /= facets_sharing_point.size();
[ # # ]
405 : : }
406 : : else
407 : : {
408 : : //case 2: get the 2 normals of the 2 neighboring facets and average them
409 : : int index;
410 : : CubitFacetEdge *shared_facet_edge;
411 [ # # ]: 0 : shared_facet_edge = closest_facet->edge_from_pts( pt1, pt2, index);
412 [ # # ]: 0 : CubitFacet *other_facet = shared_facet_edge->other_facet( closest_facet );
413 [ # # ]: 0 : if(!other_facet){
414 [ # # ][ # # ]: 0 : PRINT_ERROR("Edge is not connected to two facets.\n");
[ # # ][ # # ]
415 [ # # ][ # # ]: 0 : normal = closest_facet->normal();
416 : : }
417 : : else{
418 [ # # ][ # # ]: 0 : normal = ( closest_facet->normal() + other_facet->normal() ) / 2;
[ # # ][ # # ]
[ # # ]
419 : : }
420 : 0 : }
421 : : }
422 : : else
423 : : {
424 : : //case 3: just get the normal of this facet
425 [ # # ][ # # ]: 0 : normal = closest_facet->normal();
426 : : }
427 : :
428 : : // if ( closest_surf->get_relative_surface_sense() == CUBIT_REVERSED )
429 : : // {
430 : : // PRINT_WARNING("mbrewer: This shouldn't happen anymore.\n");
431 : : // normal = -1.0*( normal );
432 : : // }
433 : :
434 : 0 : ShellSM *shell_sm = static_cast<ShellSM*>(this);
435 [ # # ][ # # ]: 0 : if( closest_surf->get_shell_sense( shell_sm ) == CUBIT_REVERSED )
436 : : {
437 [ # # ][ # # ]: 0 : normal = -1.0*( normal );
438 : : }
439 [ # # ][ # # ]: 0 : if( (point-closest_location)%(normal) > 0 )
[ # # ]
440 : 0 : return CUBIT_PNT_OUTSIDE;
441 : : else
442 : 0 : return CUBIT_PNT_INSIDE;
443 : : }
444 : :
445 : : //Determine whether this shell is a sheet (ie, closed or not)
446 : 0 : CubitBoolean FacetShell::is_sheet()
447 : : {
448 : : //get a list of all the facets in the sheet
449 [ # # ]: 0 : DLIList<CubitFacet*> facet_list;
450 : : int i;
451 [ # # ][ # # ]: 0 : for (i = mySurfs.size(); i--; )
452 : : {
453 [ # # ][ # # ]: 0 : FacetSurface* surf = dynamic_cast<FacetSurface*>(mySurfs.next(i));
454 [ # # ]: 0 : surf->tris(facet_list);
455 : : }
456 : : //should be unique... doesn't hurt anything if it isn't
457 : : //facet_list.uniquify_ordered();
458 : : CubitFacet* this_facet;
459 : : CubitPoint* node_1;
460 : : CubitPoint* node_2;
461 : : CubitPoint* node_3;
462 : : //if any of the facets don't have another facet across a given
463 : : // edge... this is a sheet shell because it isn't closed.
464 [ # # ][ # # ]: 0 : for (i = facet_list.size(); i--; ){
465 [ # # ]: 0 : this_facet=facet_list.get_and_step();
466 [ # # ]: 0 : if(!this_facet){
467 [ # # ][ # # ]: 0 : PRINT_ERROR("Unexpected NULL pointer.");
[ # # ][ # # ]
468 : 0 : return CUBIT_TRUE;
469 : : }
470 [ # # ]: 0 : this_facet->tri_nodes(node_1,node_2,node_3);
471 [ # # ][ # # ]: 0 : if(!this_facet->shared_facet( node_1, node_2 ) ||
[ # # ]
472 [ # # ][ # # ]: 0 : !this_facet->shared_facet( node_1, node_3 ) ||
[ # # ]
473 [ # # ]: 0 : !this_facet->shared_facet( node_2, node_3 ) ){
474 : 0 : return CUBIT_TRUE;
475 : : }
476 : : }
477 : : //otherwise we made it through without finding a gap so it is close...
478 : : // thus not a sheet.
479 [ # # ]: 0 : return CUBIT_FALSE;
480 [ + - ][ + - ]: 6540 : }
481 : :
482 : :
483 : :
484 : : // ********** END PUBLIC FUNCTIONS **********
485 : :
486 : : // ********** BEGIN PROTECTED FUNCTIONS **********
487 : : // ********** END PROTECTED FUNCTIONS **********
488 : :
489 : : // ********** BEGIN PRIVATE FUNCTIONS **********
490 : : // ********** END PRIVATE FUNCTIONS **********
491 : :
492 : : // ********** BEGIN HELPER CLASSES **********
493 : : // ********** END HELPER CLASSES **********
494 : :
495 : : // ********** BEGIN EXTERN FUNCTIONS **********
496 : : // ********** END EXTERN FUNCTIONS **********
497 : :
498 : : // ********** BEGIN STATIC FUNCTIONS **********
499 : : // ********** END STATIC FUNCTIONS **********
500 : :
|