Branch data Line data Source code
1 : : //-------------------------------------------------------------------------
2 : : // Filename : PartitionEngine.cpp
3 : : //
4 : : // Purpose :
5 : : //
6 : : // Special Notes :
7 : : //
8 : : // Creator : Jason Kraftcheck
9 : : //
10 : : // Creation Date : 04/23/02
11 : : //-------------------------------------------------------------------------
12 : :
13 : : #include "PartitionEngine.hpp"
14 : : #include "CompositeEngine.hpp"
15 : :
16 : : #include "SubCurve.hpp"
17 : : #include "SubSurface.hpp"
18 : : #include "SegmentedCurve.hpp"
19 : : #include "PartitionPoint.hpp"
20 : : #include "PartitionCoEdge.hpp"
21 : : #include "PartitionLoop.hpp"
22 : : #include "PartitionSurface.hpp"
23 : : #include "PartitionLump.hpp"
24 : : #include "PartitionBody.hpp"
25 : : #include "PartPTCurve.hpp"
26 : : #include "PartitionShell.hpp"
27 : : #include "BodySM.hpp"
28 : :
29 : :
30 : : #include "GMem.hpp"
31 : : #include "GeometryQueryEngine.hpp"
32 : : #include "GeometryModifyEngine.hpp"
33 : : #include "GeometryModifyTool.hpp"
34 : :
35 : : #include "VGLoopTool.hpp"
36 : :
37 : : #include "FacetProjectTool.hpp"
38 : : #include "CubitFacetData.hpp"
39 : : #include "CubitFacetEdgeData.hpp"
40 : : #include "CubitPointData.hpp"
41 : : #include "TDVGFacetOwner.hpp"
42 : : #include "TDVGFacetSplit.hpp"
43 : : #include "FacetEvalTool.hpp"
44 : : #include "FacetDataUtil.hpp"
45 : : #include "PartSurfFacetTool.hpp"
46 : : #include "PartitionTool.hpp"
47 : :
48 : : #include "CompositeSurface.hpp"
49 : : #include "CompositePoint.hpp"
50 : : #include "CompositeCurve.hpp"
51 : : #include "PartitionLumpImprint.hpp"
52 : : #include "GfxDebug.hpp"
53 : : #include "BridgeManager.hpp"
54 : :
55 : : #include "CADefines.hpp"
56 : :
57 : : #include <set>
58 : : #include "GeometryQueryTool.hpp"
59 : :
60 : : #include "CubitTransformMatrix.hpp"
61 : : #include "CubitObservable.hpp"
62 : : #include "AppUtil.hpp"
63 : : #include "GeometryEvent.hpp"
64 : :
65 : : const char* const PARTITION_GEOM_ATTRIB_NAME = "PARTITION_GEOM";
66 : :
67 : : static CubitStatus get_edge_replacements(
68 : : std::vector<CubitFacetData*> &facet_list,
69 : : std::vector<CubitFacetEdgeData*> replacement_edges[3]);
70 : :
71 : :
72 : : PartitionEngine* PartitionEngine::instance_ = NULL;
73 : :
74 : :
75 [ # # ]: 0 : PartitionEngine::~PartitionEngine()
76 : : {
77 [ # # ][ # # ]: 0 : GeometryQueryTool::instance()->unregister_intermediate_engine(this);
78 [ # # ]: 0 : }
79 : :
80 : 0 : void PartitionEngine::delete_instance()
81 : : {
82 [ # # ]: 0 : if( NULL != instance_ )
83 : : {
84 [ # # ]: 0 : delete instance_;
85 : 0 : instance_ = NULL;
86 : : }
87 : 0 : }
88 : :
89 : :
90 : : //-------------------------------------------------------------------------
91 : : // Purpose : Constructor
92 : : //
93 : : // Special Notes :
94 : : //
95 : : // Creator : Jason Kraftcheck
96 : : //
97 : : // Creation Date : 08/25/03
98 : : //-------------------------------------------------------------------------
99 [ + - ]: 1682 : PartitionEngine::PartitionEngine()
100 : : {
101 [ + - ][ + - ]: 841 : CubitStatus r = GeometryQueryTool::instance()->register_intermediate_engine(this);
102 [ - + ]: 841 : assert(r == CUBIT_SUCCESS);
103 [ - + ]: 841 : if (CUBIT_SUCCESS != r) {
104 [ # # ][ # # ]: 0 : PRINT_ERROR("Failed to register intermediate engine.\n");
[ # # ][ # # ]
105 : : }
106 : 841 : }
107 : :
108 : : //-------------------------------------------------------------------------
109 : : // Purpose : Get instance
110 : : //
111 : : // Special Notes :
112 : : //
113 : : // Creator : Jason Kraftcheck
114 : : //
115 : : // Creation Date : 02/23/03
116 : : //-------------------------------------------------------------------------
117 : 841 : PartitionEngine& PartitionEngine::instance()
118 : : {
119 [ + - ]: 841 : if( instance_ == NULL )
120 : : {
121 [ + - ]: 841 : instance_ = new PartitionEngine();
122 [ - + ]: 841 : assert( instance_ != NULL );
123 : : }
124 : :
125 : 841 : return *instance_;
126 : : }
127 : :
128 : : //-------------------------------------------------------------------------
129 : : // Purpose : Used by SubEntitySet to update ID map.
130 : : //
131 : : // Special Notes :
132 : : //
133 : : // Creator : Jason Kraftcheck
134 : : //
135 : : // Creation Date : 02/23/03
136 : : //-------------------------------------------------------------------------
137 : 0 : CubitStatus PartitionEngine::add_to_id_map( SubEntitySet* set, int unique_id )
138 : : {
139 [ # # ][ # # ]: 0 : if( uniqueIdMap.find(unique_id) != uniqueIdMap.end() )
[ # # ]
140 : 0 : { assert(0); return CUBIT_FAILURE; }
141 : 0 : uniqueIdMap[unique_id] = set;
142 : 0 : return CUBIT_SUCCESS;
143 : : }
144 : :
145 : : //-------------------------------------------------------------------------
146 : : // Purpose : Used by SubEntitySet to update ID map.
147 : : //
148 : : // Special Notes :
149 : : //
150 : : // Creator : Jason Kraftcheck
151 : : //
152 : : // Creation Date : 02/23/03
153 : : //-------------------------------------------------------------------------
154 : 0 : CubitStatus PartitionEngine::remove_from_id_map( SubEntitySet* set, int id )
155 : : {
156 [ # # ]: 0 : std::map<int,SubEntitySet*>::iterator itor = uniqueIdMap.find(id);
157 [ # # ][ # # ]: 0 : if( itor == uniqueIdMap.end() || itor->second != set )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
158 : 0 : { assert(0); return CUBIT_FAILURE; }
159 [ # # ]: 0 : uniqueIdMap.erase(itor);
160 : 0 : return CUBIT_SUCCESS;
161 : : }
162 : :
163 : : //-------------------------------------------------------------------------
164 : : // Purpose : Retreive an entity from the ID map
165 : : //
166 : : // Special Notes :
167 : : //
168 : : // Creator : Jason Kraftcheck
169 : : //
170 : : // Creation Date : 02/23/03
171 : : //-------------------------------------------------------------------------
172 : 0 : SubEntitySet* PartitionEngine::get_from_id_map( int id )
173 : : {
174 [ # # ]: 0 : std::map<int,SubEntitySet*>::iterator itor = uniqueIdMap.find(id);
175 [ # # ][ # # ]: 0 : return itor == uniqueIdMap.end() ? 0 : itor->second;
[ # # ][ # # ]
176 : : }
177 : :
178 : : //-------------------------------------------------------------------------
179 : : // Purpose : Replicate solid model topology in partition layer
180 : : //
181 : : // Special Notes :
182 : : //
183 : : // Creator : Jason Kraftcheck
184 : : //
185 : : // Creation Date : 02/23/03
186 : : //-------------------------------------------------------------------------
187 : 0 : SubCurve* PartitionEngine::replace_curve( Curve* curve )
188 : : {
189 [ # # ]: 0 : SubCurve* result = dynamic_cast<SubCurve*>(curve);
190 [ # # ]: 0 : if( result )
191 : 0 : return result;
192 : :
193 [ # # ][ # # ]: 0 : if( dynamic_cast<SegmentedCurve*>(curve) )
[ # # ]
194 : 0 : return 0;
195 : :
196 [ # # ]: 0 : DLIList<TopologyBridge*> list;
197 : : //curve->get_children_virt( list );
198 : : //fix_up_query_results( list );
199 [ # # ][ # # ]: 0 : curve->get_children(list, false, layer());
200 : 0 : PartitionPoint *start_pt = 0, *end_pt = 0;
201 : 0 : bool new_start = false, new_end = false;
202 [ # # ]: 0 : list.reset();
203 [ # # ]: 0 : TopologyBridge* bridge = list.get_and_step();
204 [ # # ]: 0 : start_pt = dynamic_cast<PartitionPoint*>(bridge);
205 [ # # ]: 0 : if( ! start_pt )
206 : : {
207 [ # # ][ # # ]: 0 : start_pt = replace_point( dynamic_cast<TBPoint*>(bridge) );
208 [ # # ]: 0 : if( ! start_pt )
209 : 0 : return 0;
210 : 0 : new_start = true;
211 : : }
212 [ # # ][ # # ]: 0 : if( list.size() == 1 )
213 : : {
214 : 0 : end_pt = start_pt;
215 : : }
216 [ # # ][ # # ]: 0 : else if( list.size() == 2 )
217 : : {
218 [ # # ]: 0 : bridge = list.get();
219 [ # # ]: 0 : end_pt = dynamic_cast<PartitionPoint*>(bridge);
220 [ # # ]: 0 : if( !end_pt )
221 : : {
222 [ # # ][ # # ]: 0 : end_pt = replace_point( dynamic_cast<TBPoint*>(bridge) );
223 : 0 : new_end = true;
224 [ # # ]: 0 : if( !end_pt )
225 : : {
226 [ # # ]: 0 : if( new_start )
227 [ # # ]: 0 : restore_point( start_pt );
228 : 0 : return 0;
229 : : }
230 : : }
231 : : }
232 : :
233 [ # # ][ # # ]: 0 : assert( start_pt && end_pt );
234 : :
235 [ # # ][ # # ]: 0 : result = new SubCurve( curve );
236 [ # # ][ # # ]: 0 : if( ! result->start_point( start_pt ) ||
[ # # ][ # # ]
237 [ # # ]: 0 : ! result->end_point( end_pt ) )
238 : : {
239 [ # # ]: 0 : result->start_point(0);
240 [ # # ]: 0 : result->end_point(0);
241 [ # # ][ # # ]: 0 : delete result;
242 [ # # ]: 0 : if( new_start )
243 [ # # ]: 0 : restore_point( start_pt );
244 [ # # ]: 0 : if( new_end )
245 [ # # ]: 0 : restore_point( end_pt );
246 : 0 : return 0;
247 : : }
248 [ # # ][ # # ]: 0 : if( curve->owner() )
249 : : {
250 [ # # ][ # # ]: 0 : curve->owner()->swap_bridge(curve, result, false);
251 : : }
252 [ # # ][ # # ]: 0 : curve->owner(&(result->sub_entity_set()));
253 : :
254 [ # # ]: 0 : list.clean_out();
255 [ # # ]: 0 : curve->get_parents_virt( list );
256 : : //fix_up_query_results( list );
257 : :
258 [ # # ][ # # ]: 0 : for( int i = list.size(); i--; )
259 : : {
260 [ # # ]: 0 : bridge = list.get_and_step();
261 [ # # ]: 0 : CoEdgeSM* coedge = dynamic_cast<CoEdgeSM*>(bridge);
262 [ # # ]: 0 : assert( coedge != NULL );
263 [ # # ][ # # ]: 0 : PartitionCoEdge* pcoedge = new PartitionCoEdge( coedge );
264 [ # # ]: 0 : CubitStatus s = result->add( pcoedge );
265 [ # # ]: 0 : assert( s );
266 [ # # ]: 0 : if (CUBIT_SUCCESS != s) {
267 [ # # ][ # # ]: 0 : PRINT_ERROR("Failed to add coedge to SubCurve.\n");
[ # # ][ # # ]
268 : 0 : return NULL;
269 : : }
270 [ # # ][ # # ]: 0 : if( coedge->owner() )
271 [ # # ][ # # ]: 0 : coedge->owner()->swap_bridge(coedge, pcoedge, false);
272 [ # # ][ # # ]: 0 : coedge->owner(&(pcoedge->sub_entity_set()));
273 : : }
274 : :
275 : :
276 : 0 : PartitionBody* body = 0;
277 [ # # ][ # # ]: 0 : if( result->start_point()->sub_entity_set().body() )
[ # # ][ # # ]
278 [ # # ][ # # ]: 0 : body = result->start_point()->sub_entity_set().body();
[ # # ]
279 [ # # ][ # # ]: 0 : else if( result->end_point()->sub_entity_set().body() )
[ # # ][ # # ]
280 [ # # ][ # # ]: 0 : body = result->end_point()->sub_entity_set().body();
[ # # ]
281 : : else
282 [ # # ]: 0 : body = make_body(result);
283 : :
284 [ # # ]: 0 : if( body )
285 : : {
286 [ # # ][ # # ]: 0 : if( !result->start_point()->sub_entity_set().body() )
[ # # ][ # # ]
287 [ # # ][ # # ]: 0 : body->add(result->start_point()->sub_entity_set());
[ # # ]
288 [ # # ][ # # ]: 0 : if( !result->end_point()->sub_entity_set().body() )
[ # # ][ # # ]
289 [ # # ][ # # ]: 0 : body->add(result->end_point()->sub_entity_set());
[ # # ]
290 [ # # ][ # # ]: 0 : body->add(result->sub_entity_set());
291 : 0 : PartitionCoEdge* coedge = 0;
292 [ # # ][ # # ]: 0 : while ( (coedge = result->next_coedge(coedge)) )
293 [ # # ][ # # ]: 0 : if ( !coedge->sub_entity_set().body() )
[ # # ]
294 [ # # ][ # # ]: 0 : body->add(coedge->sub_entity_set());
295 : : }
296 : :
297 : : // we must notify the graphics of the modify from "real" to virtual -- KGM
298 : : // I realize that this is not where the other notifies are completed but there
299 : : // is no knowledge of the change later on.
300 [ # # ][ # # ]: 0 : CubitObservable* observable = dynamic_cast<CubitObservable*>(result->topology_entity());
301 [ # # ]: 0 : if (observable)
302 : : {
303 [ # # ][ # # ]: 0 : AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, dynamic_cast<RefEntity*>(result->topology_entity())));
[ # # ][ # # ]
[ # # ][ # # ]
304 : : }
305 : :
306 [ # # ]: 0 : return result;
307 : : }
308 : :
309 : : //-------------------------------------------------------------------------
310 : : // Purpose : Replicate solid model topology in partition layer
311 : : //
312 : : // Special Notes :
313 : : //
314 : : // Creator : Jason Kraftcheck
315 : : //
316 : : // Creation Date : 02/23/03
317 : : //-------------------------------------------------------------------------
318 : 0 : SubSurface* PartitionEngine::replace_surface( Surface* surface )
319 : : {
320 : : int i, j;
321 : :
322 : : // check if the input surface is already a SubSurface
323 [ # # ]: 0 : SubSurface* result = dynamic_cast<SubSurface*>(surface);
324 [ # # ]: 0 : if( result )
325 : 0 : return result;
326 : :
327 : : // check if the input surface is already a PartitionSurface
328 [ # # ][ # # ]: 0 : if( dynamic_cast<PartitionSurface*>(surface) )
[ # # ]
329 : 0 : return 0;
330 : :
331 : : // create a new SubSurface, swap out the TBOwner if it
332 : : // exists and reset the input surface TBOwner.
333 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> loop_list, coe_list, curve_list;
[ # # ][ # # ]
[ # # ]
334 [ # # ][ # # ]: 0 : surface->get_children( loop_list, false, layer() );
335 [ # # ][ # # ]: 0 : result = new SubSurface( surface );
336 [ # # ][ # # ]: 0 : if( surface->owner() )
337 [ # # ][ # # ]: 0 : surface->owner()->swap_bridge(surface, result, false);
338 [ # # ][ # # ]: 0 : surface->owner(&(result->sub_entity_set()));
339 : :
340 : : // Add the loop onto the new surface
341 [ # # ]: 0 : loop_list.reset();
342 [ # # ][ # # ]: 0 : for( i = loop_list.size(); i--; )
343 : : {
344 [ # # ][ # # ]: 0 : LoopSM* loop = dynamic_cast<LoopSM*>(loop_list.get_and_step());
345 [ # # ][ # # ]: 0 : PartitionLoop* partloop = new PartitionLoop();
346 [ # # ]: 0 : result->add( partloop );
347 [ # # ][ # # ]: 0 : if( loop->owner() )
348 [ # # ][ # # ]: 0 : loop->owner()->swap_bridge( loop, partloop, false );
349 [ # # ]: 0 : loop->owner(0);
350 : :
351 : : // Take care of the curves in the loop
352 [ # # ]: 0 : coe_list.clean_out();
353 [ # # ][ # # ]: 0 : loop->get_children( coe_list, false, layer() );
354 : :
355 [ # # ]: 0 : coe_list.reset();
356 [ # # ][ # # ]: 0 : for( j = coe_list.size(); j--; )
357 : : {
358 [ # # ][ # # ]: 0 : CoEdgeSM* coedge = dynamic_cast<CoEdgeSM*>(coe_list.get_and_step());
359 [ # # ][ # # ]: 0 : if(!dynamic_cast<PartitionCoEdge*>(coedge) &&
[ # # ][ # # ]
360 [ # # ][ # # ]: 0 : !dynamic_cast<SubEntitySet*>(coedge->owner()) )
361 : : {
362 [ # # ]: 0 : curve_list.clean_out();
363 [ # # ]: 0 : coedge->get_children_virt( curve_list );
364 [ # # ][ # # ]: 0 : assert( curve_list.size() == 1 );
365 : :
366 [ # # ][ # # ]: 0 : Curve* curve = dynamic_cast<Curve*>(curve_list.get());
367 [ # # ][ # # ]: 0 : assert(! dynamic_cast<PartitionCurve*>(curve) );
368 [ # # ]: 0 : SubCurve* pcurve = replace_curve( curve );
369 [ # # ]: 0 : assert(pcurve != NULL);
370 [ # # ]: 0 : if (NULL == pcurve) {
371 [ # # ][ # # ]: 0 : PRINT_ERROR("Failed to replace curve.\n");
[ # # ][ # # ]
372 : 0 : return NULL;
373 : : }
374 : : }
375 : : }
376 : :
377 [ # # ]: 0 : coe_list.clean_out();
378 [ # # ][ # # ]: 0 : loop->get_children( coe_list, false, layer() );
379 : :
380 [ # # ]: 0 : coe_list.reset();
381 : 0 : PartitionCoEdge *curr, *prev = 0;
382 [ # # ]: 0 : coe_list.reset();
383 [ # # ][ # # ]: 0 : for( j = coe_list.size(); j--; )
384 : : {
385 [ # # ][ # # ]: 0 : curr = dynamic_cast<PartitionCoEdge*>(coe_list.get_and_step());
386 [ # # ]: 0 : assert( curr != NULL );
387 [ # # ]: 0 : partloop->insert_after( curr, prev );
388 : 0 : prev = curr;
389 : : }
390 : :
391 : : }
392 : :
393 : : // If the facet data is incorrect put everything back
394 [ # # ][ # # ]: 0 : if (!result->init_facet_data()) {
395 [ # # ]: 0 : restore_surface( result );
396 : 0 : return 0;
397 : : }
398 : :
399 : : // finalize by making the body
400 [ # # ]: 0 : PartitionBody* body = make_body(result);
401 [ # # ]: 0 : if( body )
402 [ # # ][ # # ]: 0 : body->add(result->sub_entity_set());
403 : :
404 [ # # ]: 0 : return result;
405 : : }
406 : :
407 : : //-------------------------------------------------------------------------
408 : : // Purpose : Replicate solid model topology in partition layer
409 : : //
410 : : // Special Notes :
411 : : //
412 : : // Creator : Jason Kraftcheck
413 : : //
414 : : // Creation Date : 02/23/03
415 : : //-------------------------------------------------------------------------
416 : 0 : PartitionLump* PartitionEngine::replace_lump( Lump* lump )
417 : : {
418 : : int i, j;
419 [ # # ]: 0 : PartitionLump* result = dynamic_cast<PartitionLump*>(lump);
420 [ # # ]: 0 : if( result )
421 : 0 : return result;
422 : :
423 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> shell_list, surface_list;
[ # # ]
424 [ # # ][ # # ]: 0 : lump->get_children( shell_list, false, layer() );
425 : :
426 [ # # ][ # # ]: 0 : DLIList<PartitionShell*> new_shells;
427 [ # # ]: 0 : shell_list.reset();
428 [ # # ][ # # ]: 0 : for( i = shell_list.size(); i--; )
429 : : {
430 [ # # ][ # # ]: 0 : ShellSM* shell = dynamic_cast<ShellSM*>(shell_list.get_and_step());
431 [ # # ][ # # ]: 0 : PartitionShell* pshell = new PartitionShell();
432 [ # # ]: 0 : new_shells.append(pshell);
433 [ # # ][ # # ]: 0 : if( shell->owner() )
434 [ # # ][ # # ]: 0 : shell->owner()->swap_bridge( shell, pshell, false );
435 [ # # ]: 0 : shell->owner(0);
436 : :
437 [ # # ]: 0 : surface_list.clean_out();
438 [ # # ][ # # ]: 0 : shell->get_children( surface_list, false, layer() );
439 : :
440 [ # # ]: 0 : surface_list.reset();
441 [ # # ][ # # ]: 0 : for( j = surface_list.size(); j--; )
442 : : {
443 [ # # ][ # # ]: 0 : Surface* surface = dynamic_cast<Surface*>(surface_list.get_and_step());
444 [ # # ]: 0 : PartitionSurface* psurf = dynamic_cast<PartitionSurface*>(surface);
445 [ # # ]: 0 : if( !psurf )
446 : : {
447 [ # # ]: 0 : psurf = replace_surface( surface );
448 [ # # ]: 0 : if (!psurf)
449 : : {
450 [ # # ][ # # ]: 0 : while (new_shells.size())
451 [ # # ][ # # ]: 0 : destroy_shell(new_shells.pop());
452 : 0 : return 0;
453 : : }
454 : : }
455 : :
456 [ # # ][ # # ]: 0 : Surface* real_surf = dynamic_cast<Surface*>(psurf->partitioned_entity());
457 [ # # ]: 0 : assert(!!real_surf);
458 [ # # ]: 0 : CubitSense sense = real_surf->get_shell_sense(shell);
459 [ # # ][ # # ]: 0 : assert(sense == CUBIT_FORWARD || sense == CUBIT_REVERSED);
460 [ # # ]: 0 : pshell->add( psurf, sense );
461 : : }
462 : : }
463 : :
464 [ # # ][ # # ]: 0 : result = new PartitionLump( lump );
465 [ # # ][ # # ]: 0 : if( lump->owner() )
466 [ # # ][ # # ]: 0 : lump->owner()->swap_bridge(lump, result, false);
467 [ # # ][ # # ]: 0 : lump->owner(&(result->sub_entity_set()));
468 [ # # ]: 0 : new_shells.reverse();
469 [ # # ][ # # ]: 0 : while( new_shells.size() )
470 [ # # ][ # # ]: 0 : result->add(new_shells.pop());
471 : :
472 [ # # ]: 0 : PartitionBody* body = make_body(result);
473 [ # # ]: 0 : if( body )
474 [ # # ][ # # ]: 0 : body->add( result->sub_entity_set() );
475 : :
476 [ # # ]: 0 : return result;
477 : : }
478 : :
479 : : //-------------------------------------------------------------------------
480 : : // Purpose : Replicate solid model topology in partition layer
481 : : //
482 : : // Special Notes :
483 : : //
484 : : // Creator : Jason Kraftcheck
485 : : //
486 : : // Creation Date : 02/23/03
487 : : //-------------------------------------------------------------------------
488 : 0 : PartitionPoint* PartitionEngine::replace_point( TBPoint* point )
489 : : {
490 [ # # ]: 0 : PartitionPoint* result = dynamic_cast<PartitionPoint*>(point);
491 [ # # ]: 0 : if( !result )
492 : : {
493 [ # # ]: 0 : result = new PartitionPoint( point );
494 : : }
495 : :
496 [ # # ]: 0 : if( result )
497 : : {
498 [ # # ]: 0 : if( point->owner() )
499 : 0 : point->owner()->swap_bridge( point, result, false );
500 : 0 : point->owner( &(result->sub_entity_set()) );
501 : : }
502 : :
503 : 0 : return result;
504 : : }
505 : :
506 : : //-------------------------------------------------------------------------
507 : : // Purpose : Restore original solid model topology. (Inverse of
508 : : // replace_point.)
509 : : //
510 : : // Special Notes :
511 : : //
512 : : // Creator : Jason Kraftcheck
513 : : //
514 : : // Creation Date : 02/23/03
515 : : //-------------------------------------------------------------------------
516 : 0 : TBPoint* PartitionEngine::restore_point( PartitionPoint* point )
517 : : {
518 [ # # ]: 0 : if( point->num_curves() )
519 : 0 : return 0;
520 : :
521 : 0 : TBPoint* result = point->real_point();
522 [ # # ]: 0 : if( result )
523 : : {
524 : 0 : point->sub_entity_set().unwrap_attributes();
525 : 0 : point->sub_entity_set().remove_bridge(result);
526 [ # # ]: 0 : if( point->owner() )
527 : 0 : point->owner()->swap_bridge( point, result, false );
528 [ # # ]: 0 : delete point;
529 : : }
530 : :
531 : 0 : return result;
532 : : }
533 : :
534 : : //-------------------------------------------------------------------------
535 : : // Purpose : Restore original solid model topology. (Inverse of
536 : : // replace_curve.)
537 : : //
538 : : // Special Notes :
539 : : //
540 : : // Creator : Jason Kraftcheck
541 : : //
542 : : // Creation Date : 02/23/03
543 : : //-------------------------------------------------------------------------
544 : 0 : Curve* PartitionEngine::restore_curve( SubCurve* curve )
545 : : {
546 [ # # ]: 0 : if( curve->num_partitions() > 1 )
547 : 0 : return 0;
548 : :
549 : 0 : PartitionCoEdge* coedge = 0;
550 [ # # ]: 0 : while( (coedge = curve->next_coedge( coedge )) )
551 [ # # ]: 0 : if( coedge->get_loop() )
552 : 0 : return 0;
553 : :
554 [ # # ]: 0 : while( (coedge = curve->next_coedge(0)) )
555 : : {
556 : 0 : curve->remove( coedge );
557 : 0 : CoEdgeSM* real_coedge = coedge->real_coedge();
558 [ # # ]: 0 : if( real_coedge )
559 : : {
560 : 0 : coedge->sub_entity_set().remove_bridge( real_coedge );
561 [ # # ]: 0 : if( coedge->owner() )
562 : 0 : coedge->owner()->swap_bridge( coedge, real_coedge, false );
563 : : }
564 [ # # ]: 0 : delete coedge;
565 : : }
566 : :
567 : 0 : PartitionPoint* start = curve->start_point();
568 : 0 : curve->start_point( 0 );
569 [ # # ]: 0 : if( start->num_curves() == 0 )
570 : : {
571 [ # # ]: 0 : if( start->real_point() )
572 : 0 : restore_point( start );
573 : : else
574 [ # # ]: 0 : delete start;
575 : : }
576 : :
577 : 0 : PartitionPoint* end = curve->end_point();
578 : 0 : curve->end_point(0);
579 [ # # ]: 0 : if( end->num_curves() == 0 )
580 : : {
581 [ # # ]: 0 : if( end->real_point() )
582 : 0 : restore_point( end );
583 : : else
584 [ # # ]: 0 : delete end;
585 : : }
586 : :
587 : 0 : Curve* result = curve->real_curve();
588 : 0 : curve->sub_entity_set().unwrap_attributes();
589 : 0 : curve->sub_entity_set().remove_bridge( result );
590 [ # # ]: 0 : if( curve->owner() )
591 : 0 : curve->owner()->swap_bridge( curve, result, false );
592 [ # # ]: 0 : delete curve;
593 : :
594 : : // we must notify the graphics of the modify from "real" to virtual -- KGM
595 : : // I realize that this is not where the other notifies are completed but there
596 : : // is no knowledge of the change later on.
597 [ # # ]: 0 : CubitObservable* observable = dynamic_cast<CubitObservable*>(result->topology_entity());
598 [ # # ]: 0 : if (observable)
599 : : {
600 [ # # ][ # # ]: 0 : AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, dynamic_cast<RefEntity*>(result->topology_entity())));
[ # # ]
601 : : }
602 : :
603 : 0 : return result;
604 : : }
605 : :
606 : :
607 : : //-------------------------------------------------------------------------
608 : : // Purpose : Restore original solid model topology. (Inverse of
609 : : // replace_surface.)
610 : : //
611 : : // Special Notes :
612 : : //
613 : : // Creator : Jason Kraftcheck
614 : : //
615 : : // Creation Date : 02/23/03
616 : : //-------------------------------------------------------------------------
617 : 0 : Surface* PartitionEngine::restore_surface( SubSurface* surface )
618 : : {
619 [ # # ][ # # ]: 0 : if( surface->sub_entity_set().has_lower_order() || surface->next_co_surface() )
[ # # ]
620 : 0 : return 0;
621 : :
622 [ # # ]: 0 : while( PartitionLoop* loop = surface->next_loop() )
623 : : // while surface has loops...
624 : : {
625 : 0 : surface->remove( loop );
626 : :
627 [ # # ]: 0 : while( loop->first_coedge() )
628 : : {
629 : 0 : PartitionCoEdge* coedge = loop->first_coedge();
630 : 0 : loop->remove( coedge );
631 : :
632 [ # # ]: 0 : SubCurve* curve = dynamic_cast<SubCurve*>(coedge->get_curve());
633 [ # # ][ # # ]: 0 : if( !curve || curve->sub_entity_set().has_lower_order() )
[ # # ]
634 : 0 : continue;
635 : :
636 : 0 : bool remove = true;
637 : 0 : coedge = 0;
638 [ # # ]: 0 : while( (coedge = curve->next_coedge( coedge )) )
639 : : {
640 [ # # ]: 0 : if( coedge->get_loop() )
641 : : {
642 : 0 : remove = false;
643 : 0 : break;
644 : : }
645 : : }
646 : :
647 [ # # ]: 0 : if( remove )
648 : : {
649 : 0 : restore_curve( curve );
650 : : }
651 : :
652 : : }
653 : :
654 [ # # ]: 0 : delete loop;
655 : : }
656 : :
657 : :
658 : 0 : Surface* result = surface->partitioned_surface();
659 : 0 : surface->sub_entity_set().unwrap_attributes();
660 : 0 : surface->sub_entity_set().remove_bridge( result );
661 [ # # ]: 0 : if( surface->owner() )
662 : 0 : surface->owner()->swap_bridge( surface, result, false );
663 [ # # ]: 0 : delete surface;
664 : 0 : return result;
665 : : }
666 : :
667 : : //-------------------------------------------------------------------------
668 : : // Purpose : Destroy a single partition of a volume.
669 : : //
670 : : // Special Notes : Will restore original volume if this is the last/only
671 : : // partition.
672 : : //
673 : : // Creator : Jason Kraftcheck
674 : : //
675 : : // Creation Date : 02/11/03
676 : : //-------------------------------------------------------------------------
677 : 0 : CubitStatus PartitionEngine::destroy_lump( PartitionLump* lump )
678 : : {
679 : : /* only partition lump? */
680 [ # # ]: 0 : if ( ! lump->sub_entity_set().has_multiple_sub_entities() )
681 : : {
682 [ # # ]: 0 : DLIList<PartitionEntity*> child_entities;
683 [ # # ][ # # ]: 0 : lump->sub_entity_set().get_lower_order( child_entities );
684 [ # # ][ # # ]: 0 : DLIList<PartitionSurface*> surf_list;
685 [ # # ][ # # ]: 0 : CAST_LIST( child_entities, surf_list, PartitionSurface );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
686 : :
687 [ # # ][ # # ]: 0 : while( surf_list.size() )
688 [ # # ][ # # ]: 0 : if( ! remove_surface( surf_list.pop() ) )
[ # # ]
689 : 0 : return CUBIT_FAILURE;
690 : :
691 [ # # ][ # # ]: 0 : return restore_lump(lump) ? CUBIT_SUCCESS : CUBIT_FAILURE;
[ # # ]
692 : : }
693 : :
694 : : PartitionShell* shell;
695 [ # # ]: 0 : while ( (shell = lump->next_shell(0)) )
696 : : {
697 : 0 : lump->remove(shell);
698 : 0 : destroy_shell(shell);
699 : : }
700 [ # # ]: 0 : delete lump;
701 : :
702 : 0 : return CUBIT_SUCCESS;
703 : : }
704 : :
705 : :
706 : :
707 : : //-------------------------------------------------------------------------
708 : : // Purpose : Restore original solid model topology. (Inverse of
709 : : // replace_lump.)
710 : : //
711 : : // Special Notes :
712 : : //
713 : : // Creator : Jason Kraftcheck
714 : : //
715 : : // Creation Date : 02/23/03
716 : : //-------------------------------------------------------------------------
717 : 0 : Lump* PartitionEngine::restore_lump( PartitionLump* lump )
718 : : {
719 [ # # ]: 0 : if( lump->sub_entity_set().has_lower_order() )
720 : 0 : return 0;
721 : :
722 [ # # ]: 0 : while( PartitionShell* shell = lump->next_shell() )
723 : : // while surface has loops...
724 : : {
725 : 0 : lump->remove( shell );
726 : 0 : destroy_shell( shell );
727 : : }
728 : :
729 : :
730 : 0 : Lump* result = lump->real_lump();
731 : 0 : lump->sub_entity_set().unwrap_attributes();
732 : 0 : lump->sub_entity_set().remove_bridge( result );
733 [ # # ]: 0 : if( lump->owner() )
734 : 0 : lump->owner()->swap_bridge( lump, result, false );
735 [ # # ]: 0 : delete lump;
736 : 0 : return result;
737 : : }
738 : :
739 : 0 : bool PartitionEngine::is_partition(TBOwner *bridge_owner)
740 : : {
741 : 0 : bool ret = false;
742 [ # # ]: 0 : if(bridge_owner)
743 : : {
744 [ # # ][ # # ]: 0 : if(dynamic_cast<SubEntitySet*>(bridge_owner))
[ # # ]
745 : : {
746 : 0 : ret = true;
747 : : }
748 : : }
749 : 0 : return ret;
750 : : }
751 : :
752 : 0 : bool PartitionEngine::is_composite(TBOwner *bridge_owner)
753 : : {
754 : 0 : return false;
755 : : }
756 : :
757 : 0 : bool PartitionEngine::is_composite(TopologyBridge *bridge)
758 : : {
759 : 0 : return false;
760 : : }
761 : :
762 : : //-------------------------------------------------------------------------
763 : : // Purpose : Destroy a shell
764 : : //
765 : : // Special Notes :
766 : : //
767 : : // Creator : Jason Kraftcheck
768 : : //
769 : : // Creation Date : 03/11/04
770 : : //-------------------------------------------------------------------------
771 : 0 : CubitStatus PartitionEngine::destroy_shell( PartitionShell* shell )
772 : : {
773 [ # # ]: 0 : if (shell->get_lump())
774 : : {
775 : 0 : assert(0);
776 : : return CUBIT_FAILURE;
777 : : }
778 : :
779 [ # # ]: 0 : while( PartitionCoSurf* cosurf = shell->next_co_surface() )
780 : : {
781 : 0 : shell->remove( cosurf );
782 : :
783 [ # # ]: 0 : SubSurface* psurf = dynamic_cast<SubSurface*>(cosurf->get_surface());
784 [ # # ]: 0 : if (psurf)
785 : : {
786 : 0 : psurf->remove(cosurf);
787 : :
788 : : // If PartitionSurface is the same as the underlying surface
789 : : // and is not part of any other PartitionLumps, remove it.
790 [ # # # # ]: 0 : if( !psurf->sub_entity_set().has_lower_order() &&
[ # # ]
791 : 0 : psurf->next_co_surface() == 0 )
792 : 0 : restore_surface( psurf );
793 : : }
794 : :
795 [ # # ]: 0 : delete cosurf;
796 : : }
797 : :
798 [ # # ]: 0 : delete shell;
799 : 0 : return CUBIT_SUCCESS;
800 : : }
801 : :
802 : :
803 : :
804 : : //-------------------------------------------------------------------------
805 : : // Purpose : Partition a curve
806 : : //
807 : : // Special Notes : public interface to curve partitioning
808 : : //
809 : : // Creator : Jason Kraftcheck
810 : : //
811 : : // Creation Date : 02/23/03
812 : : //-------------------------------------------------------------------------
813 : 0 : TBPoint* PartitionEngine::insert_point( Curve* curve, double u )
814 : : {
815 [ # # ]: 0 : PartitionCurve* pcurve = dynamic_cast<PartitionCurve*>(curve);
816 : 0 : bool replaced_curve = false;
817 : :
818 [ # # ]: 0 : if( !pcurve )
819 : : {
820 [ # # ][ # # ]: 0 : if( CompositeCurve* comp = dynamic_cast<CompositeCurve*>(curve) )
821 : : {
822 [ # # ][ # # ]: 0 : return CompositeEngine::instance().insert_point( comp, u );
823 : : }
824 : :
825 [ # # ]: 0 : pcurve = replace_curve( curve );
826 [ # # ]: 0 : if( !pcurve )
827 : 0 : return 0;
828 : 0 : replaced_curve = true;
829 : : }
830 : :
831 [ # # ]: 0 : CubitVector coords;
832 [ # # ][ # # ]: 0 : if( ! pcurve->position_from_u( u, coords ) )
833 : : {
834 [ # # ]: 0 : if( replaced_curve )
835 [ # # ][ # # ]: 0 : restore_curve( dynamic_cast<SubCurve*>(pcurve) );
836 : 0 : return 0;
837 : : }
838 : :
839 [ # # ][ # # ]: 0 : PartitionPoint* npoint = new PartitionPoint( coords, pcurve );
[ # # ]
840 [ # # ]: 0 : PartitionCurve* ncurve = insert_point(pcurve, npoint);
841 : :
842 [ # # ]: 0 : if( !ncurve )
843 : : {
844 [ # # ]: 0 : if( replaced_curve )
845 [ # # ][ # # ]: 0 : restore_curve( dynamic_cast<SubCurve*>(pcurve) );
846 [ # # ][ # # ]: 0 : delete npoint;
847 : 0 : return 0;
848 : : }
849 : :
850 : 0 : return npoint;
851 : : }
852 : :
853 : :
854 : : //-------------------------------------------------------------------------
855 : : // Purpose : Partition a curve
856 : : //
857 : : // Special Notes : not public
858 : : //
859 : : // Creator : Jason Kraftcheck
860 : : //
861 : : // Creation Date : 02/23/03
862 : : //-------------------------------------------------------------------------
863 : 0 : PartitionCurve* PartitionEngine::insert_point( PartitionCurve* pcurve,
864 : : PartitionPoint* npoint )
865 : : {
866 : 0 : const double TOLSQR = GEOMETRY_RESABS * GEOMETRY_RESABS;
867 [ # # ]: 0 : CubitVector coords = npoint->coordinates();
868 [ # # ]: 0 : double u = pcurve->u_from_position(coords);
869 : : double u_min, u_max;
870 [ # # ]: 0 : pcurve->get_param_range( u_min, u_max );
871 : :
872 [ # # ]: 0 : if(u_min > u_max)
873 : : {
874 : 0 : double dtemp = u_min;
875 : 0 : u_min = u_max;
876 : 0 : u_max = dtemp;
877 : : }
878 : :
879 [ # # ][ # # ]: 0 : if( u - u_min < CUBIT_RESABS || u_max - u < CUBIT_RESABS )
880 : 0 : return 0;
881 : :
882 [ # # ][ # # ]: 0 : if( (pcurve->start_point()->coordinates() - coords).length_squared() < TOLSQR
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # ]
883 [ # # ][ # # ]: 0 : || (pcurve->end_point()->coordinates() - coords).length_squared() < TOLSQR )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
884 : 0 : return 0;
885 : :
886 [ # # ]: 0 : PartitionCurve* ncurve = pcurve->split( u );
887 [ # # ]: 0 : if( !ncurve )
888 : 0 : return 0;
889 : :
890 [ # # ][ # # ]: 0 : ncurve->end_point( pcurve->end_point() );
891 [ # # ]: 0 : pcurve->end_point( npoint );
892 [ # # ]: 0 : ncurve->start_point( npoint );
893 [ # # ]: 0 : pcurve->fix_facet_data( ncurve );
894 : :
895 : 0 : PartitionCoEdge *pcoedge = 0, *ncoedge = 0;
896 [ # # ][ # # ]: 0 : while( (pcoedge = pcurve->next_coedge( pcoedge )) )
897 : : {
898 [ # # ][ # # ]: 0 : ncoedge = new PartitionCoEdge( pcoedge );
899 [ # # ]: 0 : ncurve->add( ncoedge );
900 [ # # ][ # # ]: 0 : if( pcoedge->get_loop() )
901 : : {
902 [ # # ][ # # ]: 0 : if( pcoedge->sense() == CUBIT_FORWARD )
903 [ # # ][ # # ]: 0 : pcoedge->get_loop()->insert_after( ncoedge, pcoedge );
904 : : else
905 [ # # ][ # # ]: 0 : pcoedge->get_loop()->insert_before( ncoedge, pcoedge );
906 : : }
907 : : }
908 : :
909 [ # # ][ # # ]: 0 : if( pcurve->owner() )
910 [ # # ][ # # ]: 0 : pcurve->owner()->notify_split( ncurve, pcurve );
911 : :
912 : 0 : return ncurve;
913 : : }
914 : :
915 : : //-------------------------------------------------------------------------
916 : : // Purpose : un-partition a curve
917 : : //
918 : : // Special Notes :
919 : : //
920 : : // Creator : Jason Kraftcheck
921 : : //
922 : : // Creation Date : 02/23/03
923 : : //-------------------------------------------------------------------------
924 : 0 : Curve* PartitionEngine::remove_point( PartitionPoint* point,
925 : : PartitionCurve* dead_curves[2] )
926 : : {
927 [ # # ]: 0 : if( dead_curves )
928 : 0 : dead_curves[0] = dead_curves[1] = 0;
929 : :
930 [ # # ][ # # ]: 0 : if( point->num_curves() > 2 )
931 : 0 : return 0;
932 : :
933 [ # # ]: 0 : DLIList<TopologyBridge*> curve_bridges;
934 [ # # ]: 0 : point->get_parents_virt( curve_bridges );
935 [ # # ][ # # ]: 0 : if( curve_bridges.size() > 2 )
936 : 0 : return 0;
937 : :
938 [ # # ][ # # ]: 0 : if( curve_bridges.size() == 1 )
939 : : {
940 [ # # ][ # # ]: 0 : PartPTCurve* point_curve = dynamic_cast<PartPTCurve*>(curve_bridges.get());
941 [ # # ]: 0 : if( ! point_curve )
942 : 0 : return 0;
943 : :
944 [ # # ]: 0 : if( dead_curves )
945 : 0 : dead_curves[0] = point_curve;
946 [ # # ]: 0 : remove_point_curve( point );
947 : 0 : return 0;
948 : : }
949 : :
950 : : /*
951 : : TopologyBridge* real = point->partitioned_entity();
952 : : if( dynamic_cast<TBPoint*>(real) )
953 : : {
954 : : Curve* curve1 = dynamic_cast<Curve*>(curve_bridges.get());
955 : : Curve* curve2 = dynamic_cast<Curve*>(curve_bridges.next());
956 : : PartitionCurve* pc1 = dynamic_cast<PartitionCurve*>(curve1);
957 : : PartitionCurve* pc2 = dynamic_cast<PartitionCurve*>(curve2);
958 : : assert( pc1 || pc2 );
959 : : if( !pc1 )
960 : : pc1 = replace_curve( curve1 );
961 : : if( !pc2 )
962 : : pc2 = replace_curve( curve2 );
963 : :
964 : : CompositeEngine::instance()->remove_point( dynamic_cast<TBPoint*>(real) );
965 : : bool reverse = ( pc1->start_point() == pc2->start_point() ||
966 : : pc2->end_point() == pc2->end_point() );
967 : : if( pc1->partitioned_entity() == 0 )
968 : : {
969 : : bool prepend = false;
970 : : if( pc1->other_point( pc2->start_point() ) )
971 : : prepend = true;
972 : : pc2->sub_entity_set().merge( pc1->sub_entity_set(), reverse, prepend );
973 : : }
974 : : else if( pc2->partitioned_entity() == 0 )
975 : : {
976 : : bool prepend = false;
977 : : if( pc2->other_point( pc1->start_point() ) )
978 : : prepend = true;
979 : : pc1->sub_entity_set().merge( pc2->sub_entity_set(), reverse, prepend );
980 : : }
981 : : else
982 : : return 0;
983 : : }
984 : : */
985 [ # # ][ # # ]: 0 : if( point->num_curves() != 2 )
986 : 0 : return 0;
987 : :
988 [ # # ]: 0 : PartitionCurve* survivor = point->next_curve(0);
989 [ # # ]: 0 : PartitionCurve* casualty = point->next_curve(survivor);
990 [ # # ][ # # ]: 0 : if( survivor->start_point() == point &&
[ # # ][ # # ]
991 [ # # ]: 0 : casualty->end_point() == point )
992 : : {
993 : : // swap
994 : 0 : survivor = casualty;
995 [ # # ]: 0 : casualty = point->next_curve(0);
996 : : }
997 : :
998 [ # # ][ # # ]: 0 : if( ! survivor->combine( casualty ) )
999 : 0 : return 0;
1000 : :
1001 : : PartitionPoint* other_pt =
1002 [ # # ]: 0 : casualty->start_point() == point ?
1003 [ # # ][ # # ]: 0 : casualty->end_point() : casualty->start_point();
[ # # ]
1004 [ # # ]: 0 : casualty->start_point(0);
1005 [ # # ]: 0 : casualty->end_point(0);
1006 : :
1007 [ # # ][ # # ]: 0 : if( survivor->start_point() == point )
1008 [ # # ]: 0 : survivor->start_point( other_pt );
1009 : : else
1010 [ # # ]: 0 : survivor->end_point( other_pt );
1011 : :
1012 [ # # ][ # # ]: 0 : delete point;
1013 : :
1014 [ # # ][ # # ]: 0 : while( PartitionCoEdge* coedge = casualty->next_coedge(0) )
1015 : : {
1016 [ # # ][ # # ]: 0 : if( coedge->get_loop() )
1017 [ # # ][ # # ]: 0 : coedge->get_loop()->remove( coedge );
1018 [ # # ]: 0 : casualty->remove( coedge );
1019 [ # # ][ # # ]: 0 : delete coedge;
1020 : : }
1021 [ # # ][ # # ]: 0 : delete casualty;
1022 [ # # ]: 0 : if( dead_curves )
1023 : 0 : dead_curves[0] = casualty;
1024 : :
1025 : 0 : Curve* result = survivor;
1026 [ # # ]: 0 : SubCurve* subcurve = dynamic_cast<SubCurve*>(survivor);
1027 [ # # ][ # # ]: 0 : if( subcurve && !survivor->sub_entity_set().has_multiple_sub_entities() )
[ # # ][ # # ]
[ # # ]
1028 : : {
1029 [ # # ]: 0 : Curve* real_curve = restore_curve( subcurve );
1030 [ # # ]: 0 : if (real_curve)
1031 : : {
1032 : 0 : result = real_curve;
1033 [ # # ]: 0 : if (dead_curves)
1034 : 0 : dead_curves[1] = survivor;
1035 : : }
1036 : : }
1037 : :
1038 [ # # ]: 0 : return result;
1039 : : }
1040 : :
1041 : : //-------------------------------------------------------------------------
1042 : : // Purpose : Remove a point-curve (point imprinted on a surface)
1043 : : //
1044 : : // Special Notes :
1045 : : //
1046 : : // Creator : Jason Kraftcheck
1047 : : //
1048 : : // Creation Date : 02/23/03
1049 : : //-------------------------------------------------------------------------
1050 : 0 : CubitStatus PartitionEngine::remove_point_curve( PartitionPoint* point )
1051 : : {
1052 [ # # ]: 0 : if( point->num_curves() != 1 )
1053 : 0 : return CUBIT_FAILURE;
1054 : :
1055 [ # # ]: 0 : PartPTCurve* curve = dynamic_cast<PartPTCurve*>(point->next_curve(0));
1056 [ # # ]: 0 : if( !curve )
1057 : 0 : return CUBIT_FAILURE;
1058 : :
1059 : 0 : PartitionSurface* surf = 0;
1060 [ # # ]: 0 : if( curve->num_coedges() )
1061 : : {
1062 [ # # ]: 0 : assert( curve->num_coedges() == 1 );
1063 : 0 : PartitionCoEdge* coedge = curve->next_coedge(0);
1064 : 0 : PartitionLoop* loop = coedge->get_loop();
1065 [ # # ]: 0 : if( loop )
1066 : : {
1067 : 0 : surf = loop->get_surface();
1068 : 0 : surf->remove( loop );
1069 : 0 : loop->remove( coedge );
1070 [ # # ]: 0 : assert( loop->num_coedges() == 0 );
1071 [ # # ]: 0 : delete loop;
1072 : : }
1073 : 0 : curve->remove( coedge );
1074 [ # # ]: 0 : delete coedge;
1075 : : }
1076 : :
1077 : 0 : curve->start_point(0);
1078 : 0 : curve->end_point(0);
1079 [ # # ]: 0 : delete curve;
1080 [ # # ]: 0 : delete point;
1081 : :
1082 [ # # ][ # # ]: 0 : if( surf && surf->owner() )
[ # # ]
1083 : 0 : surf->owner()->notify_topology_modified( surf );
1084 : :
1085 : 0 : return CUBIT_SUCCESS;
1086 : : }
1087 : :
1088 : : //-------------------------------------------------------------------------
1089 : : // Purpose : Topological modifications for surface partitioning
1090 : : //
1091 : : // Special Notes : non-public, assumes surface facets have already been
1092 : : // imprinted and the polyline of the imprint is already
1093 : : // associated with the passed curve.
1094 : : //
1095 : : // Creator : Jason Kraftcheck
1096 : : //
1097 : : // Creation Date : 02/23/03
1098 : : //-------------------------------------------------------------------------
1099 : 0 : PartitionSurface* PartitionEngine::insert_curve( PartitionSurface* surface,
1100 : : SegmentedCurve* curve )
1101 : : {
1102 : 0 : PartitionSurface* new_surface = 0;
1103 [ # # ][ # # ]: 0 : assert( &(curve->sub_entity_set()) == &(surface->sub_entity_set()) );
[ # # ]
1104 : :
1105 [ # # ]: 0 : PartitionPoint *start_point = curve->start_point();
1106 [ # # ]: 0 : PartitionPoint *end_point = curve->end_point();
1107 : 0 : PartitionLoop *start_loop = 0, *end_loop = 0;
1108 : 0 : PartitionCoEdge *start_prev_coedge = 0, *start_next_coedge = 0;
1109 : 0 : PartitionCoEdge *end_prev_coedge = 0, *end_next_coedge = 0;
1110 : :
1111 : : // find where to insert new curve in loop
1112 [ # # ][ # # ]: 0 : if ( !find_coedges( surface, curve, start_point, start_prev_coedge, start_next_coedge ) )
1113 : 0 : return 0;
1114 [ # # ][ # # ]: 0 : if ( !find_coedges( surface, curve, end_point, end_prev_coedge, end_next_coedge ))
1115 : 0 : return 0;
1116 : :
1117 [ # # ][ # # ]: 0 : assert((!start_prev_coedge && !start_next_coedge) ||
[ # # ][ # # ]
[ # # ][ # # ]
1118 : : (start_prev_coedge && start_next_coedge &&
1119 [ # # ]: 0 : start_prev_coedge->get_loop() == start_next_coedge->get_loop()));
1120 [ # # ][ # # ]: 0 : assert((!end_prev_coedge && !end_next_coedge) ||
[ # # ][ # # ]
[ # # ][ # # ]
1121 : : (end_prev_coedge && end_next_coedge &&
1122 [ # # ]: 0 : end_prev_coedge->get_loop() == end_next_coedge->get_loop()));
1123 [ # # ]: 0 : if ( start_prev_coedge )
1124 [ # # ]: 0 : start_loop = start_prev_coedge->get_loop();
1125 [ # # ]: 0 : if ( end_prev_coedge )
1126 [ # # ]: 0 : end_loop = end_prev_coedge->get_loop();
1127 : :
1128 : :
1129 : : // remove any point-curves
1130 : : PartitionCurve* pt_curve;
1131 : : PartPTCurve* point_curve;
1132 [ # # ]: 0 : for ( int i = 0; i < 2; i++ ) // do once for each end point
1133 : : {
1134 [ # # ]: 0 : PartitionPoint* pt = i ? end_point : start_point;
1135 [ # # ]: 0 : pt_curve = pt->next_curve(0);
1136 [ # # ]: 0 : while ( pt_curve )
1137 : : {
1138 [ # # ]: 0 : point_curve = dynamic_cast<PartPTCurve*>(pt_curve);
1139 [ # # ]: 0 : pt_curve = pt->next_curve(pt_curve);
1140 [ # # ][ # # ]: 0 : if (point_curve && point_curve->next_coedge(0)->get_loop()->get_surface() == surface)
[ # # ][ # # ]
[ # # ][ # # ]
1141 : : {
1142 [ # # ]: 0 : point_curve->start_point(0);
1143 [ # # ]: 0 : point_curve->end_point(0);
1144 : :
1145 [ # # ]: 0 : PartitionCoEdge* coedge = point_curve->next_coedge(0);
1146 [ # # ]: 0 : point_curve->remove(coedge);
1147 [ # # ][ # # ]: 0 : assert( !point_curve->next_coedge(0) );
1148 [ # # ]: 0 : PartitionLoop* loop = coedge->get_loop();
1149 [ # # ]: 0 : loop->remove(coedge);
1150 [ # # ][ # # ]: 0 : assert( !loop->first_coedge() );
1151 [ # # ]: 0 : surface->remove(loop);
1152 [ # # ][ # # ]: 0 : delete loop;
1153 [ # # ][ # # ]: 0 : delete coedge;
1154 [ # # ][ # # ]: 0 : delete point_curve;
1155 : : }
1156 : : }
1157 : : }
1158 : :
1159 : :
1160 [ # # ][ # # ]: 0 : PartitionCoEdge* forward = new PartitionCoEdge( surface, CUBIT_FORWARD );
1161 [ # # ][ # # ]: 0 : PartitionCoEdge* reverse = new PartitionCoEdge( surface, CUBIT_REVERSED );
1162 [ # # ]: 0 : curve->add(forward);
1163 [ # # ]: 0 : curve->add(reverse);
1164 : :
1165 : : // new one-curve loop?
1166 [ # # ][ # # ]: 0 : if( !start_loop && !end_loop )
1167 : : {
1168 [ # # ][ # # ]: 0 : PartitionLoop* new_loop = new PartitionLoop();
1169 [ # # ]: 0 : surface->add( new_loop );
1170 [ # # ]: 0 : new_loop->insert_after( forward, 0 );
1171 : :
1172 [ # # ][ # # ]: 0 : if( curve->start_point() == curve->end_point() )
[ # # ]
1173 : : {
1174 [ # # ][ # # ]: 0 : PartitionLoop* loop2 = new PartitionLoop();
1175 [ # # ]: 0 : loop2->insert_after( reverse, 0 );
1176 : :
1177 [ # # ]: 0 : if( VGLoopTool
1178 : : <PartitionSurface,PartitionLoop,PartitionCoEdge,PartitionCurve,PartitionPoint>
1179 [ # # ]: 0 : ::loop_angle_metric( forward ) > 0 )
1180 : : {
1181 : 0 : new_loop = loop2;
1182 : : }
1183 : : else
1184 : : {
1185 [ # # ]: 0 : surface->remove(new_loop);
1186 [ # # ]: 0 : surface->add( loop2 );
1187 : : }
1188 : :
1189 [ # # ][ # # ]: 0 : new_surface = split_surface( surface, new_loop->first_coedge() );
1190 [ # # ]: 0 : new_surface->add( new_loop );
1191 : : }
1192 : : else
1193 : : {
1194 [ # # ]: 0 : new_loop->insert_after( reverse, forward );
1195 : 0 : }
1196 : : }
1197 : :
1198 : : // sipe
1199 [ # # ][ # # ]: 0 : else if( !start_loop || !end_loop )
1200 : : {
1201 : : PartitionCoEdge* prev;
1202 : : PartitionLoop* loop;
1203 [ # # ]: 0 : if( start_loop )
1204 : : {
1205 : 0 : loop = start_loop;
1206 : 0 : prev = start_prev_coedge;
1207 : : }
1208 : : else
1209 : : {
1210 : 0 : loop = end_loop;
1211 : 0 : prev = end_prev_coedge;
1212 : : }
1213 : :
1214 [ # # ][ # # ]: 0 : if( forward->start_point() == prev->end_point() )
[ # # ]
1215 : : {
1216 [ # # ]: 0 : loop->insert_after( forward, prev );
1217 [ # # ]: 0 : loop->insert_after( reverse, forward );
1218 : : }
1219 : : else
1220 : : {
1221 [ # # ][ # # ]: 0 : assert( reverse->start_point() == prev->end_point() );
[ # # ]
1222 [ # # ]: 0 : loop->insert_after( reverse, prev );
1223 [ # # ]: 0 : loop->insert_after( forward, reverse );
1224 : 0 : }
1225 : : }
1226 : :
1227 : : // join loops
1228 [ # # ]: 0 : else if( start_loop != end_loop )
1229 : : {
1230 : 0 : PartitionCoEdge* prev = start_prev_coedge;
1231 : 0 : PartitionCoEdge* coedge = end_next_coedge;
1232 : 0 : PartitionCoEdge* next = 0, *other_coedge;
1233 : :
1234 [ # # ][ # # ]: 0 : if( forward->start_point() == prev->end_point() )
[ # # ]
1235 : : {
1236 [ # # ]: 0 : start_loop->insert_after( forward, prev );
1237 : 0 : prev = forward;
1238 : 0 : other_coedge = reverse;
1239 : : }
1240 : : else
1241 : : {
1242 [ # # ][ # # ]: 0 : assert( reverse->start_point() == prev->end_point() );
[ # # ]
1243 [ # # ]: 0 : start_loop->insert_after( reverse, prev );
1244 : 0 : prev = reverse;
1245 : 0 : other_coedge = forward;
1246 : : }
1247 : :
1248 [ # # ][ # # ]: 0 : while ( end_loop->first_coedge() )
1249 : : {
1250 [ # # ]: 0 : next = end_loop->next_coedge( coedge );
1251 [ # # ]: 0 : end_loop->remove( coedge );
1252 [ # # ]: 0 : start_loop->insert_after( coedge, prev );
1253 : 0 : prev = coedge;
1254 : 0 : coedge = next;
1255 : : }
1256 : :
1257 : : // The other coedge for the curve we are restoring...
1258 [ # # ]: 0 : start_loop->insert_after( other_coedge, prev );
1259 : :
1260 [ # # ][ # # ]: 0 : assert( end_loop->num_coedges() == 0 );
1261 [ # # ]: 0 : surface->remove( end_loop );
1262 [ # # ][ # # ]: 0 : delete end_loop;
1263 : : }
1264 : :
1265 : : // split a loop (and create a new surface)
1266 : : else
1267 : : {
1268 [ # # ]: 0 : assert( start_loop == end_loop );
1269 : :
1270 : : // If the curve we are adding results in a hole that
1271 : : // intersects the loop we are splitting at a single
1272 : : // vertex, we need to figure out which of the coedges
1273 : : // goes in the hole and which is added to the loop
1274 : : // we are splitting.
1275 [ # # ][ # # ]: 0 : if( forward->start_point() == forward->end_point() )
[ # # ]
1276 : : {
1277 [ # # ]: 0 : assert( start_next_coedge == end_next_coedge );
1278 [ # # ]: 0 : assert( start_prev_coedge == end_prev_coedge );
1279 : :
1280 [ # # ][ # # ]: 0 : CubitVector prev_tan, forward_tan, reverse_tan, normal, junk;
[ # # ][ # # ]
[ # # ]
1281 [ # # ][ # # ]: 0 : CubitVector point = forward->start_point()->coordinates();
1282 [ # # ][ # # ]: 0 : start_prev_coedge->get_curve()->closest_point( point, junk, &prev_tan );
1283 [ # # ][ # # ]: 0 : if( start_prev_coedge->sense() == CUBIT_FORWARD ) // yes, forward!!!
1284 [ # # ]: 0 : prev_tan *= -1.0;
1285 [ # # ][ # # ]: 0 : forward->get_curve()->closest_point( point, junk, &forward_tan );
1286 [ # # ][ # # ]: 0 : reverse_tan = forward_tan * -1.0;
1287 [ # # ]: 0 : surface->closest_point( point, 0, &normal );
1288 : :
1289 [ # # ]: 0 : double angle1 = normal.vector_angle( prev_tan, forward_tan );
1290 [ # # ]: 0 : double angle2 = normal.vector_angle( prev_tan, reverse_tan );
1291 : :
1292 [ # # ]: 0 : if( angle2 < angle1 )
1293 : : {
1294 : 0 : PartitionCoEdge* temp = reverse;
1295 : 0 : reverse = forward;
1296 : 0 : forward = temp;
1297 : : }
1298 : : }
1299 : :
1300 : : else
1301 : : {
1302 [ # # ][ # # ]: 0 : if( forward->end_point() == end_next_coedge->start_point() )
[ # # ]
1303 : : {
1304 : 0 : PartitionCoEdge* temp = reverse;
1305 : 0 : reverse = forward;
1306 : 0 : forward = temp;
1307 : : }
1308 : : }
1309 : :
1310 [ # # ][ # # ]: 0 : end_loop = new PartitionLoop();
1311 [ # # ]: 0 : start_loop->insert_after( forward, end_prev_coedge );
1312 [ # # ]: 0 : end_loop->insert_after( reverse, 0 );
1313 : :
1314 : 0 : PartitionCoEdge* coedge = end_next_coedge;
1315 : 0 : PartitionCoEdge* prev = reverse;
1316 [ # # ]: 0 : while( coedge != start_next_coedge )
1317 : : {
1318 [ # # ]: 0 : PartitionCoEdge* next = start_loop->next_coedge( coedge );
1319 [ # # ]: 0 : start_loop->remove( coedge );
1320 [ # # ]: 0 : end_loop->insert_after( coedge, prev );
1321 : 0 : prev = coedge;
1322 : 0 : coedge = next;
1323 : : }
1324 : :
1325 [ # # ]: 0 : new_surface = split_surface( surface, reverse );
1326 [ # # ]: 0 : new_surface->add( end_loop );
1327 : : }
1328 : :
1329 [ # # ]: 0 : if( new_surface )
1330 : : {
1331 : 0 : PartitionCoSurf* cos = 0;
1332 [ # # ][ # # ]: 0 : while( (cos = surface->next_co_surface( cos )) )
1333 [ # # ][ # # ]: 0 : cos->get_shell()->add( new_surface, cos->sense() );
[ # # ]
1334 [ # # ][ # # ]: 0 : if( surface->owner() )
1335 [ # # ][ # # ]: 0 : surface->owner()->notify_split( new_surface, surface );
1336 : 0 : return new_surface;
1337 : : }
1338 : : else
1339 : : {
1340 [ # # ][ # # ]: 0 : if( surface->owner() )
1341 [ # # ][ # # ]: 0 : surface->owner()->notify_topology_modified( surface );
1342 : 0 : return surface;
1343 : : }
1344 : : }
1345 : :
1346 : :
1347 : : //-------------------------------------------------------------------------
1348 : : // Purpose : Find where to insert a curve in a loop
1349 : : //
1350 : : // Special Notes :
1351 : : //
1352 : : // Creator : Jason Kraftcheck
1353 : : //
1354 : : // Creation Date : 03/24/03
1355 : : //-------------------------------------------------------------------------
1356 : 0 : CubitStatus PartitionEngine::find_coedges( PartitionSurface* surface,
1357 : : PartitionCurve* curve,
1358 : : PartitionPoint* point,
1359 : : PartitionCoEdge*& previous,
1360 : : PartitionCoEdge*& next )
1361 : : {
1362 : 0 : const char* const bad_loop_message = "Internal error: Invalid loop. (%s:%d)\n";
1363 : :
1364 : : // Find list of all coedges around passed point
1365 : : // and in passed surface.
1366 [ # # ]: 0 : DLIList<PartitionCoEdge*> point_coedges;
1367 : : PartitionCoEdge* coedge;
1368 : 0 : PartitionCurve* pt_curve = 0;
1369 [ # # ][ # # ]: 0 : while ( (pt_curve = point->next_curve(pt_curve)) )
1370 : : {
1371 : 0 : coedge = 0;
1372 [ # # ][ # # ]: 0 : while ( (coedge = pt_curve->next_coedge(coedge)) )
1373 : : {
1374 [ # # ][ # # ]: 0 : if (coedge->get_loop() &&
[ # # ]
1375 [ # # ][ # # ]: 0 : coedge->get_loop()->get_surface() == surface &&
[ # # ][ # # ]
1376 [ # # ][ # # ]: 0 : !dynamic_cast<PartPTCurve*>(coedge->get_curve()))
1377 [ # # ]: 0 : point_coedges.append(coedge);
1378 : : }
1379 : : }
1380 : :
1381 : : // TBPoint is at end of a sipe/hardline
1382 [ # # ][ # # ]: 0 : if ( point_coedges.size() == 0 )
1383 : : {
1384 : 0 : previous = next = 0;
1385 : 0 : return CUBIT_SUCCESS;
1386 : : }
1387 : :
1388 : : // One coedge - closed curve
1389 [ # # ][ # # ]: 0 : if ( point_coedges.size() == 1 &&
[ # # ][ # # ]
1390 [ # # ][ # # ]: 0 : point_coedges.get()->start_point() ==
1391 [ # # ][ # # ]: 0 : point_coedges.get()->end_point() )
1392 : : {
1393 [ # # ]: 0 : previous = next = point_coedges.get();
1394 : 0 : return CUBIT_SUCCESS;
1395 : : }
1396 : :
1397 : : // Broken loop?
1398 [ # # ][ # # ]: 0 : if ( point_coedges.size() % 2 != 0 )
1399 : : {
1400 [ # # ][ # # ]: 0 : PRINT_ERROR(bad_loop_message,__FILE__,__LINE__);
[ # # ][ # # ]
1401 : 0 : assert(0);
1402 : : return CUBIT_FAILURE;
1403 : : }
1404 : :
1405 : : // If only two coedges, then we're done
1406 : : // If closed curve, the answer may be the same coedge for both
1407 : : // prev and next. E.g. A torus cracked along the outside major
1408 : : // radius and a sipe that intersects that crack curve. Need
1409 : : // to fall though to the more complex check below in that case.
1410 [ # # ][ # # ]: 0 : if ( point_coedges.size() == 2 &&
[ # # ]
1411 [ # # ][ # # ]: 0 : point_coedges.get()->get_curve()->start_point() !=
[ # # ]
1412 [ # # ][ # # ]: 0 : point_coedges.get()->get_curve()->end_point() &&
[ # # ][ # # ]
[ # # ]
1413 [ # # ][ # # ]: 0 : point_coedges.next()->get_curve()->start_point() !=
[ # # ]
1414 [ # # ][ # # ]: 0 : point_coedges.next()->get_curve()->end_point() )
[ # # ]
1415 : : {
1416 [ # # ]: 0 : previous = point_coedges.get();
1417 [ # # ]: 0 : next = point_coedges.next();
1418 : :
1419 [ # # ][ # # ]: 0 : if ( previous->start_point() == point )
1420 [ # # ]: 0 : std::swap(previous, next);
1421 : :
1422 : 0 : return CUBIT_SUCCESS;
1423 : : }
1424 : :
1425 : : // Find previous/next coedges by using order of
1426 : : // facet edges about point in surface facetting.
1427 [ # # ]: 0 : CubitPointData* facet_point = point->facet_point();
1428 [ # # ][ # # ]: 0 : DLIList<CubitFacetEdgeData*> curve_edges;
1429 [ # # ]: 0 : curve->get_facet_data(curve_edges);
1430 : :
1431 : : CubitFacetEdgeData* edge;
1432 : : //bool edge_reversed;
1433 [ # # ][ # # ]: 0 : if ( point == curve->start_point() )
1434 : : {
1435 [ # # ]: 0 : curve_edges.reset();
1436 [ # # ]: 0 : edge = curve_edges.get();
1437 : : }
1438 : : else
1439 : : {
1440 [ # # ][ # # ]: 0 : assert(curve->end_point() == point);
1441 [ # # ]: 0 : curve_edges.last();
1442 [ # # ]: 0 : edge = curve_edges.get();
1443 : : }
1444 : :
1445 : : PartitionCurve *prev_curve, *next_curve;
1446 [ # # ]: 0 : prev_curve = next_curve_around_point( surface, edge, facet_point, true );
1447 [ # # ]: 0 : next_curve = next_curve_around_point( surface, edge, facet_point, false );
1448 : :
1449 [ # # ][ # # ]: 0 : if ( !prev_curve || !next_curve )
1450 : : {
1451 [ # # ][ # # ]: 0 : PRINT_ERROR(bad_loop_message,__FILE__,__LINE__);
[ # # ][ # # ]
1452 : 0 : assert(0);
1453 : : return CUBIT_FAILURE;
1454 : : }
1455 : :
1456 : 0 : coedge = 0;
1457 [ # # ][ # # ]: 0 : while ( (coedge = prev_curve->next_coedge(coedge)) )
1458 : : {
1459 [ # # ][ # # ]: 0 : if ( coedge->get_loop() && // parent not a partition surface?
[ # # ]
1460 [ # # ][ # # ]: 0 : coedge->get_loop()->get_surface() == surface &&
[ # # ][ # # ]
1461 [ # # ]: 0 : coedge->end_point() == point )
1462 : : {
1463 : 0 : previous = coedge;
1464 : 0 : break;
1465 : : }
1466 : : }
1467 : 0 : coedge = 0;
1468 [ # # ][ # # ]: 0 : while ( (coedge = next_curve->next_coedge(coedge)) )
1469 : : {
1470 [ # # ][ # # ]: 0 : if ( coedge->get_loop() &&
[ # # ]
1471 [ # # ][ # # ]: 0 : coedge->get_loop()->get_surface() == surface &&
[ # # ][ # # ]
1472 [ # # ]: 0 : coedge->start_point() == point )
1473 : : {
1474 : 0 : next = coedge;
1475 : 0 : break;
1476 : : }
1477 : : }
1478 : :
1479 [ # # ]: 0 : return CUBIT_SUCCESS;
1480 : : }
1481 : :
1482 : 0 : PartitionCurve* PartitionEngine::next_curve_around_point(
1483 : : PartitionSurface *const surface,
1484 : : CubitFacetEdgeData *const start_edge,
1485 : : CubitPointData *const point,
1486 : : const bool backwards )
1487 : : {
1488 : : //PartitionCoEdge* result = 0;
1489 : 0 : CubitFacetEdge* edge = start_edge;
1490 : :
1491 [ # # ]: 0 : while ( edge->num_adj_facets() == 2 )
1492 : : {
1493 : 0 : CubitFacet* facet1 = edge->adj_facet(0);
1494 : 0 : CubitFacet* facet2 = edge->adj_facet(1);
1495 [ # # ][ # # ]: 0 : assert (TDVGFacetOwner::get(facet1) == surface);
1496 [ # # ][ # # ]: 0 : assert (TDVGFacetOwner::get(facet2) == surface);
1497 : :
1498 : 0 : bool edge_reversed = edge->point(1) == point;
1499 [ # # ]: 0 : int facet_sense = edge_reversed == backwards ? -1 : 1;
1500 : 0 : int facet1_index = facet1->edge_index(edge);
1501 : : #ifndef NDEBUG
1502 : 0 : int facet2_index = facet2->edge_index(edge);
1503 [ # # ]: 0 : assert(facet1->edge_use(facet1_index) == -facet2->edge_use(facet2_index));
1504 : : #endif
1505 : :
1506 [ # # ]: 0 : if ( facet_sense == facet1->edge_use(facet1_index) )
1507 : 0 : edge = facet1->next_edge_at_point( edge, point );
1508 : : else
1509 : 0 : edge = facet2->next_edge_at_point( edge, point );
1510 : :
1511 [ # # ]: 0 : assert(edge != start_edge);
1512 : :
1513 : 0 : PartitionEntity* edge_owner = TDVGFacetOwner::get(edge);
1514 [ # # ]: 0 : PartitionCurve* curve = dynamic_cast<PartitionCurve*>(edge_owner);
1515 [ # # ]: 0 : if ( curve )
1516 : 0 : return curve;
1517 : : }
1518 : :
1519 : 0 : return 0;
1520 : : }
1521 : :
1522 : :
1523 : :
1524 : : //-------------------------------------------------------------------------
1525 : : // Purpose : Un-partition a surface
1526 : : //
1527 : : // Special Notes :
1528 : : //
1529 : : // Creator : Jason Kraftcheck
1530 : : //
1531 : : // Creation Date : 02/23/03
1532 : : //-------------------------------------------------------------------------
1533 : 0 : Surface* PartitionEngine::remove_curve( PartitionCurve* passed_curve,
1534 : : PartitionSurface* dead_surfs[2] )
1535 : : {
1536 [ # # ]: 0 : if( dead_surfs )
1537 : 0 : dead_surfs[0] = dead_surfs[1] = 0;
1538 : :
1539 [ # # ]: 0 : PartPTCurve* point_curve = dynamic_cast<PartPTCurve*>(passed_curve);
1540 [ # # ]: 0 : if( point_curve )
1541 : : {
1542 : : PartitionSurface* surf =
1543 [ # # ][ # # ]: 0 : point_curve->next_coedge(0)->get_loop()->get_surface();
[ # # ]
1544 [ # # ][ # # ]: 0 : if( !remove_point_curve( point_curve->start_point() ) )
[ # # ]
1545 : 0 : return 0;
1546 : :
1547 [ # # ]: 0 : SubSurface* subsurf = dynamic_cast<SubSurface*>(surf);
1548 [ # # ][ # # ]: 0 : if( subsurf && !subsurf->next_co_surface() &&
[ # # ][ # # ]
[ # # ]
1549 [ # # ][ # # ]: 0 : !subsurf->sub_entity_set().has_lower_order() )
1550 : : {
1551 [ # # ]: 0 : Surface* result = restore_surface( subsurf );
1552 [ # # ][ # # ]: 0 : if( result && dead_surfs )
1553 : 0 : dead_surfs[0] = subsurf;
1554 : 0 : return result;
1555 : : }
1556 : : else
1557 : 0 : return surf;
1558 : : }
1559 : :
1560 [ # # ]: 0 : SegmentedCurve* curve = dynamic_cast<SegmentedCurve*>(passed_curve);
1561 : :
1562 [ # # ]: 0 : if( !curve )
1563 : : {
1564 : 0 : assert(0);
1565 : : }
1566 : : /*
1567 : : assert( dynamic_cast<SubCurve*>(passed_curve) );
1568 : :
1569 : : PartitionCoEdge* coedge1 = passed_curve->next_coedge(0);
1570 : : PartitionCoEdge* coedge2 = passed_curve->next_coedge(coedge1);
1571 : : if( !coedge2 || passed_curve->next_coedge(coedge2) )
1572 : : return 0;
1573 : :
1574 : : DLIList<TopologyBridge*> surfaces;
1575 : : coedge1->find_parent_loop()->get_parents_virt( surfaces );
1576 : : fix_up_query_results( surfaces );
1577 : : assert( surfaces.size() == 1 );
1578 : : Surface* surface1 = dynamic_cast<Surface*>(surfaces.get());
1579 : : surfaces.clean_out();
1580 : : coedge2->find_parent_loop()->get_parents_virt( surfaces );
1581 : : fix_up_query_results( surfaces );
1582 : : assert( surfaces.size() == 1 );
1583 : : Surface* surface2 = dynamic_cast<Surface*>(surfaces.get());
1584 : :
1585 : : SubSurface* surf1 = dynamic_cast<SubSurface*>(surface1);
1586 : : SubSurface* surf2 = dynamic_cast<SubSurface*>(surface2);
1587 : : if( surface1 == surface2 )
1588 : : {
1589 : : if( !surf1 )
1590 : : surf1 = surf2 = replace_surface( surface1 );
1591 : : }
1592 : : else
1593 : : {
1594 : : if( !surf1 )
1595 : : surf1 = replace_surface( surface1 );
1596 : : if( !surf2 )
1597 : : surf2 = replace_surface( surface2 );
1598 : : }
1599 : :
1600 : : // create SegmentedCurves from SubCurves
1601 : :
1602 : :
1603 : : CompositeEngine::instance()->
1604 : : remove_curve( dynamic_cast<Curve*>(passed_curve->partitioned_entity()) );
1605 : : }
1606 : : */
1607 [ # # ]: 0 : DLIList<TopologyBridge*> tb_list;
1608 : :
1609 : : // get two coedges to remove
1610 [ # # ]: 0 : curve->get_parents_virt( tb_list );
1611 [ # # ][ # # ]: 0 : if( tb_list.size() != 2 )
1612 : 0 : return 0;
1613 [ # # ][ # # ]: 0 : PartitionCoEdge* coedge1 = dynamic_cast<PartitionCoEdge*>(tb_list.get_and_step());
1614 [ # # ][ # # ]: 0 : PartitionCoEdge* coedge2 = dynamic_cast<PartitionCoEdge*>(tb_list.get_and_step());
1615 [ # # ][ # # ]: 0 : assert( coedge1 && coedge2 );
1616 : :
1617 : : // get two loops and surfaces
1618 [ # # ]: 0 : PartitionLoop* loop1 = coedge1->get_loop();
1619 [ # # ]: 0 : PartitionLoop* loop2 = coedge2->get_loop();
1620 [ # # ]: 0 : PartitionSurface* surf1 = loop1->get_surface();
1621 [ # # ]: 0 : PartitionSurface* surf2 = loop2->get_surface();
1622 [ # # ][ # # ]: 0 : assert( surf1 && surf2 );
1623 : :
1624 : : // surfaces must be partitions of the same real surface
1625 [ # # ][ # # ]: 0 : if( surf1->partitioned_entity() != surf2->partitioned_entity() )
[ # # ]
1626 : 0 : return 0;
1627 : :
1628 : : // surfaces must have same parent shells
1629 : 0 : PartitionCoSurf* cos = 0;
1630 [ # # ][ # # ]: 0 : while( (cos = surf1->next_co_surface( cos )) )
1631 [ # # ][ # # ]: 0 : if( ! surf2->find_first( cos->get_shell(), cos->sense() ) )
[ # # ][ # # ]
1632 : 0 : return 0;
1633 : :
1634 : : // same loop : remove a sipe or split a loop
1635 [ # # ]: 0 : if( loop1 == loop2 )
1636 : : {
1637 [ # # ][ # # ]: 0 : if( loop1->next_coedge( coedge1 ) != coedge2 &&
[ # # ][ # # ]
1638 [ # # ]: 0 : loop1->prev_coedge( coedge1 ) != coedge2 )
1639 : : {
1640 [ # # ][ # # ]: 0 : loop2 = new PartitionLoop();
1641 [ # # ]: 0 : PartitionCoEdge* coedge = loop1->next_coedge( coedge1 );
1642 : 0 : PartitionCoEdge* prev = 0;
1643 [ # # ]: 0 : while( coedge != coedge2 )
1644 : : {
1645 [ # # ]: 0 : loop1->remove( coedge );
1646 [ # # ]: 0 : loop2->insert_after( coedge, prev );
1647 : 0 : prev = coedge;
1648 [ # # ]: 0 : coedge = loop1->next_coedge( coedge1 );
1649 : : }
1650 : :
1651 [ # # ]: 0 : surf1->add( loop2 );
1652 : : }
1653 : :
1654 [ # # ]: 0 : loop1->remove( coedge1 );
1655 [ # # ]: 0 : loop1->remove( coedge2 );
1656 [ # # ][ # # ]: 0 : if( loop1->first_coedge() == 0 )
1657 : : {
1658 [ # # ]: 0 : surf1->remove( loop1 );
1659 [ # # ][ # # ]: 0 : delete loop1;
1660 : : }
1661 : : }
1662 : : // stitch loops
1663 : : else
1664 : : {
1665 : : // insert coedges
1666 [ # # ][ # # ]: 0 : while( loop2->next_coedge(coedge2) != coedge2 ) // all but the dead one
1667 : : {
1668 [ # # ]: 0 : PartitionCoEdge* coedge = loop2->next_coedge( coedge2 );
1669 [ # # ]: 0 : loop2->remove( coedge );
1670 [ # # ]: 0 : loop1->insert_before( coedge, coedge1 );
1671 : : }
1672 [ # # ]: 0 : loop1->remove( coedge1 );
1673 [ # # ]: 0 : loop2->remove( coedge2 );
1674 [ # # ][ # # ]: 0 : assert( loop2->first_coedge() == 0 );
1675 [ # # ]: 0 : surf2->remove( loop2 );
1676 [ # # ][ # # ]: 0 : if( loop1->num_coedges() == 0 )
1677 : : {
1678 [ # # ]: 0 : surf1->remove( loop1 );
1679 [ # # ][ # # ]: 0 : delete loop1;
1680 : : }
1681 : :
1682 [ # # ][ # # ]: 0 : delete loop2;
1683 : : }
1684 : :
1685 [ # # ]: 0 : curve->remove( coedge1 );
1686 [ # # ]: 0 : curve->remove( coedge2 );
1687 [ # # ][ # # ]: 0 : delete coedge1;
1688 [ # # ][ # # ]: 0 : delete coedge2;
1689 [ # # ]: 0 : PartitionPoint* start_pt = curve->start_point();
1690 [ # # ]: 0 : PartitionPoint* end_pt = curve->end_point();
1691 [ # # ]: 0 : curve->start_point(0);
1692 [ # # ]: 0 : curve->end_point(0);
1693 [ # # ][ # # ]: 0 : delete curve;
1694 [ # # ][ # # ]: 0 : if ( !start_pt->next_curve() )
1695 : : {
1696 [ # # ][ # # ]: 0 : if ( start_pt->real_point() )
1697 [ # # ]: 0 : restore_point(start_pt);
1698 : : else
1699 [ # # ][ # # ]: 0 : delete start_pt;
1700 : : }
1701 [ # # ][ # # ]: 0 : if ( end_pt != start_pt && !end_pt->next_curve() )
[ # # ][ # # ]
1702 : : {
1703 [ # # ][ # # ]: 0 : if ( end_pt->real_point() )
1704 [ # # ]: 0 : restore_point(end_pt);
1705 : : else
1706 [ # # ][ # # ]: 0 : delete end_pt;
1707 : : }
1708 : :
1709 : : // need to combine surfaces?
1710 [ # # ]: 0 : if( surf1 != surf2 )
1711 : : {
1712 [ # # ]: 0 : surf1->combine( surf2 );
1713 [ # # ][ # # ]: 0 : while( PartitionLoop* loop = surf2->next_loop() )
1714 : : {
1715 [ # # ]: 0 : surf2->remove( loop );
1716 [ # # ]: 0 : surf1->add( loop );
1717 : : }
1718 : :
1719 [ # # ][ # # ]: 0 : while( PartitionCoSurf* cos = surf2->next_co_surface() )
1720 : : {
1721 [ # # ][ # # ]: 0 : if( cos->get_shell() )
1722 [ # # ][ # # ]: 0 : cos->get_shell()->remove( cos );
1723 [ # # ]: 0 : surf2->remove( cos );
1724 [ # # ][ # # ]: 0 : delete cos;
1725 : : }
1726 : :
1727 [ # # ]: 0 : if( dead_surfs )
1728 : 0 : dead_surfs[0] = surf2;
1729 [ # # ][ # # ]: 0 : delete surf2;
1730 : : }
1731 : :
1732 : : // can remove partition surface?
1733 [ # # ]: 0 : SubSurface* subsurf = dynamic_cast<SubSurface*>(surf1);
1734 [ # # ][ # # ]: 0 : if( subsurf && !subsurf->next_co_surface() &&
[ # # ][ # # ]
[ # # ]
1735 [ # # ][ # # ]: 0 : !subsurf->sub_entity_set().has_lower_order() )
1736 : : {
1737 [ # # ]: 0 : if( dead_surfs )
1738 : : {
1739 [ # # ]: 0 : if( dead_surfs[0] )
1740 : 0 : dead_surfs[1] = surf1;
1741 : : else
1742 : 0 : dead_surfs[0] = surf1;
1743 : : }
1744 [ # # ]: 0 : return restore_surface( subsurf );
1745 : : }
1746 : : else
1747 [ # # ]: 0 : return surf1;
1748 : : }
1749 : :
1750 : : //-------------------------------------------------------------------------
1751 : : // Purpose : Find the facet that:
1752 : : // - contains the passed edge
1753 : : // - uses the passed edge in the specified orientation
1754 : : // - is owned by the passed entity
1755 : : //
1756 : : // Special Notes :
1757 : : //
1758 : : // Creator : Jason Kraftcheck
1759 : : //
1760 : : // Creation Date : 02/23/03
1761 : : //-------------------------------------------------------------------------
1762 : 0 : static CubitFacetData* find_facet( CubitFacetEdge* edge,
1763 : : bool sense,
1764 : : PartitionEntity* owner )
1765 : : {
1766 [ # # ]: 0 : DLIList<CubitFacet*> facets(2);
1767 [ # # ]: 0 : edge->facets(facets);
1768 [ # # ]: 0 : facets.reset();
1769 [ # # ][ # # ]: 0 : for ( int i = facets.size(); i--; ) {
1770 [ # # ]: 0 : CubitFacet* facet = facets.get();
1771 [ # # ]: 0 : int edge_index = facet->edge_index(edge);
1772 [ # # ]: 0 : assert(edge_index >= 0);
1773 [ # # ][ # # ]: 0 : bool forward = edge->point(0) == facet->point((edge_index+1)%3);
1774 [ # # ][ # # ]: 0 : if ( forward != sense || TDVGFacetOwner::get(facet) != owner )
[ # # ][ # # ]
1775 [ # # ]: 0 : facets.extract();
1776 : : else
1777 [ # # ]: 0 : facets.step();
1778 : : }
1779 : :
1780 [ # # ][ # # ]: 0 : return facets.size() == 1 ? dynamic_cast<CubitFacetData*>(facets.get()) : 0;
[ # # ][ # # ]
[ # # ]
1781 : : }
1782 : :
1783 : : //-------------------------------------------------------------------------
1784 : : // Purpose : Find a facet adjacent to the passed point and owned by
1785 : : // the passed PartitionEntity
1786 : : //
1787 : : // Special Notes :
1788 : : //
1789 : : // Creator : Jason Kraftcheck
1790 : : //
1791 : : // Creation Date : 02/23/03
1792 : : //-------------------------------------------------------------------------
1793 : 0 : static CubitFacetData* find_facet( CubitPoint* pt, PartitionEntity* owner )
1794 : : {
1795 [ # # ]: 0 : DLIList<CubitFacet*> facets;
1796 [ # # ]: 0 : pt->facets(facets);
1797 [ # # ]: 0 : facets.reset();
1798 [ # # ][ # # ]: 0 : for ( int i = facets.size(); i--; )
1799 : : {
1800 [ # # ][ # # ]: 0 : if ( TDVGFacetOwner::get(facets.get()) == owner )
[ # # ]
1801 [ # # ]: 0 : facets.step();
1802 : : else
1803 [ # # ]: 0 : facets.extract();
1804 : : }
1805 : :
1806 [ # # ][ # # ]: 0 : return facets.size() == 1 ? dynamic_cast<CubitFacetData*>(facets.get()) : 0;
[ # # ][ # # ]
[ # # ]
1807 : : }
1808 : :
1809 : : //-------------------------------------------------------------------------
1810 : : // Purpose : Find the facet adjacent to the passed facet on the
1811 : : // specified edge, and owned by the passed PartitionEntity
1812 : : //
1813 : : // Special Notes :
1814 : : //
1815 : : // Creator : Jason Kraftcheck
1816 : : //
1817 : : // Creation Date : 02/23/03
1818 : : //-------------------------------------------------------------------------
1819 : 0 : static CubitFacetData* other_facet( CubitFacetData* facet,
1820 : : int edge,
1821 : : PartitionEntity* owner )
1822 : : {
1823 [ # # ]: 0 : DLIList<CubitFacet*> facets;
1824 : 0 : facet->shared_facets( facet->point((edge+1)%3),
1825 : 0 : facet->point((edge+2)%3),
1826 [ # # ][ # # ]: 0 : facets );
[ # # ]
1827 [ # # ][ # # ]: 0 : for ( int i = facets.size(); i--; )
1828 : : {
1829 [ # # ]: 0 : CubitFacet* facet = facets.get();
1830 [ # # ][ # # ]: 0 : if( TDVGFacetOwner::get(facet) != owner )
1831 [ # # ]: 0 : facets.extract();
1832 : : else
1833 [ # # ]: 0 : facets.step();
1834 : : }
1835 : :
1836 [ # # ][ # # ]: 0 : return facets.size() == 1 ? dynamic_cast<CubitFacetData*>(facets.get()) : 0;
[ # # ][ # # ]
[ # # ]
1837 : : }
1838 : : /*
1839 : : static void draw_facet_edges( CubitFacet* facet, int color )
1840 : : {
1841 : : float x1, y1, z1, x2, y2, z2;
1842 : : for ( int i = 0; i < 3; i++ )
1843 : : {
1844 : : x1 = (float)facet->point(i)->coordinates().x();
1845 : : y1 = (float)facet->point(i)->coordinates().y();
1846 : : z1 = (float)facet->point(i)->coordinates().z();
1847 : : x2 = (float)facet->point((i+1)%3)->coordinates().x();
1848 : : y2 = (float)facet->point((i+1)%3)->coordinates().y();
1849 : : z2 = (float)facet->point((i+1)%3)->coordinates().z();
1850 : : GfxDebug::draw_line(x1,y1,z1,x2,y2,z2,color);
1851 : : }
1852 : : GfxDebug::flush();
1853 : : }
1854 : :
1855 : : static void draw_facet_point( CubitPoint* pt, int color )
1856 : : {
1857 : : float x = (float)pt->coordinates().x();
1858 : : float y = (float)pt->coordinates().y();
1859 : : float z = (float)pt->coordinates().z();
1860 : : GfxDebug::draw_point( x, y, z, color );
1861 : : GfxDebug::flush();
1862 : : }
1863 : :
1864 : : static void draw_facet_points( CubitFacet* facet, int color )
1865 : : {
1866 : : draw_facet_point(facet->point(0), color);
1867 : : draw_facet_point(facet->point(1), color);
1868 : : draw_facet_point(facet->point(2), color);
1869 : : }
1870 : : */
1871 : :
1872 : :
1873 : : //-------------------------------------------------------------------------
1874 : : // Purpose : Split surface using facet data, given a coedge along
1875 : : // the split chain.
1876 : : //
1877 : : // Special Notes :
1878 : : //
1879 : : // Creator : Jason Kraftcheck
1880 : : //
1881 : : // Creation Date : 02/23/03
1882 : : //-------------------------------------------------------------------------
1883 : 0 : PartitionSurface* PartitionEngine::split_surface( PartitionSurface* surface,
1884 : : PartitionCoEdge* new_coedge )
1885 : : {
1886 : : int i;
1887 : :
1888 : : // get surface facets and make sure marks are cleared
1889 [ # # ]: 0 : DLIList<CubitFacetData*> faces;
1890 [ # # ]: 0 : surface->get_facet_data(faces);
1891 [ # # ][ # # ]: 0 : for( i = faces.size(); i--; )
1892 [ # # ][ # # ]: 0 : faces.get_and_step()->marked(0);
1893 : :
1894 : :
1895 : : // get curve and curve's facet edges
1896 [ # # ]: 0 : PartitionCurve* new_curve = dynamic_cast<PartitionCurve*>(new_coedge->get_curve());
1897 [ # # ][ # # ]: 0 : DLIList<CubitFacetEdgeData*> edges;
1898 [ # # ]: 0 : new_curve->get_facet_data( edges );
1899 [ # # ][ # # ]: 0 : assert(edges.size());
1900 : :
1901 : : // get the first point in the curve's facet edges
1902 [ # # ]: 0 : edges.reset();
1903 [ # # ]: 0 : CubitFacetEdgeData* edge = edges.get();
1904 [ # # ]: 0 : CubitPoint* pt = edge->point(0);
1905 [ # # ][ # # ]: 0 : if ( TDVGFacetOwner::get(pt) != new_curve->start_point() )
[ # # ][ # # ]
1906 : : {
1907 [ # # ]: 0 : pt = edge->point(1);
1908 [ # # ][ # # ]: 0 : assert(TDVGFacetOwner::get(pt) == new_curve->start_point());
[ # # ][ # # ]
1909 : : }
1910 : :
1911 : : // get the facets on the surface on the inside size of
1912 : : // the coedge
1913 [ # # ]: 0 : bool coedge_forward = new_coedge->sense() == CUBIT_FORWARD;
1914 [ # # ][ # # ]: 0 : DLIList<CubitFacetData*> front( faces.size() );
[ # # ]
1915 [ # # ][ # # ]: 0 : for ( i = edges.size(); i--; )
1916 : : {
1917 [ # # ]: 0 : edge = edges.get_and_step();
1918 [ # # ]: 0 : bool edge_forward = edge->point(0) == pt;
1919 : 0 : bool sense = edge_forward == coedge_forward;
1920 [ # # ][ # # ]: 0 : CubitFacetData* face = find_facet( edge, sense, surface );
1921 [ # # ][ # # ]: 0 : if( face->marked() == 0 )
1922 : : {
1923 : : //draw_facet_edges(face,CUBIT_RED_INDEX);
1924 [ # # ]: 0 : face->marked(1);
1925 [ # # ]: 0 : front.append( face );
1926 : : }
1927 [ # # ]: 0 : pt = edge->other_point(pt);
1928 : : }
1929 : :
1930 : : // mark all adjacent facets traversing only over
1931 : : // edges that are in the interior of the surface
1932 [ # # ][ # # ]: 0 : while( front.size() )
1933 : : {
1934 [ # # ]: 0 : CubitFacetData* face = front.pop();
1935 [ # # ]: 0 : for( i = 0; i < 3; i++ )
1936 : : {
1937 [ # # ][ # # ]: 0 : if( face->edge(i) && TDVGFacetOwner::get(face->edge(i)) )
[ # # ][ # # ]
[ # # ][ # # ]
1938 : 0 : continue;
1939 : :
1940 [ # # ][ # # ]: 0 : CubitFacetData* other = other_facet( face, i, surface );
1941 [ # # ][ # # ]: 0 : if ( other->marked() == 0 )
1942 : : {
1943 : : //draw_facet_edges(face,CUBIT_BLUE_INDEX);
1944 [ # # ]: 0 : other->marked(1);
1945 [ # # ]: 0 : front.append(other);
1946 : : }
1947 : : }
1948 : : }
1949 : :
1950 : : // reuse front to hold all the facets we marked
1951 [ # # ][ # # ]: 0 : for( i = faces.size(); i--; )
1952 : : {
1953 [ # # ]: 0 : CubitFacetData* face = faces.get_and_step();
1954 [ # # ][ # # ]: 0 : if( face->marked() )
1955 [ # # ]: 0 : front.append( face );
1956 : : }
1957 : :
1958 : : // if we got back all the facets, then the surface
1959 : : // was not split!
1960 [ # # ][ # # ]: 0 : if( front.size() == faces.size() )
[ # # ]
1961 : : {
1962 [ # # ][ # # ]: 0 : for( i = faces.size(); i--; )
1963 [ # # ][ # # ]: 0 : faces.get_and_step()->marked(0);
1964 : :
1965 : 0 : return surface;
1966 : : }
1967 : : // split off a new PartitionSurface
1968 [ # # ]: 0 : PartitionSurface* new_surf = surface->split( front );
1969 : :
1970 : : // get list of all loops in surface
1971 [ # # ][ # # ]: 0 : DLIList<PartitionLoop*> loops( surface->num_loops() );
[ # # ]
1972 : 0 : PartitionLoop* loop = 0;
1973 [ # # ][ # # ]: 0 : while( (loop = surface->next_loop( loop )) )
1974 [ # # ]: 0 : loops.append( loop );
1975 : :
1976 : : // check which loops we need to move to the new surface
1977 [ # # ][ # # ]: 0 : while( loops.size() )
1978 : : {
1979 [ # # ]: 0 : loop = loops.pop();
1980 [ # # ]: 0 : PartitionCoEdge* coe = loop->first_coedge();
1981 : :
1982 [ # # ]: 0 : if( !coe )
1983 : 0 : continue;
1984 : :
1985 [ # # ]: 0 : PartitionCurve* curve = coe->get_curve();
1986 : :
1987 : 0 : CubitFacetData* face =0;
1988 [ # # ][ # # ]: 0 : if( PartPTCurve* ptc = dynamic_cast<PartPTCurve*>(curve) )
1989 : : {
1990 [ # # ][ # # ]: 0 : face = find_facet( ptc->start_point()->facet_point(), new_surf );
[ # # ][ # # ]
1991 : : }
1992 : : else
1993 : : {
1994 [ # # ]: 0 : edges.clean_out();
1995 [ # # ]: 0 : curve->get_facet_data( edges );
1996 [ # # ][ # # ]: 0 : if (edges.size() > 0) // normal facet
1997 : : {
1998 [ # # ]: 0 : edges.reset();
1999 [ # # ]: 0 : edge = edges.get();
2000 [ # # ][ # # ]: 0 : CubitPoint* start_pt = curve->start_point()->facet_point();
2001 [ # # ]: 0 : bool forward = edge->point(0) == start_pt;
2002 [ # # ][ # # ]: 0 : assert( forward || edge->point(1) == start_pt );
[ # # ]
2003 [ # # ][ # # ]: 0 : if ( coe->sense() == CUBIT_REVERSED )
2004 : 0 : forward = !forward;
2005 [ # # ][ # # ]: 0 : face = find_facet( edge, forward, new_surf );
2006 : : }
2007 : : else // this is a hardpoint there is a curve with no facets (length)
2008 : : // and the start and end points are the same
2009 : : {
2010 [ # # ][ # # ]: 0 : TBPoint* hardpoint = curve->start_point()->real_point();
2011 [ # # ][ # # ]: 0 : if (hardpoint && curve->start_point() == curve->end_point() )
[ # # ][ # # ]
[ # # ]
2012 : : {
2013 [ # # ]: 0 : CubitVector hardpoint_coord = hardpoint->coordinates();
2014 [ # # ][ # # ]: 0 : CubitVector new_closest, old_closest;
2015 [ # # ][ # # ]: 0 : new_surf->closest_point_trimmed( hardpoint_coord, new_closest );
2016 [ # # ][ # # ]: 0 : surface->closest_point_trimmed( hardpoint_coord, old_closest );
2017 : : // It appears that the new_surf is really the original surface
2018 [ # # ][ # # ]: 0 : if ( new_closest.length_squared() > old_closest.length_squared() )
[ # # ]
2019 : 0 : face = reinterpret_cast<CubitFacetData*>(1); // just set the point to non-zero (true)
2020 : : }
2021 : : }
2022 : : }
2023 : :
2024 [ # # ]: 0 : if( face )
2025 : : {
2026 [ # # ]: 0 : surface->remove( loop );
2027 [ # # ]: 0 : new_surf->add( loop );
2028 : : }
2029 : : }
2030 : : /*
2031 : : PartitionCoSurf* cos = 0;
2032 : : while( (cos = surface->next_co_surface( cos )) )
2033 : : cos->get_shell()->add( new_surf, cos->sense() );
2034 : : */
2035 [ # # ][ # # ]: 0 : for( i = faces.size(); i--; )
2036 [ # # ][ # # ]: 0 : faces.get_and_step()->marked(0);
2037 : :
2038 [ # # ]: 0 : return new_surf;
2039 : : }
2040 : :
2041 : :
2042 : : //-------------------------------------------------------------------------
2043 : : // Purpose : Public interface to surface partitioning.
2044 : : //
2045 : : // Special Notes :
2046 : : //
2047 : : // Creator : Jason Kraftcheck
2048 : : //
2049 : : // Creation Date : 02/23/03
2050 : : //-------------------------------------------------------------------------
2051 : 0 : Surface* PartitionEngine::insert_curve( Surface* surface,
2052 : : DLIList<CubitVector*>& segment_points,
2053 : : DLIList<Curve*>& new_curves,
2054 : : const double *tolerance_length)
2055 : : {
2056 [ # # ][ # # ]: 0 : DLIList<Surface*> input_surfs(1), output_surfs(2);
[ # # ]
2057 [ # # ]: 0 : input_surfs.append(surface);
2058 [ # # ]: 0 : if ( ! insert_curve(input_surfs, segment_points, output_surfs, new_curves,
2059 [ # # ]: 0 : tolerance_length) )
2060 : 0 : return 0;
2061 : :
2062 [ # # ][ # # ]: 0 : return output_surfs.size() ? output_surfs.get() : surface;
[ # # ][ # # ]
2063 : : }
2064 : :
2065 : : //-------------------------------------------------------------------------
2066 : : // Purpose : Public interface to surface partitioning
2067 : : //
2068 : : // Special Notes :
2069 : : //
2070 : : // Creator : Jason Kraftcheck
2071 : : //
2072 : : // Creation Date : 02/23/03
2073 : : //-------------------------------------------------------------------------
2074 : 0 : CubitStatus PartitionEngine::insert_curve(
2075 : : DLIList<Surface*>& input_surfaces,
2076 : : DLIList<CubitVector*>& segment_points,
2077 : : DLIList<Surface*>& new_surfaces,
2078 : : DLIList<Curve*>& new_curves,
2079 : : const double *tolerance_length,
2080 : : DLIList<Surface*>* surfs_to_reverse)
2081 : : {
2082 : : int i;
2083 : 0 : CubitStatus result = CUBIT_SUCCESS;
2084 : :
2085 [ # # ][ # # ]: 0 : for ( i = input_surfaces.size(); i--; )
2086 [ # # ][ # # ]: 0 : if ( dynamic_cast<CompositeSurface*>(input_surfaces.get_and_step()) )
[ # # ][ # # ]
2087 [ # # ]: 0 : return CompositeEngine::instance().insert_curve(
2088 [ # # ]: 0 : input_surfaces, segment_points, new_surfaces, new_curves );
2089 : :
2090 [ # # ]: 0 : DLIList<SubSurface*> replaced_surfaces;
2091 [ # # ][ # # ]: 0 : DLIList<PartitionSurface*> surface_list, new_part_surfs;
[ # # ][ # # ]
2092 [ # # ][ # # ]: 0 : DLIList<PartitionCurve*> curve_list;
2093 : :
2094 : : // get partition surfaces
2095 [ # # ][ # # ]: 0 : for ( i = input_surfaces.size(); i--; )
2096 : : {
2097 : 0 : int reverse_surf = 0;
2098 [ # # ]: 0 : Surface* surf = input_surfaces.get_and_step();
2099 : :
2100 : : // We will need to reverse the surface and its facets if it
2101 : : // is in the passed-in list of surfaces to reverse.
2102 [ # # ][ # # ]: 0 : if(surfs_to_reverse && surfs_to_reverse->is_in_list(surf))
[ # # ][ # # ]
2103 : 0 : reverse_surf = 1;
2104 [ # # ]: 0 : PartitionSurface* partsurf = dynamic_cast<PartitionSurface*>(surf);
2105 [ # # ]: 0 : if( partsurf )
2106 : : {
2107 [ # # ]: 0 : surface_list.append(partsurf);
2108 [ # # ]: 0 : if(reverse_surf)
2109 [ # # ]: 0 : partsurf->reverse_sense();
2110 : : }
2111 : : else
2112 : : {
2113 [ # # ]: 0 : SubSurface* subsurf = replace_surface(surf);
2114 [ # # ]: 0 : if (!subsurf)
2115 : : {
2116 : 0 : result = CUBIT_FAILURE;
2117 : 0 : break;
2118 : : }
2119 : :
2120 [ # # ]: 0 : replaced_surfaces.append( subsurf );
2121 [ # # ]: 0 : surface_list.append(subsurf);
2122 [ # # ]: 0 : if(reverse_surf)
2123 [ # # ]: 0 : subsurf->reverse_sense();
2124 : : }
2125 : : }
2126 : :
2127 [ # # ]: 0 : if (result)
2128 : : {
2129 : : result = insert_curve( surface_list, segment_points, new_part_surfs, curve_list,
2130 [ # # ]: 0 : tolerance_length);
2131 : : }
2132 [ # # ]: 0 : if (!result)
2133 : : {
2134 : : // we replaced the original surface we need to clean up also
2135 [ # # ][ # # ]: 0 : for ( i = replaced_surfaces.size(); i--; )
2136 : : {
2137 [ # # ]: 0 : SubSurface* surf = replaced_surfaces.step_and_get();
2138 [ # # ]: 0 : restore_surface( surf ); // this also deletes the virtual surface
2139 : : }
2140 : :
2141 : 0 : return result;
2142 : : }
2143 : :
2144 [ # # ][ # # ]: 0 : CAST_LIST_TO_PARENT(curve_list,new_curves);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2145 [ # # ][ # # ]: 0 : CAST_LIST_TO_PARENT(new_part_surfs,new_surfaces);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2146 : :
2147 : : // clean up any partition surfaces we created but didn't modify
2148 [ # # ][ # # ]: 0 : for ( i = replaced_surfaces.size(); i--; )
2149 : : {
2150 [ # # ]: 0 : SubSurface* surf = replaced_surfaces.step_and_get();
2151 [ # # ][ # # ]: 0 : if ( !surf->sub_entity_set().has_lower_order() &&
[ # # ][ # # ]
[ # # ]
2152 [ # # ]: 0 : !surf->next_co_surface(0) )
2153 : : {
2154 [ # # ]: 0 : restore_surface( surf );
2155 : : }
2156 : : else
2157 : : {
2158 [ # # ]: 0 : new_surfaces.append( surf );
2159 : : }
2160 : : }
2161 : :
2162 [ # # ]: 0 : return result;
2163 : : }
2164 : :
2165 : 0 : void PartitionEngine::curves_from_surfaces( const DLIList<PartitionSurface*>& surfs,
2166 : : DLIList<PartitionCurve*>& curves )
2167 : : {
2168 : : int i;
2169 : :
2170 [ # # ]: 0 : for (i = curves.size(); i--; )
2171 : 0 : curves.step_and_get()->mark = 1;
2172 : :
2173 [ # # ]: 0 : for (i = surfs.size(); i--; )
2174 : : {
2175 : 0 : PartitionSurface* surf = surfs.next(i);
2176 : 0 : PartitionLoop* loop = 0;
2177 [ # # ]: 0 : while ( (loop = surf->next_loop(loop)) )
2178 : : {
2179 : 0 : PartitionCoEdge* coedge = loop->first_coedge();
2180 [ # # ]: 0 : do {
2181 [ # # ]: 0 : PartitionCurve* curve = coedge->get_curve();
2182 [ # # ]: 0 : if (!curve->mark)
2183 : : {
2184 : 0 : curve->mark = 1;
2185 [ # # ]: 0 : curves.append(curve);
2186 : : }
2187 : :
2188 [ # # ]: 0 : coedge = loop->next_coedge(coedge);
2189 : 0 : } while (coedge != loop->first_coedge());
2190 : : }
2191 : : }
2192 : :
2193 [ # # ]: 0 : for ( i = curves.size(); i--; )
2194 : 0 : curves.step_and_get()->mark = 0;
2195 : 0 : curves.reset();
2196 : 0 : }
2197 : :
2198 : :
2199 : 0 : CubitStatus PartitionEngine::insert_curve( DLIList<PartitionSurface*>& surface_list,
2200 : : DLIList<CubitVector*>& segment_points,
2201 : : DLIList<PartitionSurface*>& new_part_surfs,
2202 : : DLIList<PartitionCurve*>& curve_list,
2203 : : const double *tolerance_length)
2204 : : {
2205 : : int i;
2206 : 0 : const double TOL_SQR = GEOMETRY_RESABS*GEOMETRY_RESABS;
2207 : :
2208 : : // Get curves
2209 [ # # ]: 0 : DLIList<PartitionCurve*> curves;
2210 [ # # ]: 0 : curves_from_surfaces( surface_list, curves );
2211 : :
2212 : : // Check for intersections with boundary curves
2213 [ # # ]: 0 : segment_points.reset();
2214 [ # # ]: 0 : curves.reset();
2215 [ # # ][ # # ]: 0 : for ( i = segment_points.size(); i--; )
2216 : : {
2217 [ # # ]: 0 : CubitVector& pos = *segment_points.get_and_step();
2218 : 0 : bool debug = false;
2219 [ # # ]: 0 : if (debug)
2220 : : {
2221 [ # # ]: 0 : GfxDebug::draw_point(pos, CUBIT_BLUE_INDEX);
2222 [ # # ]: 0 : GfxDebug::mouse_xforms();
2223 : : }
2224 [ # # ][ # # ]: 0 : for ( int j = curves.size(); j--; )
2225 : : {
2226 [ # # ]: 0 : PartitionCurve* curve = curves.get_and_step();
2227 [ # # ][ # # ]: 0 : if ((curve->start_point()->coordinates() - pos).length_squared() < TOL_SQR)
[ # # ][ # # ]
[ # # ]
2228 : : {
2229 [ # # ][ # # ]: 0 : pos = curve->start_point()->coordinates();
[ # # ]
2230 : 0 : break;
2231 : : }
2232 : :
2233 [ # # ][ # # ]: 0 : if ((curve->end_point()->coordinates() - pos).length_squared() < TOL_SQR)
[ # # ][ # # ]
[ # # ]
2234 : : {
2235 [ # # ][ # # ]: 0 : pos = curve->end_point()->coordinates();
[ # # ]
2236 : 0 : break;
2237 : : }
2238 : :
2239 [ # # ]: 0 : CubitVector closest;
2240 [ # # ]: 0 : curve->closest_point_trimmed( pos, closest );
2241 : :
2242 [ # # ][ # # ]: 0 : if ( (pos - closest).length_squared() > TOL_SQR )
[ # # ]
2243 : 0 : continue;
2244 : :
2245 [ # # ][ # # ]: 0 : if ((curve->start_point()->coordinates() - closest).length_squared() < TOL_SQR)
[ # # ][ # # ]
[ # # ]
2246 : : {
2247 [ # # ][ # # ]: 0 : pos = curve->start_point()->coordinates();
[ # # ]
2248 : 0 : break;
2249 : : }
2250 : :
2251 [ # # ][ # # ]: 0 : if ((curve->end_point()->coordinates() - closest).length_squared() < TOL_SQR)
[ # # ][ # # ]
[ # # ]
2252 : : {
2253 [ # # ][ # # ]: 0 : pos = curve->end_point()->coordinates();
[ # # ]
2254 : 0 : break;
2255 : : }
2256 : : /*
2257 : : double u = curve->u_from_position(closest);
2258 : : TBPoint* point = insert_point( curve, u );
2259 : : if (!point)
2260 : : {
2261 : : PRINT_ERROR("Error splitting curve. Aborting.\n");
2262 : : return CUBIT_FAILURE;
2263 : : }
2264 : : pos = point->coordinates();
2265 : : */
2266 [ # # ]: 0 : pos = closest;
2267 : 0 : break;
2268 : : }
2269 : : }
2270 : :
2271 : :
2272 : : // get surface facets
2273 [ # # ][ # # ]: 0 : DLIList<CubitFacetData*> surf_facets, facet_list;
[ # # ][ # # ]
2274 [ # # ]: 0 : surface_list.reset();
2275 [ # # ][ # # ]: 0 : for ( i = surface_list.size(); i--; )
2276 : : {
2277 [ # # ]: 0 : surf_facets.clean_out();
2278 [ # # ][ # # ]: 0 : surface_list.get_and_step()->get_facet_data( surf_facets );
2279 [ # # ]: 0 : facet_list += surf_facets;
2280 : : }
2281 : :
2282 : : // Do facet projection
2283 [ # # ][ # # ]: 0 : DLIList<CubitFacetEdgeData*> polyline;
2284 [ # # ][ # # ]: 0 : DLIList<CubitPointData*> polyline_pts;
2285 [ # # ]: 0 : project_to_surface( facet_list, segment_points, polyline, polyline_pts, tolerance_length);
2286 : :
2287 [ # # ][ # # ]: 0 : if(segment_points.size() == polyline_pts.size())
[ # # ]
2288 : : {
2289 : : // Move facet points to real geometry
2290 [ # # ]: 0 : DLIList<CubitFacetEdge*> edge_list;
2291 [ # # ][ # # ]: 0 : DLIList<CubitFacet*> pt_facets;
2292 [ # # ]: 0 : segment_points.reset();
2293 [ # # ]: 0 : polyline_pts.reset();
2294 : 0 : int count = 0;
2295 [ # # ][ # # ]: 0 : for ( i = segment_points.size(); i--; )
2296 : : {
2297 [ # # ]: 0 : CubitPointData* facet_pt = polyline_pts.get_and_step();
2298 [ # # ][ # # ]: 0 : CubitVector position( *segment_points.get_and_step() );
2299 [ # # ]: 0 : if ( !facet_pt )
2300 : 0 : continue;
2301 : :
2302 [ # # ][ # # ]: 0 : PartitionPoint* point = dynamic_cast<PartitionPoint*>(TDVGFacetOwner::get(facet_pt));
2303 [ # # ]: 0 : if ( point )
2304 : : {
2305 : 0 : count++;
2306 : 0 : continue;
2307 : : }
2308 : :
2309 : 0 : PartitionCurve* curve = 0;
2310 [ # # ]: 0 : edge_list.clean_out();
2311 [ # # ]: 0 : facet_pt->edges( edge_list );
2312 [ # # ][ # # ]: 0 : while ( edge_list.size() )
2313 : : {
2314 : :
2315 [ # # ][ # # ]: 0 : PartitionEntity* owner = TDVGFacetOwner::get(edge_list.pop());
2316 [ # # ]: 0 : if ( owner )
2317 : : {
2318 [ # # ][ # # ]: 0 : assert(!curve || curve == owner);
[ # # ]
2319 [ # # ]: 0 : curve = dynamic_cast<PartitionCurve*>(owner);
2320 : : }
2321 : : }
2322 [ # # ]: 0 : if ( curve )
2323 : : {
2324 [ # # ][ # # ]: 0 : Surface* surface = dynamic_cast<Surface*>(curve->partitioned_entity());
2325 [ # # ]: 0 : if ( surface )
2326 : : {
2327 [ # # ]: 0 : CubitVector surf_pos;
2328 [ # # ]: 0 : surface->closest_point( position, &surf_pos );
2329 [ # # ][ # # ]: 0 : if (facet_pt->check_inverted_facets(surf_pos))
2330 [ # # ]: 0 : facet_pt->set( surf_pos );
2331 : : }
2332 : : else
2333 [ # # ]: 0 : curve->relax_to_geometry( facet_pt, &position );
2334 : :
2335 : 0 : continue;
2336 : : }
2337 : :
2338 : 0 : PartitionSurface* surf = 0;
2339 [ # # ]: 0 : pt_facets.clean_out();
2340 [ # # ]: 0 : facet_pt->facets( pt_facets );
2341 [ # # ][ # # ]: 0 : while ( pt_facets.size() )
2342 : : {
2343 [ # # ][ # # ]: 0 : PartitionEntity* owner = TDVGFacetOwner::get(pt_facets.pop());
2344 [ # # ]: 0 : if ( owner )
2345 : : {
2346 [ # # ][ # # ]: 0 : assert(!surf || surf == owner);
[ # # ]
2347 [ # # ]: 0 : surf = dynamic_cast<PartitionSurface*>(owner);
2348 : : }
2349 : : }
2350 [ # # ][ # # ]: 0 : if ( surf && dynamic_cast<SubSurface*>(surf) )
[ # # ][ # # ]
2351 : : {
2352 [ # # ]: 0 : surf->relax_to_geometry( facet_pt, &position );
2353 : : }
2354 [ # # ]: 0 : }
2355 : : }
2356 : :
2357 [ # # ][ # # ]: 0 : if ( !polyline.size() )
2358 : 0 : return CUBIT_FAILURE;
2359 : :
2360 : : //In the following lines we see if we need to split curves on
2361 : : //the boundary of the surface. This is necessary when the endpoints of
2362 : : //the polylines used for partitioning are not coincident with
2363 : : //boundary curves.
2364 : :
2365 : : //get all the facet points of the polyline
2366 [ # # ][ # # ]: 0 : DLIList<CubitPoint*> points_on_polyline;
2367 [ # # ][ # # ]: 0 : for( int k=polyline.size(); k--; )
2368 : : {
2369 [ # # ]: 0 : CubitFacetEdgeData *tmp_edge = polyline.get_and_step();
2370 [ # # ]: 0 : if( !tmp_edge )
2371 : 0 : continue;
2372 [ # # ][ # # ]: 0 : points_on_polyline.append_unique( tmp_edge->start_node() );
2373 [ # # ][ # # ]: 0 : points_on_polyline.append_unique( tmp_edge->end_node() );
2374 : : }
2375 : :
2376 : : //get all the resulting facets
2377 [ # # ][ # # ]: 0 : DLIList<CubitFacet*> facets_after;
2378 [ # # ][ # # ]: 0 : for ( i = surface_list.size(); i--; )
2379 : : {
2380 [ # # ]: 0 : surf_facets.clean_out();
2381 [ # # ][ # # ]: 0 : surface_list.get_and_step()->get_facet_data( surf_facets );
2382 [ # # ][ # # ]: 0 : for( int s=surf_facets.size(); s--; )
2383 [ # # ][ # # ]: 0 : facets_after.append( surf_facets.get_and_step() );
2384 : : }
2385 : :
2386 : : //from the facets, collect all the boundary points
2387 [ # # ][ # # ]: 0 : DLIList<CubitPoint*> boundary_pts;
2388 [ # # ]: 0 : FacetDataUtil::get_boundary_points( facets_after, boundary_pts );
2389 : :
2390 : : //for each polyline points...
2391 [ # # ][ # # ]: 0 : for( int k=points_on_polyline.size(); k--; )
2392 : : {
2393 [ # # ]: 0 : CubitPoint *tmp_pt = points_on_polyline.get_and_step();
2394 : :
2395 : : //if the point is on the boundary...
2396 [ # # ][ # # ]: 0 : if( boundary_pts.is_in_list( tmp_pt ) )
2397 : : {
2398 [ # # ][ # # ]: 0 : PartitionPoint* point = dynamic_cast<PartitionPoint*>(TDVGFacetOwner::get(tmp_pt));
2399 [ # # ]: 0 : if( !point ) //if the point is not already a vertex on the boundary...
2400 : : {
2401 : : //find the adjacent boundary curve that we'll insert these points into
2402 [ # # ]: 0 : DLIList<CubitFacetEdge*> adj_edges;
2403 [ # # ]: 0 : tmp_pt->edges( adj_edges );
2404 : :
2405 [ # # ][ # # ]: 0 : for( int s=adj_edges.size(); s--; )
2406 : : {
2407 [ # # ]: 0 : CubitFacetEdge *tmp_edge = adj_edges.get_and_step();
2408 [ # # ][ # # ]: 0 : PartitionCurve* curve = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(tmp_edge));
2409 [ # # ]: 0 : if( curve )
2410 : : {
2411 [ # # ]: 0 : DLIList<TopologyBridge*> bridges;
2412 [ # # ]: 0 : get_tbs_with_bridge_manager_as_owner(curve, bridges );
2413 : :
2414 [ # # ][ # # ]: 0 : if( bridges.size() == 0 )
2415 [ # # ][ # # ]: 0 : CompositeEngine::instance().get_tbs_with_bridge_manager_as_owner( curve, bridges );
2416 : :
2417 [ # # ][ # # ]: 0 : RefEdge *ref_edge = dynamic_cast<RefEdge*>(bridges.get()->topology_entity());
[ # # ]
2418 : : RefEdge *edge1, *edge2;
2419 : :
2420 : : //now do the split
2421 [ # # ][ # # ]: 0 : PartitionTool::instance()->partition( ref_edge, tmp_pt->coordinates(), edge1, edge2 );
[ # # ]
2422 [ # # ]: 0 : break;
2423 : : }
2424 [ # # ]: 0 : }
2425 : : }
2426 : : }
2427 : : }
2428 : :
2429 : : // construct the curves
2430 [ # # ][ # # ]: 0 : DLIList<CubitFacetEdgeData*> cubit_edges;
2431 [ # # ][ # # ]: 0 : DLIList<CubitFacetEdge*> pt_edges;
2432 [ # # ]: 0 : polyline.reset();
2433 [ # # ][ # # ]: 0 : for ( i = polyline.size(); i > 0; )
2434 : : {
2435 : : // get list of FacetPoints for Curve
2436 [ # # ]: 0 : cubit_edges.clean_out();
2437 [ # # ]: 0 : CubitFacetEdgeData* edge = polyline.get_and_step();
2438 [ # # ]: 0 : if (!edge) { i--; continue; }
2439 : :
2440 [ # # ][ # # ]: 0 : assert(!TDVGFacetOwner::get(edge) &&
[ # # ][ # # ]
[ # # ]
2441 : : edge->num_adj_facets() < 3 &&
2442 [ # # ]: 0 : edge->num_adj_facets() > 0);
2443 : :
2444 [ # # ][ # # ]: 0 : PartitionEntity* owner = TDVGFacetOwner::get(edge->adj_facet(0));
2445 [ # # ][ # # ]: 0 : assert( edge->num_adj_facets() == 1 ||
[ # # ][ # # ]
2446 [ # # ]: 0 : TDVGFacetOwner::get(edge->adj_facet(1)) == owner );
2447 : :
2448 [ # # ]: 0 : cubit_edges.append( edge );
2449 : :
2450 [ # # ][ # # ]: 0 : while( polyline.get() )
2451 : : {
2452 [ # # ][ # # ]: 0 : CubitPoint* pt = edge->shared_point(polyline.get());
2453 [ # # ]: 0 : edge = polyline.get();
2454 : :
2455 [ # # ][ # # ]: 0 : assert(!TDVGFacetOwner::get(edge) &&
[ # # ][ # # ]
[ # # ][ # # ]
2456 : : edge->num_adj_facets() < 3 &&
2457 [ # # ]: 0 : edge->num_adj_facets() > 0 && pt);
2458 : :
2459 [ # # ][ # # ]: 0 : PartitionEntity* tmp = TDVGFacetOwner::get(edge->adj_facet(0));
2460 [ # # ][ # # ]: 0 : assert( edge->num_adj_facets() == 1 ||
[ # # ][ # # ]
2461 [ # # ]: 0 : TDVGFacetOwner::get(edge->adj_facet(1)) == tmp );
2462 : :
2463 : 0 : bool edge_owner = false;
2464 [ # # ]: 0 : pt->edges(pt_edges);
2465 [ # # ][ # # ]: 0 : while (pt_edges.size())
2466 [ # # ][ # # ]: 0 : if (TDVGFacetOwner::get(pt_edges.pop()))
[ # # ]
2467 : 0 : edge_owner = true;
2468 : :
2469 [ # # ][ # # ]: 0 : if ( tmp != owner || TDVGFacetOwner::get(pt) || edge_owner )
[ # # ][ # # ]
[ # # ]
2470 : 0 : break;
2471 : :
2472 [ # # ][ # # ]: 0 : cubit_edges.append( polyline.get_and_step() );
2473 : : }
2474 [ # # ][ # # ]: 0 : if (NULL == polyline.get())
2475 : : {
2476 [ # # ]: 0 : polyline.step();
2477 : 0 : i -= 1;
2478 : : }
2479 [ # # ]: 0 : i -= cubit_edges.size();
2480 : :
2481 : : // create curve and partition surface
2482 [ # # ]: 0 : PartitionCurve* new_curve = insert_curve( cubit_edges, &segment_points );
2483 [ # # ]: 0 : if ( new_curve )
2484 [ # # ]: 0 : curve_list.append(new_curve);
2485 : : }
2486 : :
2487 : : // find new surfaces to return
2488 [ # # ][ # # ]: 0 : for ( i = curve_list.size(); i--; )
2489 : : {
2490 [ # # ]: 0 : PartitionCurve* curve = curve_list.step_and_get();
2491 : 0 : PartitionCoEdge* coedge = 0;
2492 [ # # ][ # # ]: 0 : while( (coedge = curve->next_coedge(coedge)) )
2493 : : {
2494 [ # # ][ # # ]: 0 : new_part_surfs.append( coedge->get_loop()->get_surface() );
[ # # ]
2495 : : }
2496 : : }
2497 : :
2498 [ # # ][ # # ]: 0 : if ( curve_list.size() )
2499 : : {
2500 : : // do facet cleanup
2501 [ # # ][ # # ]: 0 : for ( i = curve_list.size(); i--; )
2502 [ # # ][ # # ]: 0 : curve_list.get_and_step()->do_facet_cleanup();
2503 : : //for ( i = new_part_surfs.size(); i--; )
2504 : : // new_part_surfs.get_and_step()->do_facet_cleanup();
2505 : : }
2506 : :
2507 : :
2508 [ # # ][ # # ]: 0 : for ( i = new_part_surfs.size(); i--; )
2509 [ # # ]: 0 : new_part_surfs.step_and_get()->mark = 1;
2510 [ # # ][ # # ]: 0 : for ( i = surface_list.size(); i--; )
2511 [ # # ]: 0 : surface_list.step_and_get()->mark = 0;
2512 [ # # ][ # # ]: 0 : for ( i = new_part_surfs.size(); i--; )
2513 [ # # ][ # # ]: 0 : if ( new_part_surfs.step_and_get()->mark )
2514 [ # # ]: 0 : new_part_surfs.get()->mark = 0;
2515 : : else
2516 [ # # ]: 0 : new_part_surfs.change_to(0);
2517 [ # # ]: 0 : new_part_surfs.remove_all_with_value(0);
2518 : :
2519 [ # # ][ # # ]: 0 : return curve_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
[ # # ]
2520 : : }
2521 : :
2522 : : //-------------------------------------------------------------------------
2523 : : // Purpose : Given a polyline-imprint on the surface facetting,
2524 : : // construct a new and insert it in the surface topology.
2525 : : //
2526 : : // Special Notes :
2527 : : //
2528 : : // Creator : Jason Kraftcheck
2529 : : //
2530 : : // Creation Date : 02/23/03
2531 : : //-------------------------------------------------------------------------
2532 : 0 : SegmentedCurve* PartitionEngine::insert_curve(
2533 : : DLIList<CubitFacetEdgeData*>& segments,
2534 : : DLIList<CubitVector*>* /*curve_geom*/ )
2535 : : {
2536 : : int i;
2537 : :
2538 : : // find surface
2539 : 0 : PartitionSurface* surface = 0;
2540 [ # # ]: 0 : DLIList<CubitFacet*> facets;
2541 [ # # ][ # # ]: 0 : for ( i = segments.size(); i--; )
2542 : : {
2543 [ # # ]: 0 : CubitFacetEdgeData* edge = segments.get_and_step();
2544 [ # # ]: 0 : facets.clean_out();
2545 [ # # ]: 0 : edge->facets(facets);
2546 [ # # ][ # # ]: 0 : assert(facets.size() == 2);
2547 [ # # ][ # # ]: 0 : for (int j = 0; j < facets.size(); j++ )
2548 : : {
2549 [ # # ]: 0 : CubitFacet* facet = facets.get_and_step();
2550 [ # # ]: 0 : PartitionEntity* fowner = TDVGFacetOwner::get(facet);
2551 [ # # ]: 0 : PartitionSurface* surf = dynamic_cast<PartitionSurface*>(fowner);
2552 [ # # ][ # # ]: 0 : if ( !surf || (surface && surf != surface) )
[ # # ]
2553 : : {
2554 [ # # ][ # # ]: 0 : PRINT_ERROR("Internal Error in PartitionEngine. Corrupt facet data.\n");
[ # # ][ # # ]
2555 : 0 : assert(0);
2556 : : return 0;
2557 : : }
2558 : 0 : surface = surf;
2559 : : }
2560 : : }
2561 : :
2562 : : // if there is a real surface, relax facet points to surface
2563 [ # # ][ # # ]: 0 : Surface* real_surf = dynamic_cast<Surface*>(surface->partitioned_entity());
2564 : :
2565 : : // find start and end facet points
2566 : : CubitPointData* pts[2];
2567 : : CubitPoint* pt;
2568 : :
2569 [ # # ][ # # ]: 0 : if( segments.size() == 1 )
2570 : : {
2571 [ # # ][ # # ]: 0 : pts[0] = dynamic_cast<CubitPointData*>(segments.get()->point(0));
[ # # ]
2572 [ # # ][ # # ]: 0 : pts[1] = dynamic_cast<CubitPointData*>(segments.get()->point(1));
[ # # ]
2573 : : }
2574 : : else
2575 : : {
2576 [ # # ]: 0 : segments.last();
2577 [ # # ][ # # ]: 0 : pt = segments.get()->shared_point( segments.prev() );
[ # # ]
2578 [ # # ][ # # ]: 0 : pt = segments.get()->other_point( pt );
2579 [ # # ]: 0 : pts[1] = dynamic_cast<CubitPointData*>(pt);
2580 [ # # ]: 0 : segments.reset();
2581 [ # # ][ # # ]: 0 : pt = segments.get()->shared_point( segments.next() );
[ # # ]
2582 [ # # ][ # # ]: 0 : pt = segments.get()->other_point( pt );
2583 [ # # ]: 0 : pts[0] = dynamic_cast<CubitPointData*>(pt);
2584 : : }
2585 : :
2586 : : // create end points (partition curves if necessary)
2587 : 0 : bool okay = true;
2588 [ # # ][ # # ]: 0 : DLIList<CubitFacetEdge*> edges;
2589 : 0 : bool created_pts[2] = {false,false};
2590 : 0 : PartitionPoint* end_pts[2] = {0,0};
2591 [ # # ][ # # ]: 0 : for ( i = 0; okay && i < 2; i++ )
2592 : : {
2593 [ # # ][ # # ]: 0 : end_pts[i] = dynamic_cast<PartitionPoint*>(TDVGFacetOwner::get(pts[i]));
2594 [ # # ]: 0 : if( end_pts[i] ) continue;
2595 : :
2596 [ # # ]: 0 : edges.clean_out();
2597 [ # # ]: 0 : pts[i]->edges(edges);
2598 : 0 : PartitionCurve* curve = 0;
2599 [ # # ][ # # ]: 0 : for ( int j = edges.size(); !curve && j--; )
[ # # ][ # # ]
2600 [ # # ][ # # ]: 0 : curve = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(edges.get_and_step()));
[ # # ]
2601 : :
2602 [ # # ]: 0 : if( curve )
2603 : : {
2604 [ # # ]: 0 : curve->relax_to_geometry( pts[i] );
2605 [ # # ][ # # ]: 0 : PartitionPoint* new_pt = new PartitionPoint( pts[i]->coordinates(), curve );
[ # # ][ # # ]
2606 [ # # ][ # # ]: 0 : if ( insert_point( curve, new_pt ) )
2607 : : {
2608 : 0 : end_pts[i] = new_pt;
2609 : 0 : created_pts[i] = true;
2610 [ # # ][ # # ]: 0 : assert( TDVGFacetOwner::get(pts[i]) == new_pt );
[ # # ]
2611 : : }
2612 : : else
2613 : : {
2614 [ # # ][ # # ]: 0 : delete new_pt;
2615 : 0 : okay = false;
2616 : : }
2617 : 0 : continue;
2618 : : }
2619 : :
2620 [ # # ]: 0 : facets.clean_out();
2621 [ # # ]: 0 : pts[i]->facets(facets);
2622 [ # # ][ # # ]: 0 : for ( int k = facets.size(); k--; )
2623 [ # # ][ # # ]: 0 : if( TDVGFacetOwner::get(facets.get_and_step()) != surface )
[ # # ][ # # ]
2624 : : {
2625 [ # # ][ # # ]: 0 : PRINT_ERROR("Internal Error in PartitionEngine. Corrupt facet data.\n");
[ # # ][ # # ]
2626 : 0 : okay = false;
2627 : 0 : break;
2628 : : }
2629 : :
2630 [ # # ]: 0 : if( okay )
2631 : : {
2632 [ # # ]: 0 : if( real_surf )
2633 [ # # ]: 0 : surface->relax_to_geometry( pts[i] );
2634 : :
2635 [ # # ][ # # ]: 0 : end_pts[i] = new PartitionPoint( pts[i]->coordinates(), surface );
[ # # ][ # # ]
2636 [ # # ]: 0 : end_pts[i]->facet_point( pts[i] );
2637 : : }
2638 : : }
2639 : :
2640 : : // create curve
2641 : 0 : SegmentedCurve* curve = 0;
2642 [ # # ]: 0 : if( okay )
2643 : : {
2644 [ # # ][ # # ]: 0 : DLIList<CubitVector*> vectors(segments.size()+1), *curve_geom_ptr;
2645 : : // if( curve_geom )
2646 : : // {
2647 : : // curve_geom_ptr = curve_geom;
2648 : : // }
2649 : : // else
2650 : : {
2651 [ # # ]: 0 : segments.reset();
2652 : 0 : pt = pts[0];
2653 [ # # ][ # # ]: 0 : vectors.append( new CubitVector( pt->coordinates() ) );
[ # # ]
2654 [ # # ][ # # ]: 0 : for( i = segments.size(); i--; )
2655 : : {
2656 [ # # ][ # # ]: 0 : pt = segments.get_and_step()->other_point(pt);
2657 [ # # ][ # # ]: 0 : if ( real_surf && i > 0 )
2658 : : {
2659 [ # # ]: 0 : surface->relax_to_geometry( pt );
2660 : : }
2661 [ # # ]: 0 : assert(!!pt);
2662 [ # # ][ # # ]: 0 : vectors.append( new CubitVector( pt->coordinates() ) );
[ # # ]
2663 : : }
2664 : 0 : curve_geom_ptr = &vectors;
2665 : : }
2666 : :
2667 [ # # ][ # # ]: 0 : curve = new SegmentedCurve( surface, *curve_geom_ptr );
2668 : :
2669 [ # # ][ # # ]: 0 : while( vectors.size() ) delete vectors.pop();
[ # # ]
2670 : :
2671 [ # # ]: 0 : curve->start_point( end_pts[0] );
2672 [ # # ]: 0 : curve->end_point( end_pts[1] );
2673 [ # # ]: 0 : curve->set_facet_data(segments);
2674 : :
2675 [ # # ][ # # ]: 0 : if( insert_curve( surface, curve ) )
2676 [ # # ][ # # ]: 0 : return curve;
2677 : : }
2678 : :
2679 : : // If we got this far, then something went wrong.
2680 : : // Try to clean up.
2681 : :
2682 [ # # ]: 0 : if( curve )
2683 : : {
2684 [ # # ]: 0 : curve->start_point(0);
2685 [ # # ]: 0 : curve->end_point(0);
2686 [ # # ]: 0 : segments.clean_out();
2687 [ # # ]: 0 : curve->set_facet_data(segments);
2688 [ # # ][ # # ]: 0 : delete curve;
2689 : : }
2690 : :
2691 [ # # ]: 0 : for( i = 0; i < 2; i++ )
2692 : : {
2693 [ # # ]: 0 : if( ! created_pts[i] ) continue;
2694 : :
2695 [ # # ]: 0 : end_pts[i]->facet_point(0);
2696 [ # # ][ # # ]: 0 : if( dynamic_cast<Curve*>(end_pts[i]->partitioned_entity()) )
[ # # ][ # # ]
2697 [ # # ]: 0 : remove_point( end_pts[i] );
2698 : : else
2699 [ # # ][ # # ]: 0 : delete end_pts[i];
2700 : : }
2701 : :
2702 [ # # ]: 0 : return 0;
2703 : : }
2704 : :
2705 : : /*
2706 : : //-------------------------------------------------------------------------
2707 : : // Purpose : Partition a curve using a facet point on the curve.
2708 : : //
2709 : : // Special Notes :
2710 : : //
2711 : : // Creator : Jason Kraftcheck
2712 : : //
2713 : : // Creation Date : 02/23/03
2714 : : //-------------------------------------------------------------------------
2715 : : PartitionPoint* PartitionEngine::insert_point( CubitPointData* pt )
2716 : : {
2717 : : DLIList<CubitFacetEdge*> edges;
2718 : : pt->edges(edges);
2719 : :
2720 : : PartitionCurve* curve = 0;
2721 : : for ( int i = edges.size(); i--; )
2722 : : {
2723 : : CubitFacetEdge* edge = edges.step_and_get();
2724 : : PartitionCurve* c = dynamic_cast<PartitionCurve*>(TDVGFacetOwner::get(edge));
2725 : : if( c )
2726 : : {
2727 : : if( !curve )
2728 : : curve = c;
2729 : : else if( curve != c )
2730 : : {
2731 : : PRINT_ERROR("Internal Error in PartitionEngine. Corrupt facet data.\n");
2732 : : return 0;
2733 : : }
2734 : : }
2735 : : }
2736 : :
2737 : : DLIList<CubitFacetEdgeData*> segments, other_segments;
2738 : : curve->get_facet_data(segments);
2739 : : segments.last();
2740 : : while( !segments.get()->contains( pt ) )
2741 : : {
2742 : : other_segments.append( segments.pop() );
2743 : : segments.last();
2744 : : }
2745 : : other_segments.reverse();
2746 : :
2747 : : PartitionPoint* new_point = new PartitionPoint( pt->coordinates(), curve );
2748 : : PartitionCurve* curve2 = insert_point( curve, new_point );
2749 : : if( !curve2 )
2750 : : {
2751 : : delete new_point;
2752 : : return 0;
2753 : : }
2754 : :
2755 : : curve->set_facet_data(segments);
2756 : : curve2->set_facet_data(other_segments);
2757 : : new_point->facet_point(pt);
2758 : : return new_point;
2759 : : }
2760 : : */
2761 : :
2762 : : //-------------------------------------------------------------------------
2763 : : // Purpose : Add point to surface facetting.
2764 : : //
2765 : : // Special Notes :
2766 : : //
2767 : : // Creator : Jason Kraftcheck
2768 : : //
2769 : : // Creation Date : 02/23/03
2770 : : //-------------------------------------------------------------------------
2771 : 0 : CubitPointData* PartitionEngine::project_to_surface(
2772 : : PartitionSurface* surface,
2773 : : const CubitVector& position )
2774 : : {
2775 : :
2776 [ # # ]: 0 : CubitVector pos;
2777 [ # # ]: 0 : CubitFacet* facet = surface->closest_facet( position, pos );
2778 [ # # ]: 0 : surface->closest_point( position, &pos );
2779 [ # # ]: 0 : CubitFacetData* facet_d = dynamic_cast<CubitFacetData*>(facet);
2780 [ # # ]: 0 : DLIList<CubitFacetEdge*> pt_edges;
2781 [ # # ]: 0 : assert(!!facet_d);
2782 : :
2783 [ # # ][ # # ]: 0 : CubitVector p[3], v[3], d[3];
[ # # ][ # # ]
[ # # ][ # # ]
2784 : : int i;
2785 : :
2786 : : // Initialize data
2787 : 0 : double dist_tol_sqr = CUBIT_DBL_MAX;
2788 [ # # ]: 0 : for ( i = 0; i < 3; i++ ) {
2789 [ # # ][ # # ]: 0 : p[i] = facet_d->point(i)->coordinates();
[ # # ]
2790 [ # # ][ # # ]: 0 : v[i] = facet_d->point((i+1)%3)->coordinates() - p[i];
[ # # ][ # # ]
2791 [ # # ]: 0 : double dist_sqr = v[i].length_squared();
2792 [ # # ]: 0 : if ( dist_sqr < dist_tol_sqr )
2793 : 0 : dist_tol_sqr = dist_sqr;
2794 [ # # ][ # # ]: 0 : d[i] = pos - p[i];
2795 : : }
2796 : 0 : dist_tol_sqr *= 0.2;
2797 [ # # ]: 0 : if( dist_tol_sqr < GEOMETRY_RESABS*GEOMETRY_RESABS )
2798 : 0 : dist_tol_sqr = GEOMETRY_RESABS*GEOMETRY_RESABS;
2799 : :
2800 : : // Check if we are within GEOMETRY_RESABS of a vertex of the
2801 : : // triangle or if one of the triangle vertices can be moved
2802 : : // to the input location.
2803 : 0 : int closest_pt = -1;
2804 : 0 : double closest_dist = dist_tol_sqr;
2805 [ # # ]: 0 : for ( i = 0; i < 3; i++ ) {
2806 [ # # ]: 0 : double dist_sqr = d[i].length_squared();
2807 [ # # ][ # # ]: 0 : bool has_owner = (0 != TDVGFacetOwner::get(facet->point(i)));
2808 [ # # ][ # # ]: 0 : if( !has_owner && dist_sqr < closest_dist ) {
2809 [ # # ]: 0 : pt_edges.clean_out();
2810 [ # # ][ # # ]: 0 : facet->point(i)->edges( pt_edges);
2811 [ # # ][ # # ]: 0 : while( pt_edges.size() )
2812 [ # # ][ # # ]: 0 : if ( TDVGFacetOwner::get(pt_edges.pop()) )
[ # # ]
2813 : 0 : has_owner = true;
2814 : : }
2815 : :
2816 [ # # ][ # # ]: 0 : if ( (!has_owner && dist_sqr < closest_dist) ||
[ # # ]
2817 : : dist_sqr < GEOMETRY_RESABS*GEOMETRY_RESABS ) {
2818 : 0 : closest_pt = i;
2819 : 0 : closest_dist = dist_sqr;
2820 : : }
2821 : : }
2822 : :
2823 [ # # ]: 0 : if( closest_pt >= 0 )
2824 : : {
2825 [ # # ][ # # ]: 0 : facet->point(closest_pt)->set(pos);
2826 [ # # ][ # # ]: 0 : return dynamic_cast<CubitPointData*>(facet->point(closest_pt));
2827 : : }
2828 : :
2829 : : // Check if the input position is within GEOMETRY_RESABS of one
2830 : : // of the triangle edges or if the edge can be 'bent' such that
2831 : : // the split point is the input position.
2832 : 0 : int closest_edge = -1;
2833 [ # # ]: 0 : for ( i = 0; i < 3; i++ ) {
2834 [ # # ][ # # ]: 0 : double t = (v[i] % d[i]) / v[i].length_squared();
2835 [ # # ][ # # ]: 0 : double dist_sqr = (d[i] - t * v[i]).length_squared();
[ # # ]
2836 [ # # ][ # # ]: 0 : CubitFacetEdge* edge = facet->point(i)->shared_edge(facet->point((i+1)%3));
[ # # ]
2837 : :
2838 [ # # ][ # # ]: 0 : bool has_owner = edge && TDVGFacetOwner::get(edge);
[ # # ]
2839 : :
2840 [ # # ][ # # ]: 0 : if( (!has_owner && dist_sqr < closest_dist) ||
[ # # ]
2841 : : dist_sqr < GEOMETRY_RESABS*GEOMETRY_RESABS )
2842 : : {
2843 : 0 : CubitFacet* other_facet = 0;
2844 [ # # ][ # # ]: 0 : for ( int j = 0; j < edge->num_adj_facets(); j++ )
2845 : : {
2846 [ # # ][ # # ]: 0 : if (edge->adj_facet(j) != facet &&
[ # # ][ # # ]
2847 [ # # ][ # # ]: 0 : TDVGFacetOwner::get(edge->adj_facet(j)) == surface)
[ # # ]
2848 : : {
2849 [ # # ]: 0 : other_facet = edge->adj_facet(j);
2850 : 0 : break;
2851 : : }
2852 : : }
2853 : :
2854 [ # # ]: 0 : if (other_facet)
2855 : : {
2856 : : // check if splitting the edge will invert some other facet
2857 [ # # ]: 0 : int edge_index = other_facet->edge_index( edge );
2858 [ # # ][ # # ]: 0 : CubitVector other_pt = other_facet->point(edge_index)->coordinates();
2859 [ # # ][ # # ]: 0 : CubitVector prev_pt = other_facet->point((edge_index+1)%3)->coordinates();
2860 [ # # ][ # # ]: 0 : CubitVector next_pt = other_facet->point((edge_index+2)%3)->coordinates();
2861 [ # # ]: 0 : prev_pt -= other_pt;
2862 [ # # ]: 0 : next_pt -= other_pt;
2863 [ # # ]: 0 : CubitVector norm = prev_pt * next_pt;
2864 [ # # ]: 0 : CubitVector new_e = pos - other_pt;
2865 : :
2866 [ # # ][ # # ]: 0 : if ( norm.vector_angle_quick(prev_pt, new_e) > CUBIT_PI ||
[ # # ][ # # ]
2867 [ # # ]: 0 : norm.vector_angle_quick(new_e, next_pt) > CUBIT_PI )
2868 : 0 : continue;
2869 : :
2870 : : // don't create adjacent sliver facets
2871 [ # # ][ # # ]: 0 : double prev_t = prev_pt % new_e / prev_pt.length_squared();
2872 [ # # ]: 0 : prev_pt *= prev_t;
2873 [ # # ]: 0 : prev_pt += other_pt;
2874 [ # # ][ # # ]: 0 : if ( (prev_pt - pos).length_squared() < dist_sqr )
[ # # ]
2875 : 0 : continue;
2876 : :
2877 [ # # ][ # # ]: 0 : double next_t = next_pt % new_e / next_pt.length_squared();
2878 [ # # ]: 0 : next_pt *= next_t;
2879 [ # # ]: 0 : next_pt += other_pt;
2880 [ # # ][ # # ]: 0 : if ( (next_pt - pos).length_squared() < dist_sqr )
[ # # ]
2881 : 0 : continue;
2882 : : }
2883 : :
2884 : :
2885 : 0 : closest_dist = dist_sqr;
2886 : 0 : closest_edge = i;
2887 : : }
2888 : : }
2889 : :
2890 [ # # ]: 0 : if( closest_edge >= 0 )
2891 : : {
2892 [ # # ]: 0 : CubitPoint* pt1 = facet->point(closest_edge);
2893 [ # # ]: 0 : CubitPoint* pt2 = facet->point((closest_edge+1)%3);
2894 [ # # ]: 0 : CubitFacetEdge* edge = pt1->shared_edge(pt2);
2895 : : CubitFacetEdge* new_edge;
2896 : : CubitFacet* new_facet;
2897 : : CubitPoint* new_point;
2898 [ # # ]: 0 : PartSurfFacetTool::split_edge(edge, pos, 0, new_point, new_edge, new_facet );
2899 [ # # ][ # # ]: 0 : if (dynamic_cast<SubSurface*>(surface))
[ # # ]
2900 [ # # ]: 0 : surface->relax_to_geometry( new_point, &position );
2901 [ # # ]: 0 : return dynamic_cast<CubitPointData*>(new_point);
2902 : : }
2903 : :
2904 : 0 : CubitFacet *new_tri1 = 0, *new_tri2 = 0;
2905 [ # # ]: 0 : CubitPoint* pt1 = facet->point(0);
2906 [ # # ]: 0 : CubitPoint* pt2 = facet->point(1);
2907 [ # # ]: 0 : CubitPoint* pt3 = facet->point(2);
2908 [ # # ]: 0 : CubitPoint* new_pt = facet->insert_point( pos, new_tri1, new_tri2 );
2909 [ # # ][ # # ]: 0 : new CubitFacetEdgeData( new_pt, pt1 );
2910 [ # # ][ # # ]: 0 : new CubitFacetEdgeData( new_pt, pt2 );
2911 [ # # ][ # # ]: 0 : new CubitFacetEdgeData( new_pt, pt3 );
2912 [ # # ]: 0 : surface->notify_split( facet, new_tri1 );
2913 [ # # ]: 0 : surface->notify_split( facet, new_tri2 );
2914 : :
2915 [ # # ][ # # ]: 0 : if (dynamic_cast<SubSurface*>(surface))
[ # # ]
2916 [ # # ]: 0 : surface->relax_to_geometry( new_pt, &position );
2917 : :
2918 [ # # ][ # # ]: 0 : return dynamic_cast<CubitPointData*>(new_pt);
2919 : : }
2920 : :
2921 : 0 : void PartitionEngine::delete_facet( CubitFacet* p_dead )
2922 : : {
2923 [ # # ][ # # ]: 0 : assert(!TDVGFacetOwner::get(p_dead));
2924 [ # # ][ # # ]: 0 : assert(dynamic_cast<CubitFacetData*>(p_dead) != NULL);
2925 : :
2926 [ # # ][ # # ]: 0 : CubitFacetEdge* edges[3] = {p_dead->edge(0), p_dead->edge(1), p_dead->edge(2)};
[ # # ]
2927 [ # # ][ # # ]: 0 : CubitPoint* pts[3] = {p_dead->point(0), p_dead->point(1), p_dead->point(2)};
[ # # ]
2928 : :
2929 : : int k;
2930 [ # # ]: 0 : for( k = 0; k < 3; k++ )
2931 : : {
2932 [ # # ]: 0 : if( pts[k] )
2933 : : {
2934 [ # # ]: 0 : pts[k]->remove_facet( p_dead );
2935 : 0 : CubitFacetData *facet_data = static_cast<CubitFacetData*>(p_dead);
2936 [ # # ]: 0 : facet_data->set_point( NULL, k);
2937 : :
2938 [ # # ][ # # ]: 0 : if( !pts[k]->num_adj_facets() )
2939 [ # # ][ # # ]: 0 : delete pts[k];
2940 : : }
2941 : : }
2942 : :
2943 [ # # ]: 0 : for( k = 0; k < 3; k++ )
2944 : : {
2945 [ # # ]: 0 : if( edges[k] )
2946 : : {
2947 [ # # ]: 0 : edges[k]->remove_facet(p_dead);
2948 [ # # ]: 0 : p_dead->edge(NULL, k);
2949 [ # # ][ # # ]: 0 : if(!edges[k]->num_adj_facets())
2950 [ # # ][ # # ]: 0 : delete edges[k];
2951 : : }
2952 : : }
2953 : :
2954 [ # # ][ # # ]: 0 : delete p_dead;
2955 : 0 : }
2956 : :
2957 : : //-------------------------------------------------------------------------
2958 : : // Purpose : Create projection of a polyline in surface facetting.
2959 : : //
2960 : : // Special Notes :
2961 : : //
2962 : : // Creator : Jason Kraftcheck
2963 : : //
2964 : : // Creation Date : 02/23/03
2965 : : //-------------------------------------------------------------------------
2966 : 0 : CubitStatus PartitionEngine::project_to_surface(
2967 : : DLIList<CubitFacetData*>& cubit_facets,
2968 : : DLIList<CubitVector*>& polyline,
2969 : : DLIList<CubitFacetEdgeData*>& polyline_out,
2970 : : DLIList<CubitPointData*>& polyline_points,
2971 : : const double *tolerance_length)
2972 : : {
2973 : : int i, j;
2974 : : unsigned u;
2975 : : PartitionSurface* p_adj_surf;
2976 : 0 : PartitionCurve* p_curve = 0;
2977 : : PartitionEntity* p_owner;
2978 : :
2979 [ # # ]: 0 : DLIList<PartitionSurface*> surfaces;
2980 [ # # ][ # # ]: 0 : for (i = cubit_facets.size(); i--; )
2981 [ # # ][ # # ]: 0 : surfaces.append_unique( dynamic_cast<PartitionSurface*>(TDVGFacetOwner::get(cubit_facets.step_and_get())));
[ # # ][ # # ]
2982 : :
2983 : : // get points
2984 : :
2985 [ # # ][ # # ]: 0 : DLIList<CubitPoint*> cubit_points(cubit_facets.size() * 3);
[ # # ]
2986 [ # # ][ # # ]: 0 : DLIList<CubitFacet*> orig_facets;
2987 [ # # ][ # # ]: 0 : CAST_LIST_TO_PARENT(cubit_facets, orig_facets);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2988 [ # # ]: 0 : FacetDataUtil::get_facet_points(orig_facets, cubit_points);
2989 : :
2990 : : // get bounding curves from the facets
2991 [ # # ][ # # ]: 0 : std::set<PartitionCurve*> boundary_curves;
2992 [ # # ][ # # ]: 0 : DLIList<CubitFacetEdge*> free_edges;
2993 [ # # ]: 0 : FacetDataUtil::edges_by_count(orig_facets, 1, free_edges);
2994 [ # # ]: 0 : free_edges.reset();
2995 [ # # ][ # # ]: 0 : for (i=free_edges.size(); i>0; i--)
2996 : : {
2997 [ # # ][ # # ]: 0 : p_owner = TDVGFacetOwner::get(free_edges.get_and_step());
2998 [ # # ]: 0 : p_curve = CAST_TO(p_owner, PartitionCurve);
2999 [ # # ]: 0 : assert(!!p_curve); // every bounding edge should be owned by a curve
3000 [ # # ]: 0 : boundary_curves.insert(p_curve);
3001 : : }
3002 : :
3003 [ # # ][ # # ]: 0 : std::vector<double> facet_points(cubit_points.size() * 3);
[ # # ]
3004 [ # # ][ # # ]: 0 : std::vector<int> simple_facets(cubit_facets.size() * 3);
[ # # ]
3005 [ # # ]: 0 : cubit_points.reset();
3006 [ # # ][ # # ]: 0 : for ( i = 0; i < cubit_points.size(); i++ )
3007 : : {
3008 [ # # ]: 0 : CubitPoint* pt = cubit_points.get_and_step();
3009 [ # # ]: 0 : pt->marked( i );
3010 : :
3011 : 0 : int j = i * 3;
3012 [ # # ][ # # ]: 0 : facet_points[j ] = pt->coordinates().x();
[ # # ]
3013 [ # # ][ # # ]: 0 : facet_points[j+1] = pt->coordinates().y();
[ # # ]
3014 [ # # ][ # # ]: 0 : facet_points[j+2] = pt->coordinates().z();
[ # # ]
3015 [ # # ][ # # ]: 0 : if (DEBUG_FLAG(145))
[ # # ]
3016 : : {
3017 [ # # ][ # # ]: 0 : GfxDebug::draw_point(pt->coordinates(), CUBIT_WHITE_INDEX);
3018 [ # # ][ # # ]: 0 : GfxDebug::draw_label(i, (float)(pt->coordinates().x()),
3019 [ # # ][ # # ]: 0 : (float)(pt->coordinates().y()),
3020 [ # # ][ # # ]: 0 : (float)(pt->coordinates().z()),
3021 [ # # ]: 0 : CUBIT_WHITE_INDEX);
3022 : : }
3023 : : }
3024 : :
3025 [ # # ]: 0 : cubit_facets.reset();
3026 [ # # ][ # # ]: 0 : for ( i = 0; i < cubit_facets.size(); i++ )
3027 : : {
3028 [ # # ]: 0 : CubitFacetData* facet = cubit_facets.get_and_step();
3029 : 0 : int j = i * 3;
3030 [ # # ][ # # ]: 0 : simple_facets[j ] = facet->point(0)->marked();
[ # # ]
3031 [ # # ][ # # ]: 0 : simple_facets[j+1] = facet->point(1)->marked();
[ # # ]
3032 [ # # ][ # # ]: 0 : simple_facets[j+2] = facet->point(2)->marked();
[ # # ]
3033 [ # # ][ # # ]: 0 : if (DEBUG_FLAG(145))
[ # # ]
3034 : : {
3035 [ # # ]: 0 : GfxDebug::draw_facet( facet, CUBIT_CYAN_INDEX );
3036 [ # # ]: 0 : CubitVector c = facet->center();
3037 [ # # ]: 0 : GfxDebug::draw_label( i, (float)(c.x()),
3038 [ # # ]: 0 : (float)(c.y()),
3039 [ # # ]: 0 : (float)(c.z()),
3040 [ # # ]: 0 : CUBIT_CYAN_INDEX);
3041 [ # # ][ # # ]: 0 : PRINT_DEBUG_145("%2d : %2d %2d %2d\n", i,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
3042 : : facet->point(0)->marked(),
3043 : : facet->point(1)->marked(),
3044 [ # # ]: 0 : facet->point(2)->marked());
3045 : : }
3046 : : }
3047 : :
3048 : : // clear point marks
3049 [ # # ][ # # ]: 0 : for ( i = 0; i < cubit_points.size(); i++ )
3050 [ # # ][ # # ]: 0 : cubit_points.step_and_get()->marked(0);
3051 : : /*
3052 : : // reduce polyline resolution
3053 : : const double dist_tol = GEOMETRY_RESABS*GEOMETRY_RESABS;
3054 : : const double COS15 = 0.96592582628906831;
3055 : : const double angle_tol = COS15*COS15;
3056 : : DLIList<CubitVector*> polyline2;
3057 : : polyline.reset();
3058 : : CubitVector *prev = polyline.get_and_step();
3059 : : polyline2.append(prev);
3060 : : for( i = polyline.size() - 2; i--; )
3061 : : {
3062 : : CubitVector *pt = polyline.get_and_step();
3063 : : CubitVector *next = polyline.get();
3064 : : CubitVector v1(*pt - *prev);
3065 : : CubitVector v2(*next - *pt);
3066 : : double len1 = v1.length_squared();
3067 : : double len2 = v2.length_squared();
3068 : : double dot = v1 % v2;
3069 : : if( len1 > dist_tol && len2 > dist_tol &&
3070 : : ((dot*dot)/(len1*len2)) < angle_tol )
3071 : : {
3072 : : polyline2.append(pt);
3073 : : prev = pt;
3074 : : }
3075 : : }
3076 : : polyline2.append(polyline.get());
3077 : : */
3078 : : // Call tool to do projection
3079 : :
3080 [ # # ][ # # ]: 0 : std::vector<double> new_facet_points;
3081 [ # # ][ # # ]: 0 : std::vector<int> dead_simple_facets, new_simple_facets,
[ # # ][ # # ]
3082 [ # # ][ # # ]: 0 : facet_replacement, new_polyline, seg_pts;
[ # # ][ # # ]
[ # # ][ # # ]
3083 [ # # ][ # # ]: 0 : FacetProjectTool tool;
3084 [ # # ]: 0 : if ( !tool.project( polyline, facet_points, simple_facets,
3085 : : dead_simple_facets, new_simple_facets,
3086 : : facet_replacement, new_facet_points,
3087 [ # # ]: 0 : new_polyline, seg_pts, tolerance_length ) )
3088 : : {
3089 : : // output the map between input polyline positions and
3090 : : // facet points
3091 [ # # ]: 0 : std::vector<int>::iterator iitor;
3092 [ # # ][ # # ]: 0 : for ( iitor = seg_pts.begin(); iitor != seg_pts.end(); ++iitor )
[ # # ][ # # ]
[ # # ]
3093 : : {
3094 [ # # ]: 0 : int pt_index = *iitor;
3095 [ # # ]: 0 : if ( pt_index == -1 )
3096 : : {
3097 [ # # ]: 0 : polyline_points.append(NULL);
3098 : : }
3099 : : else
3100 : : {
3101 : 0 : CubitPointData* ptd = NULL;
3102 [ # # ][ # # ]: 0 : if(pt_index >= 0 && pt_index < cubit_points.size())
[ # # ][ # # ]
3103 : : {
3104 [ # # ]: 0 : CubitPoint* pt = cubit_points.next( pt_index );
3105 [ # # ]: 0 : ptd = dynamic_cast<CubitPointData*>(pt);
3106 : : }
3107 [ # # ]: 0 : polyline_points.append(ptd);
3108 : : }
3109 : : }
3110 : :
3111 : 0 : return CUBIT_FAILURE;
3112 : : }
3113 : :
3114 : : // Convert back to CubitFacet rep
3115 : :
3116 : : // make new points
3117 [ # # ][ # # ]: 0 : assert( new_facet_points.size() % 3 == 0 );
3118 [ # # ][ # # ]: 0 : std::vector<CubitPointData*> new_cubit_points(new_facet_points.size()/3);
[ # # ]
3119 [ # # ]: 0 : std::vector<CubitPointData*>::iterator cpitor = new_cubit_points.begin();
3120 [ # # ]: 0 : std::vector<double>::iterator ditor = new_facet_points.begin();
3121 [ # # ][ # # ]: 0 : for ( ; cpitor != new_cubit_points.end(); ++cpitor )
[ # # ][ # # ]
3122 : : {
3123 [ # # ][ # # ]: 0 : double x = *ditor++;
3124 [ # # ][ # # ]: 0 : double y = *ditor++;
3125 [ # # ][ # # ]: 0 : double z = *ditor++;
3126 [ # # ][ # # ]: 0 : *cpitor = new CubitPointData(x,y,z);
[ # # ]
3127 [ # # ][ # # ]: 0 : cubit_points.append(*cpitor);
3128 : : }
3129 : :
3130 : : // make new facets
3131 [ # # ]: 0 : cubit_facets.reset();
3132 [ # # ]: 0 : cubit_points.reset();
3133 : 0 : int prev_index = 0;
3134 [ # # ][ # # ]: 0 : assert( new_simple_facets.size() % 3 == 0 );
3135 : :
3136 [ # # ][ # # ]: 0 : std::vector<CubitFacetData*> facet_list;
3137 [ # # ]: 0 : std::vector<CubitFacetData*>::iterator fitor;
3138 [ # # ]: 0 : std::vector<int>::iterator iitor = new_simple_facets.begin();
3139 : :
3140 : 0 : int id=0; // dummy for CubitFacetData constructor
3141 : :
3142 [ # # ][ # # ]: 0 : for( u = 0; u < dead_simple_facets.size(); u++ )
3143 : : {
3144 : : // get number of replacement facets
3145 [ # # ]: 0 : int index = facet_replacement[u];
3146 : 0 : int count = (index - prev_index) / 3;
3147 [ # # ]: 0 : assert(((index - prev_index) % 3) == 0);
3148 : :
3149 : : // make a new list to hold data
3150 [ # # ]: 0 : facet_list.clear();
3151 [ # # ]: 0 : facet_list.resize(count+1);
3152 [ # # ]: 0 : fitor = facet_list.begin();
3153 : :
3154 : : // put dead facet at beginning of list
3155 [ # # ][ # # ]: 0 : CubitFacetData* p_dead = cubit_facets.next(dead_simple_facets[u]);
3156 [ # # ][ # # ]: 0 : *fitor++ = p_dead;
3157 : :
3158 : : // get the surface that owns the dead facet
3159 [ # # ]: 0 : p_owner = TDVGFacetOwner::get(p_dead);
3160 [ # # ]: 0 : PartitionSurface* p_dead_surf = CAST_TO(p_owner, PartitionSurface);
3161 [ # # ]: 0 : assert(!!p_dead_surf);
3162 : :
3163 : : // construct and append replacement facets
3164 [ # # ]: 0 : for ( j=0; j < count; j++ )
3165 : : {
3166 [ # # ][ # # ]: 0 : CubitPoint* pt1 = cubit_points.next( *iitor++ );
[ # # ]
3167 [ # # ][ # # ]: 0 : CubitPoint* pt2 = cubit_points.next( *iitor++ );
[ # # ]
3168 [ # # ][ # # ]: 0 : CubitPoint* pt3 = cubit_points.next( *iitor++ );
[ # # ]
3169 [ # # ][ # # ]: 0 : *fitor++ = new CubitFacetData(pt1, pt2, pt3, &id);
[ # # ][ # # ]
3170 : : }
3171 : :
3172 : : // set up for next iteration
3173 [ # # ][ # # ]: 0 : assert(fitor == facet_list.end());
[ # # ][ # # ]
3174 : 0 : prev_index = index;
3175 : :
3176 : : // do something with "facet_list"
3177 : :
3178 [ # # ]: 0 : DLIList<CubitFacetData*> old_facet_list;
3179 : :
3180 : : // fill edge replacement lists
3181 [ # # ][ # # ]: 0 : std::vector<CubitFacetEdgeData*> edge_lists[3];
[ # # ][ # # ]
[ # # # # ]
3182 [ # # ]: 0 : get_edge_replacements(facet_list, edge_lists);
3183 : :
3184 : : // update edges/facets on curves and adjacent surfaces
3185 : : CubitFacetEdgeData* old_edge;
3186 [ # # ]: 0 : for (j=0; j<3; j++)
3187 : : {
3188 [ # # ]: 0 : DLIList<CubitFacetEdgeData*> new_edges;
3189 [ # # ][ # # ]: 0 : if (edge_lists[j].size()) // check for replacements
3190 : : {
3191 [ # # ]: 0 : std::vector<CubitFacetEdgeData*>::iterator eitor = edge_lists[j].begin();
3192 [ # # ][ # # ]: 0 : old_edge = *eitor++;
3193 : :
3194 [ # # ]: 0 : p_owner = TDVGFacetOwner::get(old_edge);
3195 [ # # ]: 0 : p_curve = CAST_TO(p_owner, PartitionCurve);
3196 : :
3197 [ # # ][ # # ]: 0 : for (; eitor != edge_lists[j].end(); eitor++)
[ # # ][ # # ]
3198 [ # # ][ # # ]: 0 : new_edges.append(*eitor);
3199 : :
3200 [ # # ][ # # ]: 0 : assert(new_edges.size() > 1); // shouldn't ever get 1 to 1 replacement here
3201 : :
3202 : : // split facets on adjacent surfaces if the split crosses a curve
3203 : : // on the outside boundary of the facets
3204 [ # # ][ # # ]: 0 : if (boundary_curves.find(p_curve) != boundary_curves.end())
[ # # ][ # # ]
3205 : : {
3206 : : // get facets to be replaced on adjacent surf
3207 [ # # ]: 0 : DLIList<CubitFacetData*> adj_facets;
3208 [ # # ][ # # ]: 0 : DLIList<CubitFacet*> tmp_list;
3209 [ # # ]: 0 : old_edge->facets(tmp_list);
3210 [ # # ][ # # ]: 0 : CAST_LIST(tmp_list, adj_facets, CubitFacetData);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
3211 : :
3212 [ # # ][ # # ]: 0 : if (adj_facets.size() > 1)
3213 : : {
3214 [ # # ]: 0 : DLIList<CubitFacetData*> adj_replacements;
3215 : : int i_adj;
3216 [ # # ][ # # ]: 0 : for (i_adj=adj_facets.size(); i_adj>0; i_adj--)
3217 : : {
3218 [ # # ]: 0 : CubitFacetData* p_adjacent = adj_facets.get_and_step();
3219 [ # # ]: 0 : if (p_adjacent == p_dead)
3220 : 0 : continue;
3221 : :
3222 : : // create replacement facets
3223 [ # # ]: 0 : adj_replacements.clean_out();
3224 : :
3225 : : // get the point opposite the edge being replaced
3226 [ # # ]: 0 : int e_index = p_adjacent->edge_index(old_edge);
3227 [ # # ]: 0 : bool old_reversed = -1 == p_adjacent->edge_use(e_index);
3228 : 0 : CubitPoint* prev_pt = NULL;
3229 : : //if old_reversed is false, the new_edge' reversed flag is true
3230 : : int old_prev_pt_index;
3231 [ # # ]: 0 : if (old_reversed)
3232 : : {
3233 [ # # ]: 0 : prev_pt = old_edge->point(0);
3234 : 0 : old_prev_pt_index = 0;
3235 : : }
3236 : : else
3237 : : {
3238 [ # # ]: 0 : prev_pt = old_edge->point(1);
3239 : 0 : old_prev_pt_index = 1;
3240 : : }
3241 [ # # ]: 0 : CubitPoint* opposite_pt = p_adjacent->point(e_index);
3242 : : //CubitPoint* opposite_pt = p_adjacent->point(p_adjacent->edge_index(old_edge)); // opposite edge and point have same index
3243 [ # # ]: 0 : new_edges.reset();
3244 : : int i_new;
3245 [ # # ][ # # ]: 0 : for (i_new=new_edges.size(); i_new>0; i_new--)
3246 : : {
3247 [ # # ]: 0 : CubitFacetEdge* p_edge = new_edges.get_and_step();
3248 : :
3249 [ # # ]: 0 : prev_pt = p_edge->other_point(prev_pt);
3250 [ # # ]: 0 : assert(!!prev_pt);
3251 [ # # ]: 0 : bool new_reversed = p_edge->point(old_prev_pt_index) == prev_pt;
3252 : 0 : int reversed = (int)(new_reversed != old_reversed);
3253 : :
3254 : 0 : CubitFacetData* p_facet = new CubitFacetData(p_edge->point(reversed),
3255 : 0 : p_edge->point(1-reversed),
3256 [ # # ][ # # ]: 0 : opposite_pt, &id);
[ # # ][ # # ]
3257 [ # # ]: 0 : adj_replacements.append(p_facet);
3258 : : }
3259 : :
3260 [ # # ]: 0 : p_owner = TDVGFacetOwner::get(p_adjacent);
3261 [ # # ]: 0 : p_adj_surf = CAST_TO(p_owner, PartitionSurface);
3262 [ # # ]: 0 : assert(!!p_adj_surf);
3263 [ # # ]: 0 : old_facet_list.clean_out();
3264 [ # # ]: 0 : old_facet_list.append(p_adjacent);
3265 [ # # ]: 0 : p_adj_surf->replace_facets(old_facet_list, adj_replacements);
3266 [ # # ]: 0 : delete_facet( p_adjacent );
3267 [ # # ]: 0 : }
3268 [ # # ]: 0 : }
3269 : : }
3270 : :
3271 : : // replace the curve edges
3272 [ # # ]: 0 : p_curve->replace_facet(old_edge, new_edges);
3273 : :
3274 : : // Don't delete edge yet. It's still connected to
3275 : : // at least one facet. Wait 'till the facet is deleted.
3276 : : //delete old_edge;
3277 : : }
3278 [ # # ]: 0 : }
3279 : :
3280 : : // replace dead facet
3281 [ # # ]: 0 : fitor = facet_list.begin();
3282 [ # # ]: 0 : fitor++; // skip dead facet
3283 [ # # ][ # # ]: 0 : DLIList<CubitFacetData*> new_facets;
3284 [ # # ][ # # ]: 0 : for (; fitor != facet_list.end(); fitor++)
[ # # ][ # # ]
3285 [ # # ][ # # ]: 0 : new_facets.append(*fitor);
3286 [ # # ]: 0 : old_facet_list.clean_out();
3287 [ # # ]: 0 : old_facet_list.append(p_dead);
3288 [ # # ]: 0 : p_dead_surf->replace_facets(old_facet_list, new_facets);
3289 [ # # ]: 0 : delete_facet(p_dead);
3290 [ # # ]: 0 : }
3291 : :
3292 [ # # ][ # # ]: 0 : assert(iitor == new_simple_facets.end());
[ # # ]
3293 : :
3294 : : // output the edges that make up the projected curve
3295 [ # # ]: 0 : cubit_points.reset();
3296 [ # # ]: 0 : iitor = new_polyline.begin();
3297 [ # # ][ # # ]: 0 : while( *iitor )
3298 : : {
3299 [ # # ][ # # ]: 0 : int count = *iitor++;
3300 [ # # ][ # # ]: 0 : CubitPoint* prev_point = cubit_points.next( *iitor++ );
[ # # ]
3301 [ # # ]: 0 : for ( i = 1; i < count; i++ ) {
3302 [ # # ][ # # ]: 0 : CubitPoint* pt = cubit_points.next( *iitor++ );
[ # # ]
3303 [ # # ]: 0 : CubitFacetEdge* edge = prev_point->shared_edge(pt);
3304 [ # # ]: 0 : CubitFacetEdgeData* edge_d = dynamic_cast<CubitFacetEdgeData*>(edge);
3305 [ # # ]: 0 : assert(!!edge_d);
3306 [ # # ][ # # ]: 0 : if (TDVGFacetOwner::get(edge_d))
3307 [ # # ]: 0 : polyline_out.append(0);
3308 : : else
3309 : : {
3310 [ # # ][ # # ]: 0 : if (edge_d->point(0) == pt)
3311 [ # # ]: 0 : edge_d->flip();
3312 [ # # ]: 0 : polyline_out.append(edge_d);
3313 : : }
3314 : 0 : prev_point = pt;
3315 : : }
3316 [ # # ]: 0 : polyline_out.append(0);
3317 : : }
3318 : :
3319 : : // output the map between input polyline positions and
3320 : : // facet points
3321 [ # # ][ # # ]: 0 : for ( iitor = seg_pts.begin(); iitor != seg_pts.end(); ++iitor )
[ # # ][ # # ]
[ # # ]
3322 : : {
3323 [ # # ]: 0 : int pt_index = *iitor;
3324 [ # # ]: 0 : if ( pt_index == -1 )
3325 : : {
3326 [ # # ]: 0 : polyline_points.append(NULL);
3327 : : }
3328 : : else
3329 : : {
3330 [ # # ][ # # ]: 0 : assert(pt_index >= 0 && pt_index < cubit_points.size());
[ # # ]
3331 [ # # ]: 0 : CubitPoint* pt = cubit_points.next( pt_index );
3332 [ # # ]: 0 : CubitPointData* ptd = dynamic_cast<CubitPointData*>(pt);
3333 [ # # ]: 0 : assert(!!ptd);
3334 [ # # ]: 0 : polyline_points.append(ptd);
3335 : : }
3336 : : }
3337 : :
3338 : :
3339 [ # # ]: 0 : return CUBIT_SUCCESS;
3340 : : }
3341 : :
3342 : : //-------------------------------------------------------------------------
3343 : : // Purpose : Create a point-curve
3344 : : //
3345 : : // Special Notes :
3346 : : //
3347 : : // Creator : Jason Kraftcheck
3348 : : //
3349 : : // Creation Date : 02/23/03
3350 : : //-------------------------------------------------------------------------
3351 : 0 : TBPoint* PartitionEngine::insert_point_curve( Surface* surf,
3352 : : const CubitVector& position,
3353 : : Surface *&partitioned_surf )
3354 : : {
3355 [ # # ][ # # ]: 0 : if ( CompositeSurface* csurf = dynamic_cast<CompositeSurface*>(surf) )
3356 : : {
3357 : : TBPoint* result =
3358 : 0 : CompositeEngine::instance().insert_point_curve(csurf, position);
3359 : 0 : partitioned_surf = csurf;
3360 : 0 : return result;
3361 : : }
3362 : :
3363 : 0 : bool replaced_surface = false;
3364 [ # # ]: 0 : PartitionSurface* psurf = dynamic_cast<PartitionSurface*>(surf);
3365 [ # # ]: 0 : if ( ! psurf ) {
3366 : 0 : psurf = replace_surface(surf);
3367 : 0 : replaced_surface = true;
3368 [ # # ]: 0 : if ( ! psurf ) return 0;
3369 : : }
3370 : :
3371 : 0 : CubitPointData* facet_point = project_to_surface( psurf, position );
3372 [ # # ]: 0 : if ( !facet_point ) {
3373 [ # # ]: 0 : if( replaced_surface )
3374 [ # # ]: 0 : restore_surface( dynamic_cast<SubSurface*>(psurf) );
3375 : 0 : partitioned_surf = NULL;
3376 : 0 : return 0;
3377 : : }
3378 : :
3379 : 0 : PartitionPoint* result = insert_point_curve( psurf, facet_point );
3380 [ # # ]: 0 : if ( !result ) {
3381 [ # # ]: 0 : if( replaced_surface )
3382 [ # # ]: 0 : restore_surface( dynamic_cast<SubSurface*>(psurf) );
3383 : 0 : return 0;
3384 : : }
3385 : :
3386 : 0 : PartitionCurve* curve = result->next_curve(0);
3387 [ # # ][ # # ]: 0 : if (replaced_surface && !dynamic_cast<PartPTCurve*>(curve))
[ # # ][ # # ]
3388 : : {
3389 : 0 : TBPoint* real = result->real_point();
3390 [ # # ]: 0 : partitioned_surf = restore_surface( dynamic_cast<SubSurface*>(psurf) );
3391 [ # # ]: 0 : if (real)
3392 : : {
3393 [ # # ]: 0 : result = dynamic_cast<PartitionPoint*>(real->owner());
3394 [ # # ]: 0 : return result ? result : real;
3395 : : }
3396 : : }
3397 : : else
3398 : 0 : partitioned_surf = psurf;
3399 : :
3400 : 0 : return result;
3401 : : }
3402 : :
3403 : :
3404 : :
3405 : : //-------------------------------------------------------------------------
3406 : : // Purpose : Create point-curve
3407 : : //
3408 : : // Special Notes :
3409 : : //
3410 : : // Creator : Jason Kraftcheck
3411 : : //
3412 : : // Creation Date : 02/23/03
3413 : : //-------------------------------------------------------------------------
3414 : 0 : PartitionPoint* PartitionEngine::insert_point_curve( PartitionSurface* surf,
3415 : : CubitPointData* point )
3416 : : {
3417 : : // If imprint at existing vertex, just return that vertex
3418 [ # # ][ # # ]: 0 : if ( TDVGFacetOwner::get(point) )
3419 [ # # ][ # # ]: 0 : return dynamic_cast<PartitionPoint*>(TDVGFacetOwner::get(point));
3420 : :
3421 : : // Check if imprint point is on a curve of the surface
3422 [ # # ]: 0 : DLIList<CubitFacetEdge*> edges;
3423 [ # # ]: 0 : point->edges(edges);
3424 : 0 : PartitionEntity* owner = 0;
3425 : 0 : int owner_count = 0;
3426 : 0 : int owner_edges = 0;
3427 [ # # ][ # # ]: 0 : while (edges.size())
3428 : : {
3429 [ # # ][ # # ]: 0 : if (PartitionEntity* ent = TDVGFacetOwner::get(edges.pop()))
[ # # ]
3430 : : {
3431 [ # # ]: 0 : if (owner != ent)
3432 : 0 : owner_count++;
3433 : 0 : owner = ent;
3434 : 0 : owner_edges++;
3435 : : }
3436 : : }
3437 : :
3438 : : // If imprint is on curve, split the curve
3439 [ # # ]: 0 : if (owner)
3440 : : {
3441 [ # # ]: 0 : PartitionCurve* curve = dynamic_cast<PartitionCurve*>(owner);
3442 : :
3443 : : // check valid facet configuration. should be only one
3444 : : // owner, and owner should own exactly two of the adjacent
3445 : : // edges. And owner should be a partition curve.
3446 [ # # ][ # # ]: 0 : if (!curve || owner_count != 1 || owner_edges != 2)
[ # # ]
3447 : : {
3448 [ # # ][ # # ]: 0 : PRINT_ERROR("Internal error at %s:%d\n Invalid state.\n", __FILE__, __LINE__ );
[ # # ][ # # ]
3449 : 0 : assert(0);
3450 : : return NULL;
3451 : : }
3452 : :
3453 [ # # ][ # # ]: 0 : PartitionPoint* new_point = new PartitionPoint(point->coordinates(), curve);
[ # # ][ # # ]
3454 [ # # ]: 0 : new_point->facet_point(point);
3455 [ # # ]: 0 : curve = insert_point( curve, new_point );
3456 [ # # ]: 0 : if (!curve)
3457 : : {
3458 [ # # ][ # # ]: 0 : delete new_point;
3459 : 0 : return 0;
3460 : : }
3461 : :
3462 : 0 : return new_point;
3463 : : }
3464 : :
3465 : : // If here, point is in surface interior. Create point-curve.
3466 [ # # ][ # # ]: 0 : PartitionPoint* new_point = new PartitionPoint( point->coordinates(), surf );
[ # # ][ # # ]
3467 [ # # ]: 0 : new_point->facet_point(point);
3468 [ # # ][ # # ]: 0 : PartPTCurve* new_curve = new PartPTCurve( surf );
3469 [ # # ]: 0 : new_curve->start_point( new_point );
3470 [ # # ]: 0 : new_curve->end_point( new_point );
3471 : :
3472 [ # # ]: 0 : insert_point_curve( surf, new_curve );
3473 : :
3474 [ # # ]: 0 : return new_point;
3475 : : }
3476 : :
3477 : 0 : CubitStatus PartitionEngine::insert_point_curve( PartitionSurface* surf,
3478 : : PartPTCurve* new_curve,
3479 : : bool update_topology )
3480 : : {
3481 [ # # ]: 0 : PartitionCoEdge* new_coedge = new PartitionCoEdge( surf, CUBIT_FORWARD );
3482 : 0 : new_curve->add( new_coedge );
3483 [ # # ]: 0 : PartitionLoop* new_loop = new PartitionLoop();
3484 : 0 : new_loop->insert_after( new_coedge, 0 );
3485 : :
3486 : 0 : surf->add( new_loop );
3487 [ # # ][ # # ]: 0 : if ( surf->owner() && update_topology )
[ # # ]
3488 : 0 : surf->owner()->notify_topology_modified(surf);
3489 : 0 : return CUBIT_SUCCESS;
3490 : : }
3491 : :
3492 : :
3493 : :
3494 : : //-------------------------------------------------------------------------
3495 : : // Purpose : Construct surface for volume partitioning
3496 : : //
3497 : : // Special Notes :
3498 : : //
3499 : : // Creator : Jason Kraftcheck
3500 : : //
3501 : : // Creation Date : 01/13/03
3502 : : //-------------------------------------------------------------------------
3503 : 0 : Lump* PartitionEngine::insert_surface( Surface* surface, Lump* lump)
3504 : : {
3505 [ # # ]: 0 : GMem gmem;
3506 : : int i;
3507 [ # # ]: 0 : CubitStatus status = surface->get_geometry_query_engine()->
3508 [ # # ]: 0 : get_graphics( surface, &gmem );
3509 : :
3510 [ # # ]: 0 : if( !status )
3511 : : {
3512 [ # # ][ # # ]: 0 : PRINT_ERROR("PartitionEngine::insert_surface: GeometryEngine::"
[ # # ]
3513 [ # # ]: 0 : "get_graphics failed for surface.\n");
3514 : 0 : return 0;
3515 : : }
3516 : :
3517 : 0 : int num_pts = gmem.pointListCount;
3518 : :
3519 [ # # ][ # # ]: 0 : CubitPointData** ptarray = new CubitPointData*[num_pts];
3520 [ # # ]: 0 : GPoint *p_itor = gmem.point_list();
3521 : 0 : GPoint *p_end = p_itor + num_pts;
3522 : 0 : CubitPointData** array_itor = ptarray;
3523 [ # # ]: 0 : for( ; p_itor < p_end; p_itor++, array_itor++ )
3524 [ # # ][ # # ]: 0 : *array_itor = new CubitPointData(CubitVector(p_itor->x,p_itor->y,p_itor->z));
[ # # ]
3525 : :
3526 [ # # ][ # # ]: 0 : DLIList<CubitFacetData*> facets;
3527 [ # # ]: 0 : int* f_itor = gmem.facet_list();
3528 : 0 : int* f_end = f_itor + gmem.fListCount;
3529 : 0 : i = 0;
3530 [ # # ]: 0 : for( ; f_itor < f_end ; f_itor += (1 + *f_itor) )
3531 : : {
3532 [ # # ]: 0 : if( *f_itor != 3 )
3533 [ # # ][ # # ]: 0 : PRINT_ERROR("Non-triangular facet in PartitionEngine::insert_surface\n");
[ # # ][ # # ]
3534 : : else
3535 : 0 : facets.append( new CubitFacetData(ptarray[f_itor[1]],
3536 : 0 : ptarray[f_itor[2]],
3537 [ # # ][ # # ]: 0 : ptarray[f_itor[3]], &i) );
[ # # ]
3538 : : }
3539 : :
3540 : : // clean up any unused points
3541 [ # # ]: 0 : for( i = 0; i < num_pts; i++ )
3542 [ # # ][ # # ]: 0 : if( ptarray[i]->num_adj_facets() == 0 )
3543 [ # # ][ # # ]: 0 : delete ptarray[i];
3544 [ # # ]: 0 : delete [] ptarray;
3545 : :
3546 : :
3547 : : // create partition lump
3548 : 0 : bool created_lump = false;
3549 [ # # ]: 0 : PartitionLump* partlump = dynamic_cast<PartitionLump*>(lump);
3550 [ # # ]: 0 : if( !partlump )
3551 : : {
3552 : 0 : created_lump = true;
3553 [ # # ]: 0 : partlump = replace_lump(lump);
3554 [ # # ]: 0 : assert(partlump != NULL);
3555 : : }
3556 : :
3557 : : // Get vertex locations
3558 [ # # ][ # # ]: 0 : DLIList<CubitVector> coords;
3559 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> loops, coedges, curves, points, all_points;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
3560 [ # # ]: 0 : surface->get_children_virt(loops);
3561 [ # # ][ # # ]: 0 : while( loops.size() )
3562 : : {
3563 [ # # ][ # # ]: 0 : loops.pop()->get_children( coedges, true, layer() - 1 );
[ # # ]
3564 [ # # ][ # # ]: 0 : while ( coedges.size() )
3565 : : {
3566 [ # # ][ # # ]: 0 : coedges.pop()->get_children_virt(curves);
3567 [ # # ][ # # ]: 0 : assert(curves.size() == 1);
3568 [ # # ]: 0 : TopologyBridge* curve = curves.pop();
3569 [ # # ][ # # ]: 0 : curve->get_children( points, true, layer() - 1 );
3570 [ # # ][ # # ]: 0 : assert ( points.size() < 3 );
3571 [ # # ]: 0 : all_points.merge_unique( points );
3572 [ # # ]: 0 : points.clean_out();
3573 : : }
3574 : : }
3575 [ # # ][ # # ]: 0 : while( all_points.size() )
3576 [ # # ][ # # ]: 0 : coords.append(CubitVector( dynamic_cast<TBPoint*>(all_points.pop())->coordinates() ) );
[ # # ][ # # ]
3577 : :
3578 [ # # ][ # # ]: 0 : PartitionLumpImprint tool( partlump );
3579 [ # # ][ # # ]: 0 : DLIList<PartitionEntity*> new_entities;
3580 [ # # ]: 0 : PartitionSurface* new_surf = tool.imprint( facets, coords, new_entities );
3581 [ # # ]: 0 : if ( !new_surf )
3582 : : {
3583 [ # # ][ # # ]: 0 : if( created_lump ) restore_lump(partlump);
3584 : 0 : return 0;
3585 : : }
3586 : :
3587 [ # # ]: 0 : PartitionLump* result = insert_surface( partlump, new_surf );
3588 [ # # ]: 0 : if( !result )
3589 : : {
3590 [ # # ]: 0 : destroy_surface( new_surf );
3591 [ # # ][ # # ]: 0 : if( created_lump ) restore_lump( partlump );
3592 : 0 : return 0;
3593 : : }
3594 : :
3595 [ # # ]: 0 : return result;
3596 : : }
3597 : :
3598 : 0 : Surface* PartitionEngine::insert_surface( DLIList<CubitFacet*>& facets, Lump* lump)
3599 : : {
3600 : :
3601 : : // create partition lump and surface
3602 : 0 : bool created_lump = false;
3603 [ # # ]: 0 : PartitionLump* partlump = dynamic_cast<PartitionLump*>(lump);
3604 [ # # ]: 0 : if( !partlump )
3605 : : {
3606 : 0 : created_lump = true;
3607 [ # # ]: 0 : partlump = replace_lump(lump);
3608 [ # # ]: 0 : if (!partlump)
3609 : 0 : return 0;
3610 : : }
3611 : :
3612 [ # # ]: 0 : PartitionLumpImprint tool( partlump );
3613 [ # # ][ # # ]: 0 : DLIList<PartitionEntity*> new_list;
3614 [ # # ]: 0 : PartitionSurface* new_surf = tool.imprint( facets, new_list );
3615 [ # # ]: 0 : if ( !new_surf )
3616 : : {
3617 [ # # ][ # # ]: 0 : if( created_lump ) restore_lump(partlump);
3618 : 0 : return 0;
3619 : : }
3620 : :
3621 [ # # ]: 0 : PartitionLump* result = insert_surface( partlump, new_surf );
3622 [ # # ]: 0 : if( !result )
3623 : : {
3624 [ # # ]: 0 : destroy_surface( new_surf );
3625 [ # # ][ # # ]: 0 : if( created_lump ) restore_lump( partlump );
3626 : 0 : return 0;
3627 : : }
3628 : :
3629 [ # # ]: 0 : return new_surf;
3630 : : }
3631 : :
3632 : :
3633 : :
3634 : : //-------------------------------------------------------------------------
3635 : : // Purpose : Insert a surface into a volume
3636 : : //
3637 : : // Special Notes :
3638 : : //
3639 : : // Creator : Jason Kraftcheck
3640 : : //
3641 : : // Creation Date : 01/12/03
3642 : : //-------------------------------------------------------------------------
3643 : 0 : PartitionLump* PartitionEngine::insert_surface( PartitionLump* lump,
3644 : : PartitionSurface* surface )
3645 : : {
3646 [ # # ][ # # ]: 0 : assert( &(lump->sub_entity_set()) == &(surface->sub_entity_set()) );
[ # # ]
3647 : :
3648 : : // Find all affected shells. If any curve is not part of an
3649 : : // existing shell in the volume, set all_curves_connected to
3650 : : // false. If any curve does not intersect the volume, then
3651 : : // the volume does not need to be split into two (or the surface
3652 : : // forms a new void in the volume.)
3653 : 0 : bool all_curves_connected = true;
3654 [ # # ]: 0 : DLIList<PartitionShell*> modified_list;
3655 : 0 : PartitionLoop* loop = 0;
3656 : : PartitionCoEdge *coedge, *curve_coedge;
3657 : : PartitionCurve* curve;
3658 : : PartitionShell* shell;
3659 : : PartitionCoSurf* cosurf;
3660 [ # # ][ # # ]: 0 : while( (loop = surface->next_loop(loop)) )
3661 : : {
3662 [ # # ]: 0 : coedge = loop->first_coedge();
3663 [ # # ]: 0 : do {
3664 [ # # ]: 0 : curve = coedge->get_curve();
3665 : 0 : curve_coedge = 0;
3666 : 0 : shell = 0;
3667 [ # # ][ # # ]: 0 : while( (curve_coedge = curve->next_coedge(curve_coedge)) )
3668 : : {
3669 [ # # ][ # # ]: 0 : PartitionSurface* surf = curve_coedge->get_loop()->get_surface();
3670 : 0 : cosurf = 0;
3671 [ # # ][ # # ]: 0 : while( (cosurf = surf->next_co_surface( cosurf )) )
3672 : : {
3673 [ # # ][ # # ]: 0 : if( cosurf->get_shell()->get_lump() == lump )
[ # # ]
3674 : : {
3675 [ # # ][ # # ]: 0 : assert( !shell || cosurf->get_shell() == shell );
[ # # ]
3676 [ # # ]: 0 : shell = cosurf->get_shell();
3677 : : }
3678 : : }
3679 : : }
3680 : :
3681 [ # # ]: 0 : if( shell )
3682 [ # # ]: 0 : modified_list.append_unique(shell);
3683 : : else
3684 : 0 : all_curves_connected = false;
3685 : :
3686 [ # # ]: 0 : coedge = loop->next_coedge(coedge);
3687 [ # # ]: 0 : } while( coedge != loop->first_coedge() );
3688 : : }
3689 : :
3690 : : // Construct CoSurfaces
3691 [ # # ][ # # ]: 0 : PartitionCoSurf* cosurf1 = new PartitionCoSurf(CUBIT_FORWARD);
3692 [ # # ][ # # ]: 0 : PartitionCoSurf* cosurf2 = new PartitionCoSurf(CUBIT_REVERSED);
3693 [ # # ]: 0 : surface->add(cosurf1);
3694 [ # # ]: 0 : surface->add(cosurf2);
3695 : :
3696 : : // If there were no affected shells, we need to make a new
3697 : : // shell for a possible void in the volume.
3698 : 0 : PartitionShell* shell_to_split = 0;
3699 [ # # ][ # # ]: 0 : if( modified_list.size() == 0 )
3700 : : {
3701 [ # # ][ # # ]: 0 : shell_to_split = new PartitionShell();
3702 [ # # ]: 0 : lump->add(shell_to_split);
3703 : :
3704 : : // If surface is closed, set all_curves_connected
3705 : : // to true to indicate that volume needs to be split.
3706 : : // (Creating a one-surface void in the volume.)
3707 : 0 : loop = 0;
3708 : 0 : all_curves_connected = true;
3709 [ # # ][ # # ]: 0 : while( (loop = surface->next_loop(loop)) )
3710 : : {
3711 [ # # ]: 0 : coedge = loop->first_coedge();
3712 [ # # ]: 0 : do
3713 : : {
3714 [ # # ]: 0 : curve = coedge->get_curve();
3715 : 0 : curve_coedge = 0;
3716 : 0 : int coedge_count = 0;
3717 [ # # ][ # # ]: 0 : while( (curve_coedge = curve->next_coedge(curve_coedge)) )
3718 : : {
3719 [ # # ][ # # ]: 0 : if( curve_coedge->get_loop() == loop )
3720 : 0 : coedge_count++;
3721 : : else
3722 [ # # ][ # # ]: 0 : assert(curve_coedge->get_loop()->get_surface() != surface);
[ # # ]
3723 : : }
3724 : :
3725 [ # # ]: 0 : if( coedge_count == 1 )
3726 : 0 : all_curves_connected = false;
3727 : : else
3728 [ # # ]: 0 : assert(coedge_count == 2);
3729 : :
3730 [ # # ]: 0 : coedge = loop->next_coedge(coedge);
3731 [ # # ]: 0 : } while( coedge != loop->first_coedge() );
3732 : : }
3733 : : }
3734 : :
3735 : : // Otherwise combine all the affected shells
3736 : : else
3737 : : {
3738 [ # # ]: 0 : modified_list.reverse();
3739 [ # # ]: 0 : shell_to_split = modified_list.pop();
3740 [ # # ][ # # ]: 0 : while( modified_list.size() )
3741 : : {
3742 [ # # ]: 0 : shell = modified_list.pop();
3743 [ # # ][ # # ]: 0 : while( PartitionCoSurf* cosurf = shell->next_co_surface() )
3744 : : {
3745 [ # # ]: 0 : shell->remove(cosurf);
3746 [ # # ]: 0 : shell_to_split->add(cosurf);
3747 : : }
3748 [ # # ]: 0 : lump->remove(shell);
3749 [ # # ][ # # ]: 0 : delete shell;
3750 : 0 : }
3751 : : }
3752 : :
3753 [ # # ]: 0 : shell_to_split->add(cosurf1);
3754 [ # # ]: 0 : shell_to_split->add(cosurf2);
3755 : :
3756 : : // If we don't need to split the volume, we are done
3757 [ # # ]: 0 : if( !all_curves_connected )
3758 : 0 : return lump;
3759 : : // We probably need to split the the lump...
3760 : : else
3761 [ # # ][ # # ]: 0 : return split_lump( shell_to_split );
3762 : : }
3763 : :
3764 : : //-------------------------------------------------------------------------
3765 : : // Purpose : Test if a PartitionShell needs to be split, and
3766 : : // if so partition the shell and owning lump
3767 : : //
3768 : : // Special Notes :
3769 : : //
3770 : : // Creator : Jason Kraftcheck
3771 : : //
3772 : : // Creation Date : 01/13/03
3773 : : //-------------------------------------------------------------------------
3774 : 0 : PartitionLump* PartitionEngine::split_lump( PartitionShell* shell_to_split )
3775 : : {
3776 : : // Split shell
3777 : 0 : PartitionShell* new_shell = split_shell(shell_to_split);
3778 [ # # ]: 0 : if( !new_shell )
3779 : : {
3780 : : // shell did not need to be split
3781 : 0 : return shell_to_split->get_lump();
3782 : : }
3783 : :
3784 : : // Create the new lump and shell
3785 [ # # ]: 0 : PartitionLump* new_lump = new PartitionLump( shell_to_split->get_lump() );
3786 : 0 : new_lump->add( new_shell );
3787 : :
3788 : : // Check for any remaining shells that need to be moved
3789 : : // from the old lump to the new lump.
3790 : 0 : PartitionShell* shell = 0;
3791 : 0 : PartitionLump* lump = shell_to_split->get_lump();
3792 [ # # ]: 0 : while( (shell = lump->next_shell(shell)) )
3793 : : {
3794 [ # # ]: 0 : if( shell == shell_to_split )
3795 : 0 : continue;
3796 : :
3797 : 0 : bool some_contained = false;
3798 : 0 : bool all_contained = true;
3799 : 0 : bool all_tested = true;
3800 : 0 : PartitionCoSurf* cosurf = 0;
3801 [ # # ]: 0 : while( (cosurf = shell->next_co_surface(cosurf)) )
3802 : : {
3803 [ # # ]: 0 : PartitionSurface* surf = cosurf->get_surface();
3804 [ # # ][ # # ]: 0 : CubitVector pt, tmp = surf->bounding_box().center();
[ # # ][ # # ]
3805 [ # # ][ # # ]: 0 : surf->closest_point_trimmed( tmp, pt );
3806 [ # # ]: 0 : switch( new_shell->point_containment(pt) )
[ # # # ]
3807 : : {
3808 : : case CUBIT_PNT_INSIDE:
3809 : 0 : some_contained = true;
3810 : 0 : break;
3811 : : case CUBIT_PNT_OUTSIDE:
3812 : 0 : all_contained = false;
3813 : 0 : break;
3814 : : default:
3815 : 0 : all_tested = false;
3816 : 0 : break;
3817 : : }
3818 : : }
3819 : :
3820 : :
3821 [ # # ][ # # ]: 0 : if( !all_tested || (some_contained && !all_contained) )
[ # # ]
3822 : : {
3823 [ # # ]: 0 : PRINT_ERROR("Error splitting volume. Could not determine\n"
3824 : : "which volume shell belongs in. Geometry may be\n"
3825 [ # # ]: 0 : "invalid.\n");
3826 : : }
3827 : :
3828 [ # # ][ # # ]: 0 : if(some_contained && all_contained)
3829 : : {
3830 : 0 : lump->remove(shell);
3831 : 0 : new_lump->add(shell);
3832 : : }
3833 : : }
3834 : :
3835 : 0 : return new_lump;
3836 : : }
3837 : :
3838 : : /*
3839 : : #include "GfxDebug.hpp"
3840 : : static void draw_curve( PartitionCurve* curve, int color, bool flush = true )
3841 : : {
3842 : : GMem graphics;
3843 : : int i;
3844 : : curve->get_geometry_query_engine()->get_graphics( curve, i, &graphics );
3845 : : GfxDebug::draw_polyline(graphics.point_list(),
3846 : : graphics.pointListCount,
3847 : : color);
3848 : : if(flush) GfxDebug::flush();
3849 : : }
3850 : :
3851 : : static void draw_surface( PartitionSurface* surface, int color, bool flush = true )
3852 : : {
3853 : : // RefEntity* re = dynamic_cast<RefEntity*>(surface->owner());
3854 : : // if( re )
3855 : : // GfxDebug::draw_ref_entity( re, color, true, false );
3856 : : // else
3857 : : for( PartitionLoop* loop = 0; loop = surface->next_loop(loop); )
3858 : : {
3859 : : PartitionCoEdge* coe = loop->first_coedge();
3860 : : do {
3861 : : draw_curve(coe->get_curve(), color, false);
3862 : : coe = loop->next_coedge(coe);
3863 : : } while(coe != loop->first_coedge());
3864 : : }
3865 : : if(flush) GfxDebug::flush();
3866 : : }
3867 : :
3868 : : static void draw_cosurface( PartitionCoSurf* cosurf, int color, bool flush = true )
3869 : : {
3870 : : //draw_surface(cosurf->get_surface(), color, false);
3871 : : CubitVector p, n;
3872 : : n = cosurf->get_surface()->bounding_box().center();
3873 : : cosurf->get_surface()->closest_point_trimmed( n, p );
3874 : : cosurf->get_surface()->closest_point( p, 0, &n );
3875 : : double l = cosurf->get_surface()->bounding_box().diagonal().length() * 0.1;
3876 : : n.length(l);
3877 : : if(cosurf->sense() == CUBIT_REVERSED)
3878 : : n *= -1.0;
3879 : : GfxDebug::draw_vector(p, p+n, color);
3880 : : if(flush) GfxDebug::flush();
3881 : : }
3882 : : */
3883 : :
3884 : : //-------------------------------------------------------------------------
3885 : : // Purpose : Test if a PartitionShell needs to be split, and
3886 : : // split it
3887 : : //
3888 : : // Special Notes :
3889 : : //
3890 : : // Creator : Jason Kraftcheck
3891 : : //
3892 : : // Creation Date : 01/13/03
3893 : : //-------------------------------------------------------------------------
3894 : 0 : PartitionShell* PartitionEngine::split_shell( PartitionShell* shell_to_split )
3895 : : {
3896 : : // Make sure all cosurface surface marks are cleared
3897 : 0 : PartitionCoSurf* cosurf = 0;
3898 [ # # ][ # # ]: 0 : while( (cosurf = shell_to_split->next_co_surface( cosurf )) )
3899 : : {
3900 : 0 : cosurf->mark = 0;
3901 [ # # ]: 0 : cosurf->get_surface()->mark = 0;
3902 : : }
3903 : :
3904 : : // Identify non-manifold surfaces, marking them either
3905 : : // with a 2 if they can be used to split the volume
3906 : : // (if they are part of a connected patch for which the
3907 : : // bounadary of that patch intersects the volume boundary
3908 : : // at all curves) or a 3 if they are other non-manifold
3909 : : // surfaces. This will get a bit tricky if there are
3910 : : // non-manifold surfaces hanging off of the patch of
3911 : : // split surfaces.
3912 : :
3913 : : // First for all non-manifold surfaces, if the surface has
3914 : : // a curve that is not shared with any other surface, mark
3915 : : // it with a 3. Otherwise mark it with a 2.
3916 : 0 : cosurf = 0;
3917 [ # # ]: 0 : DLIList<PartitionSurface*> surf_stack;
3918 [ # # ][ # # ]: 0 : while ( (cosurf = shell_to_split->next_co_surface(cosurf)) )
3919 : : {
3920 [ # # ]: 0 : PartitionSurface* surf = cosurf->get_surface();
3921 : : // If we haven't done this surface yet and it is non-manifold
3922 [ # # ][ # # ]: 0 : if ( !surf->mark && surf->find_next(cosurf) )
[ # # ][ # # ]
3923 : : {
3924 : 0 : surf->mark = 2;
3925 : 0 : bool no_free_curve = true;
3926 : 0 : PartitionLoop* loop = 0;
3927 [ # # ][ # # ]: 0 : while( no_free_curve && (loop = surf->next_loop(loop)) )
[ # # ][ # # ]
3928 : : {
3929 [ # # ]: 0 : PartitionCoEdge* coedge = loop->first_coedge();
3930 [ # # ]: 0 : do
3931 : : {
3932 [ # # ]: 0 : PartitionCurve* curve = coedge->get_curve();
3933 : : // If the curve has more than one coedge, it
3934 : : // is not a free curve (this also accounts for
3935 : : // the case where the curve is a non-manifold
3936 : : // curve on the surface interioir -- e.g. a sipe)
3937 [ # # ][ # # ]: 0 : if ( !curve->next_coedge(coedge) &&
[ # # ][ # # ]
3938 [ # # ]: 0 : curve->next_coedge(0) == coedge )
3939 : : {
3940 : 0 : no_free_curve = false;
3941 : 0 : break;
3942 : : }
3943 [ # # ]: 0 : coedge = loop->next_coedge(coedge);
3944 [ # # ]: 0 : } while( coedge != loop->first_coedge() );
3945 : : }
3946 : :
3947 [ # # ]: 0 : if( !no_free_curve )
3948 : : {
3949 : 0 : surf->mark = 3;
3950 [ # # ]: 0 : surf_stack.append( surf );
3951 : : }
3952 : : }
3953 : : }
3954 : :
3955 : : // Now for each surface we marked with a three, traverse
3956 : : // and mark adjacent surfaces until we come to a curve
3957 : : // connected to more that two surfaces.
3958 [ # # ][ # # ]: 0 : while( surf_stack.size() )
3959 : : {
3960 [ # # ]: 0 : PartitionSurface* surf = surf_stack.pop();
3961 : 0 : PartitionLoop* loop = 0;
3962 [ # # ][ # # ]: 0 : while ( (loop = surf->next_loop(loop)) )
3963 : : {
3964 [ # # ]: 0 : PartitionCoEdge* coedge = loop->first_coedge();
3965 [ # # ]: 0 : do
3966 : : {
3967 [ # # ]: 0 : PartitionCurve* curve = coedge->get_curve();
3968 : 0 : int split_count = 0;
3969 : 0 : int boundary_count = 0;
3970 : 0 : PartitionCoEdge* curve_coe = 0;
3971 [ # # ][ # # ]: 0 : while ( (curve_coe = curve->next_coedge(curve_coe) ) != NULL )
3972 : : {
3973 [ # # ][ # # ]: 0 : PartitionSurface* curve_surf = curve_coe->get_loop()->get_surface();
3974 [ # # # ]: 0 : switch ( curve_surf->mark )
3975 : : {
3976 : 0 : case 0: boundary_count++; break;
3977 : 0 : case 2: split_count++; break;
3978 : : }
3979 : : }
3980 : :
3981 [ # # ][ # # ]: 0 : if ( split_count == 1 && !boundary_count )
3982 : : {
3983 : 0 : curve_coe = 0;
3984 [ # # ][ # # ]: 0 : while ( (curve_coe = curve->next_coedge(curve_coe) ) != NULL )
3985 : : {
3986 [ # # ][ # # ]: 0 : PartitionSurface* curve_surf = curve_coe->get_loop()->get_surface();
3987 [ # # ]: 0 : if ( curve_surf->mark == 2 )
3988 : : {
3989 : 0 : curve_surf->mark = 3;
3990 [ # # ]: 0 : surf_stack.append(curve_surf);
3991 : : }
3992 : : }
3993 : : }
3994 : :
3995 [ # # ]: 0 : coedge = loop->next_coedge( coedge );
3996 [ # # ]: 0 : } while( coedge != loop->first_coedge() );
3997 : : }
3998 : : }
3999 : :
4000 : : // Now build a new shell by traversing cofaces, marking
4001 : : // each with that will go in a new shell with a 1.
4002 : :
4003 : : // Start with any cosurf that does not have a free
4004 : : // non-manifold surface (marked with a 3). We'll handle
4005 : : // free non-manifold surfaces later.
4006 [ # # ]: 0 : DLIList<PartitionCoSurf*> cosurf_stack;
4007 : 0 : cosurf = 0;
4008 [ # # ][ # # ]: 0 : while ( (cosurf = shell_to_split->next_co_surface(cosurf)) )
4009 [ # # ][ # # ]: 0 : if ( cosurf->get_surface()->mark != 3 )
4010 : 0 : break;
4011 [ # # ]: 0 : if ( cosurf )
4012 : : {
4013 : 0 : cosurf->mark = 1;
4014 [ # # ]: 0 : cosurf_stack.append( cosurf );
4015 : : }
4016 : :
4017 : : // Traverse over adjacent cosurfaces, marking them with a 1
4018 [ # # ][ # # ]: 0 : while (cosurf_stack.size())
4019 : : {
4020 [ # # ]: 0 : cosurf = cosurf_stack.pop();
4021 [ # # ]: 0 : PartitionSurface* surf = cosurf->get_surface();
4022 : 0 : PartitionLoop* loop = 0;
4023 [ # # ][ # # ]: 0 : while ( (loop = surf->next_loop(loop)) )
4024 : : {
4025 [ # # ]: 0 : PartitionCoEdge* coedge = loop->first_coedge();
4026 [ # # ]: 0 : do
4027 : : {
4028 [ # # ]: 0 : PartitionCurve* curve = coedge->get_curve();
4029 : 0 : PartitionCoEdge* curve_coe = 0;
4030 : 0 : PartitionCoSurf *boundary_cosurf = 0, *split_cosurf = 0;
4031 : 0 : int split_cosurf_count = 0;
4032 [ # # ][ # # ]: 0 : while ( (curve_coe = curve->next_coedge(curve_coe)) )
4033 : : {
4034 [ # # ]: 0 : if ( curve_coe == coedge )
4035 : 0 : continue;
4036 : :
4037 [ # # ][ # # ]: 0 : bool same_coe_sense = curve_coe->sense() == coedge->sense();
4038 [ # # ][ # # ]: 0 : PartitionSurface* curve_surf = curve_coe->get_loop()->get_surface();
4039 : 0 : PartitionCoSurf* curve_cosurf = 0;
4040 [ # # ][ # # ]: 0 : while ( (curve_cosurf = curve_surf->next_co_surface(curve_cosurf)) )
4041 : : {
4042 [ # # ][ # # ]: 0 : if ( curve_cosurf->get_shell() != shell_to_split )
4043 : 0 : continue;
4044 : :
4045 [ # # ][ # # ]: 0 : bool same_cos_sense = curve_cosurf->sense() == cosurf->sense();
4046 [ # # ]: 0 : if ( same_cos_sense == same_coe_sense )
4047 : 0 : continue;
4048 : :
4049 : : // Always choose split surface first if we
4050 : : // found one
4051 [ # # ][ # # ]: 0 : if ( curve_cosurf->get_surface()->mark == 2 ) {
4052 : 0 : split_cosurf_count++;
4053 : 0 : split_cosurf = curve_cosurf;
4054 : : }
4055 : :
4056 : : // Skip other non-manifold surfaces. We'll
4057 : : // handle those later.
4058 [ # # ][ # # ]: 0 : else if( curve_cosurf->get_surface()->mark != 3 )
4059 : 0 : boundary_cosurf = curve_cosurf;
4060 : : }
4061 : : }
4062 : :
4063 [ # # ]: 0 : PartitionCoSurf* next_cosurf = split_cosurf ? split_cosurf : boundary_cosurf;
4064 [ # # ][ # # ]: 0 : if ( !next_cosurf->mark && split_cosurf_count < 2 )
4065 : : {
4066 : 0 : next_cosurf->mark = 1;
4067 [ # # ]: 0 : cosurf_stack.append(next_cosurf);
4068 : : }
4069 : :
4070 [ # # ]: 0 : coedge = loop->next_coedge(coedge);
4071 [ # # ]: 0 : } while( coedge != loop->first_coedge() );
4072 : : } // end while (loop)
4073 : : } // end while (cosurf_stack.size())
4074 : :
4075 : :
4076 : : // build lists of cosurfaces, one for each shell and
4077 : : // one of other non-manifold surfaces
4078 [ # # ][ # # ]: 0 : DLIList<PartitionCoSurf*> marked_list, unmarked_list, other_list;
[ # # ][ # # ]
[ # # ][ # # ]
4079 [ # # ][ # # ]: 0 : while( (cosurf = shell_to_split->next_co_surface(0)) )
4080 : : {
4081 [ # # ]: 0 : shell_to_split->remove(cosurf);
4082 [ # # ][ # # ]: 0 : if ( cosurf->get_surface()->mark == 3 )
4083 [ # # ]: 0 : other_list.append( cosurf );
4084 [ # # ]: 0 : else if( cosurf->mark )
4085 [ # # ]: 0 : marked_list.append( cosurf );
4086 : : else
4087 [ # # ]: 0 : unmarked_list.append( cosurf );
4088 : : }
4089 : :
4090 : : // If one of marked_list or unmarked_list is empty,
4091 : : // we can't split the shell yet. Put cofaces back in
4092 : : // shell and exit.
4093 [ # # ][ # # ]: 0 : if ( !marked_list.size() || !unmarked_list.size() )
[ # # ][ # # ]
[ # # ]
4094 : : {
4095 [ # # ]: 0 : marked_list += unmarked_list;
4096 [ # # ]: 0 : marked_list += other_list;
4097 [ # # ]: 0 : marked_list.reverse();
4098 [ # # ][ # # ]: 0 : while ( marked_list.size() )
4099 : : {
4100 [ # # ]: 0 : cosurf = marked_list.pop();
4101 : 0 : cosurf->mark = 0;
4102 [ # # ]: 0 : cosurf->get_surface()->mark = 0;
4103 [ # # ]: 0 : shell_to_split->add( cosurf );
4104 : : }
4105 : 0 : return 0;
4106 : : }
4107 : :
4108 : : // Put unmarked list back in old shell
4109 [ # # ]: 0 : unmarked_list.reverse();
4110 [ # # ][ # # ]: 0 : while ( unmarked_list.size() )
4111 : : {
4112 [ # # ]: 0 : cosurf = unmarked_list.pop();
4113 [ # # ]: 0 : cosurf->get_surface()->mark = 0;
4114 [ # # ]: 0 : shell_to_split->add(cosurf);
4115 : : }
4116 : :
4117 : : // Put marked list in new shell
4118 [ # # ][ # # ]: 0 : PartitionShell* new_shell = new PartitionShell;
4119 [ # # ]: 0 : marked_list.reverse();
4120 [ # # ][ # # ]: 0 : while ( marked_list.size() )
4121 : : {
4122 [ # # ]: 0 : cosurf = marked_list.pop();
4123 : 0 : cosurf->mark = 0;
4124 [ # # ]: 0 : cosurf->get_surface()->mark = 0;
4125 [ # # ]: 0 : new_shell->add(cosurf);
4126 : : }
4127 : :
4128 : : // Now sort out other non-manifold surfaces
4129 : :
4130 : : // Clear marks and get list of surface from cosurfaces
4131 [ # # ]: 0 : surf_stack.clean_out();
4132 [ # # ][ # # ]: 0 : while( other_list.size() )
4133 : : {
4134 [ # # ]: 0 : cosurf = other_list.pop();
4135 [ # # ]: 0 : PartitionSurface* surf = cosurf->get_surface();
4136 [ # # ]: 0 : if ( surf->mark )
4137 : : {
4138 : 0 : surf->mark = 0;
4139 [ # # ]: 0 : surf_stack.append(surf);
4140 : : }
4141 : : }
4142 : :
4143 [ # # ]: 0 : insert_nonmanifold_surfaces( surf_stack, shell_to_split, new_shell );
4144 [ # # ][ # # ]: 0 : return new_shell;
4145 : : }
4146 : :
4147 : :
4148 : : //-------------------------------------------------------------------------
4149 : : // Purpose : After a shell is split, determine which of the two
4150 : : // resulting shells each non-manifold surface belongs in.
4151 : : //
4152 : : // Special Notes :
4153 : : //
4154 : : // Creator : Jason Kraftcheck
4155 : : //
4156 : : // Creation Date : 02/23/03
4157 : : //-------------------------------------------------------------------------
4158 : 0 : void PartitionEngine::insert_nonmanifold_surfaces(
4159 : : DLIList<PartitionSurface*>& surf_stack,
4160 : : PartitionShell* shell1,
4161 : : PartitionShell* shell2 )
4162 : : {
4163 [ # # ][ # # ]: 0 : DLIList<PartitionSurface*> known_list(surf_stack.size()),
4164 [ # # ][ # # ]: 0 : unknown_list(surf_stack.size());
[ # # ]
4165 : :
4166 : : PartitionCoSurf* cosurf;
4167 : : PartitionSurface* surf;
4168 : : PartitionLoop* loop;
4169 : : PartitionCoEdge *coedge, *curve_coe;
4170 : : PartitionCurve* curve;
4171 : :
4172 : : // Loop until we've placed all the surfaces in one
4173 : : // shell or the other.
4174 [ # # ][ # # ]: 0 : while ( surf_stack.size() )
4175 : : {
4176 : 0 : bool did_some = false;
4177 : :
4178 : : // Put any surfaces for which we immediately
4179 : : // know the shell into the appropriate shell.
4180 : : // Put others in known_list or unknown_list
4181 : : // depending on if we can determine which shell
4182 : : // they go in using a geometric comparison.
4183 [ # # ]: 0 : known_list.clean_out();
4184 [ # # ]: 0 : unknown_list.clean_out();
4185 : :
4186 : : // Take all surfaces out of stack in this loop.
4187 : : // We might put some back in after the loop (thus
4188 : : // the outer loop.)
4189 [ # # ][ # # ]: 0 : while ( surf_stack.size() )
4190 : : {
4191 [ # # ]: 0 : surf = surf_stack.pop();
4192 : :
4193 : 0 : PartitionShell* known_shell = 0;
4194 : 0 : bool found_shell = false;
4195 : 0 : loop = 0;
4196 [ # # ][ # # ]: 0 : while ( (loop = surf->next_loop(loop)) )
4197 : : {
4198 [ # # ]: 0 : coedge = loop->first_coedge();
4199 [ # # ]: 0 : do
4200 : : {
4201 [ # # ]: 0 : curve = coedge->get_curve();
4202 : 0 : curve_coe = 0;
4203 [ # # ][ # # ]: 0 : while ( (curve_coe = curve->next_coedge(curve_coe)) )
4204 : : {
4205 [ # # ][ # # ]: 0 : PartitionSurface* surf = curve_coe->get_loop()->get_surface();
4206 : 0 : cosurf = 0;
4207 [ # # ][ # # ]: 0 : while ( (cosurf = surf->next_co_surface( cosurf )) )
4208 : : {
4209 [ # # ][ # # ]: 0 : if( cosurf->get_shell() == shell1 ||
[ # # ][ # # ]
4210 [ # # ]: 0 : cosurf->get_shell() == shell2 )
4211 : : {
4212 : 0 : found_shell = true;
4213 [ # # ][ # # ]: 0 : if ( known_shell && known_shell != cosurf->get_shell() )
[ # # ][ # # ]
4214 : 0 : known_shell = 0;
4215 : : else
4216 [ # # ]: 0 : known_shell = cosurf->get_shell();
4217 : : }
4218 : : }
4219 : : }
4220 : :
4221 [ # # ]: 0 : coedge = loop->next_coedge(coedge);
4222 [ # # ]: 0 : } while( coedge != loop->first_coedge() );
4223 : : } // end while(loop)
4224 : :
4225 : : // This surface does not intersect the shell at
4226 : : // any curve. We can't do this one yet.
4227 [ # # ]: 0 : if ( !found_shell )
4228 : : {
4229 [ # # ]: 0 : unknown_list.append( surf );
4230 : 0 : continue;
4231 : : }
4232 : :
4233 : : // This surface intersected both shells at some
4234 : : // curves, but did not have a curve that intersected
4235 : : // only one shell. We can do this one geometricly
4236 : : // if we have to.
4237 [ # # ]: 0 : if ( !known_shell )
4238 : : {
4239 [ # # ]: 0 : known_list.append( surf );
4240 : 0 : continue;
4241 : : }
4242 : :
4243 : : // If we got this far, then the surface had at least
4244 : : // one curve that intersected only one of the shells.
4245 : : // We know it goes in that shell.
4246 : 0 : did_some = true;
4247 [ # # ]: 0 : PartitionCoSurf* cosurf1 = surf->find_first((PartitionShell*)0);
4248 [ # # ]: 0 : PartitionCoSurf* cosurf2 = surf->find_next(cosurf1);
4249 [ # # ]: 0 : known_shell->add(cosurf1);
4250 [ # # ]: 0 : known_shell->add(cosurf2);
4251 : :
4252 : : } // while(surf_stack) -- the inside one
4253 : :
4254 : : // Unknown_list always goes back in surf_stack to
4255 : : // try again.
4256 [ # # ]: 0 : surf_stack += unknown_list;
4257 : :
4258 : : // If we did some surfaces, then put the rest back
4259 : : // in surf_stack and try again. If they intersect
4260 : : // one of the surfaces we did place in this iteration,
4261 : : // we can avoid needing to do geometric checks.
4262 [ # # ]: 0 : if ( did_some )
4263 : : {
4264 [ # # ]: 0 : surf_stack += known_list;
4265 : 0 : continue;
4266 : : }
4267 : :
4268 : : // If known_list is empty, somethings wrong (we're
4269 : : // going to loop forever.) Abort the loop and try
4270 : : // to recover as best we can.
4271 [ # # ][ # # ]: 0 : if( !known_list.size() )
4272 : 0 : break;
4273 : :
4274 : : // choose a single surface in do a geometric comparison
4275 : : // for, and put the rest back in surf_stack
4276 [ # # ]: 0 : surf = known_list.pop();
4277 [ # # ]: 0 : surf_stack += known_list;
4278 : :
4279 : 0 : bool in_shell = false;
4280 [ # # ][ # # ]: 0 : if ( ! inside_shell( shell2, surf, in_shell ) )
4281 : : {
4282 : : // if inside_shell failed, abort.
4283 [ # # ]: 0 : surf_stack.append(surf);
4284 : 0 : break;
4285 : : }
4286 : :
4287 [ # # ]: 0 : PartitionShell* shell = in_shell ? shell2 : shell1;
4288 [ # # ][ # # ]: 0 : shell->add(surf->find_first((PartitionShell*)0));
4289 [ # # ][ # # ]: 0 : shell->add(surf->find_first((PartitionShell*)0));
4290 : : }
4291 : :
4292 : : // something went wrong
4293 [ # # ][ # # ]: 0 : if( surf_stack.size() )
4294 : : {
4295 [ # # ][ # # ]: 0 : PRINT_ERROR("Internal error splitting volume at %s:%d\n"
[ # # ]
4296 : : "Topology may be invalid. Please report this.\n",
4297 [ # # ]: 0 : __FILE__, __LINE__);
4298 [ # # ][ # # ]: 0 : while( surf_stack.size() )
4299 : : {
4300 [ # # ]: 0 : PartitionSurface* surf = surf_stack.pop();
4301 : 0 : cosurf = 0;
4302 [ # # ][ # # ]: 0 : while( (cosurf = surf->next_co_surface(cosurf)) )
4303 [ # # ][ # # ]: 0 : if( !cosurf->get_shell() )
4304 [ # # ]: 0 : shell1->add(cosurf);
4305 : : }
4306 [ # # ]: 0 : }
4307 : 0 : }
4308 : :
4309 : :
4310 : 0 : CubitStatus PartitionEngine::inside_shell( PartitionShell* const shell,
4311 : : PartitionSurface* const surf,
4312 : : bool& result )
4313 : : {
4314 : : // Find the curve and coedge at which the nonmanifold surface
4315 : : // intersects the shells
4316 : 0 : PartitionLoop* loop = 0;
4317 : 0 : PartitionCoEdge *nonman_coedge = 0;
4318 [ # # ][ # # ]: 0 : while ( !nonman_coedge && (loop = surf->next_loop(loop)) )
[ # # ][ # # ]
4319 : : {
4320 [ # # ]: 0 : PartitionCoEdge* loop_coedge = loop->first_coedge();
4321 [ # # ]: 0 : do
4322 : : {
4323 : : // Check if this curve is the curve of intersection
4324 : : // Iterate through curve coedges.
4325 [ # # ]: 0 : PartitionCurve* curve = loop_coedge->get_curve();
4326 : 0 : PartitionCoEdge* curve_coedge = 0;
4327 [ # # ][ # # ]: 0 : while ( (curve_coedge = curve->next_coedge(curve_coedge)) )
4328 : : {
4329 : :
4330 [ # # ][ # # ]: 0 : PartitionSurface* coedge_surf = curve_coedge->get_loop()->get_surface();
4331 [ # # ][ # # ]: 0 : if( coedge_surf->find_first(shell) )
4332 : : {
4333 : 0 : nonman_coedge = curve_coedge;
4334 : 0 : break;
4335 : : }
4336 : : }
4337 : :
4338 [ # # ]: 0 : loop_coedge = loop->next_coedge(loop_coedge);
4339 [ # # ][ # # ]: 0 : } while( !nonman_coedge && loop_coedge != loop->first_coedge() );
[ # # ]
4340 : : }
4341 : :
4342 [ # # ]: 0 : if ( !nonman_coedge ) // bad input!
4343 : 0 : return CUBIT_FAILURE;
4344 : :
4345 : : // There must exist two surfaces in the shell that are manifold
4346 : : // in the shell and that are adjacent to the curve
4347 [ # # ]: 0 : PartitionCurve* common_curve = nonman_coedge->get_curve();
4348 : 0 : PartitionCoSurf *cosurf1 = 0, *cosurf2 = 0, *cosurf;
4349 : 0 : PartitionCoEdge *coedge1 = 0, *coedge2 = 0, *coedge = 0;
4350 [ # # ][ # # ]: 0 : while ( (coedge = common_curve->next_coedge(coedge)) )
4351 : : {
4352 [ # # ][ # # ]: 0 : PartitionSurface* surf = coedge->get_loop()->get_surface();
4353 [ # # ][ # # ]: 0 : if ( (cosurf = surf->find_first(shell)) && !surf->find_next(cosurf) )
[ # # ][ # # ]
[ # # ]
4354 : : {
4355 [ # # ]: 0 : if( coedge1 ) {
4356 : 0 : coedge2 = coedge;
4357 : 0 : cosurf2 = cosurf;
4358 : : } else {
4359 : 0 : coedge1 = coedge;
4360 : 0 : cosurf1 = cosurf;
4361 : : }
4362 : : }
4363 : : }
4364 [ # # ][ # # ]: 0 : if ( !coedge1 || !coedge2 )
4365 : 0 : return CUBIT_FAILURE;
4366 : :
4367 : : // Evaluate normals at midpoint of curve
4368 [ # # ][ # # ]: 0 : CubitVector base, tangent, point;
[ # # ]
4369 [ # # ][ # # ]: 0 : double u = (common_curve->start_param()+common_curve->end_param())/2.0;
4370 [ # # ]: 0 : common_curve->position_from_u( u, base );
4371 [ # # ]: 0 : common_curve->closest_point( base, point, &tangent );
4372 [ # # ]: 0 : tangent.normalize();
4373 : :
4374 [ # # ][ # # ]: 0 : CubitVector normal1, normal2, normal;
[ # # ]
4375 [ # # ]: 0 : surf->closest_point( base, 0, &normal );
4376 [ # # ][ # # ]: 0 : cosurf1->get_surface()->closest_point( base, 0, &normal1 );
4377 [ # # ][ # # ]: 0 : cosurf2->get_surface()->closest_point( base, 0, &normal2 );
4378 : :
4379 : : // Try to handle tangencies
4380 [ # # ][ # # ]: 0 : bool fix1 = (normal1 * normal).length_squared() < CUBIT_RESABS;
4381 [ # # ][ # # ]: 0 : bool fix2 = (normal2 * normal).length_squared() < CUBIT_RESABS;
4382 [ # # ][ # # ]: 0 : if ( fix1 || fix2 )
4383 : : {
4384 [ # # ]: 0 : CubitVector dir = tangent * normal;
4385 [ # # ]: 0 : double len = dir.length();
4386 [ # # ]: 0 : assert(len > GEOMETRY_RESABS);
4387 [ # # ]: 0 : dir /= len;
4388 [ # # ][ # # ]: 0 : if ( nonman_coedge->sense() == CUBIT_FORWARD )
4389 [ # # ][ # # ]: 0 : dir = -dir;
4390 : :
4391 [ # # ][ # # ]: 0 : CubitVector diag = surf->bounding_box().diagonal();
[ # # ]
4392 [ # # ]: 0 : if ( fix1 )
4393 : : {
4394 [ # # ][ # # ]: 0 : CubitVector d = cosurf1->get_surface()->bounding_box().diagonal();
[ # # ][ # # ]
4395 [ # # ][ # # ]: 0 : if ( diag.x() < d.x() ) diag.x(d.x());
[ # # ][ # # ]
[ # # ]
4396 [ # # ][ # # ]: 0 : if ( diag.y() < d.y() ) diag.y(d.y());
[ # # ][ # # ]
[ # # ]
4397 [ # # ][ # # ]: 0 : if ( diag.z() < d.z() ) diag.z(d.z());
[ # # ][ # # ]
[ # # ]
4398 : : }
4399 [ # # ]: 0 : if( fix2 )
4400 : : {
4401 [ # # ][ # # ]: 0 : CubitVector d = cosurf2->get_surface()->bounding_box().diagonal();
[ # # ][ # # ]
4402 [ # # ][ # # ]: 0 : if ( diag.x() < d.x() ) diag.x(d.x());
[ # # ][ # # ]
[ # # ]
4403 [ # # ][ # # ]: 0 : if ( diag.y() < d.y() ) diag.y(d.y());
[ # # ][ # # ]
[ # # ]
4404 [ # # ][ # # ]: 0 : if ( diag.z() < d.z() ) diag.z(d.z());
[ # # ][ # # ]
[ # # ]
4405 : : }
4406 : :
4407 [ # # ]: 0 : double step = 1e-3 * fabs( diag % dir );
4408 [ # # ]: 0 : if ( step < 2*GEOMETRY_RESABS )
4409 : 0 : step = 2*GEOMETRY_RESABS;
4410 : :
4411 [ # # ]: 0 : for ( int i = 0; i < 1000; i++ )
4412 : : {
4413 [ # # ][ # # ]: 0 : point = base + i * step * dir;
[ # # ]
4414 [ # # ]: 0 : surf->closest_point( base, 0, &normal );
4415 [ # # ]: 0 : if( fix1 )
4416 [ # # ][ # # ]: 0 : cosurf1->get_surface()->closest_point( base, 0, &normal1 );
4417 [ # # ]: 0 : if( fix2 )
4418 [ # # ][ # # ]: 0 : cosurf2->get_surface()->closest_point( base, 0, &normal2 );
4419 : :
4420 [ # # ][ # # ]: 0 : bool done1 = !fix1 || (normal1 * normal).length_squared() > CUBIT_RESABS;
[ # # ][ # # ]
[ # # ][ # # ]
4421 [ # # ][ # # ]: 0 : bool done2 = !fix2 || (normal2 * normal).length_squared() > CUBIT_RESABS;
[ # # ][ # # ]
[ # # ][ # # ]
4422 [ # # ][ # # ]: 0 : if ( done1 && done2 )
4423 : : {
4424 : 0 : fix1 = fix2 = false;
4425 : 0 : break;
4426 : : }
4427 : : }
4428 : : }
4429 : :
4430 [ # # ][ # # ]: 0 : if ( fix1 || fix2 )
4431 : : {
4432 [ # # ][ # # ]: 0 : PRINT_ERROR("Failed to adjust for surface tangencies.\n"
[ # # ]
4433 [ # # ]: 0 : "This is a BUG. %s:%d\n", __FILE__, __LINE__ );
4434 : 0 : return CUBIT_FAILURE;
4435 : : }
4436 : :
4437 [ # # ][ # # ]: 0 : if ( nonman_coedge->sense() == CUBIT_FORWARD )
4438 [ # # ][ # # ]: 0 : normal = -normal;
4439 [ # # ][ # # ]: 0 : if ( cosurf1->sense() == coedge1->sense() )
[ # # ]
4440 [ # # ][ # # ]: 0 : normal1 = -normal1;
4441 [ # # ][ # # ]: 0 : if ( cosurf2->sense() == coedge2->sense() )
[ # # ]
4442 [ # # ][ # # ]: 0 : normal2 = -normal2;
4443 : :
4444 [ # # ]: 0 : result = tangent.vector_angle(normal1, normal ) <=
4445 [ # # ]: 0 : tangent.vector_angle(normal1, normal2);
4446 : 0 : return CUBIT_SUCCESS;
4447 : : }
4448 : :
4449 : :
4450 : :
4451 : :
4452 : :
4453 : :
4454 : : //-------------------------------------------------------------------------
4455 : : // Purpose : Remove a partition surface previously inserted in a
4456 : : // lump via insert_surface(..).
4457 : : //
4458 : : // Special Notes :
4459 : : //
4460 : : // Creator : Jason Kraftcheck
4461 : : //
4462 : : // Creation Date : 01/13/03
4463 : : //-------------------------------------------------------------------------
4464 : 0 : Lump* PartitionEngine::remove_surface( PartitionSurface* surface )
4465 : : {
4466 : : // If surface belongs to non-partition volumes, we cannot proceed.
4467 [ # # ]: 0 : DLIList<TopologyBridge*> shell_bridges;
4468 [ # # ]: 0 : surface->get_parents_virt( shell_bridges );
4469 [ # # ][ # # ]: 0 : while( shell_bridges.size() )
4470 [ # # ][ # # ]: 0 : if( ! dynamic_cast<PartitionShell*>(shell_bridges.pop()) )
[ # # ][ # # ]
4471 : 0 : return 0;
4472 : :
4473 [ # # ]: 0 : PartitionCoSurf* cosurf1 = surface->next_co_surface(0);
4474 [ # # ]: 0 : if( ! cosurf1 )
4475 : 0 : return 0; // doesn't belong to any PartitionLumps;
4476 : :
4477 [ # # ]: 0 : PartitionCoSurf* cosurf2 = surface->next_co_surface(cosurf1);
4478 [ # # ][ # # ]: 0 : if( !cosurf2 || surface->next_co_surface(cosurf2) )
[ # # ][ # # ]
4479 : 0 : return 0; // must have exactly two parent cosurfaces.
4480 : :
4481 [ # # ]: 0 : PartitionShell* shell1 = cosurf1->get_shell();
4482 [ # # ]: 0 : PartitionShell* shell2 = cosurf2->get_shell();
4483 [ # # ]: 0 : PartitionLump* lump1 = shell1->get_lump();
4484 [ # # ]: 0 : PartitionLump* lump2 = shell2->get_lump();
4485 : :
4486 [ # # ][ # # ]: 0 : if( surface->partitioned_entity() != lump1->partitioned_entity() )
[ # # ]
4487 : 0 : return 0; // shouldn't have gotten this far, but just in case ...
4488 : :
4489 : : // remove and destroy surface
4490 [ # # ]: 0 : shell1->remove( cosurf1 );
4491 [ # # ]: 0 : shell2->remove( cosurf2 );
4492 [ # # ]: 0 : surface->remove(cosurf1);
4493 [ # # ]: 0 : surface->remove(cosurf2);
4494 [ # # ][ # # ]: 0 : delete cosurf1;
4495 [ # # ][ # # ]: 0 : delete cosurf2;
4496 [ # # ]: 0 : destroy_surface(surface);
4497 : :
4498 : :
4499 : : // combine volumes?
4500 [ # # ]: 0 : if( shell1 != shell2 )
4501 : : {
4502 [ # # ]: 0 : assert(lump1 != lump2);
4503 [ # # ][ # # ]: 0 : while( PartitionCoSurf* cosurf = shell2->next_co_surface(0) )
4504 : : {
4505 [ # # ]: 0 : shell2->remove(cosurf);
4506 [ # # ]: 0 : shell1->add(cosurf);
4507 : : }
4508 [ # # ]: 0 : lump2->remove(shell2);
4509 [ # # ][ # # ]: 0 : delete shell2;
4510 : :
4511 [ # # ][ # # ]: 0 : if( !shell1->next_co_surface(0) )
4512 : : {
4513 [ # # ]: 0 : lump1->remove(shell1);
4514 [ # # ][ # # ]: 0 : delete shell1;
4515 : : }
4516 : :
4517 [ # # ][ # # ]: 0 : while( PartitionShell* shell = lump2->next_shell(0) )
4518 : : {
4519 [ # # ]: 0 : lump2->remove(shell);
4520 [ # # ]: 0 : lump1->add(shell);
4521 : : }
4522 [ # # ][ # # ]: 0 : delete lump2;
4523 : : }
4524 : : // one-surface shell
4525 [ # # ][ # # ]: 0 : else if( !shell1->next_co_surface(0) )
4526 : : {
4527 [ # # ]: 0 : lump1->remove( shell1 );
4528 [ # # ][ # # ]: 0 : delete shell1;
4529 : : }
4530 : : // possibly split shells
4531 : : else
4532 : : {
4533 [ # # ]: 0 : PartitionShell* shell = split_shell( shell1 );
4534 [ # # ]: 0 : if( shell )
4535 [ # # ]: 0 : lump1->add(shell);
4536 : : }
4537 : :
4538 [ # # ][ # # ]: 0 : if( !lump1->sub_entity_set().has_lower_order() )
[ # # ]
4539 [ # # ]: 0 : return restore_lump( lump1 );
4540 : : else
4541 [ # # ]: 0 : return lump1;
4542 : : }
4543 : :
4544 : :
4545 : : //-------------------------------------------------------------------------
4546 : : // Purpose : tear down and free a surface
4547 : : //
4548 : : // Special Notes :
4549 : : //
4550 : : // Creator : Jason Kraftcheck
4551 : : //
4552 : : // Creation Date : 01/14/03
4553 : : //-------------------------------------------------------------------------
4554 : 0 : CubitStatus PartitionEngine::destroy_surface( PartitionSurface* surface )
4555 : : {
4556 [ # # ]: 0 : while( PartitionLoop* dead_loop = surface->next_loop(0) )
4557 : : {
4558 : 0 : surface->remove(dead_loop);
4559 [ # # ]: 0 : while( PartitionCoEdge* dead_coe = dead_loop->first_coedge() )
4560 : : {
4561 : 0 : PartitionCurve* dead_curve = dead_coe->get_curve();
4562 : 0 : dead_loop->remove(dead_coe);
4563 : 0 : dead_curve->remove(dead_coe);
4564 [ # # ]: 0 : delete dead_coe;
4565 : :
4566 [ # # ]: 0 : if( dead_curve->partitioned_entity() == surface->partitioned_entity() )
4567 : : {
4568 [ # # ]: 0 : if( dead_curve->next_coedge(0) == 0 )
4569 : : {
4570 : 0 : PartitionPoint* start_pt = dead_curve->start_point();
4571 : 0 : PartitionPoint* end_pt = dead_curve->end_point();
4572 [ # # ]: 0 : delete dead_curve;
4573 [ # # # # ]: 0 : if( start_pt->partitioned_entity() == surface->partitioned_entity() &&
[ # # ]
4574 : 0 : start_pt->next_curve() == 0 )
4575 [ # # ]: 0 : delete start_pt;
4576 [ # # # # ]: 0 : if( end_pt->partitioned_entity() == surface->partitioned_entity() &&
[ # # ]
4577 : 0 : end_pt->next_curve() == 0 )
4578 [ # # ]: 0 : delete end_pt;
4579 : : }
4580 : : }
4581 [ # # ][ # # ]: 0 : else if( SubCurve* subcurve = dynamic_cast<SubCurve*>(dead_curve) )
4582 : : {
4583 : 0 : restore_curve(subcurve);
4584 : : }
4585 : : }
4586 [ # # ]: 0 : delete dead_loop;
4587 : 0 : }
4588 [ # # ]: 0 : delete surface;
4589 : 0 : return CUBIT_SUCCESS;
4590 : : }
4591 : :
4592 : :
4593 : : //-------------------------------------------------------------------------
4594 : : // Purpose : Retreive entity from UID attrib data.
4595 : : //
4596 : : // Special Notes : Used when restoring saved geometry.
4597 : : //
4598 : : // Creator : Jason Kraftcheck
4599 : : //
4600 : : // Creation Date : 02/23/03
4601 : : //-------------------------------------------------------------------------
4602 : 0 : PartitionEntity* PartitionEngine::entity_from_id( int set_id,
4603 : : int entity_id,
4604 : : SubEntitySet& default_set )
4605 : : {
4606 [ # # ]: 0 : if( set_id == 0 )
4607 : 0 : return default_set.entity_from_id( entity_id );
4608 : :
4609 : 0 : SubEntitySet* set = get_from_id_map(set_id);
4610 [ # # ]: 0 : if( set )
4611 : 0 : return set->entity_from_id( entity_id );
4612 : :
4613 : 0 : return 0;
4614 : : }
4615 : :
4616 : : //-------------------------------------------------------------------------
4617 : : // Purpose : Restore curve partitions
4618 : : //
4619 : : // Special Notes :
4620 : : //
4621 : : // Creator : Jason Kraftcheck
4622 : : //
4623 : : // Creation Date : 02/23/03
4624 : : //-------------------------------------------------------------------------
4625 : 23275 : CubitStatus PartitionEngine::restore_from_attrib( Curve* curve )
4626 : : {
4627 : 23275 : int i, id, dim, max_id = 0;
4628 [ + - ][ + - ]: 46550 : DLIList<CubitSimpleAttrib> attribs, point_attribs, curve_attribs;
[ + - ][ + - ]
[ + - ]
4629 [ + - ][ + - ]: 46550 : DLIList<CubitVector*> empty;
4630 [ + - ][ + - ]: 46550 : DLIList<int> junk, point_conn;
[ + - ][ + - ]
4631 [ + - ][ + - ]: 46550 : DLIList<PartitionPoint*> new_points;
4632 : 23275 : CubitStatus result = CUBIT_FAILURE;
4633 : :
4634 : : {
4635 : : // Get list of partition attributes.
4636 [ + - ][ + - ]: 23275 : curve->get_simple_attribute(PARTITION_GEOM_ATTRIB_NAME,attribs);
[ + - ]
4637 [ + - ][ + - ]: 23275 : if( attribs.size() == 0 )
4638 : 23275 : return CUBIT_SUCCESS;
4639 : :
4640 : : // Group attributes into those defining partition points and
4641 : : // those defining the subcurves. Also find max ID of all
4642 : : // partition geometry on this curve
4643 [ # # ]: 0 : attribs.reset();
4644 [ # # ][ # # ]: 0 : for( i = attribs.size(); i--; )
4645 : : {
4646 [ # # ]: 0 : const CubitSimpleAttrib& attrib = attribs.get_and_step();
4647 [ # # ]: 0 : dim = SubEntitySet::get_geom_dimension(attrib);
4648 [ # # ]: 0 : if( dim == 0 )
4649 [ # # ]: 0 : point_attribs.append(attrib);
4650 [ # # ]: 0 : else if( dim == 1 )
4651 [ # # ]: 0 : curve_attribs.append(attrib);
4652 : : else
4653 : 0 : goto CLEANUP_CURVE_FROM_ATTRIB;
4654 : :
4655 [ # # ]: 0 : id = SubEntitySet::get_geom_id( attrib );
4656 [ # # ]: 0 : if( id > max_id )
4657 : 0 : max_id = id;
4658 : : }
4659 : :
4660 : : // Create first curve (duplicate of input curve)
4661 [ # # ]: 0 : PartitionCurve* first_curve = replace_curve( curve );
4662 [ # # ]: 0 : if( ! first_curve )
4663 : 0 : goto CLEANUP_CURVE_FROM_ATTRIB;
4664 : :
4665 : : // Set up SubEntitySet such that new entities get IDs
4666 : : // larger than max_id as they are created.
4667 [ # # ][ # # ]: 0 : first_curve->sub_entity_set().renumerate( max_id + 1, false );
4668 : :
4669 : : // Create all the partition points
4670 [ # # ]: 0 : point_attribs.reset();
4671 [ # # ][ # # ]: 0 : for( i = point_attribs.size(); i--; )
4672 : : {
4673 [ # # ]: 0 : const CubitSimpleAttrib& attrib = point_attribs.get_and_step();
4674 [ # # ][ # # ]: 0 : PartitionPoint* point = new PartitionPoint( attrib, first_curve );
[ # # ]
4675 [ # # ]: 0 : if( !point )
4676 : 0 : goto CLEANUP_CURVE_FROM_ATTRIB;
4677 : :
4678 [ # # ]: 0 : curve->remove_simple_attribute_virt(attrib);
4679 : : }
4680 : :
4681 : : // Now partition the curve and assign the ID from each
4682 : : // curve attribute the the appropriate curve partition.
4683 : : //
4684 : : // We're going to do this in order along the curve, such
4685 : : // that the first subcurve will begin at the start_point() of
4686 : : // the original curve.
4687 [ # # ]: 0 : PartitionPoint* prev_point = first_curve->start_point();
4688 : 0 : PartitionCurve* next_curve = first_curve;
4689 [ # # ][ # # ]: 0 : while( curve_attribs.size() )
4690 : : {
4691 : : // Search for attribute corresponding to curve
4692 : : // beginning at prev_point
4693 : 0 : PartitionPoint *start = 0, *end = 0;
4694 [ # # ]: 0 : CubitSimpleAttrib curve_attrib;
4695 [ # # ]: 0 : curve_attribs.last();
4696 [ # # ][ # # ]: 0 : for( i = curve_attribs.size(); i--; )
4697 : : {
4698 : : // Get data from attribute
4699 [ # # ]: 0 : const CubitSimpleAttrib& attrib = curve_attribs.step_and_get();
4700 [ # # ]: 0 : point_conn.clean_out();
4701 [ # # ][ # # ]: 0 : if( !SubEntitySet::read_geometry(id,dim,empty,junk,point_conn,junk,attrib)
4702 [ # # ][ # # ]: 0 : || empty.size() || junk.size() || dim != 1 || point_conn.size() != 4)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
4703 : 0 : goto CLEANUP_CURVE_FROM_ATTRIB;
4704 : :
4705 : : // Get start point from IDs
4706 [ # # ]: 0 : point_conn.reset();
4707 [ # # ]: 0 : int sid = point_conn.get_and_step();
4708 [ # # ]: 0 : int eid = point_conn.get_and_step();
4709 [ # # ][ # # ]: 0 : PartitionEntity* ent = entity_from_id(sid, eid, first_curve->sub_entity_set());
4710 [ # # ]: 0 : start = dynamic_cast<PartitionPoint*>(ent);
4711 : :
4712 [ # # ]: 0 : if( start == prev_point )
4713 : : {
4714 : : // Found the attrib we want.
4715 : : // Get the end point and break the loop.
4716 [ # # ]: 0 : sid = point_conn.get_and_step();
4717 [ # # ]: 0 : eid = point_conn.get_and_step();
4718 [ # # ][ # # ]: 0 : ent = entity_from_id(sid, eid, first_curve->sub_entity_set());
4719 [ # # ]: 0 : end = dynamic_cast<PartitionPoint*>(ent);
4720 : :
4721 [ # # ][ # # ]: 0 : curve_attrib = curve_attribs.extract();
[ # # ]
4722 : 0 : break;
4723 : : }
4724 : : }
4725 : :
4726 : : // Make sure we found an attrib to do
4727 [ # # ][ # # ]: 0 : if( curve_attrib.isEmpty() || !start || !end )
[ # # ][ # # ]
[ # # ]
4728 : 0 : goto CLEANUP_CURVE_FROM_ATTRIB;
4729 : :
4730 : : // Unless this is the last partition (no more splitting
4731 : : // required), split the curve at the end point. Make
4732 : : // next_curve point to the (unpartitioned) remainder of
4733 : : // the curve.
4734 : 0 : PartitionCurve* new_curve = next_curve;
4735 [ # # ][ # # ]: 0 : if( next_curve->end_point() != end )
4736 : : {
4737 [ # # ]: 0 : next_curve = insert_point( new_curve, end );
4738 [ # # ]: 0 : if( !next_curve )
4739 : 0 : goto CLEANUP_CURVE_FROM_ATTRIB;
4740 : : }
4741 : :
4742 : : // Set the new curve's ID to whatever it is stored
4743 : : // as in the attribute.
4744 [ # # ]: 0 : new_curve->sub_entity_set().set_id( new_curve,
4745 [ # # ][ # # ]: 0 : SubEntitySet::get_geom_id( curve_attrib ) );
[ # # ]
4746 : :
4747 : : // Remove processed attributes.
4748 [ # # ]: 0 : curve->remove_simple_attribute_virt( curve_attrib );
4749 : :
4750 : : // Next iteration
4751 [ # # ][ # # ]: 0 : prev_point = end;
4752 : 0 : }
4753 : :
4754 : : // Compress SubEntitySet ID space
4755 [ # # ][ # # ]: 0 : next_curve->sub_entity_set().renumerate( max_id + 1, true );
4756 : 0 : result = CUBIT_SUCCESS;
4757 : : }
4758 : :
4759 : : CLEANUP_CURVE_FROM_ATTRIB:
4760 : :
4761 [ # # ][ # # ]: 0 : for( i = new_points.size(); i--; )
4762 : : {
4763 [ # # ]: 0 : PartitionPoint* pt = new_points.get_and_step();
4764 [ # # ][ # # ]: 0 : if( !pt->next_curve(0) )
4765 [ # # ][ # # ]: 0 : delete pt;
4766 : : }
4767 : :
4768 [ # # ]: 0 : if (!result)
4769 [ # # ][ # # ]: 0 : PRINT_ERROR("Error restoring curve partitions from attributes.\n");
[ # # ][ # # ]
4770 : :
4771 [ + - ]: 23275 : return result;
4772 : : }
4773 : :
4774 : :
4775 : : //-------------------------------------------------------------------------
4776 : : // Purpose : Restore surface partitions
4777 : : //
4778 : : // Special Notes :
4779 : : //
4780 : : // Creator : Jason Kraftcheck
4781 : : //
4782 : : // Creation Date : 02/23/03
4783 : : //-------------------------------------------------------------------------
4784 : 11189 : CubitStatus PartitionEngine::restore_from_attrib( Surface* surf )
4785 : : {
4786 : 11189 : int i, j, k, id, dim, max_id = 0;
4787 [ + - ]: 11189 : DLIList<CubitSimpleAttrib> attribs;
4788 [ + - ][ + - ]: 22378 : DLIList<CubitFacetEdgeData*> polyline_edges;
4789 [ + - ][ + - ]: 22378 : DLIList<CubitPointData*> polyline_pts;
4790 [ + - ][ + - ]: 22378 : DLIList<CubitFacetData*> surf_facets;
4791 [ + - ][ + - ]: 22378 : DLIList<CubitVector*> positions;
4792 [ + - ][ + - ]: 22378 : DLIList<PartitionEntity*> new_geom;
4793 [ + - ][ + - ]: 22378 : DLIList<PartitionLoop*> loops;
4794 [ + - ][ + - ]: 22378 : DLIList<int> facets(0), connectivity, pt_owners;
[ + - ][ + - ]
[ + - ][ + - ]
4795 : 11189 : CubitStatus result = CUBIT_FAILURE;
4796 : 11189 : SubSurface* first_surf = 0;
4797 : :
4798 : :
4799 : : {
4800 : : // Get partition attributes from entity. Return if there aren't any.
4801 [ + - ][ + - ]: 11189 : surf->get_simple_attribute(PARTITION_GEOM_ATTRIB_NAME,attribs);
[ + - ]
4802 [ + - ][ + - ]: 11189 : if( attribs.size() == 0 )
4803 : 11189 : return CUBIT_SUCCESS;
4804 : :
4805 [ # # ][ # # ]: 0 : PRINT_DEBUG_86("Reading partition geometry on %s %p\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4806 [ # # ]: 0 : fix_type_name( typeid(*surf).name() ), (void*)surf );
4807 : :
4808 : : // Find max ID
4809 [ # # ]: 0 : attribs.reset();
4810 [ # # ][ # # ]: 0 : for( i = attribs.size(); i--; )
4811 : : {
4812 [ # # ][ # # ]: 0 : id = SubEntitySet::get_geom_id( attribs.get_and_step() );
4813 [ # # ]: 0 : if( id > max_id )
4814 : 0 : max_id = id;
4815 : : }
4816 : :
4817 : : // Create first partition surface (initially a duplicate of
4818 : : // the input surface)
4819 [ # # ]: 0 : first_surf = replace_surface( surf );
4820 [ # # ]: 0 : if( ! first_surf )
4821 : : {
4822 [ # # ][ # # ]: 0 : PRINT_ERROR("Internal Error: PartitionEngine::replace_surface() failed.\n");
[ # # ][ # # ]
4823 : 0 : goto CLEANUP_SURF_FROM_ATTRIB;
4824 : : }
4825 : :
4826 : : // Update SubEntitySet such that new entities get assigned
4827 : : // IDs greater than max_id when they are created. This
4828 : : // leaves the range 0->max_id free so that we can reassign
4829 : : // the saved IDs after the entities are created.
4830 [ # # ][ # # ]: 0 : first_surf->sub_entity_set().renumerate( max_id + 1, false );
4831 : :
4832 : : // create all interior vertices
4833 [ # # ]: 0 : attribs.reset();
4834 [ # # ][ # # ]: 0 : for( i = attribs.size(); i--; )
4835 : : {
4836 : : // Only want point attributes (dimension of zero)
4837 [ # # ][ # # ]: 0 : CubitSimpleAttrib attrib = attribs.get();
4838 [ # # ][ # # ]: 0 : if( SubEntitySet::get_geom_dimension(attrib) != 0 )
4839 : : {
4840 [ # # ]: 0 : attribs.step();
4841 : 0 : continue;
4842 : : }
4843 : :
4844 : : // Create the point at the location specified in the attrib.
4845 [ # # ][ # # ]: 0 : attribs.extract();
4846 [ # # ]: 0 : surf->remove_simple_attribute_virt(attrib);
4847 [ # # ][ # # ]: 0 : PartitionPoint* new_pt = new PartitionPoint( attrib, first_surf );
[ # # ]
4848 [ # # ][ # # ]: 0 : CubitPointData* data = project_to_surface( first_surf, new_pt->coordinates() );
4849 [ # # ]: 0 : new_pt->facet_point(data);
4850 [ # # ][ # # ]: 0 : new_geom.append(new_pt);
4851 [ # # ][ # # ]: 0 : PRINT_DEBUG_86(" Created Point %p (%d in subset) at (%f,%f,%f)\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4852 : : (void*)new_pt, new_pt->sub_entity_set().get_id(new_pt),
4853 : : new_pt->coordinates().x(), new_pt->coordinates().y(),
4854 [ # # ]: 0 : new_pt->coordinates().z() );
4855 [ # # ][ # # ]: 0 : if (DEBUG_FLAG(86))
[ # # ]
4856 : : {
4857 [ # # ][ # # ]: 0 : GfxDebug::draw_point(new_pt->coordinates(), new_pt->sub_entity_set().get_id(new_pt));
[ # # ][ # # ]
[ # # ]
4858 [ # # ][ # # ]: 0 : GfxDebug::flush();
[ # # ]
4859 : : }
4860 : 0 : }
4861 : :
4862 : : // create all interior curves
4863 [ # # ]: 0 : attribs.reset();
4864 [ # # ][ # # ]: 0 : for( i = attribs.size(); i--; )
4865 : : {
4866 : : // Only want curve attributes (dimension of one)
4867 [ # # ][ # # ]: 0 : CubitSimpleAttrib attrib = attribs.get();
4868 [ # # ][ # # ]: 0 : if( SubEntitySet::get_geom_dimension(attrib) != 1 )
4869 : : {
4870 [ # # ]: 0 : attribs.step();
4871 : 0 : continue;
4872 : : }
4873 : :
4874 : : // Remove this attrib from the real geom, as we are
4875 : : // handling it
4876 [ # # ][ # # ]: 0 : attribs.extract();
4877 [ # # ]: 0 : surf->remove_simple_attribute_virt(attrib);
4878 : :
4879 [ # # ][ # # ]: 0 : if ( SubEntitySet::get_segment_count(attrib) == 0 )
4880 : : {
4881 [ # # ]: 0 : PartPTCurve* pt_curve = PartPTCurve::construct(attrib, first_surf);
4882 [ # # ]: 0 : if (!pt_curve)
4883 : : {
4884 [ # # ][ # # ]: 0 : PRINT_ERROR("point-curve construction failed -- corrupt data?\n");
[ # # ][ # # ]
4885 : 0 : goto CLEANUP_SURF_FROM_ATTRIB;
4886 : : }
4887 [ # # ][ # # ]: 0 : new_geom.append( pt_curve );
4888 [ # # ][ # # ]: 0 : PRINT_DEBUG_86(" Created point-curve %p (%d in subset) with\n"
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
4889 : : " point %p (%d in subset) at (%f,%f,%f)\n",
4890 : : (void*)pt_curve,
4891 : : pt_curve->sub_entity_set().get_id(pt_curve),
4892 : : (void*)pt_curve->start_point(),
4893 : : pt_curve->start_point()->sub_entity_set().get_id(pt_curve->start_point()),
4894 : : pt_curve->start_point()->coordinates().x(),
4895 : : pt_curve->start_point()->coordinates().y(),
4896 [ # # ]: 0 : pt_curve->start_point()->coordinates().z() );
4897 : :
4898 [ # # ][ # # ]: 0 : CubitPointData* pt = project_to_surface( first_surf, pt_curve->start_point()->coordinates() );
[ # # ]
4899 [ # # ]: 0 : if ( !pt )
4900 : : {
4901 [ # # ][ # # ]: 0 : PRINT_ERROR("projection of position onto surface facets failed.\n");
[ # # ][ # # ]
4902 : 0 : goto CLEANUP_SURF_FROM_ATTRIB;
4903 : : }
4904 : :
4905 [ # # ][ # # ]: 0 : pt_curve->start_point()->facet_point( pt );
4906 : 0 : continue;
4907 : : }
4908 : :
4909 : : // Create the curve
4910 [ # # ][ # # ]: 0 : SegmentedCurve* new_curve = SegmentedCurve::construct( attrib, first_surf );
4911 [ # # ]: 0 : if( !new_curve )
4912 : : {
4913 [ # # ][ # # ]: 0 : PRINT_ERROR("segmented curve construction failed -- corrupt data?\n");
[ # # ][ # # ]
4914 : 0 : goto CLEANUP_SURF_FROM_ATTRIB;
4915 : : }
4916 [ # # ][ # # ]: 0 : new_geom.append(new_curve);
4917 [ # # ][ # # ]: 0 : PRINT_DEBUG_86(" Created polyline curve %p (%d in subset) with %d segments.\n"
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
4918 : : " start point %p (%d in subset) at (%f,%f,%f)\n"
4919 : : " end point %p (%d in subset) at (%f,%f,%f)\n",
4920 : : (void*)new_curve,
4921 : : new_curve->sub_entity_set().get_id(new_curve),
4922 : : new_curve->point_count() - 1,
4923 : : (void*)new_curve->start_point(),
4924 : : new_curve->start_point()->sub_entity_set().get_id(new_curve->start_point()),
4925 : : new_curve->start_point()->coordinates().x(),
4926 : : new_curve->start_point()->coordinates().y(),
4927 : : new_curve->start_point()->coordinates().z(),
4928 : : (void*)new_curve->end_point(),
4929 : : new_curve->end_point()->sub_entity_set().get_id(new_curve->end_point()),
4930 : : new_curve->end_point()->coordinates().x(),
4931 : : new_curve->end_point()->coordinates().y(),
4932 [ # # ]: 0 : new_curve->end_point()->coordinates().z() );
4933 : :
4934 : : // Get curve segments
4935 [ # # ]: 0 : positions.clean_out();
4936 [ # # ]: 0 : polyline_edges.clean_out();
4937 [ # # ]: 0 : new_curve->get_segments( positions );
4938 : :
4939 [ # # ][ # # ]: 0 : if (DEBUG_FLAG(86))
[ # # ]
4940 : : {
4941 [ # # ][ # # ]: 0 : GPoint* array = new GPoint[positions.size()];
[ # # ]
4942 [ # # ]: 0 : positions.reset();
4943 [ # # ][ # # ]: 0 : for (int dd = 0; dd < positions.size(); dd++ )
4944 : : {
4945 [ # # ][ # # ]: 0 : array[dd].x = (float)positions.next(dd)->x();
4946 [ # # ][ # # ]: 0 : array[dd].y = (float)positions.next(dd)->y();
4947 [ # # ][ # # ]: 0 : array[dd].z = (float)positions.next(dd)->z();
4948 : : }
4949 : :
4950 : : GfxDebug::draw_polyline(array, positions.size(),
4951 [ # # ][ # # ]: 0 : new_curve->sub_entity_set().get_id(new_curve));
[ # # ][ # # ]
[ # # ]
4952 [ # # ]: 0 : GfxDebug::flush();
4953 : : }
4954 : :
4955 : : // Make sure segment end points are on curve end points
4956 [ # # ]: 0 : positions.last();
4957 [ # # ][ # # ]: 0 : *positions.get() = new_curve->end_point()->coordinates();
[ # # ][ # # ]
4958 [ # # ]: 0 : positions.reset();
4959 [ # # ][ # # ]: 0 : *positions.get() = new_curve->start_point()->coordinates();
[ # # ][ # # ]
4960 : :
4961 : : // Project curve into surface facets
4962 [ # # ]: 0 : surf_facets.clean_out();
4963 [ # # ]: 0 : first_surf->get_facet_data( surf_facets );
4964 : : CubitStatus s = project_to_surface( surf_facets, positions,
4965 [ # # ]: 0 : polyline_edges, polyline_pts );
4966 [ # # ][ # # ]: 0 : while( positions.size() )
4967 : : {
4968 [ # # ]: 0 : CubitVector* position = positions.pop();
4969 [ # # ]: 0 : if(s)
4970 : : {
4971 : : // assert(polyline_pts.size());
4972 [ # # ]: 0 : CubitPointData* point = polyline_pts.pop();
4973 [ # # ][ # # ]: 0 : if (point && point->check_inverted_facets(*position))
[ # # ][ # # ]
4974 [ # # ]: 0 : point->set(*position);
4975 : : }
4976 : 0 : delete position;
4977 : : }
4978 [ # # ][ # # ]: 0 : if( !s || !polyline_edges.size() )
[ # # ][ # # ]
4979 : : {
4980 [ # # ][ # # ]: 0 : PRINT_ERROR("Imprint of polyline onto surface facets failed.\n");
[ # # ][ # # ]
4981 : 0 : goto CLEANUP_SURF_FROM_ATTRIB;
4982 : : }
4983 : :
4984 : :
4985 : : // move facet points onto surface
4986 [ # # ]: 0 : for ( j = 0; j < 2; j++ )
4987 [ # # ][ # # ]: 0 : for ( k = polyline_edges.size(); k--; )
4988 [ # # ][ # # ]: 0 : if ( CubitFacetEdgeData* edge = polyline_edges.get_and_step() )
4989 [ # # ][ # # ]: 0 : edge->point(j)->marked(1);
4990 : :
4991 [ # # ][ # # ]: 0 : for ( j = polyline_edges.size(); j--; )
4992 : : {
4993 [ # # ]: 0 : CubitFacetEdgeData* edge = polyline_edges.get_and_step();
4994 [ # # ]: 0 : if ( !edge ) continue;
4995 [ # # ]: 0 : for ( k = 0; k < 2; k++ )
4996 : : {
4997 [ # # ]: 0 : CubitPoint* pt = edge->point(k);
4998 [ # # ][ # # ]: 0 : if ( pt->marked() )
4999 : : {
5000 [ # # ]: 0 : pt->marked(0);
5001 [ # # ]: 0 : first_surf->relax_to_geometry(pt);
5002 : : }
5003 : : }
5004 : : }
5005 : :
5006 : :
5007 : : // Associate facet data with geometry
5008 : :
5009 : : CubitPoint *last_pt, *first_pt;
5010 [ # # ]: 0 : polyline_edges.last();
5011 [ # # ][ # # ]: 0 : assert(!polyline_edges.get());
5012 [ # # ]: 0 : polyline_edges.pop();
5013 : :
5014 [ # # ][ # # ]: 0 : if( polyline_edges.size() == 1 )
5015 : : {
5016 [ # # ][ # # ]: 0 : last_pt = polyline_edges.get()->point(1);
5017 [ # # ][ # # ]: 0 : first_pt = polyline_edges.get()->point(0);
5018 : : }
5019 : : else
5020 : : {
5021 : : CubitFacetEdgeData *edge, *neighbor;
5022 : :
5023 [ # # ]: 0 : polyline_edges.last();
5024 [ # # ]: 0 : edge = polyline_edges.get();
5025 [ # # ]: 0 : neighbor = polyline_edges.prev();
5026 [ # # ][ # # ]: 0 : if( !edge || !neighbor )
5027 : : {
5028 [ # # ][ # # ]: 0 : PRINT_ERROR("Bad surface facets.\n");
[ # # ][ # # ]
5029 : 0 : goto CLEANUP_SURF_FROM_ATTRIB;
5030 : : }
5031 [ # # ]: 0 : last_pt = edge->shared_point(neighbor);
5032 [ # # ]: 0 : last_pt = edge->other_point(last_pt);
5033 : :
5034 [ # # ]: 0 : polyline_edges.reset();
5035 [ # # ]: 0 : edge = polyline_edges.get();
5036 [ # # ]: 0 : neighbor = polyline_edges.next();
5037 [ # # ][ # # ]: 0 : if( !edge || !neighbor )
5038 : : {
5039 [ # # ][ # # ]: 0 : PRINT_ERROR("Bad surface facets.\n");
[ # # ][ # # ]
5040 : 0 : goto CLEANUP_SURF_FROM_ATTRIB;
5041 : : }
5042 [ # # ]: 0 : first_pt = edge->shared_point(neighbor);
5043 [ # # ]: 0 : first_pt = edge->other_point(first_pt);
5044 : : }
5045 : :
5046 [ # # ]: 0 : PartitionEntity* owner1 = TDVGFacetOwner::get( first_pt );
5047 [ # # ]: 0 : PartitionEntity* owner2 = TDVGFacetOwner::get( last_pt );
5048 : :
5049 [ # # ][ # # ]: 0 : if ( new_curve->start_point() == new_curve->end_point() )
[ # # ]
5050 : : {
5051 [ # # ][ # # ]: 0 : if ( owner1 == owner2 && owner1 == new_curve->start_point() )
[ # # ][ # # ]
[ # # ]
5052 : : {
5053 [ # # ][ # # ]: 0 : first_pt = polyline_edges.get()->other_point( first_pt );
5054 [ # # ]: 0 : polyline_edges.last();
5055 [ # # ][ # # ]: 0 : last_pt = polyline_edges.get()->other_point( last_pt );
5056 [ # # ][ # # ]: 0 : double u1 = new_curve->u_from_position( first_pt->coordinates() );
5057 [ # # ][ # # ]: 0 : double u2 = new_curve->u_from_position( last_pt->coordinates() );
5058 [ # # ]: 0 : if ( u2 < u1 )
5059 [ # # ]: 0 : polyline_edges.reverse();
5060 [ # # ]: 0 : polyline_edges.reset();
5061 : : }
5062 : : else
5063 : : {
5064 : 0 : s = CUBIT_FAILURE;
5065 : : }
5066 : : }
5067 [ # # ][ # # ]: 0 : else if ( owner1 == new_curve->end_point() &&
[ # # ][ # # ]
[ # # ]
5068 [ # # ][ # # ]: 0 : owner2 == new_curve->start_point() )
5069 : : {
5070 [ # # ]: 0 : polyline_edges.reverse();
5071 [ # # ]: 0 : polyline_edges.reset();
5072 : : }
5073 [ # # ][ # # ]: 0 : else if( owner1 != new_curve->start_point() ||
[ # # ][ # # ]
[ # # ]
5074 [ # # ][ # # ]: 0 : owner2 != new_curve->end_point() )
5075 : : {
5076 : 0 : s = CUBIT_FAILURE;
5077 : : }
5078 : :
5079 [ # # ]: 0 : if (!s)
5080 : : {
5081 [ # # ][ # # ]: 0 : PRINT_ERROR("Tolerance problems when restoring surface partitions.\n");
[ # # ][ # # ]
5082 : 0 : goto CLEANUP_SURF_FROM_ATTRIB;
5083 : : }
5084 : :
5085 [ # # ][ # # ]: 0 : new_curve->set_facet_data( polyline_edges );
[ # # # ]
5086 : 0 : }
5087 : :
5088 : : // while there are more surface partitions to create
5089 : 0 : PartitionEntity* ent = 0;
5090 [ # # ][ # # ]: 0 : while( attribs.size() )
5091 : : {
5092 : : // read attribute
5093 [ # # ]: 0 : CubitSimpleAttrib surf_attr = attribs.pop();
5094 [ # # ]: 0 : connectivity.clean_out();
5095 : : CubitStatus s = SubEntitySet::
5096 [ # # ]: 0 : read_geometry( id, dim, positions, facets, connectivity, pt_owners, surf_attr );
5097 : :
5098 [ # # ][ # # ]: 0 : if( !s || dim != 2 || positions.size() || facets.size() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5099 : : {
5100 [ # # ][ # # ]: 0 : PRINT_ERROR("Corrupt/inconsistent subsurface data.\n");
[ # # ][ # # ]
5101 : 0 : goto CLEANUP_SURF_FROM_ATTRIB;
5102 : : }
5103 : :
5104 [ # # ][ # # ]: 0 : PRINT_DEBUG_86(" Constructing SubSurface (%d in subset)\n", id);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5105 : :
5106 : : // construct surface loops
5107 [ # # ]: 0 : int j = connectivity.size();
5108 : 0 : PartitionCoEdge* curve_coedge = 0; // save one non-point-curve coedge
5109 [ # # ]: 0 : while ( j > 0 )
5110 : : {
5111 [ # # ]: 0 : int loop = connectivity.get_and_step();
5112 : 0 : j--;
5113 : :
5114 [ # # ][ # # ]: 0 : PartitionLoop* new_loop = new PartitionLoop();
5115 [ # # ]: 0 : loops.append( new_loop );
5116 : 0 : PartitionCoEdge* prev_coedge = 0;
5117 [ # # ][ # # ]: 0 : PRINT_DEBUG_86(" Loop: ");
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5118 : :
5119 [ # # ]: 0 : while( loop-- )
5120 : : {
5121 [ # # ]: 0 : int set_id = connectivity.get_and_step();
5122 [ # # ]: 0 : int ent_id = connectivity.get_and_step();
5123 [ # # ]: 0 : int sense = ent_id < 0 ? -1 : 1;
5124 : 0 : ent_id *= sense;
5125 : 0 : j -= 2;
5126 : :
5127 [ # # ][ # # ]: 0 : ent = entity_from_id( set_id, ent_id, first_surf->sub_entity_set() );
5128 [ # # ]: 0 : PartitionCurve* curve = dynamic_cast<PartitionCurve*>(ent);
5129 [ # # ][ # # ]: 0 : PRINT_DEBUG_86(" %p,%d,%d%c", (void*)curve, set_id, ent_id*sense, loop?',':'\n');
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5130 [ # # ]: 0 : if(!curve)
5131 : : {
5132 [ # # ][ # # ]: 0 : PRINT_ERROR("Nonexistant curve specified in saved connectivity.\n");
[ # # ][ # # ]
5133 : 0 : goto CLEANUP_SURF_FROM_ATTRIB;
5134 : : }
5135 : :
5136 [ # # ]: 0 : CubitSense cubit_sense = sense == -1 ? CUBIT_REVERSED : CUBIT_FORWARD;
5137 : 0 : PartitionCoEdge* coedge = 0;
5138 [ # # ][ # # ]: 0 : while ( (coedge = curve->next_coedge(coedge)) )
5139 : : {
5140 [ # # ][ # # ]: 0 : if ( coedge->sense() == cubit_sense &&
[ # # ]
5141 [ # # ][ # # ]: 0 : coedge->get_loop() &&
[ # # ]
5142 [ # # ][ # # ]: 0 : coedge->get_loop()->get_surface() == first_surf )
5143 : : {
5144 [ # # ][ # # ]: 0 : coedge->get_loop()->remove( coedge );
5145 : 0 : break;
5146 : : }
5147 : : }
5148 [ # # ]: 0 : if ( !coedge )
5149 : : {
5150 [ # # ][ # # ]: 0 : coedge = new PartitionCoEdge( first_surf, cubit_sense );
5151 [ # # ]: 0 : curve->add(coedge);
5152 : : }
5153 : :
5154 [ # # ][ # # ]: 0 : if (!curve_coedge && curve->geometry_type() != POINT_CURVE_TYPE)
[ # # ][ # # ]
5155 : 0 : curve_coedge = coedge;
5156 : :
5157 [ # # ]: 0 : new_loop->insert_after( coedge, prev_coedge );
5158 : 0 : prev_coedge = coedge;
5159 : : }
5160 : : }
5161 : :
5162 [ # # ]: 0 : if (!curve_coedge)
5163 : : {
5164 [ # # ][ # # ]: 0 : PRINT_ERROR("Nonexistant co-edge specified in saved connectivity.\n");
[ # # ][ # # ]
5165 : 0 : goto CLEANUP_SURF_FROM_ATTRIB;
5166 : : }
5167 : :
5168 [ # # ]: 0 : PartitionSurface* new_surf = split_surface( first_surf, curve_coedge );
5169 [ # # ][ # # ]: 0 : if (new_surf == first_surf && attribs.size() > 0)
[ # # ][ # # ]
5170 : : {
5171 [ # # ][ # # ]: 0 : PRINT_ERROR("Surface splitting failed -- bad topology?.\n");
[ # # ][ # # ]
5172 : 0 : goto CLEANUP_SURF_FROM_ATTRIB;
5173 : : }
5174 : :
5175 [ # # ][ # # ]: 0 : new_surf->sub_entity_set().set_id( new_surf, id );
[ # # ]
5176 [ # # ][ # # ]: 0 : while ( loops.size() )
[ # # ][ # # ]
5177 [ # # ][ # # ]: 0 : new_surf->add( loops.pop() );
5178 : 0 : }
5179 : :
5180 : 0 : result = CUBIT_SUCCESS;
5181 : : }
5182 : :
5183 : : CLEANUP_SURF_FROM_ATTRIB:
5184 : :
5185 : : // clean up any unused loops from failed surface creation
5186 [ # # ][ # # ]: 0 : while ( loops.size() )
5187 : : {
5188 [ # # ]: 0 : PartitionLoop* loop = loops.pop();
5189 [ # # ][ # # ]: 0 : while ( loop->first_coedge() )
5190 : : {
5191 [ # # ]: 0 : PartitionCoEdge* coedge = loop->first_coedge();
5192 [ # # ]: 0 : loop->remove(coedge);
5193 [ # # ][ # # ]: 0 : if (coedge->get_curve())
5194 [ # # ][ # # ]: 0 : coedge->get_curve()->remove(coedge);
5195 [ # # ][ # # ]: 0 : delete coedge;
5196 : : }
5197 [ # # ][ # # ]: 0 : delete loop;
5198 : : }
5199 : :
5200 : : // first_surf will contain dead loops - clean them up
5201 : 0 : PartitionLoop* surf_loop = 0;
5202 [ # # ][ # # ]: 0 : while ( (surf_loop = first_surf->next_loop( surf_loop ) ) != NULL )
5203 [ # # ][ # # ]: 0 : if ( !surf_loop->first_coedge() )
5204 [ # # ]: 0 : loops.append( surf_loop );
5205 [ # # ][ # # ]: 0 : while ( loops.size() )
5206 : : {
5207 [ # # ]: 0 : surf_loop = loops.pop();
5208 [ # # ]: 0 : first_surf->remove( surf_loop );
5209 [ # # ][ # # ]: 0 : delete surf_loop;
5210 : : }
5211 : :
5212 [ # # ]: 0 : new_geom.reset();
5213 [ # # ][ # # ]: 0 : while( new_geom.size() )
5214 : : {
5215 [ # # ]: 0 : PartitionEntity* ent = new_geom.pop();
5216 [ # # ][ # # ]: 0 : if( PartitionPoint* pt = dynamic_cast<PartitionPoint*>(ent) )
5217 : : {
5218 [ # # ][ # # ]: 0 : if( !pt->next_curve(0) )
5219 [ # # ][ # # ]: 0 : delete pt;
5220 : : }
5221 [ # # ][ # # ]: 0 : else if( PartitionCurve* curve = dynamic_cast<PartitionCurve*>(ent) )
5222 : : {
5223 [ # # ][ # # ]: 0 : if( !curve->next_coedge(0) )
5224 [ # # ][ # # ]: 0 : delete curve;
5225 : : }
5226 : : }
5227 : :
5228 [ # # ][ # # ]: 0 : first_surf->sub_entity_set().renumerate( max_id + 1, true );
5229 : :
5230 [ # # ]: 0 : if (!result)
5231 [ # # ][ # # ]: 0 : PRINT_ERROR("Error restoring surface partitions from attributes.\n");
[ # # ][ # # ]
5232 : :
5233 [ + - ]: 11189 : return result;
5234 : : }
5235 : :
5236 : : //-------------------------------------------------------------------------
5237 : : // Purpose : Restore volume partitions from an attribute
5238 : : //
5239 : : // Special Notes :
5240 : : //
5241 : : // Creator : Jason Kraftcheck
5242 : : //
5243 : : // Creation Date : 01/22/03
5244 : : //-------------------------------------------------------------------------
5245 : 1613 : CubitStatus PartitionEngine::restore_from_attrib( Lump* lump )
5246 : : {
5247 : 1613 : int i, id, dim, max_id = 0;
5248 [ + - ]: 1613 : DLIList<CubitSimpleAttrib> attribs;
5249 [ + - ][ + - ]: 3226 : DLIList<CubitVector*> positions;
5250 [ + - ][ + - ]: 3226 : DLIList<int> facets, connectivity, pt_owners;
[ + - ][ + - ]
[ + - ][ + - ]
5251 [ + - ][ + - ]: 3226 : DLIList<PartitionEntity*> new_geom;
5252 : 1613 : CubitStatus result = CUBIT_FAILURE;
5253 : 1613 : PartitionLump* first_lump = 0;
5254 : 1613 : PartitionLump* new_lump = 0;
5255 : :
5256 : : { // pseudo-'try'-block
5257 : :
5258 : : // get partition attributes from entity. Return if none.
5259 [ + - ][ + - ]: 1613 : lump->get_simple_attribute(PARTITION_GEOM_ATTRIB_NAME,attribs);
[ + - ]
5260 [ + - ][ + - ]: 1613 : if( attribs.size() == 0 )
5261 : 1613 : return CUBIT_SUCCESS;
5262 : :
5263 : : // find max ID
5264 [ # # ]: 0 : attribs.reset();
5265 [ # # ][ # # ]: 0 : for( i = attribs.size(); i--; )
5266 : : {
5267 [ # # ][ # # ]: 0 : id = SubEntitySet::get_geom_id( attribs.get_and_step() );
5268 [ # # ]: 0 : if( id > max_id )
5269 : 0 : max_id = id;
5270 : : }
5271 : :
5272 : : // Create first parition lump (initially a duplicate of
5273 : : // the input lump)
5274 [ # # ]: 0 : first_lump = replace_lump( lump );
5275 [ # # ]: 0 : if( ! first_lump )
5276 : 0 : goto CLEANUP_LUMP_FROM_ATTRIB;
5277 : :
5278 : : // Update SubEntitySet such that new entities get assigned
5279 : : // IDs greater than max_id when they are created. This
5280 : : // leaves the range 0->max_id free so that we can reassign
5281 : : // the saved IDs after the entities are created.
5282 [ # # ][ # # ]: 0 : first_lump->sub_entity_set().renumerate( max_id + 1, false );
5283 : :
5284 : : // create all interior vertices
5285 [ # # ]: 0 : attribs.reset();
5286 [ # # ][ # # ]: 0 : for( i = attribs.size(); i--; )
5287 : : {
5288 : : // skip any non-point geometry
5289 [ # # ][ # # ]: 0 : CubitSimpleAttrib attrib = attribs.get();
5290 [ # # ][ # # ]: 0 : if( SubEntitySet::get_geom_dimension(attrib) != 0 )
5291 : : {
5292 [ # # ]: 0 : attribs.step();
5293 : 0 : continue;
5294 : : }
5295 : :
5296 : : // create the point as specified in the attrib
5297 [ # # ][ # # ]: 0 : attribs.extract();
5298 [ # # ]: 0 : lump->remove_simple_attribute_virt(attrib);
5299 [ # # ][ # # ]: 0 : PartitionPoint* new_pt = new PartitionPoint( attrib, first_lump );
[ # # ]
5300 [ # # ][ # # ]: 0 : new_geom.append(new_pt);
[ # # ][ # # ]
5301 : 0 : }
5302 : :
5303 : : // create all interior curves
5304 [ # # ]: 0 : attribs.reset();
5305 [ # # ][ # # ]: 0 : for( i = attribs.size(); i--; )
5306 : : {
5307 : : // skip attribs for anything but curves
5308 [ # # ][ # # ]: 0 : CubitSimpleAttrib attrib = attribs.get();
5309 [ # # ][ # # ]: 0 : if( SubEntitySet::get_geom_dimension(attrib) != 1 )
5310 : : {
5311 [ # # ]: 0 : attribs.step();
5312 : 0 : continue;
5313 : : }
5314 : :
5315 : : // create curve from attrib
5316 [ # # ][ # # ]: 0 : attribs.extract();
5317 [ # # ]: 0 : lump->remove_simple_attribute_virt(attrib);
5318 [ # # ][ # # ]: 0 : SegmentedCurve* new_curve = SegmentedCurve::construct( attrib, first_lump );
5319 [ # # ]: 0 : if( !new_curve )
5320 : 0 : goto CLEANUP_LUMP_FROM_ATTRIB;
5321 : :
5322 [ # # ][ # # ]: 0 : new_geom.append(new_curve);
[ # # ]
[ # # # ]
5323 : 0 : }
5324 : :
5325 : : // create all interior surfaces
5326 [ # # ]: 0 : attribs.reset();
5327 [ # # ][ # # ]: 0 : for( i = attribs.size(); i--; )
5328 : : {
5329 : : // skip non-surface attributes
5330 [ # # ][ # # ]: 0 : CubitSimpleAttrib attrib = attribs.get();
5331 [ # # ][ # # ]: 0 : if( SubEntitySet::get_geom_dimension(attrib) != 2 )
5332 : : {
5333 [ # # ]: 0 : attribs.step();
5334 : 0 : continue;
5335 : : }
5336 : :
5337 : : // create surface from attribute
5338 [ # # ][ # # ]: 0 : attribs.extract();
5339 [ # # ]: 0 : lump->remove_simple_attribute_virt(attrib);
5340 [ # # ]: 0 : PartitionSurface* new_surf = PartitionSurface::construct( attrib, first_lump );
5341 [ # # ]: 0 : if( !new_surf )
5342 : 0 : goto CLEANUP_LUMP_FROM_ATTRIB;
5343 : :
5344 [ # # ][ # # ]: 0 : new_geom.append(new_surf);
[ # # ]
[ # # # ]
5345 : 0 : }
5346 : :
5347 : :
5348 : : // while there are more volume partitions to create
5349 : 0 : PartitionEntity* ent = 0;
5350 [ # # ][ # # ]: 0 : while( attribs.size() )
5351 : : {
5352 : : // Read data from attribute
5353 [ # # ]: 0 : const CubitSimpleAttrib& attr = attribs.pop();
5354 [ # # ]: 0 : connectivity.clean_out();
5355 : : CubitStatus s = SubEntitySet::
5356 [ # # ]: 0 : read_geometry( id, dim, positions, facets, connectivity, pt_owners, attr );
5357 [ # # ][ # # ]: 0 : if( !s || dim != 3 || positions.size() || facets.size() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5358 : : {
5359 : 0 : new_lump = 0;
5360 : 0 : goto CLEANUP_LUMP_FROM_ATTRIB;
5361 : : }
5362 : :
5363 [ # # ][ # # ]: 0 : new_lump = new PartitionLump( first_lump );
5364 : :
5365 : : // Get list of bounding co-surfaces from attrib data
5366 [ # # ]: 0 : int j = connectivity.size();
5367 [ # # ]: 0 : while( j > 0 )
5368 : : {
5369 [ # # ]: 0 : int shell = connectivity.get_and_step();
5370 : 0 : j--;
5371 [ # # ][ # # ]: 0 : PartitionShell* new_shell = new PartitionShell();
5372 [ # # ]: 0 : new_lump->add(new_shell);
5373 [ # # ]: 0 : while( shell-- )
5374 : : {
5375 [ # # ]: 0 : int set_id = connectivity.get_and_step();
5376 [ # # ]: 0 : int ent_id = connectivity.get_and_step();
5377 : 0 : j -= 2;
5378 : :
5379 : 0 : CubitSense sense = CUBIT_FORWARD;
5380 [ # # ]: 0 : if ( ent_id < 0 )
5381 : : {
5382 : 0 : ent_id = -ent_id;
5383 : 0 : sense = CUBIT_REVERSED;
5384 : : }
5385 : :
5386 [ # # ][ # # ]: 0 : ent = entity_from_id( set_id, ent_id, first_lump->sub_entity_set() );
5387 [ # # ]: 0 : PartitionSurface* surf = dynamic_cast<PartitionSurface*>(ent);
5388 [ # # ]: 0 : if(!surf)
5389 : 0 : goto CLEANUP_LUMP_FROM_ATTRIB;
5390 : :
5391 [ # # ][ # # ]: 0 : PartitionCoSurf* new_cosurf = new PartitionCoSurf(sense);
5392 [ # # ]: 0 : surf->add(new_cosurf);
5393 [ # # ]: 0 : new_shell->add(new_cosurf);
5394 : : }
5395 : : }
5396 : :
5397 [ # # ][ # # ]: 0 : new_lump->sub_entity_set().set_id( new_lump, id );
[ # # ]
5398 [ # # ][ # # ]: 0 : new_lump = 0; // we succeeded with this one, so don't try to
5399 : : // destroy it if we fail before creating the next.
5400 : 0 : }
5401 : :
5402 : 0 : result = CUBIT_SUCCESS;
5403 : : }
5404 : :
5405 : : CLEANUP_LUMP_FROM_ATTRIB:
5406 : :
5407 [ # # ]: 0 : if( new_lump ) // created a lump but didn't successfully complete it
5408 : : {
5409 : 0 : PartitionShell* shell = 0;
5410 [ # # ]: 0 : while ( shell )
5411 : : {
5412 [ # # ]: 0 : new_lump->remove(shell);
5413 [ # # ]: 0 : shell->remove_all_surfaces();
5414 : 0 : PartitionShell* old_shell = shell;
5415 [ # # ]: 0 : shell = new_lump->next_shell(shell);
5416 [ # # ][ # # ]: 0 : delete old_shell;
5417 : : }
5418 : : }
5419 : :
5420 [ # # ]: 0 : DLIList<PartitionEntity*> lump_list;
5421 [ # # ]: 0 : if( first_lump )
5422 : : {
5423 : : // Get list of other lumps created
5424 [ # # ][ # # ]: 0 : first_lump->sub_entity_set().get_sub_entities( lump_list );
5425 [ # # ][ # # ]: 0 : lump_list.move_to(first_lump);
5426 [ # # ][ # # ]: 0 : assert( lump_list.get() == first_lump );
[ # # ]
5427 [ # # ]: 0 : lump_list.extract();
5428 : :
5429 : : // Destroy first_lump (it is the union of all the partitions)
5430 [ # # ]: 0 : DLIList<PartitionSurface*> surfaces;
5431 : 0 : PartitionShell* shell = 0;
5432 [ # # ]: 0 : while ( shell )
5433 : : {
5434 [ # # ]: 0 : first_lump->remove(shell);
5435 [ # # ]: 0 : shell->remove_all_surfaces( &surfaces );
5436 : 0 : PartitionShell* old_shell = shell;
5437 [ # # ]: 0 : shell = first_lump->next_shell(shell);
5438 [ # # ][ # # ]: 0 : delete old_shell;
5439 [ # # ][ # # ]: 0 : while( surfaces.size() )
5440 : : {
5441 [ # # ][ # # ]: 0 : SubSurface* surf = dynamic_cast<SubSurface*>(surfaces.pop());
5442 [ # # ][ # # ]: 0 : if ( surf && !surf->next_co_surface(0) &&
[ # # ][ # # ]
[ # # ]
5443 [ # # ][ # # ]: 0 : !surf->sub_entity_set().has_lower_order() )
5444 [ # # ]: 0 : restore_surface( surf );
5445 : : }
5446 : : }
5447 [ # # ][ # # ]: 0 : delete first_lump;
[ # # ]
5448 : : }
5449 : :
5450 : : // destroy any unused split geometry
5451 [ # # ]: 0 : new_geom.reset();
5452 [ # # ][ # # ]: 0 : while( new_geom.size() )
5453 : : {
5454 [ # # ]: 0 : PartitionEntity* ent = new_geom.pop();
5455 [ # # ][ # # ]: 0 : if( PartitionPoint* pt = dynamic_cast<PartitionPoint*>(ent) )
5456 : : {
5457 [ # # ][ # # ]: 0 : if( !pt->next_curve(0) )
5458 [ # # ][ # # ]: 0 : delete pt;
5459 : : }
5460 [ # # ][ # # ]: 0 : else if( PartitionCurve* curve = dynamic_cast<PartitionCurve*>(ent) )
5461 : : {
5462 [ # # ][ # # ]: 0 : if( !curve->next_coedge(0) )
5463 [ # # ][ # # ]: 0 : delete curve;
5464 : : }
5465 [ # # ][ # # ]: 0 : else if( PartitionSurface* surf = dynamic_cast<PartitionSurface*>(ent) )
5466 : : {
5467 [ # # ][ # # ]: 0 : if( !surf->next_co_surface(0) )
5468 [ # # ]: 0 : destroy_surface( surf );
5469 : : }
5470 : : }
5471 : :
5472 : : // if there are any remaining partitions of the volume,
5473 : : // compress the ID space
5474 [ # # ][ # # ]: 0 : if ( lump_list.size() )
5475 : : {
5476 [ # # ][ # # ]: 0 : lump_list.get()->sub_entity_set().renumerate( max_id + 1, true );
[ # # ]
5477 : : }
5478 : :
5479 [ # # ]: 0 : if (!result)
5480 [ # # ][ # # ]: 0 : PRINT_ERROR("Error restoring volume partitions from attributes.\n");
[ # # ][ # # ]
5481 : :
5482 [ # # ][ + - ]: 1613 : return result;
5483 : : }
5484 : :
5485 : :
5486 : :
5487 : : //-------------------------------------------------------------------------
5488 : : // Purpose : Save partition geometry
5489 : : //
5490 : : // Special Notes :
5491 : : //
5492 : : // Creator : Jason Kraftcheck
5493 : : //
5494 : : // Creation Date : 02/23/03
5495 : : //-------------------------------------------------------------------------
5496 : 615 : CubitStatus PartitionEngine::export_geometry( DLIList<TopologyBridge*>& list )
5497 : : {
5498 : : int i;
5499 : 615 : CubitStatus result = CUBIT_SUCCESS;
5500 : :
5501 [ + + + - ]: 1032 : if ( CGMApp::instance()->attrib_manager()->auto_update_flag(CA_PARTITION_VG) &&
[ + + ]
5502 : 417 : CGMApp::instance()->attrib_manager()->auto_write_flag(CA_PARTITION_VG) )
5503 : : {
5504 : :
5505 : : // Get all child topology to export
5506 : :
5507 [ + - ]: 417 : DLIList<Curve*> curve_list;
5508 [ + - ][ + - ]: 834 : DLIList<Surface*> surface_list;
5509 [ + - ][ + - ]: 834 : DLIList<Lump*> lump_list;
5510 [ + - ][ + - ]: 834 : DLIList<BodySM*> body_list;
5511 [ + - ][ + - ]: 834 : DLIList<TopologyBridge*> bridge_list, temp_list, coe_curves(1), surf_curves;
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
5512 : :
5513 [ + - ][ + - ]: 1149 : CAST_LIST( list, curve_list, Curve );
[ + - ][ - + ]
[ - + ][ # # ]
[ + + ]
5514 [ + - ][ + - ]: 1149 : CAST_LIST( list, surface_list, Surface );
[ + - ][ - + ]
[ + + ][ + - ]
[ + + ]
5515 [ + - ][ + - ]: 1149 : CAST_LIST( list, lump_list, Lump );
[ + - ][ - + ]
[ - + ][ # # ]
[ + + ]
5516 [ + - ][ + - ]: 1149 : CAST_LIST( list, body_list, BodySM );
[ + - ][ - + ]
[ + + ][ + - ]
[ + + ]
5517 : :
5518 [ + - ][ + + ]: 1138 : for( i = body_list.size(); i--; )
5519 : : {
5520 [ + - ]: 721 : BodySM* body = body_list.get_and_step();
5521 [ + - ][ + - ]: 721 : body->get_children( bridge_list, true, layer() );
5522 [ + - ][ + + ]: 1452 : while( bridge_list.size() )
5523 [ + - ][ - + ]: 731 : lump_list.append( dynamic_cast<Lump*>(bridge_list.pop()) );
[ + - ]
5524 : : }
5525 : :
5526 [ + - ][ + + ]: 1148 : for( i = lump_list.size(); i--; )
5527 : : {
5528 [ + - ]: 731 : Lump* lump = lump_list.get_and_step();
5529 [ + - ][ + - ]: 731 : lump->get_children( bridge_list, true, layer() );
5530 [ + - ][ + + ]: 1462 : while( bridge_list.size() )
5531 : : {
5532 [ + - ][ + - ]: 731 : bridge_list.pop()->get_children( temp_list, true, layer() );
[ + - ]
5533 [ + - ][ + + ]: 4294 : while( temp_list.size() )
5534 [ + - ][ - + ]: 3563 : surface_list.append( dynamic_cast<Surface*>(temp_list.pop()) );
[ + - ]
5535 : : }
5536 : : }
5537 : :
5538 [ + - ][ + + ]: 3991 : for( i = surface_list.size(); i--; )
5539 : : {
5540 [ + - ]: 3574 : Surface* surf = surface_list.get_and_step();
5541 [ + - ][ + - ]: 3574 : surf->get_children( bridge_list, true, layer() );
5542 [ + - ][ + + ]: 7384 : while( bridge_list.size() )
5543 : : {
5544 [ + - ][ + - ]: 3810 : bridge_list.pop()->get_children( temp_list, true, layer() );
[ + - ]
5545 [ + - ][ + + ]: 17109 : while( temp_list.size() )
5546 : : {
5547 [ + - ][ + - ]: 13299 : temp_list.pop()->get_children_virt( coe_curves );
5548 [ + - ][ - + ]: 13299 : assert(coe_curves.size() == 1);
5549 [ + - ][ + - ]: 13299 : surf_curves.append(coe_curves.pop());
5550 : : }
5551 : : }
5552 [ + - ]: 3574 : surf_curves.uniquify_ordered();
5553 [ + - ][ + + ]: 16445 : while( surf_curves.size() )
5554 [ + - ][ - + ]: 12871 : curve_list.append( dynamic_cast<Curve*>(surf_curves.pop()) );
[ + - ]
5555 : : }
5556 : :
5557 : :
5558 : : // save curve partitions
5559 : :
5560 [ + - ][ + - ]: 834 : DLIList<SubEntitySet*> set_list;
5561 [ + - ][ + + ]: 13288 : for( i = curve_list.size(); i--; )
5562 : : {
5563 [ + - ][ - + ]: 12871 : SubCurve* curve = dynamic_cast<SubCurve*>(curve_list.get_and_step());
5564 [ - + ]: 12871 : if( curve )
5565 [ # # ][ # # ]: 0 : set_list.append( &(curve->sub_entity_set()) );
5566 : : }
5567 [ + - ]: 417 : set_list.uniquify_ordered();
5568 [ + - ][ - + ]: 417 : for( i = set_list.size(); i--; )
5569 [ # # ][ # # ]: 0 : if( ! set_list.get_and_step()->save_geometry() )
[ # # ]
5570 : 0 : result = CUBIT_FAILURE;
5571 : :
5572 : :
5573 : : // save surface partitions
5574 : :
5575 [ + - ]: 417 : set_list.clean_out();
5576 [ + - ][ + + ]: 3991 : for( i = surface_list.size(); i--; )
5577 : : {
5578 [ + - ][ - + ]: 3574 : SubSurface* surf = dynamic_cast<SubSurface*>(surface_list.get_and_step());
5579 [ - + ]: 3574 : if( surf )
5580 [ # # ][ # # ]: 0 : set_list.append( &(surf->sub_entity_set()) );
5581 : : }
5582 [ + - ]: 417 : set_list.uniquify_ordered();
5583 [ + - ][ - + ]: 417 : for( i = set_list.size(); i--; )
5584 [ # # ][ # # ]: 0 : if( ! set_list.get_and_step()->save_geometry() )
[ # # ]
5585 : 0 : result = CUBIT_FAILURE;
5586 : :
5587 : :
5588 : : // save volume partitions
5589 : :
5590 [ + - ]: 417 : set_list.clean_out();
5591 [ + - ][ + + ]: 1148 : for( i = lump_list.size(); i--; )
5592 : : {
5593 [ + - ][ - + ]: 731 : PartitionLump* lump = dynamic_cast<PartitionLump*>(lump_list.get_and_step());
5594 [ - + ]: 731 : if( lump )
5595 [ # # ][ # # ]: 0 : set_list.append( &(lump->sub_entity_set()) );
5596 : : }
5597 [ + - ]: 417 : set_list.uniquify_ordered();
5598 [ + - ][ - + ]: 417 : for( i = set_list.size(); i--; )
5599 [ # # ][ # # ]: 0 : if( ! set_list.get_and_step()->save_geometry() )
[ # # ]
5600 [ + - ]: 417 : result = CUBIT_FAILURE;
5601 : : }
5602 : :
5603 : : // replace partitions in passed list with the real
5604 : : // entities they partition
5605 : :
5606 : 615 : PartitionEntity* p_ent = 0;
5607 : 615 : list.last() ;
5608 [ + + ]: 2711 : for ( i = list.size(); i--; )
5609 : : {
5610 [ - + ][ - + ]: 2096 : if( (p_ent = dynamic_cast<PartitionEntity*>(list.step_and_get())) )
5611 : : {
5612 [ # # ][ # # ]: 0 : if( list.is_in_list(p_ent->partitioned_entity()) )
5613 : 0 : list.change_to(0);
5614 : : else
5615 : 0 : list.change_to(p_ent->partitioned_entity());
5616 : : }
5617 : : }
5618 [ + - ]: 615 : list.remove_all_with_value(0);
5619 : :
5620 : 615 : return result;
5621 : : }
5622 : :
5623 : :
5624 : : //-------------------------------------------------------------------------
5625 : : // Purpose : Restore form attributes
5626 : : //
5627 : : // Special Notes :
5628 : : //
5629 : : // Creator : Jason Kraftcheck
5630 : : //
5631 : : // Creation Date : 01/23/03
5632 : : //-------------------------------------------------------------------------
5633 : 1257 : CubitStatus PartitionEngine::import_geometry( DLIList<TopologyBridge*>& list )
5634 : : {
5635 : : int i;
5636 : 1257 : CubitStatus result = CUBIT_SUCCESS;
5637 : :
5638 [ + - ][ + - ]: 2514 : DLIList<Curve*> curve_list, temp_curves;
[ + - ]
5639 [ + - ][ + - ]: 2514 : DLIList<Surface*> surface_list, temp_surfaces;
[ + - ][ + - ]
5640 [ + - ][ + - ]: 2514 : DLIList<Lump*> lump_list, temp_lumps;
[ + - ][ + - ]
5641 [ + - ][ + - ]: 2514 : DLIList<BodySM*> body_list;
5642 : :
5643 [ + - ][ + - ]: 3410 : CAST_LIST( list, curve_list, Curve );
[ + - ][ - + ]
[ + + ][ + - ]
[ + + ]
5644 [ + - ][ + - ]: 3410 : CAST_LIST( list, surface_list, Surface );
[ + - ][ - + ]
[ + + ][ + - ]
[ + + ]
5645 [ + - ][ + - ]: 3410 : CAST_LIST( list, lump_list, Lump );
[ + - ][ - + ]
[ - + ][ # # ]
[ + + ]
5646 [ + - ][ + - ]: 3410 : CAST_LIST( list, body_list, BodySM );
[ + - ][ - + ]
[ + + ][ + - ]
[ + + ]
5647 : :
5648 [ + - ][ + + ]: 3201 : for( i = body_list.size(); i--; )
5649 : : {
5650 [ + - ]: 1944 : temp_lumps.clean_out();
5651 [ + - ][ + - ]: 1944 : body_list.get_and_step()->lumps( temp_lumps );
5652 [ + - ]: 1944 : lump_list += temp_lumps;
5653 : : }
5654 : :
5655 [ + - ][ + + ]: 3397 : for( i = lump_list.size(); i--; )
5656 : : {
5657 [ + - ]: 2140 : temp_surfaces.clean_out();
5658 [ + - ][ + - ]: 2140 : lump_list.get_and_step()->surfaces( temp_surfaces );
5659 [ + - ]: 2140 : surface_list += temp_surfaces;
5660 : : }
5661 : :
5662 [ + - ][ + + ]: 15091 : for( i = surface_list.size(); i--; )
5663 : : {
5664 [ + - ]: 13834 : temp_curves.clean_out();
5665 [ + - ][ + - ]: 13834 : surface_list.get_and_step()->curves( temp_curves );
5666 [ + - ]: 13834 : curve_list += temp_curves;
5667 : : }
5668 : :
5669 : :
5670 [ + - ][ + - ]: 2317 : if ( CGMApp::instance()->attrib_manager()->auto_actuate_flag(CA_PARTITION_VG) &&
[ + - ][ + + ]
[ + - ][ + + ]
5671 [ + - ][ + - ]: 1060 : CGMApp::instance()->attrib_manager()->auto_read_flag(CA_PARTITION_VG) )
[ + - ]
5672 : : {
5673 : :
5674 [ + - ]: 1060 : curve_list.uniquify_ordered();
5675 [ + - ][ + + ]: 24335 : for( i = curve_list.size(); i--; )
5676 [ + - ][ + - ]: 23275 : if( ! restore_from_attrib( curve_list.get_and_step() ) )
[ - + ]
5677 : 0 : result = CUBIT_FAILURE;
5678 : :
5679 [ + - ]: 1060 : surface_list.uniquify_ordered();
5680 [ + - ][ + + ]: 12249 : for( i = surface_list.size(); i--; )
5681 [ + - ][ + - ]: 11189 : if( ! restore_from_attrib( surface_list.get_and_step() ) )
[ - + ]
5682 : 0 : result = CUBIT_FAILURE;
5683 : :
5684 [ + - ]: 1060 : lump_list.uniquify_ordered();
5685 [ + - ][ + + ]: 2673 : for( i = lump_list.size(); i--; )
5686 [ + - ][ + - ]: 1613 : if( ! restore_from_attrib( lump_list.get_and_step() ) )
[ - + ]
5687 : 0 : result = CUBIT_FAILURE;
5688 : :
5689 : : // update imported list
5690 [ + - ]: 1060 : list.last();
5691 [ + - ]: 1060 : DLIList<PartitionEntity*> entity_list;
5692 [ + - ][ + - ]: 2120 : DLIList<TopologyBridge*> temp_list;
5693 [ + - ][ + + ]: 2499 : for( i = list.size(); i--; )
5694 : : {
5695 [ + - ]: 1439 : TopologyBridge* bridge = list.step_and_get();
5696 [ + - ][ + + ]: 1439 : SubEntitySet* set = dynamic_cast<SubEntitySet*>(bridge->owner());
5697 [ + - ]: 1439 : if( !set ) continue;
5698 : :
5699 [ # # ]: 0 : entity_list.clean_out();
5700 [ # # ]: 0 : temp_list.clean_out();
5701 [ # # ]: 0 : set->get_sub_entities( entity_list );
5702 [ # # ][ # # ]: 0 : CAST_LIST( entity_list, temp_list, TopologyBridge );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5703 : :
5704 [ # # ]: 0 : temp_list.reset();
5705 [ # # ][ # # ]: 0 : list.change_to( temp_list.get_and_step() );
5706 [ # # ][ # # ]: 0 : for( int j = temp_list.size(); j > 1; j-- )
5707 [ # # ][ # # ]: 0 : list.append( temp_list.get_and_step() );
5708 [ + - ]: 1060 : }
5709 : : }
5710 : : else
5711 : : {
5712 [ + - ]: 197 : curve_list.uniquify_ordered();
5713 [ + - ]: 197 : surface_list.uniquify_ordered();
5714 [ + - ]: 197 : lump_list.uniquify_ordered();
5715 : :
5716 [ + - ][ + - ]: 394 : DLIList<TopologyBridge*> point_list(curve_list.size()*2), tmp_points(2);
[ + - ][ + - ]
5717 [ + - ][ + + ]: 7621 : for ( i = curve_list.size(); i--; )
5718 : : {
5719 [ + - ]: 7424 : tmp_points.clean_out();
5720 [ + - ][ + - ]: 7424 : curve_list.get()->get_children(tmp_points);
5721 [ + - ]: 7424 : point_list += tmp_points;
5722 [ + - ][ + - ]: 7424 : SubEntitySet::strip_attributes( curve_list.get_and_step() );
5723 : : }
5724 [ + - ]: 197 : point_list.uniquify_ordered();
5725 [ + - ][ + + ]: 6019 : for ( i = point_list.size(); i--; )
5726 [ + - ][ + - ]: 5822 : SubEntitySet::strip_attributes( point_list.get_and_step() );
5727 [ + - ][ + + ]: 2842 : for ( i = surface_list.size(); i--; )
5728 [ + - ][ + - ]: 2645 : SubEntitySet::strip_attributes( surface_list.get_and_step() );
5729 [ + - ][ + + ]: 724 : for ( i = lump_list.size(); i--; )
5730 [ + - ][ + - ]: 724 : SubEntitySet::strip_attributes( lump_list.get_and_step() );
[ + - ]
5731 : : }
5732 : :
5733 [ + - ]: 1257 : return result;
5734 : : }
5735 : : /*
5736 : : void PartitionEngine::destroy_facet( CubitFacetData* facet )
5737 : : {
5738 : : int i;
5739 : :
5740 : : for( i = 0; i < 3; i++ )
5741 : : {
5742 : : CubitFacetEdgeData* edge = dynamic_cast<CubitFacetEdgeData*>(facet->edge(i));
5743 : : if( edge )
5744 : : {
5745 : : facet->edge(0, i);
5746 : : if( edge->number_tris() == 0 )
5747 : : delete edge;
5748 : : }
5749 : : }
5750 : :
5751 : : for( i = 0; i < 3; i++ )
5752 : : {
5753 : : CubitPointData* point = dynamic_cast<CubitPointData*>(facet->point(0));
5754 : : assert(point);
5755 : : point->remove_facet( facet );
5756 : : if( point->num_adj_facets() == 0 )
5757 : : delete point;
5758 : : }
5759 : :
5760 : : delete facet;
5761 : : }
5762 : : */
5763 : : //-------------------------------------------------------------------------
5764 : : // Purpose : Core functionality of make_body( X* ) methods.
5765 : : //
5766 : : // Special Notes :
5767 : : //
5768 : : // Creator : Jason Kraftcheck
5769 : : //
5770 : : // Creation Date : 02/23/03
5771 : : //-------------------------------------------------------------------------
5772 : 0 : PartitionBody* PartitionEngine::make_body_internal( TopologyBridge* bridge )
5773 : : {
5774 : : // query topology for BodySM
5775 [ # # ]: 0 : DLIList<TopologyBridge*> list;
5776 : : BodySM* body;
5777 [ # # ][ # # ]: 0 : while( !(body = dynamic_cast<BodySM*>(bridge)) )
5778 : : {
5779 [ # # ]: 0 : list.clean_out();
5780 [ # # ]: 0 : bridge->get_parents_virt(list);
5781 [ # # ][ # # ]: 0 : if( !list.size() )
5782 : 0 : return 0;
5783 [ # # ]: 0 : bridge = list.get();
5784 : : }
5785 : :
5786 [ # # ][ # # ]: 0 : SubEntitySet* set = dynamic_cast<SubEntitySet*>(body->owner());
5787 [ # # ]: 0 : if( set )
5788 [ # # ]: 0 : return set->body();
5789 : :
5790 [ # # ][ # # ]: 0 : PartitionBody* result = new PartitionBody(body);
5791 [ # # ][ # # ]: 0 : if( body->owner() )
5792 [ # # ][ # # ]: 0 : body->owner()->swap_bridge( body, result, false );
5793 [ # # ][ # # ]: 0 : body->owner( &(result->sub_entity_set()) );
5794 [ # # ]: 0 : return result;
5795 : : }
5796 : :
5797 : : //-------------------------------------------------------------------------
5798 : : // Purpose : Find or make an owning bodySM
5799 : : //
5800 : : // Special Notes :
5801 : : //
5802 : : // Creator : Jason Kraftcheck
5803 : : //
5804 : : // Creation Date : 02/23/03
5805 : : //-------------------------------------------------------------------------
5806 : 0 : PartitionBody* PartitionEngine::make_body( PartitionLump* lump )
5807 : : {
5808 [ # # ]: 0 : if( lump->get_body() )
5809 : 0 : return lump->get_body();
5810 : :
5811 : 0 : return make_body_internal( lump );
5812 : : }
5813 : :
5814 : : //-------------------------------------------------------------------------
5815 : : // Purpose : Find or make an owning bodySM
5816 : : //
5817 : : // Special Notes :
5818 : : //
5819 : : // Creator : Jason Kraftcheck
5820 : : //
5821 : : // Creation Date : 02/23/03
5822 : : //-------------------------------------------------------------------------
5823 : 0 : PartitionBody* PartitionEngine::make_body( PartitionSurface* surf )
5824 : : {
5825 [ # # ]: 0 : if( surf->sub_entity_set().body() )
5826 : 0 : return surf->sub_entity_set().body();
5827 : :
5828 [ # # ]: 0 : if( surf->next_co_surface(0) )
5829 : 0 : return make_body(surf->next_co_surface(0)->get_shell()->get_lump());
5830 : :
5831 : 0 : return make_body_internal(surf);
5832 : : }
5833 : :
5834 : : //-------------------------------------------------------------------------
5835 : : // Purpose : Find or make an owning bodySM
5836 : : //
5837 : : // Special Notes :
5838 : : //
5839 : : // Creator : Jason Kraftcheck
5840 : : //
5841 : : // Creation Date : 02/23/03
5842 : : //-------------------------------------------------------------------------
5843 : 0 : PartitionBody* PartitionEngine::make_body( PartitionCurve* curve )
5844 : : {
5845 [ # # ]: 0 : if( curve->sub_entity_set().body() )
5846 : 0 : return curve->sub_entity_set().body();
5847 : :
5848 : 0 : PartitionCoEdge* coedge = 0;
5849 [ # # ]: 0 : while( (coedge = curve->next_coedge(coedge)) )
5850 [ # # ]: 0 : if( coedge->get_loop() )
5851 : 0 : return make_body(coedge->get_loop()->get_surface());
5852 : :
5853 : 0 : return make_body_internal(curve);
5854 : : }
5855 : :
5856 : : //-------------------------------------------------------------------------
5857 : : // Purpose : Find or make an owning bodySM
5858 : : //
5859 : : // Special Notes :
5860 : : //
5861 : : // Creator : Jason Kraftcheck
5862 : : //
5863 : : // Creation Date : 02/23/03
5864 : : //-------------------------------------------------------------------------
5865 : 0 : PartitionBody* PartitionEngine::make_body( PartitionPoint* pt )
5866 : : {
5867 [ # # ]: 0 : if( pt->sub_entity_set().body() )
5868 : 0 : return pt->sub_entity_set().body();
5869 : :
5870 [ # # ]: 0 : if( pt->next_curve(0) )
5871 : 0 : return make_body(pt->next_curve(0));
5872 : :
5873 : 0 : return make_body_internal(pt);
5874 : : }
5875 : 0 : static CubitStatus get_edge_replacements(
5876 : : std::vector<CubitFacetData*> &facet_list,
5877 : : std::vector<CubitFacetEdgeData*> replace_edge_lists[3])
5878 : : {
5879 : : // first facet is the facet to replace
5880 : : // make sure more than one facet to replace the first
5881 [ # # ][ # # ]: 0 : assert(facet_list.size() > 2);
5882 : :
5883 : : // make sure the lists of replacement edges are empty
5884 [ # # ][ # # ]: 0 : assert(replace_edge_lists[0].size() == 0);
5885 [ # # ][ # # ]: 0 : assert(replace_edge_lists[1].size() == 0);
5886 [ # # ][ # # ]: 0 : assert(replace_edge_lists[2].size() == 0);
5887 : :
5888 : :
5889 [ # # ]: 0 : CubitFacetData* p_dead = facet_list[0]; // facet to be replaced
5890 : :
5891 : : // look for edges on the facet that are owned by curves
5892 : : int i;
5893 : : //int replace_edge = 0;
5894 : :
5895 : : // get the edges
5896 : : CubitFacetEdgeData *edges[3];
5897 [ # # ]: 0 : for (i=0; i<3; i++)
5898 : : {
5899 [ # # ][ # # ]: 0 : edges[i] = CAST_TO(p_dead->edge(i), CubitFacetEdgeData);
5900 [ # # ]: 0 : assert(edges[i] != NULL);
5901 : : }
5902 : :
5903 : : PartitionEntity *p_owner;
5904 : : PartitionCurve *p_curve;
5905 : :
5906 : : // see if any are owned by a curve
5907 : 0 : CubitBoolean b_boundary = CUBIT_FALSE;
5908 [ # # ][ # # ]: 0 : for (i=0; i<3 && !b_boundary; i++)
5909 : : {
5910 [ # # ]: 0 : p_owner = TDVGFacetOwner::get(edges[i]);
5911 [ # # ]: 0 : p_curve = CAST_TO(p_owner, PartitionCurve);
5912 [ # # ]: 0 : if (p_curve)
5913 : 0 : b_boundary = CUBIT_TRUE;
5914 : : }
5915 : :
5916 : : // if the facet has an edge on a curve, replace the edge with the edges of the
5917 : : // replacement facets and split the facet on the adjacent surface.
5918 [ # # ]: 0 : if (b_boundary)
5919 : : {
5920 : : // make a list with just the new facets -- skip the first facet
5921 [ # # ][ # # ]: 0 : DLIList<CubitFacet*> new_facets(facet_list.size() - 1);
5922 [ # # ][ # # ]: 0 : for (unsigned u = 1; u < facet_list.size(); u++)
5923 [ # # ][ # # ]: 0 : new_facets.append(facet_list[u]);
5924 : :
5925 : : // get a point edge chain around the boundary of the replacement facets
5926 [ # # ][ # # ]: 0 : DLIList<FacetEntity*> point_edge_chain;
[ # # ]
5927 [ # # ]: 0 : FacetDataUtil::ordered_point_edge_bdry(new_facets, point_edge_chain);
5928 : :
5929 : : // for each edge on a curve get corresponding points and edges from the
5930 : : // replacement facets
5931 : : //std::vector<CubitFacetEdgeData*>::iterator eitor;
5932 [ # # ][ # # ]: 0 : for (i=0; i<3; i++)
[ # # ]
5933 : : {
5934 [ # # ]: 0 : p_owner = TDVGFacetOwner::get(edges[i]);
5935 [ # # ]: 0 : p_curve = CAST_TO(p_owner, PartitionCurve);
5936 [ # # ]: 0 : if (p_curve)
5937 : : {
5938 : : // fill the replacement list for this edge
5939 : : // add the edge to be replaced first
5940 : : //eitor = replace_edge_lists[i].begin();
5941 : :
5942 : : // get the points from the edge of the dead facet - in the correct order
5943 : : CubitPoint* pt1;
5944 : : CubitPoint* pt2;
5945 : :
5946 [ # # ]: 0 : p_dead->get_edge_pts(i, pt1, pt2);
5947 : :
5948 : : // get the corresponding chain of points and edges from the replacement facets
5949 [ # # ]: 0 : DLIList<FacetEntity*> replacement_chain;
5950 : : CubitStatus res = FacetDataUtil::partial_chain(point_edge_chain,
5951 [ # # ]: 0 : pt1, pt2, replacement_chain);
5952 [ # # ]: 0 : if (CUBIT_FAILURE == res)
5953 : 0 : return CUBIT_FAILURE;
5954 : :
5955 : : // there should be an odd number of list entries, since it includes points
5956 : : // and edges, beginning and ending with a point
5957 [ # # ][ # # ]: 0 : assert( (replacement_chain.size() % 2) == 1 );
5958 : :
5959 : : // if only one replacement edge, it should be the same edge
5960 [ # # ]: 0 : replacement_chain.reset();
5961 [ # # ][ # # ]: 0 : if (replacement_chain.size() == 3)
5962 : : {
5963 [ # # ][ # # ]: 0 : assert(replacement_chain.next(1) == edges[i]);
5964 : : }
5965 : : else
5966 : : {
5967 : : // add the replacement edges to the list - edge to replace first
5968 : : //*eitor++ = edges[i];
5969 [ # # ]: 0 : replace_edge_lists[i].push_back(edges[i]);
5970 : : int j;
5971 : : CubitFacetEdgeData* p_edge;
5972 [ # # ][ # # ]: 0 : for (j=1; j<replacement_chain.size(); j+=2)
[ # # ][ # # ]
5973 : : {
5974 : : //replacement_chain.step();
5975 [ # # ][ # # ]: 0 : p_edge = CAST_TO(replacement_chain.next(j), CubitFacetEdgeData);
5976 [ # # ]: 0 : assert(p_edge != NULL);
5977 : : //*eitor++ = p_edge;
5978 [ # # ]: 0 : replace_edge_lists[i].push_back(p_edge);
5979 : : }
5980 : 0 : }
5981 : : }
5982 : 0 : }
5983 : : }
5984 : :
5985 : 0 : return CUBIT_SUCCESS;
5986 : : }
5987 : :
5988 : : //-------------------------------------------------------------------------
5989 : : // Purpose : clean up for deleted geometry
5990 : : //
5991 : : // Special Notes :
5992 : : //
5993 : : // Creator : Jason Kraftcheck
5994 : : //
5995 : : // Creation Date : 04/03/03
5996 : : //-------------------------------------------------------------------------
5997 : 0 : CubitStatus PartitionEngine::delete_solid_model_entities(
5998 : : PartitionBody* body, BodySM*& real_body )
5999 : : {
6000 : 0 : real_body = body->real_body();
6001 : 0 : body->destroy_all_children();
6002 : 0 : return CUBIT_SUCCESS;
6003 : : }
6004 : :
6005 : 0 : CubitStatus PartitionEngine::delete_solid_model_entities(
6006 : : PartitionSurface* surf,
6007 : : Surface*& real_surf )
6008 : : {
6009 [ # # ]: 0 : DLIList<TopologyBridge*> parents(0);
6010 [ # # ]: 0 : surf->get_parents_virt(parents);
6011 [ # # ][ # # ]: 0 : if ( parents.size() )
6012 : 0 : return CUBIT_FAILURE;
6013 : :
6014 : 0 : real_surf = 0;
6015 [ # # ][ # # ]: 0 : if ( !surf->sub_entity_set().has_multiple_sub_entities() )
[ # # ]
6016 [ # # ][ # # ]: 0 : real_surf = dynamic_cast<Surface*>(surf->partitioned_entity());
6017 [ # # ]: 0 : destroy_surface(surf);
6018 [ # # ]: 0 : return CUBIT_SUCCESS;
6019 : : }
6020 : :
6021 : 0 : CubitStatus PartitionEngine::delete_solid_model_entities(
6022 : : PartitionCurve* curve,
6023 : : Curve*& real_curve )
6024 : : {
6025 [ # # ]: 0 : if( curve->next_coedge(0) )
6026 : 0 : return CUBIT_FAILURE;
6027 : :
6028 : 0 : real_curve = 0;
6029 [ # # ]: 0 : if ( !curve->sub_entity_set().has_multiple_sub_entities() )
6030 [ # # ]: 0 : real_curve = dynamic_cast<Curve*>(curve->partitioned_entity());
6031 : 0 : PartitionPoint* start = curve->start_point();
6032 : 0 : PartitionPoint* end = curve->end_point();
6033 [ # # ]: 0 : delete curve;
6034 [ # # ]: 0 : if ( start->num_curves() == 0 )
6035 [ # # ]: 0 : delete start;
6036 [ # # ]: 0 : if ( end->num_curves() == 0 )
6037 [ # # ]: 0 : delete end;
6038 : 0 : return CUBIT_SUCCESS;
6039 : : }
6040 : :
6041 : 0 : CubitStatus PartitionEngine::translate( PartitionEntity* ent,
6042 : : const CubitVector& delta )
6043 : : {
6044 [ # # ][ # # ]: 0 : GeometryEntity* geom = dynamic_cast<GeometryEntity*>(ent->partitioned_entity());
6045 [ # # ][ # # ]: 0 : if (!geom->get_geometry_query_engine()->translate( geom, delta ))
[ # # ]
6046 : 0 : return CUBIT_FAILURE;
6047 : :
6048 [ # # ]: 0 : CubitTransformMatrix xform;
6049 [ # # ]: 0 : xform.translate( delta );
6050 [ # # ]: 0 : notify_transform_internal( geom, xform );
6051 [ # # ]: 0 : return CUBIT_SUCCESS;
6052 : : }
6053 : :
6054 : 0 : CubitStatus PartitionEngine::rotate( PartitionEntity* ent,
6055 : : const CubitVector& axis,
6056 : : double degrees )
6057 : : {
6058 [ # # ][ # # ]: 0 : GeometryEntity* geom = dynamic_cast<GeometryEntity*>(ent->partitioned_entity());
6059 [ # # ][ # # ]: 0 : if (!geom->get_geometry_query_engine()->rotate( geom, axis, degrees ))
[ # # ]
6060 : 0 : return CUBIT_FAILURE;
6061 : :
6062 [ # # ]: 0 : CubitTransformMatrix xform;
6063 [ # # ]: 0 : xform.rotate( degrees, axis );
6064 [ # # ]: 0 : notify_transform_internal( geom, xform );
6065 [ # # ]: 0 : return CUBIT_SUCCESS;
6066 : : }
6067 : :
6068 : 0 : CubitStatus PartitionEngine::scale( PartitionEntity* ent,
6069 : : const CubitVector& factors )
6070 : : {
6071 [ # # ][ # # ]: 0 : GeometryEntity* geom = dynamic_cast<GeometryEntity*>(ent->partitioned_entity());
6072 [ # # ][ # # ]: 0 : if (!geom->get_geometry_query_engine()->scale( geom, factors ))
[ # # ]
6073 : 0 : return CUBIT_FAILURE;
6074 : :
6075 [ # # ]: 0 : CubitTransformMatrix xform;
6076 [ # # ]: 0 : xform.scale_about_origin( factors );
6077 [ # # ]: 0 : notify_transform_internal( geom, xform );
6078 [ # # ]: 0 : return CUBIT_SUCCESS;
6079 : : }
6080 : :
6081 : 0 : CubitStatus PartitionEngine::reflect( PartitionEntity* ent,
6082 : : const CubitVector& axis )
6083 : : {
6084 [ # # ][ # # ]: 0 : GeometryEntity* geom = dynamic_cast<GeometryEntity*>(ent->partitioned_entity());
6085 [ # # ][ # # ]: 0 : if (!geom->get_geometry_query_engine()->reflect( geom, axis ))
[ # # ]
6086 : 0 : return CUBIT_FAILURE;
6087 : :
6088 [ # # ]: 0 : CubitTransformMatrix xform;
6089 [ # # ]: 0 : xform.reflect( axis );
6090 [ # # ]: 0 : notify_transform_internal( geom, xform );
6091 [ # # ]: 0 : return CUBIT_SUCCESS;
6092 : : }
6093 : :
6094 : 0 : CubitStatus PartitionEngine::translate( PartitionBody* ent,
6095 : : const CubitVector& delta )
6096 : : {
6097 [ # # ]: 0 : BodySM* body = ent->real_body();
6098 [ # # ][ # # ]: 0 : if (!body->get_geometry_query_engine()->translate( body, delta ))
[ # # ]
6099 : 0 : return CUBIT_FAILURE;
6100 : :
6101 [ # # ]: 0 : CubitTransformMatrix xform;
6102 [ # # ]: 0 : xform.translate( delta );
6103 [ # # ]: 0 : notify_transform_internal( ent, xform );
6104 [ # # ]: 0 : return CUBIT_SUCCESS;
6105 : : }
6106 : :
6107 : 0 : CubitStatus PartitionEngine::rotate( PartitionBody* ent,
6108 : : const CubitVector& axis,
6109 : : double degrees )
6110 : : {
6111 [ # # ]: 0 : BodySM* body = ent->real_body();
6112 [ # # ][ # # ]: 0 : if (!body->get_geometry_query_engine()->rotate( body, axis, degrees ))
[ # # ]
6113 : 0 : return CUBIT_FAILURE;
6114 : :
6115 [ # # ]: 0 : CubitTransformMatrix xform;
6116 [ # # ]: 0 : xform.rotate( degrees, axis );
6117 [ # # ]: 0 : notify_transform_internal( ent, xform );
6118 [ # # ]: 0 : return CUBIT_SUCCESS;
6119 : : }
6120 : :
6121 : 0 : CubitStatus PartitionEngine::scale( PartitionBody* ent,
6122 : : const CubitVector& factors )
6123 : : {
6124 [ # # ]: 0 : BodySM* body = ent->real_body();
6125 : :
6126 [ # # ][ # # ]: 0 : if( factors.x() != factors.y() ||
[ # # ][ # # ]
6127 [ # # ][ # # ]: 0 : factors.y() != factors.z() ||
[ # # ][ # # ]
6128 [ # # ][ # # ]: 0 : factors.x() != factors.z() )
6129 : : {
6130 [ # # ][ # # ]: 0 : GeometryModifyEngine *tmp_engine = GeometryModifyTool::instance()->get_engine( body );
6131 [ # # ]: 0 : tmp_engine->scale( body, factors );
6132 : : }
6133 [ # # ][ # # ]: 0 : else if(!body->get_geometry_query_engine()->scale( body, factors ))
[ # # ]
6134 : 0 : return CUBIT_FAILURE;
6135 : :
6136 [ # # ]: 0 : CubitTransformMatrix xform;
6137 [ # # ]: 0 : xform.scale_about_origin( factors );
6138 [ # # ]: 0 : notify_transform_internal( ent, xform );
6139 [ # # ]: 0 : return CUBIT_SUCCESS;
6140 : : }
6141 : :
6142 : 0 : CubitStatus PartitionEngine::reflect( PartitionBody* ent,
6143 : : const CubitVector& axis )
6144 : : {
6145 [ # # ]: 0 : BodySM* body = ent->real_body();
6146 [ # # ][ # # ]: 0 : if (!body->get_geometry_query_engine()->reflect( body, axis ))
[ # # ]
6147 : 0 : return CUBIT_FAILURE;
6148 : :
6149 [ # # ]: 0 : CubitTransformMatrix xform;
6150 [ # # ]: 0 : xform.reflect( axis );
6151 [ # # ]: 0 : notify_transform_internal( ent, xform );
6152 [ # # ]: 0 : return CUBIT_SUCCESS;
6153 : : }
6154 : :
6155 : 0 : CubitStatus PartitionEngine::restore_transform( PartitionBody* ent )
6156 : : {
6157 [ # # ]: 0 : BodySM* body = ent->real_body();
6158 [ # # ]: 0 : CubitTransformMatrix xform;
6159 [ # # ]: 0 : body->get_transforms( xform );
6160 [ # # ][ # # ]: 0 : if (!body->get_geometry_query_engine()->restore_transform( body ))
[ # # ]
6161 : 0 : return CUBIT_FAILURE;
6162 : :
6163 [ # # ]: 0 : notify_transform_internal( ent, xform );
6164 [ # # ]: 0 : return CUBIT_SUCCESS;
6165 : : }
6166 : :
6167 : 444 : CubitStatus PartitionEngine::notify_transform( TopologyBridge* ,
6168 : : const CubitTransformMatrix& )
6169 : : {
6170 : 444 : return CUBIT_SUCCESS;
6171 : : }
6172 : :
6173 : 0 : CubitStatus PartitionEngine::notify_transform_internal( TopologyBridge* ent,
6174 : : const CubitTransformMatrix& xform )
6175 : : {
6176 : : int i;
6177 [ # # ]: 0 : DLIList<Surface*> surfaces;
6178 [ # # ][ # # ]: 0 : DLIList<Curve*> curves;
6179 [ # # ][ # # ]: 0 : DLIList<TBPoint*> points;
6180 : :
6181 [ # # ][ # # ]: 0 : if (PartitionBody* body = dynamic_cast<PartitionBody*>(ent))
6182 : : {
6183 [ # # ]: 0 : DLIList<PartitionEntity*> ent_list;
6184 [ # # ]: 0 : body->get_all_children( ent_list );
6185 [ # # ][ # # ]: 0 : CAST_LIST( ent_list, surfaces, PartitionSurface );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
6186 [ # # ][ # # ]: 0 : CAST_LIST( ent_list, curves, PartitionCurve );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
6187 [ # # ][ # # ]: 0 : CAST_LIST( ent_list, points, PartitionPoint );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
6188 : : }
6189 : : else
6190 : : {
6191 [ # # ][ # # ]: 0 : if(BodySM* bodysm = dynamic_cast<BodySM*>(ent))
6192 : : {
6193 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> lumps, shells, tmp_surfs;
[ # # ][ # # ]
[ # # ]
6194 [ # # ][ # # ]: 0 : bodysm->get_children( lumps, true, layer() );
6195 [ # # ][ # # ]: 0 : while (lumps.size())
6196 : : {
6197 [ # # ][ # # ]: 0 : lumps.pop()->get_children( shells, true, layer() );
[ # # ]
6198 [ # # ][ # # ]: 0 : while (shells.size())
6199 : : {
6200 [ # # ]: 0 : tmp_surfs.clean_out();
6201 [ # # ][ # # ]: 0 : shells.pop()->get_children( tmp_surfs, true, layer() );
[ # # ]
6202 [ # # ][ # # ]: 0 : while (tmp_surfs.size())
6203 [ # # ][ # # ]: 0 : surfaces.append( dynamic_cast<Surface*>(tmp_surfs.pop()) );
[ # # ]
6204 : : }
6205 : : }
6206 [ # # ][ # # ]: 0 : surfaces.uniquify_ordered();
6207 : : }
6208 [ # # ][ # # ]: 0 : else if(Surface* surf = dynamic_cast<Surface*>(ent))
6209 [ # # ]: 0 : surfaces.append( surf );
6210 [ # # ][ # # ]: 0 : else if(Curve* curv = dynamic_cast<Curve*>(ent))
6211 [ # # ]: 0 : curves.append( curv );
6212 [ # # ][ # # ]: 0 : else if(TBPoint* point = dynamic_cast<TBPoint*>(ent))
6213 [ # # ]: 0 : points.append( point );
6214 : :
6215 [ # # ][ # # ]: 0 : if (surfaces.size())
6216 : : {
6217 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> loops, coedges, tmp_curves;
[ # # ][ # # ]
[ # # ]
6218 [ # # ][ # # ]: 0 : for (i = surfaces.size(); i--; )
6219 : : {
6220 [ # # ][ # # ]: 0 : surfaces.get_and_step()->get_children( loops, true, layer() );
[ # # ]
6221 [ # # ][ # # ]: 0 : while( loops.size() )
6222 : : {
6223 [ # # ][ # # ]: 0 : loops.pop()->get_children( coedges, true, layer() );
[ # # ]
6224 [ # # ][ # # ]: 0 : while (coedges.size())
6225 : : {
6226 [ # # ][ # # ]: 0 : coedges.pop()->get_children( tmp_curves, true, layer() );
[ # # ]
6227 [ # # ][ # # ]: 0 : while (tmp_curves.size())
6228 [ # # ][ # # ]: 0 : curves.append( dynamic_cast<Curve*>(tmp_curves.pop()) );
[ # # ]
6229 : : }
6230 : : }
6231 : : }
6232 [ # # ][ # # ]: 0 : curves.uniquify_ordered();
6233 : : }
6234 : :
6235 [ # # ][ # # ]: 0 : if (curves.size())
6236 : : {
6237 [ # # ]: 0 : DLIList<TopologyBridge*> tmp_points;
6238 [ # # ][ # # ]: 0 : for (i = curves.size(); i--; )
6239 : : {
6240 [ # # ][ # # ]: 0 : curves.get_and_step()->get_children( tmp_points, true, layer() );
[ # # ]
6241 [ # # ][ # # ]: 0 : while (tmp_points.size())
6242 [ # # ][ # # ]: 0 : points.append( dynamic_cast<TBPoint*>(tmp_points.pop()) );
[ # # ]
6243 : : }
6244 [ # # ][ # # ]: 0 : points.uniquify_ordered();
6245 : : }
6246 : : }
6247 : :
6248 : : // see if the transformation is a reflection
6249 [ # # ][ # # ]: 0 : double det = xform.sub_matrix( 3, 3 ).determinant();
[ # # ]
6250 : 0 : bool reflection = det < 0.0;
6251 : :
6252 [ # # ][ # # ]: 0 : while (surfaces.size())
6253 : : {
6254 [ # # ][ # # ]: 0 : PartitionSurface* surf = dynamic_cast<PartitionSurface*>(surfaces.pop());
6255 [ # # ]: 0 : if (surf)
6256 : : {
6257 [ # # ]: 0 : surf->transform( xform );
6258 : : }
6259 : : }
6260 : :
6261 [ # # ][ # # ]: 0 : while (curves.size())
6262 : : {
6263 [ # # ][ # # ]: 0 : PartitionCurve* curv = dynamic_cast<PartitionCurve*>(curves.pop());
6264 [ # # ]: 0 : if (curv)
6265 : : {
6266 [ # # ]: 0 : curv->transform( xform );
6267 : :
6268 [ # # ]: 0 : if (reflection)
6269 : : {
6270 : : // PartitionSurface transform above reverses loops and coedges on Partition
6271 : : // surfaces. Need to reverse sense of PartitionCoEdges in loops on non
6272 : : // partition surfaces
6273 : : // reverse the coedges of this curve
6274 : 0 : PartitionCoEdge* p_coedge = 0;
6275 [ # # ][ # # ]: 0 : while ((p_coedge = curv->next_coedge(p_coedge)) != NULL)
6276 : : {
6277 [ # # ]: 0 : TopologyBridge* loop_bridge = p_coedge->find_parent_loop();
6278 [ # # ]: 0 : if (loop_bridge)
6279 : : {
6280 [ # # ][ # # ]: 0 : if (0 == dynamic_cast<PartitionLoop*>(loop_bridge))
[ # # ]
6281 : : {
6282 [ # # ]: 0 : p_coedge->reverse_sense();
6283 : : }
6284 : : }
6285 : : }
6286 : : }
6287 : : }
6288 : : }
6289 : :
6290 [ # # ][ # # ]: 0 : while (points.size())
6291 : : {
6292 [ # # ][ # # ]: 0 : PartitionPoint* pnt = dynamic_cast<PartitionPoint*>(points.pop());
6293 [ # # ]: 0 : if (pnt)
6294 [ # # ]: 0 : pnt->transform( xform );
6295 : : }
6296 : :
6297 [ # # ]: 0 : return CUBIT_SUCCESS;
6298 : : }
6299 : :
6300 : 615 : void PartitionEngine::remove_attributes( DLIList<TopologyBridge*> &list )
6301 : : {
6302 : : //for each SubEntitySet in map, change it's unique id to zero
6303 [ + - ]: 615 : std::map<int,SubEntitySet*>::iterator itor = uniqueIdMap.begin();
6304 [ + - ][ + - ]: 615 : while( itor != uniqueIdMap.end() )
[ - + ]
6305 : : {
6306 [ # # ][ # # ]: 0 : if(itor->second->get_entity())
[ # # ]
6307 : : {
6308 [ # # ][ # # ]: 0 : SubEntitySet::strip_attributes( itor->second->get_entity() );
[ # # ]
6309 [ # # ][ # # ]: 0 : itor->second->reset_unique_id();
6310 : : }
6311 [ # # ]: 0 : itor++;
6312 : : }
6313 : :
6314 : : //clean out the map
6315 [ + - ]: 615 : uniqueIdMap.clear();
6316 : 615 : }
6317 : :
6318 : 0 : void PartitionEngine::notify_deactivated (PartitionBody* body)
6319 : : {
6320 : 0 : }
6321 : 0 : void PartitionEngine::notify_deactivated(PartitionLump* vol)
6322 : : {
6323 : 0 : }
6324 : 0 : void PartitionEngine::add_to_deactivated_list(PartitionLump* vol)
6325 : : {
6326 : 0 : }
6327 : 0 : void PartitionEngine::add_to_deactivated_list(PartitionBody* body)
6328 : : {
6329 : 0 : }
6330 : 0 : void PartitionEngine::notify_deactivated (PartitionSurface* surface)
6331 : : {
6332 : 0 : }
6333 : 0 : void PartitionEngine::add_to_deactivated_list (PartitionSurface* surface)
6334 : : {
6335 : 0 : }
6336 : 0 : void PartitionEngine::notify_deactivated (PartitionCurve* curve)
6337 : : {
6338 : 0 : }
6339 : 0 : void PartitionEngine::add_to_deactivated_list (PartitionCurve* curve)
6340 : : {
6341 : 0 : }
6342 : 0 : void PartitionEngine::notify_deactivated (PartitionPoint* point)
6343 : : {
6344 : 0 : }
6345 : 0 : void PartitionEngine::add_to_deactivated_list (PartitionPoint* point)
6346 : : {
6347 : 0 : }
6348 : 1706 : void PartitionEngine::clean_out_deactivated_geometry()
6349 : : {
6350 : 1706 : }
6351 : 120 : void PartitionEngine::remove_modified(DLIList<Surface*> &all_surfs,
6352 : : DLIList<Curve*> &all_curves, DLIList<TBPoint*> &all_pts)
6353 : : {
6354 : 120 : }
6355 : :
6356 : 0 : void PartitionEngine::get_tbs_with_bridge_manager_as_owner( TopologyBridge *source_bridge,
6357 : : DLIList<TopologyBridge*> &tbs )
6358 : : {
6359 [ # # ][ # # ]: 0 : BridgeManager* bm = dynamic_cast<BridgeManager*>(source_bridge->owner());
6360 [ # # ]: 0 : if( bm )
6361 : : {
6362 [ # # ]: 0 : tbs.append( source_bridge );
6363 : 0 : return;
6364 : : }
6365 : :
6366 [ # # ][ # # ]: 0 : SubEntitySet* set = dynamic_cast<SubEntitySet*>(source_bridge->owner());
6367 [ # # ]: 0 : if( !set )
6368 : 0 : return;
6369 : :
6370 [ # # ]: 0 : DLIList<PartitionEntity*> entity_list;
6371 [ # # ]: 0 : set->get_sub_entities( entity_list );
6372 [ # # ][ # # ]: 0 : DLIList<TopologyBridge*> tb_list;
6373 [ # # ][ # # ]: 0 : CAST_LIST( entity_list, tb_list, TopologyBridge );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
6374 : :
6375 [ # # ][ # # ]: 0 : while( tb_list.size() )
6376 : : {
6377 [ # # ]: 0 : TopologyBridge *tb = tb_list.pop();
6378 [ # # ][ # # ]: 0 : if( tb->bridge_manager() )
6379 [ # # ]: 0 : tbs.append( tb );
6380 : : else
6381 : : {
6382 [ # # ]: 0 : TBOwner *owner = tb->owner();
6383 [ # # ]: 0 : TopologyBridge *tmp_tb = CAST_TO( owner, TopologyBridge );
6384 [ # # ]: 0 : if( tmp_tb )
6385 [ # # ]: 0 : tb_list.append( tmp_tb );
6386 : : else
6387 : : {
6388 [ # # ]: 0 : CompositePoint *comp_pt = CAST_TO( tb, CompositePoint );
6389 [ # # ]: 0 : if( comp_pt )
6390 [ # # ][ # # ]: 0 : CompositeEngine::instance().get_tbs_with_bridge_manager_as_owner( tb, tb_list );
6391 : : else
6392 : : {
6393 [ # # ]: 0 : CompositeCurve *comp_curve = CAST_TO( tb, CompositeCurve );
6394 [ # # ]: 0 : if( comp_curve )
6395 [ # # ][ # # ]: 0 : CompositeEngine::instance().get_tbs_with_bridge_manager_as_owner( tb, tb_list );
6396 : : }
6397 : : }
6398 : : }
6399 : : }
6400 : :
6401 [ # # ]: 0 : tbs.uniquify_ordered();
6402 : :
6403 [ # # ]: 0 : return;
6404 [ + - ][ + - ]: 6364 : }
6405 : :
|