Branch data Line data Source code
1 : : //-Class: TDSplitSurface.cpp
2 : :
3 : : #include "TDSplitSurface.hpp"
4 : : #include "RefFace.hpp"
5 : : #include "RefEdge.hpp"
6 : : #include "RefVertex.hpp"
7 : : #include "CoEdge.hpp"
8 : : #include "Loop.hpp"
9 : : #include "GMem.hpp"
10 : : #include "CubitMessage.hpp"
11 : :
12 : 0 : TDSplitSurface::TDSplitSurface( int vertex_type )
13 : : {
14 : 0 : vertexType = vertex_type;
15 : 0 : sideA = NULL;
16 : 0 : sideB = NULL;
17 : 0 : sideC = NULL;
18 : 0 : sideD = NULL;
19 : 0 : }
20 : :
21 : 0 : TDSplitSurface::TDSplitSurface( RefFace *ref_face_ptr )
22 : : {
23 : 0 : refFacePtr = ref_face_ptr;
24 : :
25 : 0 : sideA = NULL;
26 : 0 : sideB = NULL;
27 : 0 : sideC = NULL;
28 : 0 : sideD = NULL;
29 : 0 : }
30 : :
31 : 0 : TDSplitSurface::~TDSplitSurface()
32 : : {
33 [ # # ]: 0 : if( sideA )
34 [ # # ][ # # ]: 0 : delete sideA;
35 [ # # ]: 0 : if( sideB )
36 [ # # ][ # # ]: 0 : delete sideB;
37 [ # # ]: 0 : if( sideC )
38 [ # # ][ # # ]: 0 : delete sideC;
39 [ # # ]: 0 : if( sideD )
40 [ # # ][ # # ]: 0 : delete sideD;
41 [ # # ]: 0 : }
42 : :
43 : : CubitStatus
44 : 0 : TDSplitSurface::add_coedges( DLIList<CoEdge*> &co_edge_list,
45 : : int side_interval[] )
46 : : {
47 : : int i;
48 [ # # ]: 0 : co_edge_list.reset();
49 : : CoEdge *co_edge_ptr;
50 [ # # ]: 0 : DLIList<CoEdge*> chain;
51 : : RefVertex *start_vertex_ptr;
52 : :
53 : : // SIDE A
54 [ # # ]: 0 : if( side_interval[0] == 0 )
55 : : {
56 [ # # ]: 0 : co_edge_ptr = co_edge_list.get();
57 [ # # ]: 0 : start_vertex_ptr = start_vertex( co_edge_ptr );
58 [ # # ]: 0 : CubitVector tmp(start_vertex_ptr->coordinates());
59 [ # # ][ # # ]: 0 : sideA = new SSSide( refFacePtr, chain, &tmp );
60 : : }
61 : : else
62 : : {
63 [ # # ]: 0 : for( i=side_interval[0]; i--; )
64 : : {
65 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
66 [ # # ]: 0 : chain.append( co_edge_ptr );
67 : : }
68 [ # # ][ # # ]: 0 : sideA = new SSSide( refFacePtr, chain );
69 : : }
70 [ # # ]: 0 : chain.clean_out();
71 : :
72 : : // SIDE B
73 [ # # ]: 0 : if( side_interval[1] == 0 )
74 : : {
75 [ # # ]: 0 : co_edge_ptr = co_edge_list.get();
76 [ # # ]: 0 : start_vertex_ptr = start_vertex( co_edge_ptr );
77 [ # # ]: 0 : CubitVector tmp(start_vertex_ptr->coordinates());
78 [ # # ][ # # ]: 0 : sideB = new SSSide( refFacePtr, chain, &tmp );
79 : : }
80 : : else
81 : : {
82 [ # # ]: 0 : for( i=side_interval[1]; i--; )
83 : : {
84 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
85 [ # # ]: 0 : chain.append( co_edge_ptr );
86 : : }
87 [ # # ][ # # ]: 0 : sideB = new SSSide( refFacePtr, chain );
88 : : }
89 [ # # ]: 0 : chain.clean_out();
90 : :
91 : : // SIDE C
92 [ # # ]: 0 : if( side_interval[2] == 0 )
93 : : {
94 [ # # ]: 0 : co_edge_ptr = co_edge_list.get();
95 [ # # ]: 0 : start_vertex_ptr = start_vertex( co_edge_ptr );
96 [ # # ]: 0 : CubitVector tmp(start_vertex_ptr->coordinates());
97 [ # # ][ # # ]: 0 : sideC = new SSSide( refFacePtr, chain, &tmp );
98 : : }
99 : : else
100 : : {
101 [ # # ]: 0 : for( i=side_interval[2]; i--; )
102 : : {
103 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
104 [ # # ]: 0 : chain.append( co_edge_ptr );
105 : : }
106 [ # # ][ # # ]: 0 : sideC = new SSSide( refFacePtr, chain );
107 : : }
108 [ # # ]: 0 : chain.clean_out();
109 : :
110 : : // SIDE D
111 [ # # ]: 0 : if( side_interval[3] == 0 )
112 : : {
113 [ # # ]: 0 : co_edge_ptr = co_edge_list.get();
114 [ # # ]: 0 : start_vertex_ptr = start_vertex( co_edge_ptr );
115 [ # # ]: 0 : CubitVector tmp(start_vertex_ptr->coordinates());
116 [ # # ][ # # ]: 0 : sideD = new SSSide( refFacePtr, chain, &tmp );
117 : : }
118 : : else
119 : : {
120 [ # # ]: 0 : for( i=side_interval[3]; i--; )
121 : : {
122 [ # # ]: 0 : co_edge_ptr = co_edge_list.get_and_step();
123 [ # # ]: 0 : chain.append( co_edge_ptr );
124 : : }
125 [ # # ][ # # ]: 0 : sideD = new SSSide( refFacePtr, chain );
126 : : }
127 : :
128 [ # # ]: 0 : return CUBIT_SUCCESS;
129 : : }
130 : :
131 : : CubitStatus
132 : 0 : TDSplitSurface::add_a_coedges( DLIList<CoEdge*> &a_coedges,
133 : : RefVertex *start_vertex_ptr )
134 : : {
135 [ # # ]: 0 : if( start_vertex_ptr == NULL )
136 [ # # ]: 0 : sideA = new SSSide( refFacePtr, a_coedges );
137 : : else
138 : : {
139 : : // Collapsed side (for triangle)
140 [ # # ]: 0 : CubitVector tmp(start_vertex_ptr->coordinates());
141 [ # # ][ # # ]: 0 : sideA = new SSSide( refFacePtr, a_coedges, &tmp );
142 : : }
143 : 0 : return CUBIT_SUCCESS;
144 : : }
145 : :
146 : : CubitStatus
147 : 0 : TDSplitSurface::add_b_coedges( DLIList<CoEdge*> &b_coedges,
148 : : RefVertex *start_vertex_ptr )
149 : : {
150 [ # # ]: 0 : if( start_vertex_ptr == NULL )
151 [ # # ]: 0 : sideB = new SSSide( refFacePtr, b_coedges );
152 : : else
153 : : {
154 : : // Collapsed side (for triangle)
155 [ # # ]: 0 : CubitVector tmp(start_vertex_ptr->coordinates());
156 [ # # ][ # # ]: 0 : sideB = new SSSide( refFacePtr, b_coedges, &tmp );
157 : : }
158 : 0 : return CUBIT_SUCCESS;
159 : : }
160 : :
161 : : CubitStatus
162 : 0 : TDSplitSurface::add_c_coedges( DLIList<CoEdge*> &c_coedges,
163 : : RefVertex *start_vertex_ptr )
164 : : {
165 [ # # ]: 0 : if( start_vertex_ptr == NULL )
166 [ # # ]: 0 : sideC = new SSSide( refFacePtr, c_coedges );
167 : : else
168 : : {
169 : : // Collapsed side (for triangle)
170 [ # # ]: 0 : CubitVector tmp(start_vertex_ptr->coordinates());
171 [ # # ][ # # ]: 0 : sideC = new SSSide( refFacePtr, c_coedges, &tmp );
172 : : }
173 : 0 : return CUBIT_SUCCESS;
174 : : }
175 : :
176 : : CubitStatus
177 : 0 : TDSplitSurface::add_d_coedges( DLIList<CoEdge*> &d_coedges,
178 : : RefVertex *start_vertex_ptr )
179 : : {
180 [ # # ]: 0 : if( start_vertex_ptr == NULL )
181 [ # # ]: 0 : sideD = new SSSide( refFacePtr, d_coedges );
182 : : else
183 : : {
184 : : // Collapsed side (for triangle)
185 [ # # ]: 0 : CubitVector tmp(start_vertex_ptr->coordinates());
186 [ # # ][ # # ]: 0 : sideD = new SSSide( refFacePtr, d_coedges, &tmp );
187 : : }
188 : 0 : return CUBIT_SUCCESS;
189 : : }
190 : :
191 : : DLIList<CoEdge*> *
192 : 0 : TDSplitSurface::get_a_coedges()
193 : : {
194 : 0 : return sideA->co_edges();
195 : : }
196 : :
197 : : DLIList<CoEdge*> *
198 : 0 : TDSplitSurface::get_b_coedges()
199 : : {
200 : 0 : return sideB->co_edges();
201 : : }
202 : :
203 : : DLIList<CoEdge*> *
204 : 0 : TDSplitSurface::get_c_coedges()
205 : : {
206 : 0 : return sideC->co_edges();
207 : : }
208 : :
209 : : DLIList<CoEdge*> *
210 : 0 : TDSplitSurface::get_d_coedges()
211 : : {
212 : 0 : return sideD->co_edges();
213 : : }
214 : :
215 : : CubitStatus
216 : 0 : TDSplitSurface::tessellate_sides( double tol, double fraction, double distance,
217 : : int num_segs,
218 : : DLIList<RefVertex*> &through_vertex_list )
219 : : {
220 : : // Sides B and D will use the graphics tessellation to build the
221 : : // param lists.
222 [ # # ]: 0 : if( sideB->build_param_list_from_facets( tol ) == CUBIT_FAILURE )
223 : 0 : return CUBIT_FAILURE;
224 [ # # ]: 0 : if( sideD->build_param_list_from_facets( tol ) == CUBIT_FAILURE )
225 : 0 : return CUBIT_FAILURE;
226 : :
227 : : // Syncronize the lists so that we have the same number and evenly
228 : : // spaced tessellations on B and D sides
229 [ # # ]: 0 : if( sideB->syncronize_lists( sideD, tol ) == CUBIT_FAILURE )
230 : : {
231 [ # # ][ # # ]: 0 : PRINT_ERROR( "Unable to interpolate split location.\n" );
232 : 0 : return CUBIT_FAILURE;
233 : : }
234 : :
235 : : // Sides A and C typically only need to retrieve the 50% location,
236 : : // but may have a location different than 50% or multiple locations.
237 : : // Note if num_segs>2 the fraction is ignored.
238 : :
239 : : // Populate lists for side A
240 [ # # ]: 0 : if( sideA->build_param_list( fraction, distance, num_segs, through_vertex_list )
241 : : == CUBIT_FAILURE )
242 : 0 : return CUBIT_FAILURE;
243 : :
244 : : // Populate lists for side C
245 [ # # ]: 0 : if( distance != -1.0 )
246 : 0 : distance = sideC->length()-distance;
247 : :
248 [ # # ]: 0 : if( sideC->build_param_list( 1.0-fraction, distance, num_segs,
249 : 0 : through_vertex_list ) == CUBIT_FAILURE )
250 : 0 : return CUBIT_FAILURE;
251 : :
252 : 0 : return CUBIT_SUCCESS;
253 : : }
254 : :
255 : : RefVertex *
256 : 0 : TDSplitSurface::start_vertex( CoEdge *co_edge_ptr )
257 : : {
258 : 0 : RefEdge *ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
259 : :
260 [ # # ]: 0 : if ( co_edge_ptr->get_sense() == CUBIT_REVERSED )
261 : 0 : return ref_edge_ptr->end_vertex();
262 : : else
263 : 0 : return ref_edge_ptr->start_vertex();
264 : : }
265 : :
266 : : //================================================================================
267 : : // Description: A trivial class to hold two parameter values so that they
268 : : // can be stored in a DLIList. They are the min and max parameter
269 : : // space along the composite curve. (Split Surface Param)
270 : : // Author : Steve Storm
271 : : // Date : 2/3/2004
272 : : //================================================================================
273 : 0 : SSParam::SSParam( double min, double max )
274 : : {
275 : 0 : uMin = min;
276 : 0 : uMax = max;
277 : 0 : }
278 : :
279 : 0 : SSParam::~SSParam()
280 : : {
281 : 0 : }
282 : :
283 : : //================================================================================
284 : : // Description: This class (Split Surface Side) holds a chain of curves on one
285 : : // side of the surface. It is needed to handle queries using a
286 : : // composite curve concept.
287 : : // Author : Steve Storm
288 : : // Date : 2/3/2004
289 : : //================================================================================
290 : 0 : SSSide::SSSide( RefFace *ref_face_ptr, DLIList<CoEdge*> &co_edges,
291 [ # # ][ # # ]: 0 : const CubitVector *collapsed_loc_ptr )
[ # # ]
292 : : {
293 : 0 : refFacePtr = ref_face_ptr;
294 : 0 : isCollapsed = CUBIT_FALSE;
295 : :
296 [ # # ]: 0 : coEdgeChain = co_edges;
297 : 0 : double param_low = 0.0;
298 : 0 : paramHigh = 0.0;
299 : : int i;
300 : : CoEdge *co_edge_ptr;
301 [ # # ][ # # ]: 0 : for( i=coEdgeChain.size(); i--; )
302 : : {
303 [ # # ]: 0 : co_edge_ptr = coEdgeChain.get_and_step();
304 [ # # ][ # # ]: 0 : paramHigh += co_edge_ptr->get_ref_edge_ptr()->measure();
305 [ # # ][ # # ]: 0 : coEdgeParamList.append( new SSParam( param_low, paramHigh) );
[ # # ]
306 : 0 : param_low = paramHigh;
307 : : }
308 : :
309 [ # # ][ # # ]: 0 : if( !coEdgeChain.size() )
310 : : {
311 : : // Need to add a single point to hold the location of this side
312 : : // ie., the side is collapsed (point of a triangle)
313 : 0 : isCollapsed = CUBIT_TRUE;
314 : :
315 [ # # ]: 0 : assert( collapsed_loc_ptr != NULL );
316 : :
317 : 0 : paramHigh = 0.0;
318 [ # # ][ # # ]: 0 : coordList.append( new CubitVector( *collapsed_loc_ptr ) );
[ # # ]
319 [ # # ]: 0 : paramList.append( 0.0 );
320 : : }
321 : 0 : }
322 : :
323 [ # # ][ # # ]: 0 : SSSide::~SSSide()
[ # # ]
324 : : {
325 : : // Free memory
326 [ # # ][ # # ]: 0 : while( coEdgeParamList.size() )
327 [ # # ][ # # ]: 0 : delete coEdgeParamList.pop();
[ # # ]
328 [ # # ][ # # ]: 0 : while( coordList.size() )
329 [ # # ]: 0 : delete coordList.pop();
330 : 0 : }
331 : :
332 : : CubitStatus
333 : 0 : SSSide::position_from_u( double u_value, CubitVector &output_position)
334 : : {
335 [ # # ]: 0 : if( isCollapsed )
336 : : {
337 [ # # ][ # # ]: 0 : output_position = *coordList.get();
338 : 0 : return CUBIT_SUCCESS;
339 : : }
340 : :
341 : : // Determine which CoEdge the given u is on
342 : : int i;
343 [ # # ]: 0 : coEdgeChain.reset();
344 [ # # ]: 0 : coEdgeParamList.reset();
345 : 0 : CoEdge *co_edge_ptr = NULL;
346 : 0 : SSParam *param_ptr = NULL;
347 : : double coedge_param_max;
348 [ # # ][ # # ]: 0 : for( i=coEdgeChain.size(); i--; )
349 : : {
350 [ # # ]: 0 : co_edge_ptr = coEdgeChain.get_and_step();
351 [ # # ]: 0 : param_ptr = coEdgeParamList.get_and_step();
352 [ # # ]: 0 : coedge_param_max = param_ptr->umax();
353 [ # # ]: 0 : if( u_value <= coedge_param_max )
354 : 0 : break;
355 : : }
356 : :
357 : : // We have found the correct coedge. Get it's RefEdge.
358 : : // Subtract it's start parameter.
359 : : // We now have the distance along the curve to traverse.
360 [ # # ]: 0 : RefEdge *ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
361 : : double i_dist; // individual distance
362 [ # # ]: 0 : i_dist = u_value - param_ptr->umin();
363 : :
364 : : double ui_min, ui_max;
365 [ # # ]: 0 : ref_edge_ptr->get_param_range( ui_min, ui_max );
366 : :
367 [ # # ][ # # ]: 0 : if( co_edge_ptr->get_sense() == CUBIT_REVERSED )
368 [ # # ]: 0 : i_dist = ref_edge_ptr->measure() - i_dist;
369 : :
370 [ # # ]: 0 : double ui = ref_edge_ptr->u_from_arc_length( ui_min, i_dist );
371 : :
372 [ # # ]: 0 : return ref_edge_ptr->position_from_u( ui, output_position );
373 : : }
374 : :
375 : : CubitStatus
376 : 0 : SSSide::u_from_position( const CubitVector &input_position, double &u )
377 : : {
378 [ # # ]: 0 : if( isCollapsed )
379 : : {
380 : 0 : u = 0.0;
381 : 0 : return CUBIT_SUCCESS;
382 : : }
383 : :
384 : : // First check each curve to determine which one the input position is on
385 : : int i;
386 [ # # ]: 0 : coEdgeChain.reset();
387 [ # # ]: 0 : coEdgeParamList.reset();
388 : 0 : CoEdge *co_edge_ptr = NULL;
389 : 0 : SSParam *param_ptr = NULL;
390 : 0 : int found = 0;
391 : : CubitPointContainment pnt_containment;
392 [ # # ][ # # ]: 0 : for( i=coEdgeChain.size(); i--; )
393 : : {
394 [ # # ]: 0 : co_edge_ptr = coEdgeChain.get_and_step();
395 [ # # ]: 0 : param_ptr = coEdgeParamList.get_and_step();
396 [ # # ][ # # ]: 0 : pnt_containment = co_edge_ptr->get_ref_edge_ptr()->point_containment( input_position );
397 [ # # ]: 0 : if( pnt_containment == CUBIT_PNT_ON )
398 : : {
399 : 0 : found = 1;
400 : 0 : break;
401 : : }
402 : : }
403 : :
404 [ # # ]: 0 : if( !found )
405 : : {
406 [ # # ][ # # ]: 0 : PRINT_ERROR( "Position %f, %f, %f not found on any curve.\n",
[ # # ][ # # ]
[ # # ][ # # ]
407 [ # # ]: 0 : input_position.x(), input_position.y(), input_position.z() );
408 : 0 : return CUBIT_FAILURE;
409 : : }
410 : :
411 : : // Now we know which CoEdge it is on. Get the curve. Get the parameter of
412 : : // the individual curve.
413 [ # # ]: 0 : RefEdge *ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
414 [ # # ]: 0 : double ui = ref_edge_ptr->u_from_position( input_position );
415 : :
416 : : // Get the parameter of the composite curve
417 : :
418 : : // Add the distance along the curve to its start param (umin)
419 [ # # ]: 0 : double sum = param_ptr->umin();
420 : :
421 : : double ui_min, ui_max;
422 [ # # ]: 0 : ref_edge_ptr->get_param_range( ui_min, ui_max );
423 : :
424 [ # # ]: 0 : CubitSense sense = co_edge_ptr->get_sense();
425 [ # # ]: 0 : double root_param = (sense == CUBIT_FORWARD) ? ui_min : ui_max;
426 : : double lfu = ( root_param < ui ) ?
427 : : ref_edge_ptr->length_from_u( root_param, ui ) :
428 [ # # ][ # # ]: 0 : ref_edge_ptr->length_from_u( ui, root_param );
[ # # ]
429 : :
430 : 0 : u = sum + fabs( lfu );
431 : :
432 : 0 : return CUBIT_SUCCESS;
433 : : }
434 : :
435 : : // Same as above function but curve is known
436 : : CubitStatus
437 : 0 : SSSide::u_from_position( const CubitVector &input_position,
438 : : CoEdge *co_edge_ptr, SSParam *param,
439 : : double &u )
440 : : {
441 [ # # ]: 0 : if( isCollapsed )
442 : : {
443 : 0 : u = 0.0;
444 : 0 : return CUBIT_SUCCESS;
445 : : }
446 : :
447 [ # # ]: 0 : RefEdge *ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
448 [ # # ]: 0 : double ui = ref_edge_ptr->u_from_position( input_position );
449 : :
450 : : // Get the parameter of the composite curve
451 [ # # ]: 0 : double sum = param->umin();
452 : :
453 : : double ui_min, ui_max;
454 [ # # ]: 0 : ref_edge_ptr->get_param_range( ui_min, ui_max );
455 : :
456 [ # # ]: 0 : CubitSense sense = co_edge_ptr->get_sense();
457 [ # # ]: 0 : double root_param = (sense == CUBIT_FORWARD) ? ui_min : ui_max;
458 : : double lfu = ( root_param < ui ) ?
459 : : ref_edge_ptr->length_from_u( root_param, ui ) :
460 [ # # ][ # # ]: 0 : ref_edge_ptr->length_from_u( ui, root_param );
[ # # ]
461 : :
462 : 0 : u = sum + fabs( lfu );
463 : :
464 : 0 : return CUBIT_SUCCESS;
465 : : }
466 : :
467 : : CubitBoolean
468 : 0 : SSSide::is_vertex_on( RefVertex *ref_vertex_ptr )
469 : : {
470 [ # # ]: 0 : if( isCollapsed )
471 : : {
472 : : // Compare coordinates
473 [ # # ]: 0 : CubitVector *side_coord = coordList.get();
474 : :
475 [ # # ][ # # ]: 0 : if( side_coord->about_equal( ref_vertex_ptr->coordinates() ) )
[ # # ]
476 : 0 : return CUBIT_TRUE;
477 : : else
478 : 0 : return CUBIT_FALSE;
479 : : }
480 : :
481 : : // Check if it is on each coedge
482 [ # # ]: 0 : CubitVector ref_coords = ref_vertex_ptr->coordinates();
483 : : CubitPointContainment pnt_containment;
484 : : int i;
485 : : CoEdge *co_edge_ptr;
486 [ # # ]: 0 : coEdgeChain.reset();
487 [ # # ][ # # ]: 0 : for( i=coEdgeChain.size(); i--; )
488 : : {
489 [ # # ]: 0 : co_edge_ptr = coEdgeChain.get_and_step();
490 : : pnt_containment = co_edge_ptr->get_ref_edge_ptr()->
491 [ # # ][ # # ]: 0 : point_containment( ref_coords );
492 [ # # ]: 0 : if( pnt_containment == CUBIT_PNT_ON )
493 : 0 : return CUBIT_TRUE;
494 : : }
495 : :
496 : 0 : return CUBIT_FALSE;
497 : : }
498 : :
499 : : CubitStatus
500 : 0 : SSSide::build_param_list_from_facets( double tolerance )
501 : : {
502 [ # # ]: 0 : if( isCollapsed )
503 : 0 : return CUBIT_SUCCESS;
504 : :
505 : : int i, j, num_pnts;
506 : : CoEdge *co_edge_ptr;
507 : : SSParam *param_ptr;
508 : : double param;
509 [ # # ]: 0 : CubitVector vec, *vec_ptr;
510 : :
511 [ # # ]: 0 : coEdgeChain.reset();
512 [ # # ]: 0 : coEdgeParamList.reset();
513 [ # # ]: 0 : co_edge_ptr = coEdgeChain.get();
514 [ # # ]: 0 : param_ptr = coEdgeParamList.get();
515 : :
516 : : // Get the first coordinate
517 [ # # ][ # # ]: 0 : if( co_edge_ptr->get_sense() == CUBIT_FORWARD )
518 [ # # ][ # # ]: 0 : vec = co_edge_ptr->get_ref_edge_ptr()->start_coordinates();
[ # # ]
519 : : else
520 [ # # ][ # # ]: 0 : vec = co_edge_ptr->get_ref_edge_ptr()->end_coordinates();
[ # # ]
521 : :
522 : : // Add to list
523 [ # # ][ # # ]: 0 : if( u_from_position( vec, co_edge_ptr, param_ptr, param ) == CUBIT_FAILURE )
524 : 0 : return CUBIT_FAILURE;
525 [ # # ]: 0 : paramList.append( param );
526 : :
527 [ # # ][ # # ]: 0 : for( i=coEdgeChain.size(); i--; )
528 : : {
529 [ # # ]: 0 : DLIList<CubitVector*> temp_vec_list;
530 [ # # ]: 0 : co_edge_ptr = coEdgeChain.get_and_step();
531 [ # # ]: 0 : param_ptr = coEdgeParamList.get_and_step();
532 [ # # ][ # # ]: 0 : GMem *g_mem = new GMem;
533 : :
534 [ # # ][ # # ]: 0 : co_edge_ptr->get_ref_edge_ptr()->get_graphics( *g_mem, tolerance );
535 : 0 : num_pnts = g_mem->pointListCount;
536 : :
537 [ # # ]: 0 : GPoint* point_list = g_mem->point_list();
538 : :
539 [ # # ]: 0 : for( j=0; j<num_pnts; j++ )
540 : : {
541 : : vec_ptr = new CubitVector(
542 [ # # ][ # # ]: 0 : point_list[j].x, point_list[j].y, point_list[j].z );
543 [ # # ]: 0 : temp_vec_list.append( vec_ptr );
544 : : }
545 : :
546 [ # # ][ # # ]: 0 : delete g_mem;
547 : :
548 [ # # ][ # # ]: 0 : if( co_edge_ptr->get_sense() == CUBIT_REVERSED )
549 [ # # ]: 0 : temp_vec_list.reverse();
550 : :
551 : : // Calculate corresponding parameter values
552 [ # # ]: 0 : temp_vec_list.reset();
553 : : // Skip the first point since already in the list
554 [ # # ]: 0 : vec_ptr = temp_vec_list.get_and_step();
555 [ # # ]: 0 : for( j=1; j<num_pnts; j++ )
556 : : {
557 [ # # ]: 0 : vec_ptr = temp_vec_list.get_and_step();
558 [ # # ][ # # ]: 0 : if( u_from_position( *vec_ptr, co_edge_ptr, param_ptr, param )
559 : : == CUBIT_FAILURE )
560 : 0 : return CUBIT_FAILURE;
561 [ # # ]: 0 : paramList.append( param );
562 : : }
563 : :
564 [ # # ][ # # ]: 0 : while( temp_vec_list.size() )
[ # # ][ # # ]
565 [ # # ]: 0 : delete temp_vec_list.pop();
566 : 0 : }
567 : :
568 : : // Extremes of paramList should be 0.0 and paramHigh - force them to
569 : : // these values exactly. This avoids some slight roundoff errors that
570 : : // can cause an extra split point close to the start or end of a surface
571 : : // that won't even be cleaned up in syncronize_lists. This causes
572 : : // unexpected results at the start or end of the split.
573 [ # # ]: 0 : paramList.reset();
574 [ # # ]: 0 : double first_param = paramList.get_and_back();
575 [ # # ]: 0 : double last_param = paramList.get();
576 [ # # ]: 0 : paramList.reset();
577 [ # # ]: 0 : if( first_param > last_param )
578 : : {
579 [ # # ]: 0 : paramList.change_to( paramHigh );
580 [ # # ]: 0 : paramList.back();
581 [ # # ]: 0 : paramList.change_to( 0.0 );
582 : : }
583 : : else
584 : : {
585 [ # # ]: 0 : paramList.change_to( 0.0 );
586 [ # # ]: 0 : paramList.back();
587 [ # # ]: 0 : paramList.change_to( paramHigh );
588 : : }
589 : :
590 : 0 : return CUBIT_SUCCESS;
591 : : }
592 : :
593 : : CubitStatus
594 : 0 : SSSide::build_param_list( double fraction, double distance, int num_segs,
595 : : DLIList<RefVertex*> &through_vertex_list )
596 : : {
597 : : int i;
598 : : double frac, param;
599 : : // Add paramList.size to account for potential collapsed edge that already
600 : : // has an item in the list
601 [ # # ][ # # ]: 0 : for( i=1+paramList.size(); i<num_segs; i++ )
602 : : {
603 : : // Example locations (we need to fill middle only): 0 1 2 3 4
604 [ # # ]: 0 : if( num_segs > 2 )
605 : 0 : frac = (double)i/num_segs;
606 [ # # ][ # # ]: 0 : else if( through_vertex_list.size() )
607 : : {
608 : : int j;
609 : 0 : int found = 0;
610 [ # # ]: 0 : through_vertex_list.reset();
611 [ # # ][ # # ]: 0 : for( j=through_vertex_list.size(); j--; )
612 : : {
613 [ # # ]: 0 : RefVertex *ref_vertex_ptr = through_vertex_list.get_and_step();
614 [ # # ][ # # ]: 0 : if( is_vertex_on( ref_vertex_ptr ) )
615 : : {
616 [ # # ][ # # ]: 0 : coordList.append( new CubitVector( ref_vertex_ptr->coordinates() ) );
[ # # ]
617 [ # # ][ # # ]: 0 : if( u_from_position( ref_vertex_ptr->coordinates(), param ) == CUBIT_FAILURE )
[ # # ]
618 : 0 : return CUBIT_FAILURE;
619 [ # # ]: 0 : paramList.append( param );
620 : 0 : found = 1;
621 : :
622 : : // Keep track of vertices that were used - we can give a warning when
623 : : // done if some weren't used.
624 : : TDSplitSurface *tdss = (TDSplitSurface *)ref_vertex_ptr->
625 [ # # ]: 0 : get_TD(&TDSplitSurface::is_split_surface);
626 [ # # ]: 0 : if( !tdss )
627 [ # # ][ # # ]: 0 : ref_vertex_ptr->add_TD( new TDSplitSurface( 0 ) );
[ # # ]
628 : 0 : break;
629 : : }
630 : : }
631 [ # # ]: 0 : if( found )
632 : 0 : continue;
633 : : else
634 : 0 : frac = fraction;
635 : : }
636 : : else
637 : 0 : frac = fraction;
638 : :
639 [ # # ]: 0 : if( distance != -1.0 )
640 : : {
641 [ # # ]: 0 : if( distance > paramHigh )
642 : : {
643 [ # # ][ # # ]: 0 : PRINT_ERROR( "Surface %d is not wide enough to support split distance of %f\n",
[ # # ][ # # ]
644 [ # # ]: 0 : refFacePtr->id(), distance );
645 : 0 : return CUBIT_FAILURE;
646 : : }
647 : 0 : param = distance;
648 : : }
649 : : else
650 : 0 : param = frac*paramHigh;
651 : :
652 [ # # ]: 0 : paramList.append( param );
653 : :
654 [ # # ]: 0 : CubitVector vec;
655 [ # # ][ # # ]: 0 : if( position_from_u( param, vec ) == CUBIT_FAILURE )
656 : 0 : return CUBIT_FAILURE;
657 : :
658 [ # # ][ # # ]: 0 : coordList.append( new CubitVector( vec ) );
[ # # ]
659 : : }
660 : :
661 : 0 : return CUBIT_SUCCESS;
662 : : }
663 : :
664 : : CubitStatus
665 : 0 : SSSide::syncronize_lists( SSSide *other_side, double param_tol )
666 : : {
667 : : // This will syncronize paramList in "this" and other_side, also
668 : : // update coordList correspondingly in both.
669 : :
670 : : // Note: sideB and sideD (which we are operating on here) will contain the
671 : : // corner coords (sideA and sideC just contain the interior coords)
672 : :
673 : : // This should never happen but check anyway
674 [ # # ][ # # ]: 0 : if( paramHigh == 0.0 && other_side->paramHigh == 0.0 )
675 : 0 : return CUBIT_FAILURE;
676 : :
677 [ # # ]: 0 : paramList.reset();
678 [ # # ]: 0 : other_side->paramList.reset();
679 : :
680 [ # # ]: 0 : DLIList<double> other_param_list = other_side->paramList;
681 : : int i;
682 : : double param;
683 : :
684 : : // Reverse other_param_list (which is on side D) so that it is going in the
685 : : // same direction as this paramList (side B)
686 [ # # ]: 0 : other_param_list.reset();
687 [ # # ][ # # ]: 0 : for( i=other_param_list.size(); i--; )
688 : : {
689 [ # # ]: 0 : param = other_param_list.get();
690 [ # # ]: 0 : other_param_list.change_to( other_side->paramHigh - param );
691 [ # # ]: 0 : other_param_list.step();
692 : : }
693 : :
694 [ # # ]: 0 : other_param_list.reverse(); // May make sort faster
695 : :
696 : : // Parameter lists must be "scaled" to match
697 : 0 : double this_factor = 1.0;
698 : 0 : double other_factor = 1.0;
699 : 0 : double scale_factor = 1.0;
700 : :
701 : : // Only scale if neither side is a zero length side and sides are not equal
702 : : // in length
703 [ # # ][ # # ]: 0 : if( !isCollapsed && !other_side->is_collapsed() &&
[ # # ][ # # ]
[ # # ]
704 : 0 : other_side->paramHigh != paramHigh )
705 : : {
706 : : // Use longer side as "baseline" - it may have more "features"
707 : : // so we will be sure to capture those
708 [ # # ]: 0 : if( paramHigh > other_side->paramHigh )
709 : : {
710 [ # # ]: 0 : other_param_list.reset();
711 : :
712 : 0 : other_factor = paramHigh/other_side->paramHigh;
713 : 0 : scale_factor = other_factor;
714 [ # # ][ # # ]: 0 : for( i=other_param_list.size(); i--; )
715 : : {
716 [ # # ]: 0 : param = other_param_list.get();
717 [ # # ]: 0 : other_param_list.change_to( param*other_factor );
718 [ # # ]: 0 : other_param_list.step();
719 : : }
720 : : }
721 : : else
722 : : {
723 [ # # ]: 0 : paramList.reset();
724 : :
725 : 0 : this_factor = other_side->paramHigh/paramHigh;
726 : 0 : scale_factor = this_factor;
727 [ # # ][ # # ]: 0 : for( i=paramList.size(); i--; )
728 : : {
729 [ # # ]: 0 : param = paramList.get();
730 [ # # ]: 0 : paramList.change_to( param*this_factor );
731 [ # # ]: 0 : paramList.step();
732 : : }
733 : : }
734 : : }
735 : :
736 [ # # ][ # # ]: 0 : DLIList<double> combined_param_list = paramList;
737 [ # # ]: 0 : combined_param_list.merge_unique( other_param_list );
738 : :
739 : : // This should never happen, but check anyway
740 [ # # ][ # # ]: 0 : if( combined_param_list.size() < 2 )
741 : 0 : return CUBIT_FAILURE;
742 : :
743 : : // Sort the list from low to high
744 [ # # ]: 0 : combined_param_list.sort();
745 : :
746 : : // Remove near values
747 : 0 : param_tol = param_tol*scale_factor; // Scale tolerance to length
748 : : double prev_param;
749 [ # # ]: 0 : combined_param_list.reset();
750 [ # # ]: 0 : prev_param = combined_param_list.get_and_step();
751 [ # # ][ # # ]: 0 : for( i=combined_param_list.size()-2; i--; )
752 : : {
753 [ # # ]: 0 : param = combined_param_list.get();
754 [ # # ]: 0 : if( fabs(param - prev_param) < param_tol )
755 : : {
756 [ # # ]: 0 : combined_param_list.change_to( -1.0 );
757 : : }
758 : : else
759 : : {
760 : 0 : prev_param = param;
761 : : }
762 [ # # ]: 0 : combined_param_list.step();
763 : : }
764 [ # # ]: 0 : combined_param_list.remove_all_with_value(-1.0);
765 : :
766 : : // We need to check if there are near coincident points at the end of the list
767 [ # # ]: 0 : combined_param_list.last();
768 [ # # ]: 0 : prev_param = combined_param_list.get_and_back();
769 [ # # ]: 0 : param = combined_param_list.get();
770 : : // Use 10.0 * GEOMETRY_RESABS because Granite cannot handle points
771 : : // any closer together when making a spline
772 [ # # ]: 0 : if( fabs( prev_param-param ) < 10.0*GEOMETRY_RESABS*scale_factor )
773 : : {
774 : : // Remove the second to last value
775 [ # # ]: 0 : combined_param_list.last();
776 [ # # ]: 0 : combined_param_list.back();
777 [ # # ]: 0 : combined_param_list.remove();
778 : :
779 [ # # ][ # # ]: 0 : if( combined_param_list.size() < 2 )
780 : 0 : return CUBIT_FAILURE;
781 : : }
782 : :
783 : : // Also check if there are near coincident points anywhere along the
784 : : // other (shorter) side (very doubtful, but check anyway)
785 [ # # ]: 0 : if( scale_factor > 1.0 )
786 : : {
787 : 0 : param_tol = 10.0*GEOMETRY_RESABS*scale_factor;
788 : : double prev_param;
789 [ # # ]: 0 : combined_param_list.reset();
790 [ # # ]: 0 : prev_param = combined_param_list.get_and_step();
791 [ # # ][ # # ]: 0 : for( i=combined_param_list.size()-2; i--; )
792 : : {
793 [ # # ]: 0 : param = combined_param_list.get();
794 [ # # ]: 0 : if( fabs(param - prev_param) < param_tol )
795 : : {
796 [ # # ]: 0 : combined_param_list.change_to( -1.0 );
797 : : }
798 : : else
799 : : {
800 : 0 : prev_param = param;
801 : : }
802 [ # # ]: 0 : combined_param_list.step();
803 : : }
804 [ # # ]: 0 : combined_param_list.remove_all_with_value(-1.0);
805 : : }
806 : :
807 : : // Update this paramList
808 [ # # ]: 0 : if( isCollapsed )
809 : : {
810 : : // This is a collapsed triangle side, so just stuff it with the proper
811 : : // number of params and coordinates
812 [ # # ]: 0 : paramList.clean_out();
813 [ # # ][ # # ]: 0 : for( i=combined_param_list.size(); i--; )
814 [ # # ]: 0 : paramList.append( 0.0 );
815 : :
816 : : // It will already have one coordinate - copy it to the others
817 : : CubitVector *vec;
818 [ # # ]: 0 : vec = coordList.get();
819 [ # # ][ # # ]: 0 : for( i=combined_param_list.size()-1; i--; )
820 [ # # ][ # # ]: 0 : coordList.append( new CubitVector( *vec ) );
[ # # ]
821 : : }
822 : : else
823 : : {
824 [ # # ]: 0 : paramList.clean_out();
825 [ # # ]: 0 : paramList = combined_param_list;
826 : :
827 : : // Generate this coordList.
828 [ # # ]: 0 : CubitVector vec;
829 [ # # ]: 0 : paramList.reset();
830 [ # # ][ # # ]: 0 : for( i=paramList.size(); i--; )
831 : : {
832 [ # # ]: 0 : param = paramList.get();
833 : 0 : param = param/this_factor; // Normalize it
834 [ # # ]: 0 : paramList.change_to( param ); // Set proper value in paramList
835 [ # # ]: 0 : position_from_u( param, vec );
836 [ # # ][ # # ]: 0 : coordList.append( new CubitVector( vec ) );
[ # # ]
837 [ # # ]: 0 : paramList.step();
838 : : }
839 : : }
840 : :
841 : : // Do the same for the other side
842 [ # # ][ # # ]: 0 : if( other_side->is_collapsed() )
843 : : {
844 : : // This is a collapsed triangle side, so just stuff it with the proper
845 : : // number of params and coordinates
846 [ # # ]: 0 : other_side->paramList.clean_out();
847 [ # # ][ # # ]: 0 : for( i=combined_param_list.size(); i--; )
848 [ # # ]: 0 : other_side->paramList.append( 0.0 );
849 : :
850 : : // It will already have one coordinate - copy it to the others
851 : : CubitVector *vec;
852 [ # # ]: 0 : vec = other_side->coordList.get();
853 [ # # ][ # # ]: 0 : for( i=combined_param_list.size()-1; i--; )
854 [ # # ][ # # ]: 0 : other_side->coordList.append( new CubitVector( *vec ) );
[ # # ]
855 : : }
856 : : else
857 : : {
858 [ # # ]: 0 : combined_param_list.reset();
859 [ # # ][ # # ]: 0 : for( i=combined_param_list.size(); i--; )
860 : : {
861 [ # # ]: 0 : param = combined_param_list.get();
862 [ # # ]: 0 : combined_param_list.change_to( other_side->paramHigh-param/other_factor );
863 [ # # ]: 0 : combined_param_list.step();
864 : : }
865 [ # # ]: 0 : combined_param_list.reverse();
866 : :
867 [ # # ]: 0 : CubitVector vec;
868 [ # # ]: 0 : other_side->paramList.clean_out();
869 [ # # ]: 0 : other_side->paramList = combined_param_list;
870 [ # # ]: 0 : combined_param_list.reset();
871 [ # # ][ # # ]: 0 : for( i=combined_param_list.size(); i--; )
872 : : {
873 [ # # ]: 0 : param = combined_param_list.get_and_step();
874 [ # # ]: 0 : other_side->position_from_u( param, vec );
875 [ # # ][ # # ]: 0 : other_side->coordList.append( new CubitVector( vec ) );
[ # # ]
876 : : }
877 : : }
878 : :
879 [ # # ]: 0 : return CUBIT_SUCCESS;
880 : : }
881 : :
882 : : //================================================================================
883 : : // Description: This class holds data on vertices for split across extend
884 : : // Author : Steve Storm
885 : : // Date : 10/7/2007
886 : : //================================================================================
887 : 0 : TDSplitSurfaceExtend::TDSplitSurfaceExtend()
888 : : {
889 : 0 : successFlg = CUBIT_FALSE;
890 : 0 : }
891 : :
892 : 0 : TDSplitSurfaceExtend::~TDSplitSurfaceExtend()
893 : : {
894 [ + - ][ + - ]: 6540 : }
[ # # ]
|