Branch data Line data Source code
1 : : #include "PartitionLump.hpp"
2 : : #include "PartitionSurface.hpp"
3 : : #include "PartitionLoop.hpp"
4 : : #include "PartitionShell.hpp"
5 : : #include "PartitionCurve.hpp"
6 : : #include "VirtualQueryEngine.hpp"
7 : : #include "PartitionEngine.hpp"
8 : : #include "PartSurfFacetTool.hpp"
9 : : #include "PartitionTool.hpp"
10 : :
11 : : #include "CubitFacetData.hpp"
12 : : #include "TDVGFacetOwner.hpp"
13 : : #include "GMem.hpp"
14 : : #include "CubitPoint.hpp"
15 : : #include "CubitPointData.hpp"
16 : : #include "CubitFacetEdgeData.hpp"
17 : : #include "CubitTransformMatrix.hpp"
18 : : #include "GfxDebug.hpp"
19 : :
20 : : #include "RefVertex.hpp"
21 : :
22 : 0 : void PartitionSurface::draw_facets( int color ) const
23 : : {
24 [ # # ]: 0 : DLIList<CubitFacetData*> facets;
25 [ # # ]: 0 : get_facet_data(facets);
26 : : int i;
27 [ # # ][ # # ]: 0 : for ( i = facets.size(); i--; ) {
28 [ # # ]: 0 : CubitFacet* facet = facets.step_and_get();
29 [ # # ]: 0 : for ( int j = 0; j < 3; j++ )
30 [ # # ][ # # ]: 0 : if ( facet->edge(j) )
31 [ # # ][ # # ]: 0 : facet->edge(j)->marked(0);
32 : : }
33 [ # # ][ # # ]: 0 : for ( i = facets.size(); i--; ) {
34 [ # # ]: 0 : CubitFacet* facet = facets.step_and_get();
35 [ # # ]: 0 : for ( int j = 0; j < 3; j++ )
36 [ # # ][ # # ]: 0 : if ( facet->edge(j) )
37 [ # # ][ # # ]: 0 : facet->edge(j)->marked(facet->edge(j)->marked()+1);
[ # # ][ # # ]
38 : : }
39 : :
40 : :
41 [ # # ][ # # ]: 0 : for ( i = facets.size(); i--; ) {
42 [ # # ]: 0 : CubitFacetData* facet = facets.step_and_get();
43 [ # # ]: 0 : CubitVector pts[3] = {facet->point(0)->coordinates(),
44 [ # # ]: 0 : facet->point(1)->coordinates(),
45 [ # # ][ # # ]: 0 : facet->point(2)->coordinates()};
[ # # ][ # # ]
46 [ # # ]: 0 : for ( int j = 0; j < 3; j++ )
47 : : {
48 [ # # ]: 0 : CubitVector p1 = pts[j];
49 [ # # ]: 0 : CubitVector p2 = pts[(j+1)%3];
50 [ # # ]: 0 : int c = color == CUBIT_RED_INDEX ? color - 1 : CUBIT_RED_INDEX;
51 [ # # ]: 0 : CubitFacetEdge* edge = facet->edge((j+2)%3);
52 [ # # ]: 0 : if (!edge) continue;
53 : :
54 [ # # ]: 0 : switch( edge->marked() ) {
[ # # # ]
55 : 0 : case 1: c = color + 1; break;
56 : 0 : case 2: c = color; break;
57 [ # # ]: 0 : default : c = color == CUBIT_RED_INDEX ? color - 1 : CUBIT_RED_INDEX;
58 : :
59 [ # # ][ # # ]: 0 : if (edge->marked()==1 && !TDVGFacetOwner::get(edge))
[ # # ][ # # ]
[ # # ]
60 [ # # ][ # # ]: 0 : PRINT_WARNING("Boundary edge in surface facetting not owned by a curve.\n");
[ # # ][ # # ]
61 : : }
62 : :
63 [ # # ][ # # ]: 0 : GfxDebug::draw_line( (float)p1.x(), (float)p1.y(), (float)p1.z(),
[ # # ]
64 [ # # ][ # # ]: 0 : (float)p2.x(), (float)p2.y(), (float)p2.z(), c );
[ # # ][ # # ]
65 : : }
66 : :
67 : :
68 [ # # ][ # # ]: 0 : CubitVector center = ( pts[0] + pts[1] + pts[2] ) / 3.0;
[ # # ]
69 [ # # ][ # # ]: 0 : CubitVector normal = (pts[1] - pts[0]) * (pts[2] - pts[0]);
[ # # ]
70 [ # # ]: 0 : double len = normal.length();
71 [ # # ]: 0 : if ( len > GEOMETRY_RESABS ) {
72 [ # # ]: 0 : normal /= sqrt(len);
73 : : // if ( len > 1e-2 )
74 : : // normal /= len;
75 : : // else
76 : : // normal.length(1.0);
77 : :
78 [ # # ][ # # ]: 0 : GfxDebug::draw_vector( center, center + normal, color );
79 : : } else {
80 [ # # ]: 0 : GfxDebug::draw_point( center, color + 1 );
81 : : }
82 : : }
83 [ # # ]: 0 : GfxDebug::flush();
84 : :
85 [ # # ][ # # ]: 0 : for ( i = facets.size(); i--; ) {
86 [ # # ]: 0 : CubitFacet* facet = facets.step_and_get();
87 [ # # ]: 0 : for ( int j = 0; j < 3; j++ )
88 [ # # ][ # # ]: 0 : if ( facet->edge(j) )
89 [ # # ][ # # ]: 0 : facet->edge(j)->marked(0);
90 [ # # ]: 0 : }
91 : 0 : }
92 : :
93 : 0 : void PartitionSurface::print_debug_info( const char* prefix ,
94 : : bool print_sub_entity_set ) const
95 : : {
96 [ # # ]: 0 : if( !prefix ) prefix = "";
97 [ # # ][ # # ]: 0 : PRINT_INFO("%sPartitionSurface %p\n", prefix, (void*)this );
[ # # ][ # # ]
98 : 0 : PartitionLoop* loop = 0;
99 [ # # ][ # # ]: 0 : while( (loop = next_loop(loop)) )
100 : : {
101 [ # # ][ # # ]: 0 : PRINT_INFO("%s Loop %p:\n", prefix, (void*)loop );
[ # # ][ # # ]
102 [ # # ]: 0 : PartitionCoEdge* coedge = loop->first_coedge();
103 [ # # ]: 0 : do
104 : : {
105 [ # # ][ # # ]: 0 : PRINT_INFO("%s CoEdge %p %s -> Curve %p\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
106 : : prefix, (void*)coedge, coedge->sense() == CUBIT_FORWARD ? "FORWARD" :
107 : : coedge->sense() == CUBIT_REVERSED ? "REVERSE" :
108 [ # # ]: 0 : "UNKNOWN", (void*)coedge->get_curve() );
109 [ # # ]: 0 : coedge = loop->next_coedge(coedge);
110 [ # # ]: 0 : } while( coedge != loop->first_coedge() );
111 : : }
112 : :
113 : : char buffer[128];
114 : 0 : sprintf(buffer,"%s ",prefix);
115 [ # # ]: 0 : if( print_sub_entity_set )
116 [ # # ][ # # ]: 0 : sub_entity_set().print_debug_info(buffer);
117 : 0 : }
118 : :
119 : 0 : PartitionSurface::PartitionSurface()
120 [ # # ][ # # ]: 0 : : geometry_sense(CUBIT_FORWARD), firstLoop(0), firstCoSurf(0)
121 : 0 : {}
122 : :
123 : 0 : PartitionSurface::PartitionSurface( PartitionLump* lump )
124 [ # # ][ # # ]: 0 : : geometry_sense(CUBIT_FORWARD), firstLoop(0), firstCoSurf(0)
125 : : {
126 [ # # ][ # # ]: 0 : lump->sub_entity_set().add_lower_order( this );
127 : 0 : }
128 : :
129 [ # # ][ # # ]: 0 : PartitionSurface::~PartitionSurface()
130 : : {
131 [ # # ]: 0 : while( firstLoop )
132 [ # # ]: 0 : remove( firstLoop );
133 : :
134 [ # # ]: 0 : while( firstCoSurf )
135 : : {
136 : 0 : PartitionCoSurf* cos = firstCoSurf;
137 [ # # ][ # # ]: 0 : if( cos->get_shell() )
138 [ # # ][ # # ]: 0 : cos->get_shell()->remove( cos );
139 [ # # ]: 0 : remove( cos );
140 [ # # ][ # # ]: 0 : delete cos;
141 [ # # ]: 0 : assert( firstCoSurf != cos );
142 : : }
143 : :
144 : : // delete facets
145 [ # # ]: 0 : DLIList<CubitPoint*> facet_points(3);
146 [ # # ][ # # ]: 0 : DLIList<CubitFacetEdge*> facet_edges(3);
147 [ # # ][ # # ]: 0 : while( facetList.size() )
148 : : {
149 [ # # ]: 0 : CubitFacet* facet = facetList.pop();
150 [ # # ]: 0 : facet_edges.clean_out();
151 [ # # ]: 0 : facet->edges(facet_edges);
152 [ # # ]: 0 : facet_points.clean_out();
153 [ # # ]: 0 : facet->points(facet_points);
154 [ # # ]: 0 : TDVGFacetOwner::remove(facet);
155 [ # # ][ # # ]: 0 : delete facet;
156 : :
157 : : PartitionCurve* curve;
158 [ # # ][ # # ]: 0 : while( facet_edges.size() )
159 : : {
160 [ # # ]: 0 : CubitFacetEdge* edge = facet_edges.pop();
161 [ # # ][ # # ]: 0 : if( edge && !edge->num_adj_facets() ) {
[ # # ][ # # ]
162 [ # # ][ # # ]: 0 : if ( TDVGFacetOwner::get(edge) ) {
163 [ # # ][ # # ]: 0 : curve = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(edge));
164 [ # # ]: 0 : curve->remove_facet_data();
165 : : }
166 [ # # ][ # # ]: 0 : delete edge;
167 : : }
168 : : }
169 : :
170 : : PartitionPoint* ppoint;
171 [ # # ][ # # ]: 0 : while( facet_points.size() )
172 : : {
173 [ # # ]: 0 : CubitPoint* point = facet_points.pop();
174 [ # # ][ # # ]: 0 : if( point && !point->num_adj_facets() ) {
[ # # ][ # # ]
175 [ # # ][ # # ]: 0 : if ( TDVGFacetOwner::get(point) ) {
176 [ # # ][ # # ]: 0 : ppoint = dynamic_cast<PartitionPoint*>(TDVGFacetOwner::get(point));
177 [ # # ]: 0 : if( ppoint )
178 [ # # ]: 0 : ppoint->facet_point(0);
179 : : }
180 [ # # ][ # # ]: 0 : delete point;
181 : : }
182 : : }
183 [ # # ]: 0 : }
184 [ # # ]: 0 : }
185 : :
186 : 0 : CubitStatus PartitionSurface::add( PartitionLoop* loop )
187 : : {
188 [ # # ]: 0 : if( loop->mySurface )
189 : 0 : return CUBIT_FAILURE;
190 : :
191 : 0 : loop->mySurface = this;
192 : 0 : loop->nextInSurface = firstLoop;
193 : 0 : firstLoop = loop;
194 : 0 : return CUBIT_SUCCESS;
195 : : }
196 : :
197 : :
198 : 0 : CubitStatus PartitionSurface::remove( PartitionLoop* loop )
199 : : {
200 [ # # ]: 0 : if( loop->mySurface != this )
201 : 0 : return CUBIT_FAILURE;
202 : :
203 [ # # ]: 0 : if( firstLoop == loop )
204 : : {
205 : 0 : firstLoop = loop->nextInSurface;
206 : : }
207 : : else
208 : : {
209 : 0 : PartitionLoop* prev = firstLoop;
210 [ # # ][ # # ]: 0 : while( prev && prev->nextInSurface != loop )
211 : 0 : prev = prev->nextInSurface;
212 : :
213 [ # # ]: 0 : if( !prev )
214 : : {
215 : 0 : assert(0);
216 : : return CUBIT_FAILURE;
217 : : }
218 : :
219 : 0 : prev->nextInSurface = loop->nextInSurface;
220 : : }
221 : :
222 : 0 : loop->mySurface = 0;
223 : 0 : loop->nextInSurface = 0;
224 : 0 : return CUBIT_SUCCESS;
225 : : }
226 : :
227 : 0 : int PartitionSurface::num_loops() const
228 : : {
229 : 0 : int count = 0;
230 [ # # ]: 0 : for( PartitionLoop* loop = firstLoop; loop; loop = loop->nextInSurface )
231 : 0 : count++;
232 : 0 : return count;
233 : : }
234 : :
235 : 0 : CubitStatus PartitionSurface::add( PartitionCoSurf* cosurf )
236 : : {
237 [ # # ]: 0 : if( cosurf->mySurface )
238 : 0 : return CUBIT_FAILURE;
239 : :
240 : 0 : cosurf->mySurface = this;
241 : 0 : cosurf->surfaceNext = firstCoSurf;
242 : 0 : firstCoSurf = cosurf;
243 : 0 : return CUBIT_SUCCESS;
244 : : }
245 : :
246 : 0 : CubitStatus PartitionSurface::remove( PartitionCoSurf* cosurf )
247 : : {
248 [ # # ]: 0 : if( cosurf->mySurface != this )
249 : 0 : return CUBIT_FAILURE;
250 : :
251 [ # # ]: 0 : if( cosurf == firstCoSurf )
252 : : {
253 : 0 : firstCoSurf = cosurf->surfaceNext;
254 : : }
255 : : else
256 : : {
257 : 0 : PartitionCoSurf* prev = firstCoSurf;
258 [ # # ][ # # ]: 0 : while( prev && prev->surfaceNext != cosurf )
259 : 0 : prev = prev->surfaceNext;
260 : :
261 [ # # ][ # # ]: 0 : if( !prev ) { assert(prev != NULL); return CUBIT_FAILURE; }
262 : :
263 : 0 : prev->surfaceNext = cosurf->surfaceNext;
264 : : }
265 : :
266 : 0 : cosurf->mySurface = 0;
267 : 0 : cosurf->surfaceNext = 0;
268 : 0 : return CUBIT_SUCCESS;
269 : : }
270 : :
271 : 0 : PartitionCoSurf* PartitionSurface::find_first( const PartitionShell* shell ) const
272 : : {
273 : 0 : PartitionCoSurf* cos = firstCoSurf;
274 [ # # ][ # # ]: 0 : while( cos && cos->get_shell() != shell )
[ # # ]
275 : 0 : cos = cos->surfaceNext;
276 : 0 : return cos;
277 : : }
278 : :
279 : :
280 : 0 : PartitionCoSurf* PartitionSurface::find_first( const PartitionLump* lump ) const
281 : : {
282 : 0 : PartitionCoSurf* cos = firstCoSurf;
283 [ # # ][ # # ]: 0 : while( cos && (!cos->get_shell() || cos->get_shell()->get_lump() != lump ) )
[ # # ][ # # ]
284 : 0 : cos = cos->surfaceNext;
285 : 0 : return cos;
286 : : }
287 : :
288 : 0 : PartitionCoSurf* PartitionSurface::find_next( const PartitionCoSurf* prev ) const
289 : : {
290 [ # # ]: 0 : if( prev->mySurface != this )
291 : 0 : return 0;
292 : 0 : PartitionCoSurf* cos = prev->surfaceNext;
293 [ # # ][ # # ]: 0 : while( cos && cos->get_shell() != prev->get_shell() )
[ # # ]
294 : 0 : cos = cos->surfaceNext;
295 : 0 : return cos;
296 : : }
297 : :
298 : 0 : PartitionCoSurf* PartitionSurface::find_first( const PartitionShell* shell,
299 : : CubitSense sense ) const
300 : : {
301 : 0 : PartitionCoSurf* cos = firstCoSurf;
302 [ # # ][ # # ]: 0 : while( cos && (cos->get_shell() != shell || cos->sense() != sense) )
[ # # ][ # # ]
303 : 0 : cos = cos->surfaceNext;
304 : 0 : return cos;
305 : : }
306 : :
307 : : //-------------------------------------------------------------------------
308 : : // Purpose : Get child point bridges
309 : : //
310 : : // Special Notes :
311 : : //
312 : : // Creator : Jason Kraftcheck
313 : : //
314 : : // Creation Date :
315 : : //-------------------------------------------------------------------------
316 : 0 : void PartitionSurface::get_points( DLIList<PartitionPoint*>& list ) const
317 : : {
318 : 0 : PartitionLoop* loop = 0;
319 [ # # ]: 0 : while ( (loop = next_loop(loop)) )
320 : : {
321 : 0 : PartitionCoEdge* coedge = loop->first_coedge();
322 [ # # ]: 0 : do
323 : : {
324 : 0 : PartitionCurve* curve = coedge->get_curve();
325 : :
326 [ # # ]: 0 : list.append( curve->start_point() );
327 [ # # ]: 0 : list.append( curve->end_point() );
328 : :
329 : 0 : coedge = loop->next_coedge(coedge);
330 : 0 : } while( coedge != loop->first_coedge() );
331 : : }
332 : :
333 : 0 : list.reset();
334 : : int i;
335 [ # # ]: 0 : for ( i = list.size(); i--; )
336 : 0 : list.get_and_step()->mark = 1;
337 : :
338 [ # # ]: 0 : for ( i = list.size(); i--; )
339 : : {
340 : 0 : list.back();
341 [ # # ]: 0 : if( list.get()->mark )
342 : 0 : list.get()->mark = 0;
343 : : else
344 : 0 : list.change_to(0);
345 : : }
346 [ # # ]: 0 : list.remove_all_with_value(0);
347 : 0 : }
348 : :
349 : :
350 : :
351 : :
352 : 0 : GeometryQueryEngine* PartitionSurface::get_geometry_query_engine() const
353 : : {
354 : 0 : return VirtualQueryEngine::instance();
355 : : }
356 : :
357 : 0 : void PartitionSurface::get_children_virt( DLIList<TopologyBridge*>& list )
358 : : {
359 [ # # ]: 0 : for( PartitionLoop* loop = firstLoop; loop; loop = loop->nextInSurface )
360 [ # # ]: 0 : list.append( loop );
361 : 0 : }
362 : :
363 : 0 : void PartitionSurface::get_parents_virt( DLIList<TopologyBridge*>& result_list )
364 : : {
365 [ # # ]: 0 : Surface* real_surf = dynamic_cast<Surface*>(partitioned_entity());
366 [ # # ]: 0 : if( ! real_surf )
367 : : {
368 [ # # ]: 0 : for( PartitionCoSurf* cos = firstCoSurf; cos; cos = cos->surfaceNext )
369 [ # # ]: 0 : if( cos->get_shell() )
370 [ # # ]: 0 : result_list.append_unique( cos->get_shell() );
371 : : }
372 : : else
373 : : {
374 : : int i;
375 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> real_surf_shells, tmp_list;
[ # # ]
376 [ # # ]: 0 : real_surf->get_parents_virt( real_surf_shells );
377 : :
378 : : // get real volumes from real shells
379 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> real_surf_vols(real_surf_shells.size());
[ # # ]
380 [ # # ]: 0 : real_surf_shells.reset();
381 [ # # ][ # # ]: 0 : for( i = real_surf_shells.size(); i--; )
382 : : {
383 [ # # ]: 0 : tmp_list.clean_out();
384 [ # # ][ # # ]: 0 : real_surf_shells.get_and_step()->get_parents_virt( tmp_list );
385 [ # # ][ # # ]: 0 : assert(tmp_list.size() == 1);
386 [ # # ][ # # ]: 0 : real_surf_vols.append(tmp_list.get());
387 : : }
388 : :
389 : : // replace real volumes with owning partition volumes (if any)
390 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> vol_list(real_surf_vols.size());
[ # # ]
391 [ # # ]: 0 : real_surf_vols.reset();
392 [ # # ][ # # ]: 0 : for( i = real_surf_vols.size(); i--; )
393 : : {
394 [ # # ]: 0 : TopologyBridge* vol_bridge = real_surf_vols.get_and_step();
395 [ # # ][ # # ]: 0 : SubEntitySet* set = dynamic_cast<SubEntitySet*>(vol_bridge->owner());
396 [ # # ]: 0 : if( set )
397 : : {
398 [ # # ]: 0 : tmp_list.clean_out();
399 [ # # ]: 0 : set->get_owners(tmp_list);
400 [ # # ]: 0 : vol_list += tmp_list;
401 : : }
402 : : else
403 [ # # ]: 0 : vol_list.append(vol_bridge);
404 : : }
405 : :
406 : : // for each volume, get all child shells that are parents of this
407 [ # # ]: 0 : vol_list.reset();
408 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> vol_shells;
409 [ # # ][ # # ]: 0 : for( i = vol_list.size(); i--; )
410 : : {
411 [ # # ]: 0 : vol_shells.clean_out();
412 [ # # ][ # # ]: 0 : vol_list.get_and_step()->get_children( vol_shells, false, layer() );
[ # # ]
413 [ # # ]: 0 : vol_shells.reset();
414 [ # # ][ # # ]: 0 : for( int j = vol_shells.size(); j--; )
415 : : {
416 [ # # ]: 0 : TopologyBridge* shell = vol_shells.get_and_step();
417 [ # # ]: 0 : tmp_list.clean_out();
418 [ # # ][ # # ]: 0 : shell->get_children( tmp_list, false, layer() );
419 [ # # ][ # # ]: 0 : if( tmp_list.is_in_list(this) )
420 [ # # ]: 0 : result_list.append(shell);
421 : : }
422 [ # # ]: 0 : }
423 : : }
424 : 0 : }
425 : :
426 : 0 : CubitSense PartitionSurface::get_shell_sense( ShellSM* shell_ptr ) const
427 : : {
428 [ # # ][ # # ]: 0 : if( PartitionShell* pshell = dynamic_cast<PartitionShell*>(shell_ptr) )
429 : 0 : return pshell->find_sense( this );
430 : :
431 [ # # ]: 0 : Surface* real_surf = dynamic_cast<Surface*>(partitioned_entity());
432 [ # # ]: 0 : if( real_surf )
433 : : {
434 [ # # ]: 0 : DLIList<TopologyBridge*> list(2);
435 [ # # ]: 0 : real_surf->get_parents_virt( list );
436 [ # # ][ # # ]: 0 : if( list.is_in_list( shell_ptr ) )
437 [ # # ][ # # ]: 0 : return real_surf->get_shell_sense( shell_ptr );
[ # # ]
438 : : }
439 : :
440 : 0 : return CUBIT_UNKNOWN;
441 : : }
442 : :
443 : :
444 : 0 : void PartitionSurface::append_simple_attribute_virt(const CubitSimpleAttrib& csa)
445 : 0 : { sub_entity_set().add_attribute( this, csa ); }
446 : 0 : void PartitionSurface::remove_simple_attribute_virt(const CubitSimpleAttrib& csa)
447 : 0 : { sub_entity_set().rem_attribute( this, csa ); }
448 : 0 : void PartitionSurface::remove_all_simple_attribute_virt()
449 : 0 : { sub_entity_set().rem_all_attrib( this ); }
450 : 0 : CubitStatus PartitionSurface::get_simple_attribute(DLIList<CubitSimpleAttrib>& list)
451 : : {
452 : 0 : sub_entity_set().get_attributes( this, list );
453 : 0 : return CUBIT_SUCCESS;
454 : : }
455 : 0 : CubitStatus PartitionSurface::get_simple_attribute(const CubitString& name,
456 : : DLIList<CubitSimpleAttrib>& list)
457 : : {
458 : 0 : sub_entity_set().get_attributes( this, name.c_str(), list );
459 : 0 : return CUBIT_SUCCESS;
460 : : }
461 : :
462 : 0 : void PartitionSurface::reverse_loops()
463 : : {
464 : 0 : PartitionLoop* loop = 0;
465 [ # # ]: 0 : while( (loop = next_loop(loop)) )
466 : 0 : loop->reverse();
467 : 0 : }
468 : :
469 : 0 : CubitBox PartitionSurface::bounding_box() const
470 : : {
471 : : int i, j;
472 : : CubitFacet* facet;
473 [ # # ]: 0 : for ( i = 0; i< facetList.size(); i++ ) {
474 : 0 : facet = facetList.next(i);
475 : 0 : facet->point(0)->marked(1);
476 : 0 : facet->point(1)->marked(1);
477 : 0 : facet->point(2)->marked(1);
478 : : }
479 : :
480 : 0 : facet = facetList.get();
481 [ # # ]: 0 : CubitBox result(facet->point(0)->coordinates());
482 [ # # ][ # # ]: 0 : facet->point(0)->marked(0);
483 : :
484 [ # # ][ # # ]: 0 : for ( i = 0; i< facetList.size(); i++ ) {
485 [ # # ]: 0 : facet = facetList.next(i);
486 [ # # ]: 0 : for ( j = 0; j < 3; j++ ) {
487 [ # # ][ # # ]: 0 : if ( facet->point(j)->marked() ) {
[ # # ]
488 [ # # ][ # # ]: 0 : facet->point(j)->marked(0);
489 [ # # ][ # # ]: 0 : result |= facet->point(j)->coordinates();
[ # # ]
490 : : }
491 : : }
492 : : }
493 : :
494 : 0 : return result;
495 : : }
496 : :
497 : :
498 : :
499 : :
500 : 0 : double PartitionSurface::measure()
501 : : {
502 : 0 : double result = 0.;
503 [ # # ]: 0 : for ( int i = facetList.size(); i--; )
504 : 0 : result += facetList.step_and_get()->area();
505 : 0 : return result;
506 : : }
507 : :
508 : 0 : GeometryType PartitionSurface::geometry_type()
509 : : {
510 : 0 : return FACET_SURFACE_TYPE;
511 : : }
512 : :
513 : 0 : void PartitionSurface::closest_point_trimmed( CubitVector f, CubitVector& r )
514 : : {
515 : 0 : closest_facet( f, r );
516 : 0 : }
517 : :
518 : 0 : CubitStatus PartitionSurface::closest_point_along_vector(CubitVector& from_point,
519 : : CubitVector& along_vector,
520 : : CubitVector& point_on_surface)
521 : : {
522 : 0 : return CUBIT_FAILURE;
523 : : }
524 : :
525 : 0 : CubitStatus PartitionSurface::get_point_normal( CubitVector &, CubitVector & )
526 : : {
527 : 0 : return CUBIT_FAILURE;
528 : : }
529 : :
530 : 0 : CubitStatus PartitionSurface::move_to_geometry( CubitVector& pos )
531 : : {
532 [ # # ]: 0 : const CubitVector copy(pos);
533 [ # # ]: 0 : return closest_point( copy, &pos );
534 : : }
535 : :
536 : 0 : CubitStatus PartitionSurface::closest_point_uv_guess(
537 : : CubitVector const& location,
538 : : double&, double&,
539 : : CubitVector* closest_location,
540 : : CubitVector* unit_normal )
541 : : {
542 : 0 : return closest_point(location, closest_location, unit_normal);
543 : : }
544 : :
545 : :
546 : 0 : CubitStatus PartitionSurface::closest_point( const CubitVector& position,
547 : : CubitVector* closest,
548 : : CubitVector* normal,
549 : : CubitVector* curvature1,
550 : : CubitVector* curvature2 )
551 : : {
552 [ # # ][ # # ]: 0 : if ( closest || normal )
553 : : {
554 [ # # ]: 0 : CubitVector tmp_closest;
555 [ # # ]: 0 : CubitFacet* facet = closest_facet( position, tmp_closest );
556 [ # # ]: 0 : if ( closest )
557 [ # # ]: 0 : *closest = tmp_closest;
558 [ # # ]: 0 : if ( normal )
559 [ # # ][ # # ]: 0 : *normal = facet->normal();
560 : : }
561 : :
562 [ # # ]: 0 : if( curvature1 )
563 : 0 : curvature1->set( 0.0, 0.0, 0.0 );
564 [ # # ]: 0 : if( curvature2 )
565 : 0 : curvature2->set( 0.0, 0.0, 0.0 );
566 : :
567 : 0 : return CUBIT_SUCCESS;
568 : : }
569 : :
570 : 0 : CubitStatus PartitionSurface::principal_curvatures(
571 : : const CubitVector& ,
572 : : double&, double& ,
573 : : CubitVector* )
574 : : {
575 : 0 : return CUBIT_FAILURE;
576 : : }
577 : :
578 : 0 : CubitVector PartitionSurface::position_from_u_v( double , double )
579 : : {
580 : 0 : return CubitVector(0.0,0.0,0.0);
581 : : }
582 : :
583 : 0 : CubitStatus PartitionSurface::u_v_from_position( const CubitVector& ,
584 : : double&, double &,
585 : : CubitVector* )
586 : : {
587 : 0 : return CUBIT_FAILURE;
588 : : }
589 : :
590 : 0 : CubitBoolean PartitionSurface::is_periodic()
591 : : {
592 : 0 : return CUBIT_FALSE;
593 : : }
594 : :
595 : 0 : CubitBoolean PartitionSurface::is_periodic_in_U( double& )
596 : : {
597 : 0 : return CUBIT_FALSE;
598 : : }
599 : :
600 : 0 : CubitBoolean PartitionSurface::is_periodic_in_V( double& )
601 : : {
602 : 0 : return CUBIT_FALSE;
603 : : }
604 : :
605 : 0 : CubitBoolean PartitionSurface::is_singular_in_U( double )
606 : : {
607 : 0 : return CUBIT_FALSE;
608 : : }
609 : :
610 : 0 : CubitBoolean PartitionSurface::is_singular_in_V( double )
611 : : {
612 : 0 : return CUBIT_FALSE;
613 : : }
614 : :
615 : 0 : CubitBoolean PartitionSurface::is_closed_in_U()
616 : : {
617 : 0 : return CUBIT_FALSE;
618 : : }
619 : :
620 : 0 : CubitBoolean PartitionSurface::is_closed_in_V()
621 : : {
622 : 0 : return CUBIT_FALSE;
623 : : }
624 : :
625 : 0 : CubitStatus PartitionSurface::uv_derivitives( double , double ,
626 : : CubitVector& ,
627 : : CubitVector& )
628 : : {
629 : 0 : return CUBIT_FAILURE;
630 : : }
631 : :
632 : 0 : CubitBoolean PartitionSurface::is_parametric()
633 : : {
634 : 0 : return CUBIT_FALSE;
635 : : }
636 : :
637 : 0 : CubitBoolean PartitionSurface::get_param_range_U( double& , double& )
638 : : {
639 : 0 : return CUBIT_FALSE;
640 : : }
641 : :
642 : 0 : CubitBoolean PartitionSurface::get_param_range_V( double&, double& )
643 : : {
644 : 0 : return CUBIT_FALSE;
645 : : }
646 : :
647 : 0 : CubitBoolean PartitionSurface::is_position_on( CubitVector& position )
648 : : {
649 : 0 : const double tolsqr = GEOMETRY_RESABS * GEOMETRY_RESABS;
650 [ # # ]: 0 : CubitVector closest;
651 [ # # ]: 0 : closest_facet( position, closest );
652 [ # # ][ # # ]: 0 : double distsqr = (position - closest).length_squared();
653 : 0 : return (CubitBoolean)(distsqr < tolsqr);
654 : : }
655 : :
656 : 0 : CubitPointContainment PartitionSurface::point_containment( const CubitVector& point )
657 : : {
658 : 0 : PartitionCurve* curve = 0;
659 [ # # ]: 0 : CubitPointContainment result = point_containment( point, curve );
660 [ # # ]: 0 : if ( curve ) {
661 [ # # ]: 0 : CubitVector curve_closest;
662 [ # # ]: 0 : curve->closest_point( point, curve_closest );
663 [ # # ][ # # ]: 0 : if ( (point - curve_closest).length_squared() < GEOMETRY_RESABS*GEOMETRY_RESABS )
[ # # ]
664 : 0 : result = CUBIT_PNT_BOUNDARY;
665 : : }
666 : 0 : return result;
667 : : }
668 : :
669 : 0 : CubitPointContainment PartitionSurface::point_containment( const CubitVector& point,
670 : : PartitionCurve*& curve )
671 : : {
672 [ # # ]: 0 : CubitVector facet_pos;
673 [ # # ]: 0 : CubitFacet* facet = closest_facet(point, facet_pos);
674 : :
675 : : int i;
676 : 0 : double tol = 10*GEOMETRY_RESABS;
677 : 0 : int closest_edge = -1;
678 : 0 : CubitPoint* closest_point = 0;
679 : 0 : double closest_dist_sqr = CUBIT_DBL_MAX;
680 [ # # ]: 0 : CubitVector closest_pos;
681 : : CubitFacetEdge* edge;
682 : :
683 : : // Find closest edge/point on facet
684 [ # # ]: 0 : for ( i = 0; i < 3; i++ )
685 : : {
686 [ # # ]: 0 : edge = facet->edge(i);
687 : :
688 [ # # ][ # # ]: 0 : CubitVector start = edge->point(0)->coordinates();
689 [ # # ][ # # ]: 0 : CubitVector end = edge->point(1)->coordinates();
690 [ # # ]: 0 : CubitVector dir = end - start;
691 [ # # ]: 0 : double len_sqr = dir.length_squared();
692 [ # # ][ # # ]: 0 : double t = (dir % (point - start)) / len_sqr;
693 : 0 : double len = sqrt(len_sqr);
694 : 0 : double dist_from_start = t * len;
695 : 0 : double dist_from_end = (1.0 - t) * len;
696 : 0 : CubitPoint* facet_point = 0;
697 [ # # ]: 0 : CubitVector pos;
698 [ # # ]: 0 : if ( dist_from_start < tol )
699 : : {
700 [ # # ]: 0 : pos = start;
701 [ # # ]: 0 : facet_point = edge->point(0);
702 : : }
703 [ # # ]: 0 : else if( dist_from_end < tol )
704 : : {
705 [ # # ]: 0 : pos = end;
706 [ # # ]: 0 : facet_point = edge->point(1);
707 : : }
708 : : else
709 [ # # ][ # # ]: 0 : pos = t * dir + start;
[ # # ]
710 : :
711 [ # # ][ # # ]: 0 : double dist_sqr = (pos - point).length_squared();
712 [ # # ]: 0 : if ( dist_sqr < closest_dist_sqr )
713 : : {
714 : 0 : closest_edge = i;
715 : 0 : closest_point = facet_point;
716 : 0 : closest_dist_sqr = dist_sqr;
717 [ # # ]: 0 : closest_pos = pos;
718 : : }
719 : : }
720 : :
721 [ # # ]: 0 : edge = facet->edge(closest_edge);
722 : :
723 : : // If closest to an edge (not a point) ...
724 [ # # ]: 0 : if ( !closest_point )
725 : : {
726 : : // If the edge is not on the boundary of the surface facets...
727 [ # # ][ # # ]: 0 : curve = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(edge));
728 [ # # ][ # # ]: 0 : if ( !curve || curve->is_nonmanifold(this) )
[ # # ][ # # ]
729 : 0 : return CUBIT_PNT_INSIDE; // not a boundary edge
730 : :
731 : : // If within tolerance of boundary
732 [ # # ][ # # ]: 0 : if ( (point - closest_pos).length_squared() < tol*tol )
[ # # ]
733 : 0 : return CUBIT_PNT_BOUNDARY;
734 : :
735 : : // Check which side of the edge the point is on
736 [ # # ][ # # ]: 0 : CubitVector dir = edge->point(1)->coordinates() - edge->point(0)->coordinates();
[ # # ][ # # ]
[ # # ]
737 [ # # ][ # # ]: 0 : if ( facet->edge_use(closest_edge) == -1 )
738 [ # # ][ # # ]: 0 : dir = -dir;
739 [ # # ][ # # ]: 0 : double dot = facet->normal() % ((closest_pos - point) * dir);
[ # # ][ # # ]
740 [ # # ]: 0 : if ( dot < 0.0 )
741 : 0 : return CUBIT_PNT_OUTSIDE;
742 : : else
743 : 0 : return CUBIT_PNT_INSIDE;
744 : : }
745 : :
746 : :
747 : : // Get two boundary edges adjacent to point
748 [ # # ]: 0 : DLIList<CubitFacetEdge*> edge_list;
749 [ # # ]: 0 : closest_point->edges( edge_list );
750 [ # # ][ # # ]: 0 : for ( i = edge_list.size(); i--; )
751 : : {
752 [ # # ]: 0 : edge = edge_list.step_and_get();
753 [ # # ][ # # ]: 0 : curve = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(edge));
754 [ # # ][ # # ]: 0 : if ( !curve || !curve->is_in_surface(this,true) )
[ # # ][ # # ]
755 [ # # ]: 0 : edge_list.change_to(0);
756 : : }
757 [ # # ]: 0 : edge_list.remove_all_with_value(0);
758 : :
759 [ # # ][ # # ]: 0 : if (!edge_list.size())
760 : 0 : return CUBIT_PNT_INSIDE;
761 : :
762 [ # # ][ # # ]: 0 : if (edge_list.size() > 2)
763 : : {
764 : : // This is a special case. The point was closest to an
765 : : // intersection of more than two curves on the surface boundary
766 : : // (for example the point where a circular hole is tangent to
767 : : // the boundary of the surface.). If the input position is closest
768 : : // to such a point it must be outside the surface (or on the boundary).
769 : : // However, a little work is required to decide which curve to pass back.
770 [ # # ]: 0 : DLIList<PartitionCurve*> curve_list;
771 [ # # ][ # # ]: 0 : while (edge_list.size())
772 : : {
773 [ # # ][ # # ]: 0 : PartitionEntity* owner = TDVGFacetOwner::get(edge_list.pop());
774 [ # # ][ # # ]: 0 : curve_list.append_unique( dynamic_cast<PartitionCurve*>(owner) );
775 : : }
776 [ # # ][ # # ]: 0 : assert( !! TDVGFacetOwner::get(closest_point) );
777 : 0 : closest_dist_sqr = CUBIT_DBL_MAX;
778 : 0 : curve = 0;
779 [ # # ][ # # ]: 0 : while (curve_list.size())
780 : : {
781 [ # # ]: 0 : PartitionCurve* temp_curve = curve_list.pop();
782 [ # # ]: 0 : temp_curve->closest_point( point, closest_pos );
783 [ # # ][ # # ]: 0 : if ( (point - closest_pos).length_squared() < closest_dist_sqr )
[ # # ]
784 : : {
785 : 0 : curve = temp_curve;
786 [ # # ][ # # ]: 0 : closest_dist_sqr = (point - closest_pos).length_squared();
787 : : }
788 : : }
789 : :
790 [ # # ][ # # ]: 0 : if ( (point - closest_point->coordinates()).length_squared() < tol*tol )
[ # # ][ # # ]
791 : 0 : return CUBIT_PNT_BOUNDARY;
792 : : else
793 [ # # ]: 0 : return CUBIT_PNT_OUTSIDE;
794 : : }
795 : :
796 : :
797 : :
798 [ # # ][ # # ]: 0 : assert(edge_list.size() == 2);
799 [ # # ][ # # ]: 0 : CubitFacetEdge *bdy_edges[2] = {edge_list.get(), edge_list.next()};
800 : :
801 : :
802 : : // need to pass back a curve
803 [ # # ][ # # ]: 0 : curve = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(bdy_edges[0]));
804 : :
805 : : // If within tolerance of boundary
806 [ # # ][ # # ]: 0 : if ( (point - closest_pos).length_squared() < tol*tol )
[ # # ]
807 : 0 : return CUBIT_PNT_BOUNDARY;
808 : :
809 : : // Fill arrays for each of two boundary edges
810 : 0 : CubitFacet* bdy_facets[2] = {0,0}; // adjacent facet
811 : 0 : bool inside_facets[2] = {false,false}; // inside/outside of facet
812 : : CubitPoint* start_pts[2], *end_pts[2]; // edge points
813 [ # # ]: 0 : for ( int j = 0; j < 2; j++ )
814 : : {
815 [ # # ][ # # ]: 0 : for ( i = 0; i < bdy_edges[j]->num_adj_facets(); i++ )
816 : : {
817 [ # # ]: 0 : CubitFacet* facet = bdy_edges[j]->adj_facet(i);
818 [ # # ][ # # ]: 0 : if ( TDVGFacetOwner::get(facet) == this )
819 : : {
820 : 0 : bdy_facets[j] = facet;
821 : 0 : break;
822 : : }
823 : : }
824 [ # # ]: 0 : assert(!!bdy_facets[j]);
825 : :
826 [ # # ]: 0 : int index = bdy_facets[j]->edge_index(bdy_edges[j]);
827 [ # # ][ # # ]: 0 : if ( bdy_facets[j]->edge_use(index) < 0 ) {
828 [ # # ]: 0 : start_pts[j] = bdy_edges[j]->point(1);
829 [ # # ]: 0 : end_pts[j] = bdy_edges[j]->point(0);
830 : : } else {
831 [ # # ]: 0 : start_pts[j] = bdy_edges[j]->point(0);
832 [ # # ]: 0 : end_pts[j] = bdy_edges[j]->point(1);
833 : : }
834 [ # # ][ # # ]: 0 : CubitVector dir = end_pts[j]->coordinates() - start_pts[j]->coordinates();
[ # # ]
835 [ # # ][ # # ]: 0 : double dot = facet->normal() % ((closest_pos - point) * dir);
[ # # ][ # # ]
836 : 0 : inside_facets[j] = dot > 0.0;
837 : : }
838 : :
839 : : // mean normal for facets
840 [ # # ]: 0 : CubitVector normal = bdy_facets[0]->normal();
841 [ # # ][ # # ]: 0 : normal += bdy_facets[1]->normal();
842 : :
843 : : // cross product of edge vectors
844 : : // if we had edges in wrong order, need to reverse
845 : : // crossproduct
846 [ # # ]: 0 : CubitVector cross;
847 [ # # ][ # # ]: 0 : CubitVector dir1 = end_pts[0]->coordinates() - start_pts[0]->coordinates();
[ # # ]
848 [ # # ][ # # ]: 0 : CubitVector dir2 = end_pts[1]->coordinates() - start_pts[1]->coordinates();
[ # # ]
849 [ # # ][ # # ]: 0 : if ( end_pts[0] == closest_point && start_pts[1] == closest_point )
850 : : {
851 [ # # ][ # # ]: 0 : cross = dir1 * dir2;
852 : : }
853 : : else
854 : : {
855 [ # # ][ # # ]: 0 : assert( start_pts[0] == closest_point && end_pts[1] == closest_point );
856 [ # # ][ # # ]: 0 : cross = dir2 * dir1;
857 : : }
858 : :
859 [ # # ]: 0 : bool convex = (cross % normal) > 0.0;
860 [ # # ]: 0 : if ( convex )
861 [ # # ][ # # ]: 0 : return inside_facets[0] && inside_facets[1] ? CUBIT_PNT_INSIDE : CUBIT_PNT_OUTSIDE;
862 : : else
863 [ # # ][ # # ]: 0 : return inside_facets[0] || inside_facets[1] ? CUBIT_PNT_INSIDE : CUBIT_PNT_OUTSIDE;
[ # # ]
864 : : }
865 : :
866 : :
867 : :
868 : :
869 : 0 : CubitPointContainment PartitionSurface::point_containment( double , double )
870 : : {
871 : 0 : return CUBIT_PNT_UNKNOWN;
872 : : }
873 : : /*
874 : : CubitPointContainment PartitionSurface::point_containment(
875 : : CubitVector& point, double u, double v )
876 : : {
877 : : return point_containment( point );
878 : : }
879 : : */
880 : 0 : CubitSense PartitionSurface::get_geometry_sense()
881 : : {
882 : 0 : return geometry_sense;
883 : : }
884 : :
885 : 0 : void PartitionSurface::reverse_sense()
886 : : {
887 [ # # ]: 0 : reverse_loops();
888 [ # # ][ # # ]: 0 : if( owner() )
889 [ # # ][ # # ]: 0 : owner()->notify_reversed(this);
890 : :
891 [ # # ]: 0 : if(geometry_sense == CUBIT_FORWARD)
892 : 0 : geometry_sense = CUBIT_REVERSED;
893 : : else
894 : 0 : geometry_sense = CUBIT_FORWARD;
895 : :
896 : : int j;
897 [ # # ]: 0 : DLIList<CubitFacetData*> surf_facets;
898 [ # # ]: 0 : this->get_facet_data( surf_facets );
899 [ # # ][ # # ]: 0 : for(j=surf_facets.size(); j--;)
900 [ # # ][ # # ]: 0 : surf_facets.get_and_step()->flip();
[ # # ]
901 : 0 : }
902 : :
903 : 0 : PartitionSurface::PartitionSurface( PartitionSurface* split_from )
904 [ # # ][ # # ]: 0 : : geometry_sense(CUBIT_FORWARD), firstLoop(0), firstCoSurf(0)
905 : : {
906 [ # # ][ # # ]: 0 : split_from->sub_entity_set().add_lower_order( this );
907 : 0 : }
908 : :
909 : 0 : PartitionSurface* PartitionSurface::copy()
910 : : {
911 [ # # ]: 0 : return new PartitionSurface(this);
912 : : }
913 : :
914 : 0 : PartitionSurface* PartitionSurface::split( DLIList<CubitFacetData*>& facets )
915 : : {
916 : : int i;
917 : 0 : bool okay = true;
918 : :
919 : : // mark facets
920 [ # # ]: 0 : for( i = facets.size(); i--; )
921 : 0 : facets.get_and_step()->marked(0);
922 [ # # ]: 0 : for( i = facetList.size(); i--; )
923 : 0 : facetList.get_and_step()->marked(1);
924 : :
925 : : // make sure all facets in passed list are in my list,
926 : : // and clear the marks
927 [ # # ]: 0 : for( i = facets.size(); i--; ) {
928 : 0 : CubitFacetData* facet = facets.get_and_step();
929 [ # # ]: 0 : if( facet->marked() )
930 : 0 : facet->marked(0);
931 : : else
932 : 0 : okay = false;
933 : : }
934 : :
935 [ # # ]: 0 : if (!okay) {
936 [ # # ]: 0 : for( i = facetList.size(); i--; )
937 : 0 : facetList.get_and_step()->marked(0);
938 [ # # ]: 0 : assert(okay);
939 : 0 : return 0;
940 : : }
941 : :
942 [ # # ]: 0 : for( i = facetList.size(); i--; ) {
943 [ # # ]: 0 : if( facetList.step_and_get()->marked() )
944 : 0 : facetList.get()->marked(0);
945 : : else
946 : 0 : facetList.change_to(0);
947 : : }
948 [ # # ]: 0 : facetList.remove_all_with_value(0);
949 : :
950 : 0 : PartitionSurface* result = copy();
951 : 0 : result->set_facet_data(facets);
952 : 0 : return result;
953 : : }
954 : :
955 : 0 : CubitStatus PartitionSurface::combine( PartitionSurface* other_surf )
956 : : {
957 [ # # ]: 0 : for ( int i = other_surf->facetList.size(); i--; )
958 : 0 : TDVGFacetOwner::set(other_surf->facetList.step_and_get(),this);
959 : 0 : facetList += other_surf->facetList;
960 : 0 : other_surf->facetList.clean_out();
961 : 0 : return CUBIT_SUCCESS;
962 : : }
963 : :
964 : 0 : void PartitionSurface::get_facet_data( DLIList<CubitFacetData*>& result_list ) const
965 : : {
966 : 0 : result_list = facetList;
967 : 0 : }
968 : :
969 : 0 : void PartitionSurface::set_facet_data( const DLIList<CubitFacetData*>& new_list )
970 : : {
971 : : int i;
972 : :
973 [ # # ]: 0 : for ( i = facetList.size(); i--; )
974 : 0 : TDVGFacetOwner::remove(facetList.step_and_get());
975 : 0 : facetList = new_list;
976 [ # # ]: 0 : for ( i = facetList.size(); i--; )
977 : 0 : TDVGFacetOwner::set(facetList.step_and_get(),this);
978 : 0 : }
979 : :
980 : 0 : void PartitionSurface::notify_split( FacetEntity* old_tri, FacetEntity* new_tri )
981 : : {
982 [ # # ][ # # ]: 0 : if ( dynamic_cast<CubitFacetEdge*>(old_tri) )
[ # # ]
983 : 0 : return;
984 : :
985 [ # # ]: 0 : CubitFacetData* new_ptr = dynamic_cast<CubitFacetData*>(new_tri);
986 : : #ifndef NDEBUG
987 [ # # ]: 0 : CubitFacetData* old_ptr = dynamic_cast<CubitFacetData*>(old_tri);
988 [ # # ][ # # ]: 0 : assert(old_ptr && new_ptr && facetList.is_in_list(old_ptr));
[ # # ][ # # ]
989 : : #endif
990 [ # # ]: 0 : TDVGFacetOwner::set(new_ptr,this);
991 [ # # ]: 0 : facetList.append(new_ptr);
992 : : }
993 : :
994 : 0 : CubitStatus PartitionSurface::init_facet_data()
995 : : {
996 [ # # ][ # # ]: 0 : Surface* real_surf = dynamic_cast<Surface*>(partitioned_entity());
997 : : //assert(are_marks_cleared());
998 : :
999 : 0 : CubitStatus res = CUBIT_SUCCESS;
1000 [ # # ]: 0 : GMem gMem;
1001 : :
1002 : : // TODO - tolerance arguments are defaulted. Do we need to specify?
1003 [ # # ]: 0 : res = real_surf->get_geometry_query_engine()->
1004 [ # # ][ # # ]: 0 : get_graphics(real_surf, &gMem, PartitionTool::instance()->get_faceting_tolerance() );
[ # # ]
1005 [ # # ]: 0 : if( !res )
1006 : 0 : return CUBIT_FAILURE;
1007 : :
1008 : : // Work around bug w/ coincident facet points
1009 : : // for blend surfaces. Consolidate coincident points.
1010 : 0 : int old_count = gMem.pointListCount;
1011 [ # # ]: 0 : gMem.consolidate_points(GEOMETRY_RESABS);
1012 [ # # ]: 0 : if( old_count != gMem.pointListCount ) {
1013 [ # # ][ # # ]: 0 : PRINT_WARNING("Possible invalid facetting for surface. "
[ # # ]
1014 [ # # ]: 0 : "Coincident points found.\n");
1015 : : }
1016 : :
1017 [ # # ][ # # ]: 0 : DLIList<CubitFacetData*> surf_facets;
1018 [ # # ][ # # ]: 0 : CubitPointData** point_array = new CubitPointData*[gMem.pointListCount];
1019 : :
1020 : : // create CubitFacetData from GMem
1021 : : int i;
1022 : :
1023 [ # # ][ # # ]: 0 : CubitVector ipos, opos;
1024 [ # # ]: 0 : for ( i = 0; i < gMem.pointListCount; i++ ) {
1025 [ # # ][ # # ]: 0 : ipos.set( gMem.point_list()[i].x, gMem.point_list()[i].y, gMem.point_list()[i].z );
[ # # ][ # # ]
1026 [ # # ][ # # ]: 0 : if( real_surf->closest_point( ipos, &opos ) )
1027 [ # # ]: 0 : ipos = opos;
1028 [ # # ][ # # ]: 0 : point_array[i] = new CubitPointData( ipos );
1029 : : }
1030 : :
1031 : 0 : int junk = 0;
1032 : 0 : bool fail_out = false;
1033 : : CubitPoint *p1, *p2, *p3;
1034 [ # # ]: 0 : for ( i = 0; i < gMem.fListCount; i += 4 )
1035 : : {
1036 [ # # ][ # # ]: 0 : if(gMem.facet_list()[i] != 3)
1037 : 0 : fail_out = true;
1038 : : else
1039 : : {
1040 [ # # ]: 0 : p1 = point_array[ gMem.facet_list()[i+1] ];
1041 [ # # ]: 0 : p2 = point_array[ gMem.facet_list()[i+2] ];
1042 [ # # ]: 0 : p3 = point_array[ gMem.facet_list()[i+3] ];
1043 : :
1044 [ # # ][ # # ]: 0 : if(p1 == p2 || p1 == p3 || p2 == p3)
[ # # ]
1045 : 0 : fail_out = true;
1046 : : }
1047 [ # # ]: 0 : if(fail_out == true)
1048 : : {
1049 [ # # ][ # # ]: 0 : PRINT_ERROR("Non-triangular facet encountered. Aborting.\n");
[ # # ][ # # ]
1050 [ # # ][ # # ]: 0 : while (surf_facets.size())
1051 [ # # ][ # # ]: 0 : delete surf_facets.pop();
[ # # ]
1052 [ # # ]: 0 : for (i = 0; i < gMem.pointListCount; i++)
1053 [ # # ][ # # ]: 0 : delete point_array[i];
1054 [ # # ]: 0 : delete [] point_array;
1055 : 0 : return CUBIT_FAILURE;
1056 : : }
1057 : : else
1058 : : {
1059 [ # # ][ # # ]: 0 : CubitFacetData* facet = new CubitFacetData(p1, p2, p3, &junk );
1060 [ # # ]: 0 : surf_facets.append(facet);
1061 : : }
1062 : : }
1063 : :
1064 [ # # ]: 0 : delete [] point_array;
1065 : :
1066 [ # # ]: 0 : if(geometry_sense == CUBIT_REVERSED)
1067 : : {
1068 [ # # ][ # # ]: 0 : for(i=surf_facets.size(); i--;)
1069 [ # # ][ # # ]: 0 : surf_facets.get_and_step()->flip();
1070 : : }
1071 : :
1072 : : /*
1073 : : // Make sure facet orientation is consistant
1074 : : DLIList<CubitFacet*> facets(surf_facets.size());
1075 : : for ( i = surf_facets.size(); i--; )
1076 : : {
1077 : : CubitFacet* facet = surf_facets.step_and_get();
1078 : : facet->marked(1);
1079 : : facets.append(facet);
1080 : : }
1081 : : bool reversed_some = false;
1082 : : while ( facets.size() )
1083 : : {
1084 : : CubitFacet* facet = facets.pop();
1085 : : facet->marked(0);
1086 : : bool reversed[3] = {false,false,false};
1087 : : CubitFacet* neighbors[3] = {0,0,0};
1088 : : for ( i = 0; i < 3; i++ )
1089 : : {
1090 : : CubitFacetEdge* edge = facet->edge(i);
1091 : : CubitFacet* other = edge->other_facet(facet);
1092 : : if( other && other != facet )
1093 : : {
1094 : : neighbors[i] = other;
1095 : : int index = other->edge_index(edge);
1096 : : if ( facet->edge_use(i) == other->edge_use(index) )
1097 : : reversed[i] = true;
1098 : : }
1099 : : }
1100 : :
1101 : : if ( !(reversed[0] || reversed[1] || reversed[2]) )
1102 : : continue;
1103 : :
1104 : : facet->flip();
1105 : : reversed_some = true;
1106 : : reversed[0] = !reversed[0];
1107 : : reversed[1] = !reversed[1];
1108 : : reversed[2] = !reversed[2];
1109 : :
1110 : : for ( i = 0; i < 3; i++ )
1111 : : {
1112 : : if( neighbors[i] && reversed[i] && !neighbors[i]->marked() )
1113 : : {
1114 : : neighbors[i]->marked(1);
1115 : : facets.append( neighbors[i] );
1116 : : }
1117 : : }
1118 : : }
1119 : :
1120 : : if( reversed_some )
1121 : : {
1122 : : PRINT_WARNING("Possible invalid facetting for surface. "
1123 : : "Inconsistent facet orientation.\n");
1124 : : }
1125 : :
1126 : : // pick a facet and compare to surface normal to see
1127 : : // if we have them all backwards
1128 : : surf_facets.reset();
1129 : : CubitFacet* facet = surf_facets.get();
1130 : : CubitVector pts[3] = { facet->point(0)->coordinates(),
1131 : : facet->point(1)->coordinates(),
1132 : : facet->point(2)->coordinates()};
1133 : : CubitVector facet_norm = (pts[1] - pts[0]) * (pts[2] - pts[0]);
1134 : : CubitVector facet_cent = (pts[0] + pts[1] + pts[2]) / 3.0;
1135 : : CubitVector surf_norm;
1136 : : real_surf->closest_point( facet_cent, 0, &surf_norm );
1137 : : if ( facet_norm % surf_norm < 0 )
1138 : : {
1139 : : PRINT_WARNING("Possible invalid facetting for surface. "
1140 : : "Backwards facets.\n");
1141 : : for ( i = surf_facets.size(); i--; )
1142 : : surf_facets.step_and_get()->flip();
1143 : : }
1144 : : */
1145 : :
1146 [ # # ][ # # ]: 0 : PartSurfFacetTool tool(this);
1147 [ # # ][ # # ]: 0 : return tool.init_facet_data(surf_facets);
1148 : : }
1149 : :
1150 : :
1151 : 0 : void PartitionSurface::replace_facets( DLIList<CubitFacetData*> &dead_facets,
1152 : : DLIList<CubitFacetData*> &new_facets)
1153 : : {
1154 : : int i;
1155 : 0 : facetList -= dead_facets;
1156 : 0 : facetList += new_facets;
1157 : :
1158 [ # # ]: 0 : for( i = dead_facets.size(); i--; )
1159 : 0 : TDVGFacetOwner::remove( dead_facets.step_and_get() );
1160 : :
1161 [ # # ]: 0 : for( i = new_facets.size(); i--; )
1162 : 0 : TDVGFacetOwner::set( new_facets.step_and_get(), this );
1163 : :
1164 : : // TODO - memory management - where should the facets get deleted
1165 : 0 : }
1166 : :
1167 : : //-------------------------------------------------------------------------
1168 : : // Purpose : Find closest facet and point on facet
1169 : : //
1170 : : // Special Notes :
1171 : : //
1172 : : // Creator : Jason Kraftcheck
1173 : : //
1174 : : // Creation Date : 03/28/03
1175 : : //-------------------------------------------------------------------------
1176 : 0 : CubitFacet* PartitionSurface::closest_facet( const CubitVector& input_position,
1177 : : CubitVector& result_position)
1178 : : {
1179 : 0 : return PartSurfFacetTool::closest_facet( input_position, facetList, result_position );
1180 : : }
1181 : :
1182 : :
1183 : : //-------------------------------------------------------------------------
1184 : : // Purpose : Save geometry in an attribute
1185 : : //
1186 : : // Special Notes :
1187 : : //
1188 : : // Creator : Jason Kraftcheck
1189 : : //
1190 : : // Creation Date : 01/21/03
1191 : : //-------------------------------------------------------------------------
1192 : 0 : CubitStatus PartitionSurface::save( CubitSimpleAttrib& attrib )
1193 : : {
1194 [ # # ][ # # ]: 0 : assert(dynamic_cast<Lump*>(partitioned_entity()) != 0);
[ # # ]
1195 : :
1196 : : int i;
1197 [ # # ][ # # ]: 0 : int id = sub_entity_set().get_id(this);
1198 [ # # ]: 0 : if( id <= 0 ) return CUBIT_FAILURE;
1199 : :
1200 : : // get facets
1201 [ # # ]: 0 : DLIList<CubitFacetData*> facets;
1202 [ # # ]: 0 : get_facet_data( facets );
1203 : :
1204 : : // get list of points from facets
1205 [ # # ][ # # ]: 0 : DLIList<CubitPoint*> points(facets.size()*3), facet_points(3);
[ # # ][ # # ]
[ # # ]
1206 [ # # ]: 0 : facets.reset();
1207 [ # # ][ # # ]: 0 : for( i = facets.size(); i--; )
1208 : : {
1209 [ # # ]: 0 : facet_points.clean_out();
1210 [ # # ][ # # ]: 0 : facets.get_and_step()->points(facet_points);
1211 [ # # ]: 0 : points += facet_points;
1212 : : }
1213 : :
1214 [ # # ][ # # ]: 0 : for( i = points.size(); i--; )
1215 [ # # ][ # # ]: 0 : points.step_and_get()->marked(0);
1216 [ # # ][ # # ]: 0 : for( i = points.size(); i--; )
1217 : : {
1218 [ # # ]: 0 : CubitPoint* pt = points.step_and_get();
1219 [ # # ][ # # ]: 0 : pt->marked(pt->marked()+1);
1220 : : }
1221 [ # # ]: 0 : points.last();
1222 [ # # ][ # # ]: 0 : for( i = points.size(); i--; )
1223 : : {
1224 [ # # ][ # # ]: 0 : if( points.get()->marked() > 1 )
[ # # ]
1225 : : {
1226 [ # # ][ # # ]: 0 : points.get()->marked( points.get()->marked() - 1 );
[ # # ][ # # ]
1227 [ # # ]: 0 : points.change_to(0);
1228 : : }
1229 [ # # ]: 0 : points.back();
1230 : : }
1231 [ # # ]: 0 : points.remove_all_with_value(0);
1232 : :
1233 : : // construct position list
1234 [ # # ][ # # ]: 0 : DLIList<CubitVector*> pt_list(points.size());
[ # # ]
1235 [ # # ]: 0 : points.reset();
1236 [ # # ][ # # ]: 0 : for( i = 0; i < points.size(); i++ )
1237 : : {
1238 [ # # ]: 0 : CubitPoint* pt = points.get_and_step();
1239 [ # # ][ # # ]: 0 : pt_list.append( new CubitVector(pt->coordinates()) );
[ # # ]
1240 [ # # ]: 0 : pt->marked(i);
1241 : : }
1242 : :
1243 : : // connect facet connectivity list
1244 [ # # ][ # # ]: 0 : DLIList<int> facetlist( facets.size() * 3 );
[ # # ]
1245 [ # # ]: 0 : facets.reset();
1246 [ # # ][ # # ]: 0 : for( i = facets.size(); i--; )
1247 : : {
1248 [ # # ]: 0 : facet_points.clean_out();
1249 [ # # ][ # # ]: 0 : facets.get_and_step()->points(facet_points);
1250 [ # # ]: 0 : facet_points.reset();
1251 [ # # ][ # # ]: 0 : for( int j = facet_points.size(); j--; )
1252 [ # # ][ # # ]: 0 : facetlist.append( facet_points.get_and_step()->marked() );
[ # # ]
1253 : : }
1254 : :
1255 [ # # ][ # # ]: 0 : DLIList<int> facet_point_owners;
1256 [ # # ][ # # ]: 0 : DLIList<CubitFacetEdge*> pt_edges;
1257 [ # # ]: 0 : points.reset();
1258 [ # # ][ # # ]: 0 : for ( i = points.size(); i--; )
1259 : : {
1260 [ # # ]: 0 : CubitPoint* pt = points.get_and_step();
1261 [ # # ]: 0 : PartitionEntity* owner = TDVGFacetOwner::get(pt);
1262 [ # # ]: 0 : if (!owner)
1263 : : {
1264 [ # # ]: 0 : pt->edges(pt_edges);
1265 [ # # ][ # # ]: 0 : while ( pt_edges.size() )
1266 : : {
1267 [ # # ]: 0 : CubitFacetEdge* edge = pt_edges.pop();
1268 [ # # ]: 0 : PartitionEntity* tmp = TDVGFacetOwner::get(edge);
1269 [ # # ]: 0 : if ( tmp )
1270 : : {
1271 [ # # ][ # # ]: 0 : assert(!owner || owner == tmp);
1272 : 0 : owner = tmp;
1273 : : }
1274 : : }
1275 : : }
1276 [ # # ]: 0 : if ( !owner )
1277 : 0 : owner = this;
1278 : :
1279 : : int set_id, ent_id;
1280 [ # # ][ # # ]: 0 : if( &(owner->sub_entity_set()) == &(sub_entity_set()) )
[ # # ]
1281 : : {
1282 : 0 : set_id = 0;
1283 [ # # ][ # # ]: 0 : ent_id = sub_entity_set().get_id( owner );
1284 : : }
1285 : : else
1286 : : {
1287 [ # # ][ # # ]: 0 : set_id = owner->sub_entity_set().get_unique_id();
1288 [ # # ][ # # ]: 0 : ent_id = owner->sub_entity_set().get_id(owner);
1289 : : }
1290 [ # # ]: 0 : facet_point_owners.append( set_id );
1291 [ # # ]: 0 : facet_point_owners.append( ent_id );
1292 : : }
1293 : :
1294 : : // clean up point marks
1295 [ # # ][ # # ]: 0 : for( i = points.size(); i--; )
1296 [ # # ][ # # ]: 0 : points.step_and_get()->marked(0);
1297 : :
1298 [ # # ][ # # ]: 0 : DLIList<int> topo_list;
1299 [ # # ]: 0 : get_save_topology( topo_list );
1300 : :
1301 [ # # ]: 0 : return sub_entity_set().save_geometry( id, 2, &pt_list, &facetlist, &topo_list,
1302 [ # # ][ # # ]: 0 : &facet_point_owners, attrib );
1303 : : }
1304 : :
1305 : : //-------------------------------------------------------------------------
1306 : : // Purpose : Get topology connectivity list for use in saving
1307 : : //
1308 : : // Special Notes :
1309 : : //
1310 : : // Creator : Jason Kraftcheck
1311 : : //
1312 : : // Creation Date : 01/21/03
1313 : : //-------------------------------------------------------------------------
1314 : 0 : CubitStatus PartitionSurface::get_save_topology( DLIList<int>& topo_list )
1315 : : {
1316 : 0 : PartitionLoop* loop = 0;
1317 [ # # ]: 0 : while( (loop = next_loop(loop)) )
1318 : : {
1319 [ # # ]: 0 : topo_list.append(loop->num_coedges());
1320 : 0 : PartitionCoEdge* coedge = loop->first_coedge();
1321 [ # # ]: 0 : do
1322 : : {
1323 : : int set_id, crv_id;
1324 [ # # ]: 0 : PartitionCurve* curve = coedge->get_curve();
1325 [ # # ][ # # ]: 0 : if( &(curve->sub_entity_set()) == &(sub_entity_set()) )
[ # # ]
1326 : : {
1327 : 0 : set_id = 0;
1328 [ # # ][ # # ]: 0 : crv_id = sub_entity_set().get_id( curve );
[ # # ]
1329 : : }
1330 : : else
1331 : : {
1332 [ # # ][ # # ]: 0 : set_id = curve->sub_entity_set().get_unique_id();
1333 [ # # ][ # # ]: 0 : crv_id = curve->sub_entity_set().get_id(curve);
[ # # ]
1334 : : }
1335 : :
1336 [ # # ][ # # ]: 0 : if( coedge->sense() == CUBIT_REVERSED )
1337 : 0 : crv_id *= -1;
1338 [ # # ]: 0 : topo_list.append(set_id);
1339 [ # # ]: 0 : topo_list.append(crv_id);
1340 : 0 : } while( (coedge = loop->next_coedge(coedge)) != loop->first_coedge() );
1341 : : }
1342 : :
1343 : 0 : return CUBIT_SUCCESS;
1344 : : }
1345 : :
1346 : :
1347 : 0 : void PartitionSurface::interior_facet_points( DLIList<CubitPoint*>& list ) const
1348 : : {
1349 : :
1350 [ # # ][ # # ]: 0 : DLIList<CubitPoint*> point_list(facetList.size() * 3);
1351 [ # # ][ # # ]: 0 : DLIList<CubitFacetEdge*> edge_list;
1352 : : int i;
1353 [ # # ][ # # ]: 0 : for( i = 0; i < facetList.size(); i++ )
1354 : : {
1355 [ # # ]: 0 : CubitFacetData* facet = facetList.next(i);
1356 [ # # ]: 0 : for( int j = 0; j < 3; j++ )
1357 : : {
1358 [ # # ]: 0 : CubitPoint* pt = facet->point(j);
1359 [ # # ][ # # ]: 0 : if( TDVGFacetOwner::get(pt) )
1360 : 0 : continue; // not interior - on a vertex
1361 : :
1362 [ # # ]: 0 : edge_list.clean_out();
1363 [ # # ]: 0 : pt->edges( edge_list );
1364 : 0 : bool skip = false;
1365 [ # # ][ # # ]: 0 : for( int k = edge_list.size(); k--; )
1366 [ # # ][ # # ]: 0 : if( TDVGFacetOwner::get(edge_list.step_and_get()) )
[ # # ]
1367 : 0 : skip = true; // not interior - on a curve
1368 : :
1369 [ # # ]: 0 : if( !skip )
1370 [ # # ]: 0 : point_list.append(pt);
1371 : : }
1372 : : }
1373 : :
1374 : : // uniquify list
1375 [ # # ][ # # ]: 0 : for( i = point_list.size(); i--; )
1376 [ # # ][ # # ]: 0 : point_list.step_and_get()->marked(1);
1377 [ # # ][ # # ]: 0 : for( i = point_list.size(); i--; )
1378 [ # # ][ # # ]: 0 : if( point_list.step_and_get()->marked() )
[ # # ]
1379 [ # # ][ # # ]: 0 : point_list.get()->marked(0);
1380 : : else
1381 [ # # ]: 0 : point_list.change_to(0);
1382 [ # # ]: 0 : point_list.remove_all_with_value(0);
1383 [ # # ][ # # ]: 0 : list = point_list;
1384 : 0 : }
1385 : :
1386 : :
1387 : 0 : void PartitionSurface::transform( const CubitTransformMatrix& xform )
1388 : : {
1389 : : int i;
1390 : :
1391 [ # # ]: 0 : DLIList<CubitPoint*> points;
1392 [ # # ]: 0 : interior_facet_points(points);
1393 [ # # ][ # # ]: 0 : for(i = points.size(); i--; )
1394 : : {
1395 [ # # ]: 0 : CubitPoint* pt = points.step_and_get();
1396 [ # # ][ # # ]: 0 : pt->set( xform * pt->coordinates() );
[ # # ]
1397 : : }
1398 : :
1399 [ # # ][ # # ]: 0 : double det = xform.sub_matrix( 3, 3 ).determinant();
[ # # ]
1400 [ # # ]: 0 : if (det < 0.0)
1401 : : {
1402 [ # # ][ # # ]: 0 : for (i = 0; i < facetList.size(); i++)
1403 [ # # ][ # # ]: 0 : facetList.next(i)->flip();
1404 : :
1405 : 0 : PartitionLoop* loop = 0;
1406 [ # # ][ # # ]: 0 : while ((loop = next_loop(loop)))
1407 [ # # ]: 0 : loop->reverse();
1408 : : }
1409 : :
1410 [ # # ][ # # ]: 0 : for (i = 0; i < facetList.size(); i++ )
1411 : : {
1412 [ # # ][ # # ]: 0 : facetList.next(i)->update_plane();
1413 [ # # ]: 0 : }
1414 : :
1415 : 0 : }
1416 : :
1417 : :
1418 : :
1419 : 0 : PartitionSurface* PartitionSurface::construct( const CubitSimpleAttrib& attrib,
1420 : : PartitionLump* vol )
1421 : : {
1422 : : // construct surface and read attrib data
1423 [ # # ][ # # ]: 0 : PartitionSurface* new_surf = new PartitionSurface;
1424 [ # # ]: 0 : DLIList<CubitVector*> facet_points;
1425 [ # # ][ # # ]: 0 : DLIList<int> facets, curve_conn, point_owners;
[ # # ][ # # ]
[ # # ][ # # ]
1426 [ # # ]: 0 : vol->sub_entity_set().
1427 [ # # ][ # # ]: 0 : add_lower_order( new_surf, attrib, 2, facet_points, facets, curve_conn, point_owners );
1428 : :
1429 [ # # ][ # # ]: 0 : if( facets.size() % 3 != 0 )
1430 : : {
1431 [ # # ][ # # ]: 0 : assert( !(facets.size() % 3 ) );
1432 [ # # ][ # # ]: 0 : delete new_surf;
1433 : 0 : return 0;
1434 : : }
1435 : :
1436 : : // create loops and coedges
1437 [ # # ][ # # ]: 0 : DLIList<PartitionCurve*> curve_list;
1438 [ # # ]: 0 : int i = curve_conn.size();
1439 [ # # ]: 0 : curve_conn.reset();
1440 : 0 : bool okay = true;
1441 [ # # ][ # # ]: 0 : while( okay && i > 0 )
1442 : : {
1443 [ # # ]: 0 : int k = curve_conn.get_and_step();
1444 : 0 : i--;
1445 : :
1446 [ # # ][ # # ]: 0 : if( k <= 0 || i < 2*k )
1447 : 0 : { okay = false; break; }
1448 : :
1449 [ # # ][ # # ]: 0 : PartitionLoop* new_loop = new PartitionLoop();
1450 : 0 : PartitionCoEdge* prev_coedge = 0;
1451 [ # # ]: 0 : new_surf->add( new_loop );
1452 : :
1453 [ # # ][ # # ]: 0 : for( int j = 0; okay && j < k; j++ )
1454 : : {
1455 [ # # ]: 0 : int set_id = curve_conn.get_and_step();
1456 [ # # ]: 0 : int ent_id = curve_conn.get_and_step();
1457 : 0 : i -= 2;
1458 : :
1459 : 0 : CubitSense sense = CUBIT_FORWARD;
1460 [ # # ]: 0 : if( ent_id < 0 )
1461 : : {
1462 : 0 : sense = CUBIT_REVERSED;
1463 : 0 : ent_id = -ent_id;
1464 : : }
1465 : :
1466 [ # # ]: 0 : PartitionEntity* ent = PartitionEngine::instance()
1467 [ # # ][ # # ]: 0 : .entity_from_id( set_id, ent_id, vol->sub_entity_set() );
1468 [ # # ]: 0 : PartitionCurve* curve = dynamic_cast<PartitionCurve*>(ent);
1469 : :
1470 [ # # ]: 0 : if( !curve )
1471 : 0 : { okay = false; break; }
1472 : :
1473 [ # # ]: 0 : curve_list.append( curve );
1474 [ # # ][ # # ]: 0 : PartitionCoEdge* coedge = new PartitionCoEdge( new_surf, sense );
1475 [ # # ]: 0 : new_loop->insert_after( coedge, prev_coedge );
1476 : 0 : prev_coedge = coedge;
1477 [ # # ]: 0 : curve->add( coedge );
1478 : : }
1479 : : }
1480 : :
1481 [ # # ]: 0 : if( !okay )
1482 : : {
1483 [ # # ][ # # ]: 0 : PartitionEngine::instance().destroy_surface( new_surf );
1484 : 0 : return 0;
1485 : : }
1486 : :
1487 : : // construct facet points
1488 [ # # ][ # # ]: 0 : CubitPointData** points = new CubitPointData*[facet_points.size()];
[ # # ]
1489 [ # # ]: 0 : facet_points.reset();
1490 [ # # ]: 0 : point_owners.reset();
1491 [ # # ][ # # ]: 0 : for( i = 0; i < facet_points.size(); i++ )
1492 : : {
1493 [ # # ]: 0 : CubitVector* pt = facet_points.get_and_step();
1494 [ # # ][ # # ]: 0 : points[i] = new CubitPointData(*pt);
1495 : 0 : delete pt;
1496 : :
1497 [ # # ]: 0 : int set_id = point_owners.get_and_step();
1498 [ # # ]: 0 : int ent_id = point_owners.get_and_step();
1499 [ # # ]: 0 : PartitionEntity* owner = PartitionEngine::instance()
1500 [ # # ][ # # ]: 0 : .entity_from_id( set_id, ent_id, vol->sub_entity_set() );
1501 : :
1502 [ # # ]: 0 : if ( !owner )
1503 : : {
1504 : 0 : okay = false;
1505 : 0 : break;
1506 : : }
1507 : :
1508 [ # # ][ # # ]: 0 : if ( owner != new_surf )
1509 : : {
1510 [ # # ][ # # ]: 0 : if ( !dynamic_cast<PartitionPoint*>(owner) &&
[ # # ][ # # ]
1511 [ # # ]: 0 : !dynamic_cast<PartitionCurve*>(owner) )
1512 : : {
1513 : 0 : okay = false;
1514 : 0 : break;
1515 : : }
1516 [ # # ]: 0 : TDVGFacetOwner::set(points[i], owner);
1517 : : }
1518 : : }
1519 : :
1520 [ # # ]: 0 : if ( !okay )
1521 : : {
1522 [ # # ][ # # ]: 0 : for ( i = 0; i < facet_points.size(); i++ )
1523 [ # # ][ # # ]: 0 : delete points[i];
1524 [ # # ]: 0 : delete [] points;
1525 [ # # ][ # # ]: 0 : PartitionEngine::instance().destroy_surface( new_surf );
1526 : 0 : return 0;
1527 : : }
1528 : :
1529 : : // construct facets
1530 [ # # ]: 0 : facets.reset();
1531 [ # # ][ # # ]: 0 : DLIList<CubitFacetData*> facet_list;
1532 : 0 : int junk = 0;
1533 [ # # ][ # # ]: 0 : for( i = 0; i < facets.size(); i += 3 )
1534 : : {
1535 : : CubitFacetData* facet = new CubitFacetData(
1536 [ # # ]: 0 : points[facets.next(0)],
1537 [ # # ]: 0 : points[facets.next(1)],
1538 [ # # ][ # # ]: 0 : points[facets.next(2)], &junk );
[ # # ]
1539 [ # # ]: 0 : facet_list.append(facet);
1540 [ # # ]: 0 : facets.step(3);
1541 : :
1542 : : // set edge owners to this surface as a kind of mark
1543 : : // (will use this a little later)
1544 [ # # ]: 0 : for ( int j = 0; j < 3; j++ )
1545 [ # # ][ # # ]: 0 : TDVGFacetOwner::set( facet->edge(j), new_surf );
[ # # ]
1546 : : }
1547 : :
1548 : : // Seam facet points on vertices
1549 [ # # ][ # # ]: 0 : for ( i = 0; i < facet_points.size(); i++ )
1550 : : {
1551 [ # # ]: 0 : PartitionEntity* ent = TDVGFacetOwner::get(points[i]);
1552 [ # # ]: 0 : PartitionPoint* vertex = dynamic_cast<PartitionPoint*>(ent);
1553 [ # # ]: 0 : if (!vertex) continue;
1554 : :
1555 [ # # ][ # # ]: 0 : if ( !vertex->facet_point() )
1556 [ # # ]: 0 : vertex->facet_point(points[i]);
1557 [ # # ][ # # ]: 0 : else if ( vertex->facet_point() != points[i] )
1558 : : {
1559 [ # # ][ # # ]: 0 : vertex->facet_point()->merge_points(points[i]);
1560 [ # # ]: 0 : points[i] = vertex->facet_point();
1561 : : }
1562 : : }
1563 : :
1564 : : // done with point list -- delete it
1565 [ # # ]: 0 : delete [] points;
1566 : :
1567 : : // seam facet edges with curves
1568 [ # # ][ # # ]: 0 : DLIList<CubitFacetEdge*> pt_edges;
1569 [ # # ][ # # ]: 0 : DLIList<CubitFacetEdgeData*> curve_edges;
1570 [ # # ][ # # ]: 0 : while ( curve_list.size() )
1571 : : {
1572 [ # # ]: 0 : curve_edges.clean_out();
1573 [ # # ]: 0 : PartitionCurve* curve = curve_list.pop();
1574 [ # # ][ # # ]: 0 : CubitPoint* pt = curve->start_point()->facet_point();
1575 [ # # ]: 0 : if (!pt) {okay = false; break;}
1576 : :
1577 : : //For periodic curves, you can easily set up 'curve_edges'
1578 : : //in the opposite order. When finding the first edge, I added
1579 : : //the logic in the if(find_correct_direction_on_periodics) block. It
1580 : : //looks at the first facet edge in the curve and finds the appropriate
1581 : : //facet edge sharing the same point that has the smallest angle between.
1582 : : //This approach assure that we are appending the facet edges to the list
1583 : : //'curve_edges' in the same orientation as the facet edges on the curve.
1584 : 0 : bool find_correct_direction_on_periodics = false;
1585 [ # # ]: 0 : PartitionPoint* start_vtx = curve->start_point();
1586 [ # # ]: 0 : PartitionPoint* end_vtx = curve->end_point();
1587 [ # # ]: 0 : CubitPointData* start_point = start_vtx->facet_point();
1588 [ # # ]: 0 : CubitPointData* end_point = end_vtx->facet_point();
1589 [ # # ][ # # ]: 0 : if( start_vtx == end_vtx && start_point == end_point )
1590 : 0 : find_correct_direction_on_periodics = true;
1591 : :
1592 : 0 : double smallest_angle = CUBIT_DBL_MAX;
1593 : 0 : bool debug = false;
1594 : :
1595 [ # # ]: 0 : do {
1596 : :
1597 [ # # ]: 0 : if( smallest_angle != CUBIT_DBL_MAX )
1598 : 0 : find_correct_direction_on_periodics = false;
1599 : :
1600 : 0 : CubitFacetEdge *edge = 0, *pt_edge = 0;
1601 [ # # ]: 0 : pt_edges.clean_out();
1602 [ # # ]: 0 : pt->edges(pt_edges);
1603 [ # # ][ # # ]: 0 : while ( pt_edges.size() )
1604 : : {
1605 [ # # ]: 0 : CubitFacetEdge* tmp_edge = pt_edges.pop();
1606 [ # # ][ # # ]: 0 : if ( TDVGFacetOwner::get(tmp_edge) != new_surf )
[ # # ]
1607 : 0 : continue;
1608 : :
1609 [ # # ][ # # ]: 0 : PartitionEntity* owner = TDVGFacetOwner::get(tmp_edge->other_point(pt));
1610 [ # # ][ # # ]: 0 : if ( owner == curve )
1611 : : {
1612 [ # # ]: 0 : if( find_correct_direction_on_periodics )
1613 : : {
1614 : 0 : CubitPoint* start_point = pt;
1615 : :
1616 [ # # ]: 0 : DLIList<CubitFacetEdgeData*> curve_edges;
1617 [ # # ]: 0 : curve->get_facet_data(curve_edges);
1618 [ # # ]: 0 : curve_edges.reset();
1619 [ # # ]: 0 : CubitFacetEdge *first_facet_edge = curve_edges.get();
1620 [ # # ]: 0 : CubitPoint *real_next_point = first_facet_edge->other_point(start_point);
1621 [ # # ]: 0 : CubitPoint *possible_next_point = tmp_edge->other_point(start_point);
1622 : :
1623 [ # # ][ # # ]: 0 : CubitVector v1 = real_next_point->coordinates() - start_point->coordinates();
[ # # ]
1624 [ # # ][ # # ]: 0 : CubitVector v2 = possible_next_point->coordinates() - start_point->coordinates();
[ # # ]
1625 : :
1626 [ # # ]: 0 : double angle = v1.interior_angle(v2);
1627 : :
1628 [ # # ]: 0 : if( angle < smallest_angle )
1629 : : {
1630 : 0 : smallest_angle = angle;
1631 : 0 : edge = tmp_edge;
1632 [ # # ]: 0 : }
1633 : : }
1634 : : else
1635 : : {
1636 : 0 : edge = tmp_edge;
1637 : : }
1638 : : }
1639 [ # # ][ # # ]: 0 : else if ( owner == curve->end_point() )
[ # # ]
1640 : : {
1641 : 0 : pt_edge = tmp_edge;
1642 : : }
1643 : : }
1644 : :
1645 [ # # ]: 0 : if ( !edge )
1646 : 0 : edge = pt_edge;
1647 : : else
1648 : : {
1649 : : //so we don't traverse backwards
1650 [ # # ][ # # ]: 0 : TDVGFacetOwner::set(edge->other_point(pt), 0);
1651 : : }
1652 : :
1653 [ # # ]: 0 : CubitFacetEdgeData* edge_d = dynamic_cast<CubitFacetEdgeData*>(edge);
1654 [ # # ]: 0 : if (!edge_d)
1655 : : {
1656 : 0 : okay = false;
1657 : 0 : break;
1658 : : }
1659 : :
1660 [ # # ]: 0 : if( debug )
1661 : : {
1662 [ # # ]: 0 : pt->debug_draw(4);
1663 [ # # ]: 0 : GfxDebug::mouse_xforms();
1664 [ # # ]: 0 : edge_d->debug_draw(5);
1665 [ # # ]: 0 : GfxDebug::mouse_xforms();
1666 [ # # ][ # # ]: 0 : edge_d->other_point(pt)->debug_draw(6);
1667 [ # # ]: 0 : GfxDebug::mouse_xforms();
1668 : : }
1669 : :
1670 [ # # ]: 0 : curve_edges.append(edge_d);
1671 [ # # ]: 0 : pt = edge_d->other_point(pt);
1672 [ # # ][ # # ]: 0 : } while (pt != curve->end_point()->facet_point());
1673 : :
1674 [ # # ][ # # ]: 0 : if( !okay || !PartSurfFacetTool::seam_curve( curve_edges, curve, facet_list ) )
[ # # ][ # # ]
1675 : : {
1676 : 0 : okay = false;
1677 : 0 : break;
1678 : : }
1679 : : }
1680 : :
1681 : : // clean up any owner pointers on edges that were being
1682 : : // used as a kind of mark
1683 [ # # ][ # # ]: 0 : for ( i = facet_list.size(); i--; )
1684 : : {
1685 [ # # ]: 0 : CubitFacet* facet = facet_list.get_and_step();
1686 [ # # ]: 0 : for ( int j = 0; j < 3; j++ )
1687 [ # # ][ # # ]: 0 : if ( TDVGFacetOwner::get(facet->edge(j)) == new_surf )
[ # # ][ # # ]
1688 [ # # ][ # # ]: 0 : TDVGFacetOwner::set(facet->edge(j), 0);
1689 : : }
1690 : :
1691 : : // set surface facets
1692 [ # # ]: 0 : new_surf->set_facet_data( facet_list );
1693 : :
1694 [ # # ]: 0 : if (!okay)
1695 : : {
1696 [ # # ][ # # ]: 0 : PartitionEngine::instance().destroy_surface( new_surf );
1697 : 0 : return 0;
1698 : : }
1699 : :
1700 [ # # ]: 0 : return new_surf;
1701 : : }
1702 : :
1703 : :
1704 : 0 : CubitStatus PartitionSurface::notify_moving_point( CubitPoint* point,
1705 : : const CubitVector& new_pos )
1706 : : {
1707 [ # # ][ # # ]: 0 : DLIList<CubitFacetData*> old_facets, new_facets;
[ # # ]
1708 [ # # ][ # # ]: 0 : if (!PartSurfFacetTool::fix_move_point(point, new_pos, facetList, old_facets, new_facets, this))
1709 : 0 : return CUBIT_FAILURE;
1710 : :
1711 [ # # ][ # # ]: 0 : assert( !old_facets.size() == !new_facets.size() );
[ # # ]
1712 [ # # ][ # # ]: 0 : if (old_facets.size())
1713 [ # # ]: 0 : replace_facets( old_facets, new_facets );
1714 [ # # ]: 0 : return CUBIT_SUCCESS;
1715 : : }
1716 : :
1717 : 0 : void PartitionSurface::notify_destroyed( CubitFacetData* facet )
1718 : : {
1719 : 0 : facetList.move_to(facet);
1720 [ # # ][ # # ]: 0 : assert(facetList.size() && facetList.get() == facet);
1721 : 0 : facetList.extract();
1722 : 0 : }
1723 : :
1724 : :
1725 : 0 : CubitStatus PartitionSurface::evaluate( double u, double v,
1726 : : CubitVector *position,
1727 : : CubitVector *normal,
1728 : : CubitVector *curvature1,
1729 : : CubitVector *curvature2 )
1730 : : {
1731 : 0 : return CUBIT_FAILURE;
1732 : : }
1733 : :
1734 : 0 : CubitStatus PartitionSurface::get_projected_distance_on_surface( CubitVector *pos1,
1735 : : CubitVector *pos2,
1736 : : double &distance )
1737 : : {
1738 : 0 : return CUBIT_FAILURE;
1739 : : }
1740 : :
1741 : 0 : CubitStatus PartitionSurface::get_sphere_params
1742 : : (
1743 : : CubitVector ¢er,
1744 : : double &radius
1745 : : ) const
1746 : : {
1747 [ # # ][ # # ]: 0 : PRINT_ERROR("Currently, Cubit is unable to determine sphere parameters for PartitionSurfaces.\n");
1748 : 0 : return CUBIT_FAILURE;
1749 : : }
1750 : :
1751 : 0 : CubitStatus PartitionSurface::get_cone_params
1752 : : (
1753 : : CubitVector ¢er,
1754 : : CubitVector &normal,
1755 : : CubitVector &major_axis,
1756 : : double &radius_ratio,
1757 : : double &sine_angle,
1758 : : double &cos_angle
1759 : : ) const
1760 : : {
1761 [ # # ][ # # ]: 0 : PRINT_ERROR("Currently, Cubit is unable to determine cone parameters for PartitionSurfaces.\n");
1762 : 0 : return CUBIT_FAILURE;
1763 : : }
1764 : :
1765 : 0 : CubitStatus PartitionSurface::get_torus_params
1766 : : (
1767 : : CubitVector ¢er,
1768 : : CubitVector &normal,
1769 : : double &major_radius,
1770 : : double &minor_radius
1771 : : ) const
1772 : : {
1773 [ # # ][ # # ]: 0 : PRINT_ERROR("Currently, Cubit is unable to determine torus parameters for PartitionSurface.\n");
1774 : 0 : return CUBIT_FAILURE;
1775 : : }
1776 : :
1777 : 0 : CubitStatus PartitionSurface::get_nurb_params
1778 : : (
1779 : : bool &rational,
1780 : : int °ree_u,
1781 : : int °ree_v,
1782 : : int &num_cntrl_pts_u,
1783 : : int &num_cntrl_pts_v,
1784 : : DLIList<CubitVector> &cntrl_pts,
1785 : : DLIList<double> &cntrl_pt_weights,
1786 : : DLIList<double> &u_knots,
1787 : : DLIList<double> &v_knots
1788 : : ) const
1789 : : {
1790 [ # # ][ # # ]: 0 : PRINT_ERROR("Currently, Cubit is unable to determine nurbs parameters for PartitionSurface.\n");
1791 : 0 : return CUBIT_FAILURE;
1792 [ + - ][ + - ]: 6364 : }
|