Branch data Line data Source code
1 : : #include "PartitionLump.hpp"
2 : : #include "PartitionShell.hpp"
3 : : #include "PartitionSurface.hpp"
4 : : #include "VirtualQueryEngine.hpp"
5 : : #include "PartitionCurve.hpp"
6 : : #include "PartitionBody.hpp"
7 : : #include "CubitFacetData.hpp"
8 : :
9 : 0 : PartitionLump::PartitionLump( Lump* real_lump )
10 [ # # ]: 0 : : listHead(0)
11 : : {
12 [ # # ][ # # ]: 0 : assert( dynamic_cast<SubEntitySet*>(real_lump->owner()) == 0 );
[ # # ]
13 [ # # ][ # # ]: 0 : new SubEntitySet( real_lump, this );
14 : 0 : }
15 : :
16 : 0 : PartitionLump::PartitionLump( PartitionLump* split_from )
17 [ # # ]: 0 : : listHead(0)
18 : : {
19 [ # # ][ # # ]: 0 : split_from->sub_entity_set().add_partition( this );
20 : 0 : }
21 : :
22 [ # # ]: 0 : PartitionLump::~PartitionLump()
23 : : {
24 [ # # ]: 0 : remove_all_shells();
25 [ # # ]: 0 : }
26 : :
27 : 0 : Lump* PartitionLump::real_lump() const
28 : : {
29 [ # # ]: 0 : return dynamic_cast<Lump*>(partitioned_entity());
30 : : }
31 : :
32 : :
33 : 0 : CubitStatus PartitionLump::add( PartitionShell* shell )
34 : : {
35 [ # # ]: 0 : assert( shell->myLump == 0 );
36 : 0 : shell->lumpNext = listHead;
37 : 0 : shell->myLump = this;
38 : 0 : listHead = shell;
39 : 0 : return CUBIT_SUCCESS;
40 : : }
41 : :
42 : 0 : CubitStatus PartitionLump::remove( PartitionShell* shell )
43 : : {
44 [ # # ]: 0 : if( shell->myLump != this )
45 : 0 : return CUBIT_FAILURE;
46 : :
47 [ # # ]: 0 : if( listHead == shell )
48 : : {
49 : 0 : listHead = shell->lumpNext;
50 : : }
51 : : else
52 : : {
53 : 0 : PartitionShell* sh = listHead;
54 [ # # ][ # # ]: 0 : while( sh && sh->lumpNext != shell )
55 : 0 : sh = sh->lumpNext;
56 [ # # ][ # # ]: 0 : assert( sh && sh->lumpNext == shell );
57 : 0 : sh->lumpNext = shell->lumpNext;
58 : : }
59 : :
60 : 0 : shell->myLump = 0;
61 : 0 : shell->lumpNext = 0;
62 : 0 : return CUBIT_SUCCESS;
63 : : }
64 : :
65 : 0 : void PartitionLump::remove_all_shells()
66 : : {
67 [ # # ]: 0 : while( listHead )
68 : : {
69 : 0 : CubitStatus s = remove( listHead );
70 [ # # ]: 0 : assert( s );
71 [ # # ]: 0 : if (CUBIT_SUCCESS != s) {
72 [ # # ][ # # ]: 0 : PRINT_ERROR("Failed to remove all shells.\n");
73 : : }
74 : : }
75 : 0 : }
76 : :
77 : 0 : void PartitionLump::get_parents_virt( DLIList<TopologyBridge*>& list )
78 : : {
79 [ # # ]: 0 : if( get_body() )
80 [ # # ]: 0 : list.append( get_body() );
81 : : else
82 : : {
83 : 0 : real_lump()->get_parents_virt( list );
84 : : // PartitionEngine::fix_up_query_results( list );
85 : : }
86 : 0 : }
87 : :
88 : 0 : void PartitionLump::get_children_virt( DLIList<TopologyBridge*>& list )
89 : : {
90 : 0 : PartitionShell* shell = first_shell();
91 [ # # ]: 0 : while( shell )
92 : : {
93 [ # # ]: 0 : list.append( shell );
94 : 0 : shell = next_shell( shell );
95 : : }
96 : 0 : }
97 : :
98 : 0 : GeometryQueryEngine* PartitionLump::get_geometry_query_engine() const
99 : : {
100 : 0 : return VirtualQueryEngine::instance();
101 : : }
102 : :
103 : :
104 : :
105 : 0 : void PartitionLump::append_simple_attribute_virt(const CubitSimpleAttrib& csa)
106 : 0 : { sub_entity_set().add_attribute( this, csa ); }
107 : 0 : void PartitionLump::remove_simple_attribute_virt(const CubitSimpleAttrib& csa)
108 : 0 : { sub_entity_set().rem_attribute( this, csa ); }
109 : 0 : void PartitionLump::remove_all_simple_attribute_virt()
110 : 0 : { sub_entity_set().rem_all_attrib( this ); }
111 : 0 : CubitStatus PartitionLump::get_simple_attribute(DLIList<CubitSimpleAttrib>& list)
112 : : {
113 : 0 : sub_entity_set().get_attributes( this, list );
114 : 0 : return CUBIT_SUCCESS;
115 : : }
116 : 0 : CubitStatus PartitionLump::get_simple_attribute(const CubitString& name,
117 : : DLIList<CubitSimpleAttrib>& list)
118 : : {
119 : 0 : sub_entity_set().get_attributes( this, name.c_str(), list );
120 : 0 : return CUBIT_SUCCESS;
121 : : }
122 : :
123 : 0 : void PartitionLump::notify_split( FacetEntity* , FacetEntity* )
124 : 0 : { assert(0); }
125 : :
126 : 0 : void PartitionLump::reverse_sense()
127 : : {
128 : 0 : PartitionShell* shell = 0;
129 [ # # ]: 0 : while( (shell = next_shell(shell)) )
130 : : {
131 : 0 : PartitionCoSurf* cosurf = 0;
132 [ # # ]: 0 : while( (cosurf = shell->next_co_surface( cosurf )) )
133 : : {
134 : 0 : bool reversed = (cosurf->sense() == CUBIT_REVERSED);
135 [ # # ]: 0 : cosurf->sense( reversed ? CUBIT_FORWARD : CUBIT_REVERSED );
136 : : }
137 : : }
138 : 0 : }
139 : :
140 : 0 : void PartitionLump::transform(const CubitTransformMatrix&) {;}
141 : :
142 : 0 : CubitBox PartitionLump::bounding_box() const
143 : : {
144 [ # # ]: 0 : return real_lump() ? real_lump()->bounding_box() : CubitBox();
145 : : }
146 : :
147 : 0 : double PartitionLump::measure()
148 : : {
149 : : // Calculate volume of this lump from surface facets.
150 : : // Volume is calculated as the sum of the signed
151 : : // volumes of the tetrahedrons formed by this point
152 : : // with triagle.
153 [ # # ][ # # ]: 0 : CubitVector p0 = bounding_box().center();
[ # # ]
154 : :
155 : 0 : double result = 0.0;
156 : 0 : PartitionShell* shell = 0;
157 : 0 : PartitionCoSurf* cosurf = 0;
158 [ # # ]: 0 : DLIList<CubitFacetData*> facets;
159 [ # # ][ # # ]: 0 : CubitVector p1, normal;
160 : :
161 : : // calculate area around this point
162 [ # # ][ # # ]: 0 : while ( (shell = next_shell(shell)) )
163 : : {
164 : : // mark surfaces with a count of how many times they
165 : : // occur in the shell
166 : 0 : cosurf = 0;
167 [ # # ][ # # ]: 0 : while ( (cosurf = shell->next_co_surface(cosurf)) )
168 [ # # ]: 0 : cosurf->get_surface()->mark = 0;
169 : 0 : cosurf = 0;
170 [ # # ][ # # ]: 0 : while ( (cosurf = shell->next_co_surface(cosurf)) )
171 [ # # ]: 0 : cosurf->get_surface()->mark++;
172 : :
173 : : // calculate partial area for each surface
174 : 0 : cosurf = 0;
175 [ # # ][ # # ]: 0 : while ( (cosurf = shell->next_co_surface(cosurf)) )
176 : : {
177 [ # # ]: 0 : PartitionSurface* surf = cosurf->get_surface();
178 : :
179 : : // skip non-manifold surfaces
180 [ # # ]: 0 : if( surf->mark > 1 ) continue;
181 : :
182 [ # # ]: 0 : facets.clean_out();
183 [ # # ]: 0 : surf->get_facet_data( facets );
184 [ # # ][ # # ]: 0 : for ( int i = facets.size(); i--; )
185 : : {
186 : : // Tetrahedron volume is Ah/3
187 : : // Calculate 2Ah and add to result.
188 : : // Divide result by 6 when all done.
189 : :
190 [ # # ]: 0 : CubitFacet* facet = facets.step_and_get();
191 [ # # ][ # # ]: 0 : p1 = facet->point(0)->coordinates();
[ # # ]
192 [ # # ][ # # ]: 0 : normal = (facet->point(2)->coordinates() - p1)
[ # # ]
193 [ # # ][ # # ]: 0 : * (facet->point(1)->coordinates() - p1);
[ # # ][ # # ]
[ # # ]
194 : :
195 : : // Triangle area is 1/2 length of edge product
196 [ # # ]: 0 : double two_area = normal.length();
197 : :
198 [ # # ]: 0 : if ( two_area > CUBIT_RESABS )
199 : : {
200 : : // Calculating signed area - need to
201 : : // reverse facet normal for reversed
202 : : // cosurfaces.
203 [ # # ][ # # ]: 0 : if ( cosurf->sense() == CUBIT_REVERSED )
204 [ # # ][ # # ]: 0 : normal = -normal;
205 : :
206 : : // Make normal a unit vector. Already
207 : : // calculated length, so reuse that
208 : : // value.
209 [ # # ]: 0 : normal /= two_area;
210 : :
211 : : // This is where the signed part of the
212 : : // calculation comes in. If normal is
213 : : // in opposite direction as the vector
214 : : // (p0-p1), then the height is negative.
215 [ # # ][ # # ]: 0 : double height = normal % (p0 - p1);
216 : :
217 : : // Add the signed height value times
218 : : // twice the triangle area to result.
219 : 0 : result += two_area * height;
220 : : }
221 : : }
222 : : }
223 : :
224 : : // clear marks
225 : 0 : cosurf = 0;
226 [ # # ][ # # ]: 0 : while ( (cosurf = shell->next_co_surface(cosurf)) )
227 [ # # ]: 0 : cosurf->get_surface()->mark = 0;
228 : : }
229 : :
230 : : // Calculated 2Ah for each tetrahedron, so divide
231 : : // by 6 to get Ah/3.
232 [ # # ]: 0 : return result / 6.0;
233 : : }
234 : :
235 : 0 : PartitionBody* PartitionLump::get_body() const
236 : 0 : { return sub_entity_set().body(); }
237 : :
238 : 0 : TopologyBridge* PartitionLump::find_parent_body() const
239 : : {
240 [ # # ][ # # ]: 0 : if( get_body() )
241 [ # # ]: 0 : return get_body();
242 : :
243 [ # # ]: 0 : Lump* lump = real_lump();
244 [ # # ]: 0 : if(!lump) return 0;
245 : :
246 [ # # ]: 0 : DLIList<TopologyBridge*> list;
247 [ # # ]: 0 : lump->get_parents_virt(list);
248 [ # # ][ # # ]: 0 : return list.size() ? list.get() : 0;
[ # # ][ # # ]
249 : : }
250 : :
251 : 0 : CubitStatus PartitionLump::save( CubitSimpleAttrib& attrib )
252 : : {
253 [ # # ]: 0 : DLIList<int> surf_list;
254 : :
255 : 0 : PartitionShell* shell = 0;
256 [ # # ][ # # ]: 0 : while( (shell = next_shell(shell)) )
257 : : {
258 : 0 : PartitionCoSurf* cosurf = 0;
259 : 0 : int cosurf_count = 0;
260 [ # # ][ # # ]: 0 : while( (cosurf = shell->next_co_surface(cosurf)) )
261 : 0 : cosurf_count++;
262 : :
263 [ # # ]: 0 : surf_list.append(cosurf_count);
264 : 0 : cosurf = 0;
265 [ # # ][ # # ]: 0 : while( (cosurf = shell->next_co_surface(cosurf)) )
266 : : {
267 [ # # ]: 0 : PartitionSurface* surf = cosurf->get_surface();
268 : 0 : int set_id = 0;
269 [ # # ][ # # ]: 0 : int surf_id = surf->sub_entity_set().get_id(surf);
[ # # ]
270 [ # # ][ # # ]: 0 : if( &(surf->sub_entity_set()) != &sub_entity_set() )
[ # # ]
271 [ # # ][ # # ]: 0 : set_id = surf->sub_entity_set().get_unique_id();
272 : :
273 [ # # ][ # # ]: 0 : if ( cosurf->sense() == CUBIT_REVERSED )
274 : 0 : surf_id = -surf_id;
275 : :
276 [ # # ]: 0 : surf_list.append( set_id );
277 [ # # ]: 0 : surf_list.append( surf_id );
278 : : }
279 : : }
280 : :
281 [ # # ][ # # ]: 0 : int id = sub_entity_set().get_id(this);
282 [ # # ][ # # ]: 0 : return sub_entity_set().save_geometry( id, 3, 0, 0, &surf_list, 0, attrib );
[ # # ]
283 : : }
284 : :
285 : 0 : void PartitionLump::get_all_children( DLIList<PartitionEntity*>& list )
286 : : {
287 : 0 : PartitionShell* shell = 0;
288 [ # # ]: 0 : while( (shell = next_shell(shell)) )
289 : : {
290 : 0 : PartitionCoSurf* cosurf = 0;
291 [ # # ]: 0 : while( (cosurf = shell->next_co_surface(cosurf)) )
292 : : {
293 : 0 : PartitionSurface* surface = cosurf->get_surface();
294 [ # # ][ # # ]: 0 : list.append( surface );
295 : 0 : PartitionLoop* loop = 0;
296 [ # # ]: 0 : while( (loop = surface->next_loop(loop)) )
297 : : {
298 : 0 : PartitionCoEdge* coedge = loop->first_coedge();
299 [ # # ]: 0 : do {
300 : 0 : PartitionCurve* curve = coedge->get_curve();
301 [ # # ][ # # ]: 0 : list.append( curve );
302 [ # # ][ # # ]: 0 : list.append( curve->start_point() );
303 [ # # ][ # # ]: 0 : list.append( curve->end_point() );
304 : 0 : coedge = loop->next_coedge( coedge );
305 : 0 : } while( coedge != loop->first_coedge() );
306 : : }
307 : : }
308 : : }
309 : :
310 : : int i;
311 [ # # ]: 0 : for( i = list.size(); i--; )
312 : 0 : list.step_and_get()->mark = 0;
313 [ # # ]: 0 : for( i = list.size(); i--; )
314 : 0 : list.step_and_get()->mark++;
315 [ # # ]: 0 : for( i = list.size(); i--; )
316 : : {
317 : 0 : list.step_and_get()->mark--;
318 [ # # ]: 0 : if( list.get()->mark != 0 )
319 : 0 : list.change_to(0);
320 : : }
321 [ # # ]: 0 : list.remove_all_with_value(0);
322 : 0 : }
323 : :
324 : : //-------------------------------------------------------------------------
325 : : // Purpose : Mass properties
326 : : //
327 : : // Special Notes :
328 : : //
329 : : // Creator : Jason Kraftcheck
330 : : //
331 : : // Creation Date : 05/10/04
332 : : //-------------------------------------------------------------------------
333 : 0 : CubitStatus PartitionLump::mass_properties( CubitVector& centroid, double& volume )
334 : : {
335 : 0 : PartitionShell* shell = 0;
336 [ # # ]: 0 : CubitVector s_cent;
337 : : double s_vol;
338 : 0 : volume = 0.0;
339 [ # # ]: 0 : centroid.set( 0.0, 0.0, 0.0 );
340 : :
341 [ # # ][ # # ]: 0 : while ((shell = next_shell( shell )))
342 : : {
343 [ # # ][ # # ]: 0 : if (CUBIT_SUCCESS != shell->mass_properties( s_cent, s_vol ))
344 : 0 : return CUBIT_FAILURE;
345 [ # # ][ # # ]: 0 : centroid += s_vol * s_cent;
346 : 0 : volume += s_vol;
347 : : }
348 : :
349 [ # # ]: 0 : if (volume > CUBIT_RESABS)
350 [ # # ]: 0 : centroid /= volume;
351 : : else
352 [ # # ]: 0 : centroid.set( 0.0, 0.0, 0.0 );
353 : 0 : return CUBIT_SUCCESS;
354 : : }
355 : :
356 : 0 : CubitPointContainment PartitionLump::point_containment( const CubitVector& pos, double tolerance )
357 : : {
358 : 0 : PartitionCoSurf* closest_surf = NULL;
359 : 0 : double closest_dist = CUBIT_DBL_MAX;
360 [ # # ][ # # ]: 0 : CubitVector closest, normal;
361 : :
362 : 0 : PartitionShell* shell = 0;
363 [ # # ][ # # ]: 0 : while ((shell = next_shell( shell )))
364 : : {
365 : 0 : PartitionCoSurf* cosurf = 0;
366 [ # # ][ # # ]: 0 : while ((cosurf = shell->next_co_surface( cosurf )))
367 : : {
368 [ # # ]: 0 : PartitionSurface* surf = cosurf->get_surface();
369 [ # # ][ # # ]: 0 : if (!shell->is_nonmanifold( surf ))
370 : : {
371 [ # # ]: 0 : surf->closest_point( pos, &closest );
372 [ # # ][ # # ]: 0 : double dist = (pos - closest).length_squared();
373 [ # # ]: 0 : if (dist < closest_dist)
374 : : {
375 : 0 : closest_dist = dist;
376 : 0 : closest_surf = cosurf;
377 : : }
378 : : }
379 : : }
380 : : }
381 : :
382 [ # # ]: 0 : if (!closest_surf)
383 : 0 : return CUBIT_PNT_UNKNOWN;
384 : :
385 [ # # ]: 0 : if( tolerance < 0 )
386 : 0 : tolerance = GEOMETRY_RESABS;
387 : :
388 [ # # ][ # # ]: 0 : closest_surf->get_surface()->closest_point( pos, &closest, &normal );
389 [ # # ][ # # ]: 0 : if ((closest - pos).length_squared() < tolerance * tolerance )
[ # # ]
390 : 0 : return CUBIT_PNT_BOUNDARY;
391 : :
392 [ # # ][ # # ]: 0 : if (closest_surf->sense() == CUBIT_REVERSED)
393 [ # # ][ # # ]: 0 : normal = -normal;
394 : :
395 [ # # ][ # # ]: 0 : double dot = normal % (closest - pos);
396 : : return dot < CUBIT_RESABS ? CUBIT_PNT_OUTSIDE :
397 : : dot > CUBIT_RESABS ? CUBIT_PNT_INSIDE :
398 [ # # ][ # # ]: 0 : CUBIT_PNT_UNKNOWN;
399 [ + - ][ + - ]: 6364 : }
400 : :
401 : :
|