Branch data Line data Source code
1 : : #include "PartitionShell.hpp"
2 : : #include "PartitionLump.hpp"
3 : : #include "PartitionSurface.hpp"
4 : : #include "VirtualQueryEngine.hpp"
5 : : #include "CubitFacetData.hpp"
6 : :
7 : 0 : PartitionShell::PartitionShell( )
8 : 0 : : myLump(0), lumpNext(0), firstCoSurf(0)
9 : 0 : { }
10 : :
11 : 0 : PartitionShell::~PartitionShell()
12 : : {
13 [ # # ]: 0 : assert( !myLump );
14 [ # # ]: 0 : remove_all_surfaces();
15 [ # # ]: 0 : }
16 : :
17 : 0 : CubitStatus PartitionShell::add( PartitionCoSurf* cosurf )
18 : : {
19 [ # # ][ # # ]: 0 : if( cosurf->myShell || cosurf->shellNext )
20 : : {
21 [ # # ][ # # ]: 0 : assert(!cosurf->myShell && !cosurf->shellNext);
22 : 0 : return CUBIT_FAILURE;
23 : : }
24 : :
25 : 0 : cosurf->myShell = this;
26 : 0 : cosurf->shellNext = firstCoSurf;
27 : 0 : firstCoSurf = cosurf;
28 : 0 : return CUBIT_SUCCESS;
29 : : }
30 : :
31 : 0 : CubitStatus PartitionShell::remove( PartitionCoSurf* cosurf )
32 : : {
33 [ # # ]: 0 : if( cosurf->myShell != this )
34 : : {
35 [ # # ]: 0 : assert( cosurf->myShell == this );
36 : 0 : return CUBIT_FAILURE;
37 : : }
38 : :
39 [ # # ]: 0 : if( cosurf == firstCoSurf )
40 : : {
41 : 0 : firstCoSurf->shellNext = cosurf->shellNext;
42 : 0 : firstCoSurf = firstCoSurf->shellNext;
43 : : }
44 : : else
45 : : {
46 : 0 : PartitionCoSurf* prev = firstCoSurf;
47 [ # # ][ # # ]: 0 : while( prev && prev->shellNext != cosurf )
48 : 0 : prev = prev->shellNext;
49 : :
50 [ # # ]: 0 : if( !prev ) { assert(0); return CUBIT_FAILURE; }
51 : :
52 : 0 : prev->shellNext = cosurf->shellNext;
53 : : }
54 : :
55 : 0 : cosurf->myShell = 0;
56 : 0 : cosurf->shellNext = 0;
57 : 0 : return CUBIT_SUCCESS;
58 : : }
59 : :
60 : 0 : PartitionCoSurf* PartitionShell::add( PartitionSurface* surf, CubitSense sense )
61 : : {
62 [ # # ]: 0 : PartitionCoSurf* new_cos = new PartitionCoSurf( sense );
63 [ # # ][ # # ]: 0 : if( !surf->add(new_cos) || !this->add(new_cos) )
[ # # ]
64 : : {
65 [ # # ]: 0 : delete new_cos;
66 : 0 : new_cos = 0;
67 : : }
68 : 0 : return new_cos;
69 : : }
70 : :
71 : 0 : PartitionCoSurf* PartitionShell::find_first( const PartitionSurface* surf ) const
72 : : {
73 : 0 : PartitionCoSurf* cos = firstCoSurf;
74 [ # # ][ # # ]: 0 : while( cos && cos->get_surface() != surf )
[ # # ]
75 : 0 : cos = cos->shellNext;
76 : 0 : return cos;
77 : : }
78 : 0 : PartitionCoSurf* PartitionShell::find_next( const PartitionCoSurf* prev ) const
79 : : {
80 : 0 : PartitionCoSurf* cos = prev->shellNext;
81 [ # # ][ # # ]: 0 : while( cos && cos->get_surface() != prev->get_surface() )
[ # # ]
82 : 0 : cos = cos->shellNext;
83 : 0 : return cos;
84 : : }
85 : 0 : CubitSense PartitionShell::find_sense( const PartitionSurface* surf ) const
86 : : {
87 : 0 : PartitionCoSurf* cos = find_first( surf );
88 [ # # ]: 0 : if( ! cos )
89 : 0 : return CUBIT_UNKNOWN;
90 : :
91 : 0 : CubitSense result = cos->sense();
92 [ # # ]: 0 : while( (cos = find_next( cos )) )
93 [ # # ]: 0 : if( cos->sense() != result )
94 : 0 : return CUBIT_UNKNOWN;
95 : :
96 : 0 : return result;
97 : : }
98 : :
99 : :
100 : :
101 : :
102 : 0 : void PartitionShell::remove_all_surfaces( DLIList<PartitionSurface*>* list )
103 : : {
104 [ # # ]: 0 : while( PartitionCoSurf* cosurf = firstCoSurf )
105 : : {
106 [ # # ]: 0 : if( cosurf->get_surface() )
107 : : {
108 [ # # ]: 0 : if( list )
109 [ # # ]: 0 : list->append( cosurf->get_surface() );
110 : 0 : cosurf->get_surface()->remove( cosurf );
111 : : }
112 : 0 : remove( cosurf );
113 [ # # ]: 0 : delete cosurf;
114 : : }
115 : :
116 [ # # ]: 0 : if( list )
117 : 0 : list->uniquify_ordered();
118 : 0 : }
119 : :
120 : 0 : void PartitionShell::get_parents_virt( DLIList<TopologyBridge*>& parents )
121 : : {
122 [ # # ]: 0 : if( myLump )
123 [ # # ]: 0 : parents.append( myLump );
124 : 0 : }
125 : :
126 : 0 : void PartitionShell::get_children_virt( DLIList<TopologyBridge*>& children )
127 : : {
128 : 0 : PartitionCoSurf* cos = 0;
129 [ # # ]: 0 : while( (cos = next_co_surface( cos )) )
130 [ # # ]: 0 : if( cos->get_surface() )
131 [ # # ]: 0 : children.append_unique( cos->get_surface() );
132 : 0 : }
133 : :
134 : 0 : int PartitionShell::layer() const { return get_lump()->layer(); }
135 : :
136 : 0 : GeometryQueryEngine* PartitionShell::get_geometry_query_engine() const
137 : : {
138 : 0 : return VirtualQueryEngine::instance();
139 : : }
140 : :
141 : 0 : void PartitionShell::append_simple_attribute_virt( const CubitSimpleAttrib& )
142 : 0 : { }
143 : 0 : void PartitionShell::remove_simple_attribute_virt( const CubitSimpleAttrib& )
144 : 0 : { }
145 : 0 : void PartitionShell::remove_all_simple_attribute_virt()
146 : 0 : { }
147 : 0 : CubitStatus PartitionShell::get_simple_attribute( DLIList<CubitSimpleAttrib>& )
148 : 0 : { return CUBIT_FAILURE; }
149 : 0 : CubitStatus PartitionShell::get_simple_attribute( const CubitString&,
150 : : DLIList<CubitSimpleAttrib>& )
151 : 0 : { return CUBIT_FAILURE; }
152 : :
153 : 0 : void PartitionShell::print_debug_info( const char* /*prefix*/ ) const
154 : : {
155 : 0 : }
156 : :
157 : : //-------------------------------------------------------------------------
158 : : // Purpose : Determine point containment.
159 : : //
160 : : // Special Notes :
161 : : //
162 : : // Creator : Jason Kraftcheck
163 : : //
164 : : // Creation Date : 02/23/03
165 : : //-------------------------------------------------------------------------
166 : 0 : CubitPointContainment PartitionShell::point_containment( const CubitVector& pt )
167 : : {
168 : : // Find closest cosurface to passed point
169 : 0 : PartitionCoSurf* cosurf = 0;
170 : 0 : PartitionCoSurf* closest = 0;
171 : 0 : double dist_to_closest = CUBIT_DBL_MAX;
172 [ # # ]: 0 : CubitVector pt_on_surface;
173 [ # # ][ # # ]: 0 : while( (cosurf = next_co_surface(cosurf)) )
174 : : {
175 [ # # ]: 0 : PartitionSurface* surf = cosurf->get_surface();
176 : :
177 : : // Ignore surfaces that occur more than once in the
178 : : // shell.
179 : 0 : bool skip = false;
180 : 0 : PartitionCoSurf* surf_cosurf = 0;
181 [ # # ][ # # ]: 0 : while( (surf_cosurf = surf->next_co_surface(surf_cosurf)) )
182 : : {
183 [ # # ][ # # ]: 0 : if( surf_cosurf->get_shell() == this && surf_cosurf != cosurf )
[ # # ][ # # ]
184 : : {
185 : 0 : skip = true;
186 : 0 : break;
187 : : }
188 : : }
189 : :
190 [ # # ]: 0 : if( skip )
191 : 0 : continue;
192 : :
193 [ # # ][ # # ]: 0 : surf->closest_point_trimmed( pt, pt_on_surface );
194 [ # # ][ # # ]: 0 : double dist_sqr = (pt - pt_on_surface).length_squared();
195 [ # # ]: 0 : if( dist_sqr < dist_to_closest )
196 : : {
197 : 0 : closest = cosurf;
198 : 0 : dist_to_closest = dist_sqr;
199 : : }
200 : : }
201 : :
202 [ # # ]: 0 : if( !closest )
203 : 0 : return CUBIT_PNT_UNKNOWN; // already printed error messages above
204 : :
205 [ # # ]: 0 : if( dist_to_closest < (GEOMETRY_RESABS*GEOMETRY_RESABS) ) // point is on shell
206 : 0 : return CUBIT_PNT_BOUNDARY;
207 : :
208 [ # # ]: 0 : CubitVector normal;
209 [ # # ][ # # ]: 0 : closest->get_surface()->closest_point_trimmed( pt, pt_on_surface );
[ # # ]
210 [ # # ][ # # ]: 0 : closest->get_surface()->closest_point( pt_on_surface, 0, &normal );
211 [ # # ][ # # ]: 0 : if( closest->sense() == CUBIT_REVERSED )
212 [ # # ]: 0 : normal *= -1.0;
213 : :
214 [ # # ]: 0 : pt_on_surface -= pt;
215 [ # # ][ # # ]: 0 : if ( pt_on_surface.length_squared() < GEOMETRY_RESABS*GEOMETRY_RESABS )
216 : 0 : return CUBIT_PNT_BOUNDARY;
217 : :
218 [ # # ][ # # ]: 0 : return (normal % pt_on_surface) > 0.0 ? CUBIT_PNT_INSIDE : CUBIT_PNT_OUTSIDE;
219 : : }
220 : :
221 : 0 : bool PartitionShell::is_nonmanifold( PartitionSurface* surf ) const
222 : : {
223 : 0 : int count = 0;
224 : 0 : PartitionCoSurf* cosurf = 0;
225 [ # # ]: 0 : while ((cosurf = surf->next_co_surface( cosurf )))
226 [ # # ]: 0 : if (cosurf->get_shell() == this)
227 : 0 : count++;
228 : :
229 : 0 : return count != 1;
230 : : }
231 : :
232 : 0 : CubitStatus PartitionShell::mass_properties( CubitVector& centroid,
233 : : double& volume )
234 : : {
235 : 0 : PartitionCoSurf* cosurf = 0;
236 [ # # ]: 0 : DLIList<CubitFacetData*> facets;
237 [ # # ][ # # ]: 0 : CubitVector p1, p2, p3, normal;
[ # # ][ # # ]
238 [ # # ]: 0 : const CubitVector p0(0.0, 0.0, 0.0);
239 [ # # ]: 0 : centroid.set(0.0, 0.0, 0.0 );
240 : 0 : volume = 0.0;
241 : :
242 [ # # ][ # # ]: 0 : while ((cosurf = next_co_surface( cosurf )))
243 : : {
244 [ # # ][ # # ]: 0 : if (is_nonmanifold( cosurf->get_surface() ))
[ # # ]
245 : 0 : continue;
246 : :
247 [ # # ]: 0 : facets.clean_out();
248 [ # # ][ # # ]: 0 : cosurf->get_surface()->get_facet_data( facets );
249 : :
250 [ # # ][ # # ]: 0 : for (int i = facets.size(); i--; )
251 : : {
252 [ # # ]: 0 : CubitFacet* facet = facets.step_and_get();
253 [ # # ][ # # ]: 0 : p1 = facet->point(0)->coordinates();
[ # # ]
254 [ # # ][ # # ]: 0 : p2 = facet->point(1)->coordinates();
[ # # ]
255 [ # # ][ # # ]: 0 : p3 = facet->point(2)->coordinates();
[ # # ]
256 [ # # ][ # # ]: 0 : normal = (p3 - p1) * (p2 - p1);
[ # # ][ # # ]
257 : :
258 [ # # ]: 0 : double two_area = normal.length();
259 [ # # ]: 0 : if (two_area > CUBIT_RESABS )
260 : : {
261 [ # # ][ # # ]: 0 : if (cosurf->sense() == CUBIT_REVERSED)
262 [ # # ][ # # ]: 0 : normal = -normal;
263 : :
264 [ # # ]: 0 : normal /= two_area;
265 : :
266 [ # # ][ # # ]: 0 : double height = normal % (p0 - p1);
267 : 0 : double vol = two_area * height;
268 : :
269 : 0 : volume += vol;
270 [ # # ][ # # ]: 0 : centroid += vol * (p0 + p1 + p2 + p3);
[ # # ][ # # ]
[ # # ]
271 : : }
272 : : }
273 : : }
274 : :
275 [ # # ]: 0 : if (volume > CUBIT_RESABS)
276 [ # # ]: 0 : centroid /= 4.0 * volume;
277 : 0 : volume /= 6.0;
278 [ # # ]: 0 : return CUBIT_SUCCESS;
279 : : }
280 : :
|