Branch data Line data Source code
1 : :
2 : : #include "VGLoopTool.hpp"
3 : : #include "GMem.hpp"
4 : : #include "GeometryQueryEngine.hpp"
5 : : #include "CubitVector.hpp"
6 : : /*
7 : : //-------------------------------------------------------------------------
8 : : // Purpose : Remove a curve from a loop
9 : : //
10 : : // Special Notes :
11 : : //
12 : : // Creator : Jason Kraftcheck
13 : : //
14 : : // Creation Date : 08/14/02
15 : : //-------------------------------------------------------------------------
16 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
17 : : CubitStatus VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
18 : : remove_curve( COEDGE* coedge1, COEDGE* coedge2,
19 : : DLIList<COEDGE*>& new_loop_coedges )
20 : : {
21 : : new_loop_coedges.clean_out();
22 : :
23 : : if( !coedge1->get_loop() || !coedge2->get_loop() )
24 : : return CUBIT_FAILURE;
25 : :
26 : : // remove sipe or split loop?
27 : : if( coedge1->get_loop() == coedge2->get_loop() )
28 : : {
29 : : // split loop?
30 : : if( coedge1->next() != coedge2 && coedge1->prev() != coedge2 )
31 : : {
32 : : COEDGE* coedge = coedge1->next();
33 : : while( coedge != coedge2 )
34 : : {
35 : : COEDGE* next = coedge;
36 : : coedge->get_loop()->remove( coedge );
37 : : new_loop_coedges.append( coedge );
38 : : coedge = next;
39 : : }
40 : : }
41 : :
42 : : coedge1->get_loop()->remove( coedge1 );
43 : : coedge2->get_loop()->remove( coedge2 );
44 : : }
45 : :
46 : : // stitch/combine loops
47 : : else
48 : : {
49 : : COEDGE* coedge;
50 : :
51 : : // insert coedges
52 : : while( coedge2->next() != coedge2 ) // loop has more than 1 coedge
53 : : {
54 : : coedge = coedge2->next();
55 : : coedge2->get_loop()->remove( coedge );
56 : : coedge1->insert_before( coedge, coedge1 );
57 : : }
58 : : coedge1->get_loop()->remove( coedge1 );
59 : : coedge2->get_loop()->remove( coedge2 );
60 : : }
61 : :
62 : : return CUBIT_SUCCESS;
63 : : }
64 : :
65 : : //-------------------------------------------------------------------------
66 : : // Purpose : Insert a curve in a loop
67 : : //
68 : : // Special Notes :
69 : : //
70 : : // Creator : Jason Kraftcheck
71 : : //
72 : : // Creation Date : 08/14/02
73 : : //-------------------------------------------------------------------------
74 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
75 : : CubitStatus VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
76 : : insert_curve( COEDGE* coedge1, COEDGE* coedge2,
77 : : SURFACE* surface, LOOP*& new_loop1, LOOP*& new_loop2 )
78 : : {
79 : : assert( coedge1 && coedge2 &&
80 : : coedge1->get_curve() == coedge2->get_curve() &&
81 : : coedge1->sense() != coedge2->sense() );
82 : : new_loop1 = new_loop2 = 0;
83 : :
84 : : if( coedge1->sense() == CUBIT_REVERSED )
85 : : {
86 : : COEDGE* tmp = coedge1;
87 : : coedge2 = coedge2;
88 : : coedge2 = tmp;
89 : : }
90 : :
91 : : // Find loop insertion locations.
92 : : COEDGE *start_prev = 0, *end_prev = 0;
93 : : if( ! previous_coedge( coedge2, surface, start_prev ) ||
94 : : ! previous_coedge( coedge1, surface, end_prev ) )
95 : : return CUBIT_FAILURE;
96 : :
97 : : // If no loop was passed, just pass back the coedges
98 : : // so that the caller can create new loop(s)
99 : : if( !(start_prev || end_prev) )
100 : : {
101 : : new_loop1 = new LOOP;
102 : : new_loop1->insert_after( coedge1, 0 );
103 : : if( coedge1->start_point() == coedge1->end_point() )
104 : : {
105 : : new_loop2 = new LOOP;
106 : : new_loop2->insert_after( coedge2, 0 );
107 : : }
108 : : else
109 : : {
110 : : new_loop1->insert_after( coedge2, coedge1 );
111 : : }
112 : :
113 : : return CUBIT_SUCCESS;
114 : : }
115 : :
116 : :
117 : : // sipe?
118 : : if( !loop1_prev || !loop2_prev )
119 : : {
120 : : COEDGE *prev = loop1_prev ? loop1_prev : loop2_prev;
121 : : if( coedge1->start_point() == prev->end_point() )
122 : : {
123 : : prev->get_loop()->insert_after( coedge1, prev );
124 : : prev->get_loop()->insert_after( coedge2, coedge1 );
125 : : }
126 : : else if( coedge1->end_point() == prev->end_point() )
127 : : {
128 : : prev->get_loop()->insert_after( coedge2, prev );
129 : : prev->get_loop()->insert_after( coedge1, coedge2 );
130 : : }
131 : : else
132 : : {
133 : : assert(0);
134 : : return CUBIT_FAILURE;
135 : : }
136 : : }
137 : :
138 : : // combine loops?
139 : : else if( loop1_prev->get_loop() != loop2_prev->get_loop() )
140 : : {
141 : : COEDGE* prev = 0;
142 : :
143 : : // Which of the two coedges for the curve are
144 : : // inserting do we want to begin with?
145 : : if( coedge1->start_point() == loop1_prev->end_point() )
146 : : {
147 : : loop1_prev->get_loop()->insert_after( coedge1, loop1_prev );
148 : : loop1_prev->get_loop()->insert_after( coedge2, coedge1 );
149 : : prev = coedge1;
150 : : }
151 : : else if( coedge2->start_point() == loop1_prev->end_point() )
152 : : {
153 : : loop1_prev->get_loop()->insert_after( coedge2, loop1_prev );
154 : : loop1_prev->get_loop()->insert_after( coedge1, coedge2 );
155 : : prev = coedge2;
156 : : }
157 : : else
158 : : {
159 : : assert(0);
160 : : return CUBIT_FAILURE;
161 : : }
162 : :
163 : : COEDGE* coedge = loop2_prev->next();
164 : : COEDGE* next = 0;
165 : : while( loop2_prev->get_loop() != loop1_prev->get_loop() )
166 : : {
167 : : next = coedge->next();
168 : : coedge->get_loop()->remove( coedge );
169 : : loop1_prev->get_loop()->insert_after( coedge, prev );
170 : : prev = coedge;
171 : : coedge = next;
172 : : }
173 : :
174 : : }
175 : :
176 : : // split the loop
177 : : else
178 : : {
179 : : assert( loop1_prev->get_loop() == loop2_prev->get_loop() );
180 : :
181 : : // check for and handle a hole insersecting the original
182 : : // loop at just one vertex
183 : : if( coedge1->start_point() == coedge1->end_point() )
184 : : {
185 : : assert( loop1_prev == loop2_prev );
186 : :
187 : : CubitVector prev_tan, coe1_tan, coe2_tan, norm, junk;
188 : : CubitVector point = coedge1->start_point()->coordinates();
189 : : loop1_prev->get_curve()->closest_point( point, junk, &prev_tan );
190 : : if( loop1_prev->sense() == CUBIT_FORWARD ) // yes, I mean forward here!!
191 : : prev_tan *= -1.0;
192 : : coedge1->get_curve()->closest_point( point, junk, &coe1_tan );
193 : : coe2_tan = coe1_tan;
194 : : if( coedge1->sense() == CUBIT_REVERSED )
195 : : coe1_tan *= -1.0;
196 : : if( coedge2->sense() == CUBIT_REVERSED )
197 : : coe2_tan *= -1.0;
198 : : loop1_prev->get_loop()->get_surface()->closest_point( point, 0, &norm );
199 : :
200 : : double angle1 = norm.vector_angle( prev_tan, coe1_tan );
201 : : double angle2 = norm.vector_angle( prev_tan, coe2_tan );
202 : :
203 : : if( angle2 < angle1 )
204 : : {
205 : : COEDGE* temp = coedge2;
206 : : coedge2 = coedge1;
207 : : coedge1 = temp;
208 : : }
209 : : }
210 : :
211 : : else if( coedge1->end_point() == loop2_prev->end_point() )
212 : : {
213 : : COEDGE* temp = coedge2;
214 : : coedge2 = coedge1;
215 : : coedge1 = temp;
216 : : }
217 : :
218 : :
219 : : new_loop1 = new LOOP;
220 : : loop1_prev->insert_after( coedge1, loop2_prev );
221 : : new_loop1->insert_after( coedge2, 0 );
222 : : COEDGE* prev = coedge2;
223 : :
224 : : COEDGE* coedge = loop2_prev->next();
225 : : COEDGE* stop = loop1_prev->next();
226 : : while( coedge != stop )
227 : : {
228 : : COEDGE* next = coedge->next();
229 : : coedge->get_loop()->remove( coedge );
230 : : new_loop1->insert_after( coedge, prev );
231 : : prev = coedge;
232 : : coedge = next;
233 : : }
234 : :
235 : : }
236 : :
237 : : return CUBIT_SUCCESS;
238 : : }
239 : : */
240 : : /*
241 : : template <class SURFACE, class LOOP, class COEDGE, class CURVE, class POINT>
242 : : CubitStatus VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
243 : : VGLoopTool::curves_in_loop( LOOP* loop, POINT* point, DLIList<CURVE*>& results )
244 : : {
245 : : CURVE* curve = 0;
246 : : while ( (curve = point->next_curve(curve)) )
247 : : {
248 : : COEDGE* coedge = 0;
249 : : while ( (coedge = curve->next_coedge(coedge)) )
250 : : {
251 : : if (coedge->get_loop() == loop)
252 : : {
253 : : results.append(curve);
254 : : break;
255 : : }
256 : : }
257 : : }
258 : : return CUBIT_SUCCESS;
259 : : }
260 : :
261 : : template <class SURFACE, class LOOP, class COEDGE, class CURVE, class POINT>
262 : : CubitStatus VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
263 : : VGLoopTool::traverse_coedges( LOOP* loop, COEDGE* coedge, DLIList<COEDGE*>& results )
264 : : {
265 : : // Traverse coedges, appending them to the list until
266 : : // the end point is reached.
267 : : POINT* loop_point = coedge->start_point();
268 : : results.append(coedge);
269 : : DLIList<CURVE*> loop_curves;
270 : : while ( coedge->end_point() != loop_point )
271 : : {
272 : : POINT* point = coedge->end_point();
273 : : loop_curves.clean_out();
274 : : curves_in_loop( loop, point, loop_curves );
275 : :
276 : : COEDGE *boundary_coedge = 0, *split_coedge = 0;
277 : : while( loop_curves.size() )
278 : : {
279 : : CURVE* curve = loop_curves.pop();
280 : : if ( curve == coedge->get_curve() )
281 : : continue;
282 : :
283 : : COEDGE* curve_coedge = 0;
284 : : while ( (curve_coedge = curve->next_coedge(curve_coedge)) )
285 : : {
286 : : if ((curve_coedge->get_loop() != loop_to_split()) ||
287 : : (curve_coedge->start_point() != point))
288 : : continue;
289 : :
290 : : if (curve_coedge->get_curve()->mark == 2)
291 : : {
292 : : if (split_coedge)
293 : : { assert(0); return CUBIT_FAILURE; }
294 : : split_coedge = curve_coedge;
295 : : }
296 : : else if(curve_coedge->get_curve()->mark == 0)
297 : : {
298 : : if (boundary_coedge)
299 : : { assert(0); return CUBIT_FAILURE; }
300 : : boundary_coedge = curve_coedge;
301 : : }
302 : : }
303 : : }
304 : :
305 : : if (split_coedge)
306 : : coedge = split_coedge;
307 : : else if(boundary_coedge)
308 : : coedge = boundary_coedge;
309 : : else
310 : : { assert(0); return CUBIT_FAILURE; }
311 : :
312 : : results.append(coedge);
313 : : }
314 : :
315 : : return CUBIT_SUCCESS;
316 : : }
317 : :
318 : :
319 : : template <class SURFACE, class LOOP, class COEDGE, class CURVE, class POINT>
320 : : LOOP* VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
321 : : VGLoopTool::split_loop( LOOP* loop_to_split )
322 : : {
323 : : // Make sure all coedge curve marks are cleared,
324 : : // and count coedges (use the count to make sure
325 : : // things are going okay later)
326 : : int coedge_count = 0;
327 : : COEDGE* coedge = loop_to_split->first_coedge();
328 : : do {
329 : : coedge->mark = 0;
330 : : coedge->get_curve()->mark = 0;
331 : : coedge_count++;
332 : : coedge = loop_to_split->next_coedge(coedge);
333 : : } while ( coedge != loop_to_split->first_coedge() );
334 : :
335 : : // Identify non-manifold curves, marking them either
336 : : // with a 2 if they can be used to split the surface
337 : : // (if they are part of a connected patch for which the
338 : : // bounadary of that patch intersects the surface boundary
339 : : // at all points) or a 3 if they are other non-manifold
340 : : // curves. This will get a bit tricky if there are
341 : : // non-manifold curves hanging off of the patch of
342 : : // split curves.
343 : :
344 : : // First for all non-manifold curves, if the curve has
345 : : // a point that is not shared with any other curve, mark
346 : : // it with a 3. Otherwise mark it with a 2.
347 : : DLIList<CURVE*> curve_stack, loop_curves, nonman_curves;
348 : : coedge = loop_to_split->first_coedge();
349 : : do {
350 : : CURVE* curve = coedge->get_curve();
351 : : // If we haven't done this curve yet and it is non-manifold
352 : : if ( !curve->mark && curve->find_next(coedge) )
353 : : {
354 : : curve->mark = 2;
355 : :
356 : : for ( int i = 2; i--; )
357 : : {
358 : : POINT* point = i ? curve->start_point() : curve->end_point();
359 : : loop_curves.clean_out();
360 : : curves_in_loop( loop_to_split, curve->start_point(), loop_curves );
361 : : if ( loop_curves.size() == 1 )
362 : : {
363 : : curve->mark = 3;
364 : : curve_stack.append(curve);
365 : : nonman_curves.append(curve);
366 : : break;
367 : : }
368 : : }
369 : : }
370 : :
371 : : coedge = loop_to_split->next_coedge(coedge);
372 : : } while( coedge != loop_to_split->first_coedge() );
373 : :
374 : : // Now for each curve we marked with a three, traverse
375 : : // and mark adjacent curve until we come to a point
376 : : // connected to more that two curves.
377 : : while( curve_stack.size() )
378 : : {
379 : : CURVE* curve = curve_stack.pop();
380 : :
381 : : for ( int i = 2; i--; )
382 : : {
383 : : POINT* point = i ? curve->start_point() : curve->end_point();
384 : : loop_curves.clean_out();
385 : : curves_in_loop( loop_to_split, curve->start_point(), loop_curves );
386 : : if ( loop_curves.size() != 2 )
387 : : continue;
388 : :
389 : : loop_curves.move_to(curve);
390 : : CURVE* other = loop_curves.next();
391 : : assert(other && other != curve );
392 : :
393 : : if ( other->mark != 3 )
394 : : {
395 : : other->mark = 3;
396 : : curve_stack.append(other);
397 : : nonman_curves.append(other);
398 : : }
399 : : }
400 : : }
401 : :
402 : : // Find a split curve to begin at.
403 : : coedge = loop_to_split->first_coedge();
404 : : do
405 : : {
406 : : if ( coedge->get_curve()->mark == 2 )
407 : : break;
408 : : coedge = loop_to_split->next_coedge(coedge);
409 : : } while( coedge != loop_to_split->first_coedge() );
410 : :
411 : : if ( coedge->get_curve()->mark != 2 )
412 : : { assert(0); return 0; }
413 : :
414 : : // Get two coedges for split curve
415 : : COEDGE *coedge1 = coedge, *coedge2 = 0;
416 : : coedge = 0;
417 : : while ( (coedge = coedge1->get_curve()->next_coedge(coedge)) )
418 : : if (coedge != coedge1)
419 : : { coedge2 = coedge; break; }
420 : : assert( coedge2 && coedge2->sense() != coedge1->sense() );
421 : :
422 : : // Get coedges for each loop by traversing from
423 : : // split curve coedges
424 : : DLIList<COEDGE*> old_loop_coedges, new_loop_coedges;
425 : : if ( !traverse_loop(loop_to_split, coedge1, old_loop_coedges) )
426 : : return 0;
427 : : if ( !traverse_loop(loop_to_split, coedge2, new_loop_coedges) )
428 : : return 0;
429 : :
430 : : // Make sure everything adds up
431 : : if ( old_loop_coedges.size() + new_loop_coedges.size()
432 : : + 2*nonman_curves.size() != coedge_count)
433 : : { assert(0); return 0; }
434 : :
435 : : // Leave the larger list on the existing loop, as this
436 : : // is more likely to result in the expected behavior
437 : : if (new_loop_coedges.size() > old_loop_coedges.size())
438 : : {
439 : : DLIList<COEDGE*> tmp_list(old_loop_coedges);
440 : : old_loop_coedges = new_loop_coedges;
441 : : new_loop_coedges = tmp_list;
442 : : }
443 : :
444 : : // Remove all coedges from old loop (faster this way)
445 : : while( loop_to_split->first_coedge() )
446 : : loop_to_split->remove( loop_to_split->first_coedge() );
447 : :
448 : : // Put old_loop_coedges in loop_to_split
449 : : COEDGE* next = 0;
450 : : while ( old_loop_coedges.size() )
451 : : {
452 : : coedge = old_loop_coedges.pop();
453 : : coedge->get_curve()->mark = 0;
454 : : loop_to_split->insert_before( coedge, next );
455 : : next = coedge;
456 : : }
457 : :
458 : : // Put new_loop_coedges in new_loop
459 : : LOOP* new_loop = new LOOP;
460 : : next = 0;
461 : : while ( new_loop_coedges.size() )
462 : : {
463 : : coedge = new_loop_coedges.pop();
464 : : coedge->get_curve()->mark = 0;
465 : : new_loop->insert_before( coedge, next );
466 : : next = coedge;
467 : : }
468 : :
469 : : // Now sort out other non-manifold curves
470 : :
471 : : // Clear marks
472 : : for ( int j = nonman_curves.size(); j--; )
473 : : nonman_curves->step_and_get()->mark = 0;
474 : :
475 : : if( nonman_curves.size() )
476 : : insert_nonmanifold_curves( nonman_curves, loop_to_split, new_loop );
477 : : return new_shell;
478 : : }
479 : :
480 : : template <class SURFACE, class LOOP, class COEDGE, class CURVE, class POINT>
481 : : CubitStatus VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
482 : : VGLoopTool::insert_nonmanifold_curves( DLIList<CURVE*>& curve_stack,
483 : : LOOP* loop1, LOOP* loop2 )
484 : : {
485 : : return CUBIT_FAILURE;
486 : : }
487 : :
488 : : */
489 : :
490 : : /*
491 : : //-------------------------------------------------------------------------
492 : : // Purpose : Check if a curve occurs an odd number of times in a loop
493 : : //
494 : : // Special Notes : Input is the coedge connecting the relevent curve & loop
495 : : //
496 : : // Creator : Jason Kraftcheck
497 : : //
498 : : // Creation Date : 08/14/02
499 : : //-------------------------------------------------------------------------
500 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
501 : : bool VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
502 : : odd_coedge_count( COEDGE* coedge )
503 : : {
504 : : COEDGE* curve_coedge = 0;
505 : : int count = 0;
506 : : while( curve_coedge = coedge->get_curve()->next_coedge( curve_coedge ) )
507 : : if( curve_coedge->get_loop() == coedge->get_loop() )
508 : : count++;
509 : :
510 : : return (bool)(count % 2);
511 : : }
512 : :
513 : : //-------------------------------------------------------------------------
514 : : // Purpose : Find the previous coedge in loop
515 : : //
516 : : // Special Notes :
517 : : //
518 : : // Creator : Jason Kraftcheck
519 : : //
520 : : // Creation Date : 10/28/02
521 : : //-------------------------------------------------------------------------
522 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
523 : : CubitStatus VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
524 : : previous_coedge( COEDGE* coedge, SURFACE* surface, COEDGE*& result )
525 : : {
526 : : result = 0;
527 : :
528 : : POINT* point = coedge->end_point();
529 : : CubitVector normal, tanget, closest;
530 : : surface->closest_point( point->coordinates(), &closest, &normal );
531 : :
532 : : coedge->get_curve()->closest_point( point->coordinates(), closest, &tangent );
533 : : if( coedge->sense() == CUBIT_REVERSED )
534 : : tangent *= -1.0;
535 : :
536 : : CURVE* curve = 0;
537 : : while( curve = point->next_curve( curve ) )
538 : : {
539 : : COEDGE* coedge = 0;
540 : : while( coedge = curve->next_coedge( coedge ) )
541 : : {
542 : : if( coedge->end_point() != point )
543 : : continue;
544 : :
545 : : if( !coedge->get_loop() || coedge->get_loop()->get_surface() != surface )
546 : : continue;
547 : :
548 : : if( ! result )
549 : : {
550 : : result = coedge;
551 : : }
552 : : else if( result->get_loop() != coedge->get_loop() )
553 : : {
554 : : result = 0;
555 : : return CUBIT_FAILURE;
556 : : }
557 : : else
558 : : {
559 : : CubitVector result_tan, coedge_tan, closest;
560 : : result->get_curve()->closest_point( point->coordinates(), closest, &result_tan );
561 : : coedge->get_curve()->closest_point( point->coordinates(), closest, &coedge_tan );
562 : : if( result->sense() == CUBIT_FORWARD )
563 : : result_tan *= -1.0;
564 : : if( coedge->sense() == CUBIT_FORWARD )
565 : : result_tan *= -1.0;
566 : :
567 : : double result_angle = normal.vector_angle( result_tan, tangent );
568 : : double coedge_angle = normal.vector_angle( coedge_tan, tangent );
569 : : if( result_angle < 0.0 ) result_angle += 2.0*CUBIT_PI;
570 : : if( coedge_angle < 0.0 ) coedge_angle += 2.0*CUBIT_PI;
571 : : if( coedge_angle < result_angle )
572 : : result = coedge;
573 : : }
574 : : }
575 : : }
576 : :
577 : : return CUBIT_SUCCESS;
578 : : }
579 : :
580 : : */
581 : :
582 : :
583 : : //-------------------------------------------------------------------------
584 : : // Purpose : Get a polygon representation of a loop as a point list
585 : : //
586 : : // Special Notes :
587 : : //
588 : : // Creator : Jason Kraftcheck
589 : : //
590 : : // Creation Date : 08/14/02
591 : : //-------------------------------------------------------------------------
592 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
593 : 0 : CubitStatus VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
594 : : get_loop_polygon( COEDGE* first_coedge, DLIList<CubitVector*>& polygon )
595 : : {
596 [ # # ]: 0 : if( !first_coedge )
597 : 0 : return CUBIT_FAILURE;
598 : :
599 [ # # ]: 0 : DLIList<CubitVector*> interior;
600 : : CubitSense sense;
601 [ # # ]: 0 : polygon.clean_out();
602 : :
603 : 0 : COEDGE* coedge = first_coedge;
604 [ # # ]: 0 : do
605 : : {
606 [ # # ][ # # ]: 0 : polygon.append( new CubitVector( coedge->start_point()->coordinates() ) );
[ # # ][ # # ]
607 : :
608 [ # # ]: 0 : interior.clean_out();
609 [ # # ][ # # ]: 0 : if( !coedge->get_curve()->get_interior_extrema( interior, sense ) )
[ # # ]
610 : : {
611 [ # # ][ # # ]: 0 : while( polygon.size() ) delete polygon.pop();
[ # # ]
612 : 0 : return CUBIT_FAILURE;
613 : : }
614 : :
615 [ # # ][ # # ]: 0 : if( sense != coedge->sense() )
616 [ # # ]: 0 : interior.reverse();
617 [ # # ]: 0 : polygon += interior;
618 : :
619 [ # # ]: 0 : coedge = coedge->next();
620 : : } while( coedge != first_coedge );
621 : :
622 [ # # ]: 0 : return CUBIT_SUCCESS;
623 : : }
624 : :
625 : :
626 : : //-------------------------------------------------------------------------
627 : : // Purpose : Calculate loop angle metric
628 : : //
629 : : // Special Notes :
630 : : //
631 : : // Creator : Jason Kraftcheck
632 : : //
633 : : // Creation Date : 08/14/02
634 : : //-------------------------------------------------------------------------
635 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
636 : 0 : double VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
637 : : loop_angle_metric( COEDGE* first_coedge )
638 : : {
639 [ # # ]: 0 : if( !first_coedge )
640 : 0 : return 0.0;
641 : :
642 [ # # ][ # # ]: 0 : assert( first_coedge
[ # # ][ # # ]
[ # # ][ # # ]
643 : : && first_coedge->get_loop()
644 : : && first_coedge->get_loop()->get_surface() );
645 : :
646 [ # # ]: 0 : DLIList<CubitVector*> polygon;
647 [ # # ]: 0 : get_loop_polygon( first_coedge, polygon );
648 : :
649 : 0 : double result = 0.0;
650 [ # # ][ # # ]: 0 : CubitVector *point[3], segment[2], normal;
[ # # ]
651 [ # # ]: 0 : point[0] = polygon.step_and_get();
652 [ # # ]: 0 : point[1] = polygon.step_and_get();
653 [ # # ][ # # ]: 0 : segment[0] = *point[1] - *point[0];
654 [ # # ][ # # ]: 0 : for( int i = polygon.size(); i--; )
655 : : {
656 [ # # ]: 0 : point[2] = polygon.step_and_get();
657 [ # # ][ # # ]: 0 : segment[1] = *point[1] - *point[2];
658 [ # # ][ # # ]: 0 : first_coedge->get_loop()->get_surface()->closest_point( *point[1], 0, &normal );
[ # # ]
659 [ # # ]: 0 : result += normal.vector_angle( segment[1], segment[0] );
660 : :
661 : 0 : point[1] = point[2];
662 [ # # ][ # # ]: 0 : segment[0] = -segment[1];
663 : : }
664 : :
665 : 0 : result /= CUBIT_PI;
666 [ # # ]: 0 : result -= polygon.size();
667 : :
668 [ # # ][ # # ]: 0 : while( polygon.size() )
669 [ # # ]: 0 : delete polygon.pop();
670 : :
671 [ # # ]: 0 : return result;
672 : : }
673 : :
674 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
675 : 0 : void VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
676 : : get_loop_polyline( COEDGE* first_coedge, std::vector<CubitVector>& list )
677 : : {
678 : 0 : COEDGE* coedge = first_coedge;
679 [ # # ]: 0 : GMem gmem;
680 [ # # ][ # # ]: 0 : list.resize(0);
681 : :
682 [ # # ]: 0 : do {
683 [ # # ][ # # ]: 0 : coedge->get_curve()->get_geometry_query_engine()->
[ # # ][ # # ]
684 : : get_graphics( coedge->get_curve(), &gmem );
685 : 0 : int num_pts = gmem.pointListCount;
686 [ # # ]: 0 : if ( num_pts > 1 ) {
687 : :
688 [ # # ]: 0 : int start = list.size();
689 [ # # ][ # # ]: 0 : list.resize( start + num_pts - 1 );
690 [ # # ][ # # ]: 0 : std::vector<CubitVector>::iterator itor = list.begin() + start;
691 [ # # ][ # # ]: 0 : if ( coedge->sense() == CUBIT_FORWARD ) {
692 [ # # ]: 0 : GPoint* pitor = gmem.point_list();
693 : 0 : GPoint* pend = pitor + num_pts - 1;
694 [ # # ]: 0 : for ( ; pitor != pend; ++pitor ) {
695 [ # # ][ # # ]: 0 : itor->set( pitor->x, pitor->y, pitor->z );
696 [ # # ]: 0 : ++itor;
697 : : }
698 : : } else {
699 [ # # ]: 0 : GPoint* pend = gmem.point_list();
700 : 0 : GPoint* pitor = pend + num_pts - 1;
701 [ # # ]: 0 : for ( ; pitor != pend; --pitor ) {
702 [ # # ][ # # ]: 0 : itor->set( pitor->x, pitor->y, pitor->z );
703 [ # # ]: 0 : ++itor;
704 : : }
705 : : }
706 : : }
707 : :
708 [ # # ]: 0 : coedge = coedge->next();
709 [ # # ]: 0 : } while ( coedge != first_coedge );
710 : 0 : }
711 : :
712 : :
713 : : /*
714 : : //-------------------------------------------------------------------------
715 : : // Purpose : Check if a position is to the "left" of a coedge
716 : : //
717 : : // Special Notes :
718 : : //
719 : : // Creator : Jason Kraftcheck
720 : : //
721 : : // Creation Date : 08/14/02
722 : : //-------------------------------------------------------------------------
723 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
724 : : bool VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
725 : : inside_of_curve( const CubitVector& tangent,
726 : : const CubitVector& curve_pos,
727 : : const CubitVector& surf_pos,
728 : : const CubitVector& normal )
729 : : {
730 : : CubitVector cross = tangent * ( surf_pos - curve_pos );
731 : : return cross % normal > -CUBIT_RESABS;
732 : : }
733 : :
734 : : //-------------------------------------------------------------------------
735 : : // Purpose : Find the coedge in a loop that is closest to the passed
736 : : // point
737 : : //
738 : : // Special Notes :
739 : : //
740 : : // Creator : Jason Kraftcheck
741 : : //
742 : : // Creation Date : 08/14/02
743 : : //-------------------------------------------------------------------------
744 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
745 : : COEDGE* VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
746 : : closest_loop_coedge( const CubitVector& from_pt,
747 : : COEDGE* first_coedge,
748 : : COEDGE*& other_coedge,
749 : : CubitVector* closest )
750 : : {
751 : : CubitVector closest_pt, current_pt;
752 : : double current_dst, closest_dst;
753 : : COEDGE* closest_coedge = 0;
754 : : other_coedge = 0;
755 : :
756 : : // Skip coedges for curves that occur twice in the loop (sipes, etc)
757 : : COEDGE* coedge = first_coedge;
758 : : while( !odd_coedge_count(coedge) )
759 : : {
760 : : coedge = coedge->next();
761 : : if( coedge == first_coedge )
762 : : return false;
763 : : }
764 : :
765 : : // Search for a) a curve who's bounding box contains the point
766 : : // or b) the curve who's box is closest to the point
767 : : closest_coedge = coedge;
768 : : closest_dst = coedge->get_curve()->bounding_box().distance_squared(from_pt);
769 : : coedge = coedge->next();
770 : : while( (coedge != first_coedge) && (closest_dst > CUBIT_RESABS) )
771 : : {
772 : : if( odd_coedge_count(coedge) )
773 : : {
774 : : current_dst = coedge->get_curve()->bounding_box().distance_squared(from_pt);
775 : : if( current_dst < closest_dst )
776 : : {
777 : : closest_coedge = coedge;
778 : : closest_dst = current_dst;
779 : : }
780 : : }
781 : : coedge = coedge->next();
782 : : }
783 : :
784 : : // Now find actual distance from the curve
785 : : closest_coedge->get_curve()->closest_point_trimmed( from_pt, closest_pt );
786 : : closest_dst = (from_pt - closest_pt).length_squared();
787 : :
788 : : // Look for any curves that are closer
789 : : first_coedge = closest_coedge;
790 : : coedge = first_coedge.next();
791 : : while( coedge != first_coedge )
792 : : {
793 : : if( odd_coedge_count(coedge) )
794 : : {
795 : : if( coedge->get_curve()->bounding_box().distance_squared(from_pt) < closest_dst )
796 : : {
797 : : coedge->get_curve()->closest_point_trimmed( from_pt, current_pt );
798 : : current_dst = (from_pt - current_pt).length_squared();
799 : :
800 : : if( (closest_pt - current_pt).length_squared() < RESSQR )
801 : : {
802 : : if( current_dst < closest_dst )
803 : : {
804 : : closest_dst = current_dst;
805 : : closest_pt = current_pt;
806 : : }
807 : : other_coedge = coedge;
808 : : }
809 : : else if( current_dst < closest_dst )
810 : : {
811 : : closest_coedge = coedge;
812 : : closest_dst = current_dst;
813 : : closest_pt = current_pt;
814 : : other_coedge = 0;
815 : : }
816 : : }
817 : : }
818 : : coedge = coedge->next();
819 : : }
820 : :
821 : : //make sure we have things in the correct order
822 : : if( other_coedge )
823 : : {
824 : : if( closest_coedge->start_point() == other_coedge->end_point() )
825 : : {
826 : : COEDGE* tmp = closest_coedge;
827 : : closest_coedge = other_coedge;
828 : : other_coedge = tmp;
829 : : }
830 : : else if( closest_coedge->end_point() != other_coedge->start_point() )
831 : : {
832 : : other_coedge = 0;
833 : : }
834 : : }
835 : :
836 : : if( closest ) *closest = closest_pt;
837 : : return closest_coedge;
838 : : }
839 : :
840 : :
841 : : //-------------------------------------------------------------------------
842 : : // Purpose : Test if a position is on the surface side of a loop.
843 : : //
844 : : // Special Notes :
845 : : //
846 : : // Creator : Jason Kraftcheck
847 : : //
848 : : // Creation Date : 08/14/02
849 : : //-------------------------------------------------------------------------
850 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
851 : : bool VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
852 : : is_position_within_loop( const CubitVector& position,
853 : : COEDGE* first_coedge,
854 : : CubitVector* closest_on_loop,
855 : : CubitVector* passed_normal )
856 : : {
857 : : CubitVector surf_point, normal, pt_on_curve;
858 : : if( passed_normal )
859 : : {
860 : : surf_point = position;
861 : : normal = *pased_normal;
862 : : }
863 : : else
864 : : {
865 : : first_coedge->get_loop()->get_surface()
866 : : ->closest_point( position, &surf_point, &normal );
867 : : }
868 : :
869 : : COEDGE* other_coedge = 0;
870 : : COEDGE* closest_coedge =
871 : : closest_loop_coedge( first_coedge, position, other_coedge, &pt_on_curve );
872 : : if( !closest_coedge )
873 : : return true;
874 : :
875 : : if( closest_on_loop )
876 : : *closest_on_loop = pt_on_curve;
877 : :
878 : : CubitVector coe_normal, coe_cross, tangent1, tangent2, junk;
879 : :
880 : : if( ! other_coedge )
881 : : {
882 : : double u = closest_coedge->get_curve()->u_from_position( pt_on_curve );
883 : :
884 : : // Special case: closest point on loop at G1 discontinuity
885 : : if( closest_coedge->get_curve()->G1_discontinuous( u, &tangent1, &tangent2 ) )
886 : : {
887 : : if( closest_coedge->sense() == CUBIT_REVERSED )
888 : : {
889 : : tangent1 *= -1.0;
890 : : tangent2 *= -1.0;
891 : : }
892 : :
893 : : closest_coedge->get_loop()->get_surface()->
894 : : closest_point( pt_on_curve, 0, &coe_normal );
895 : : coe_cross = tangent1 * tangent2;
896 : : bool inside1 = inside_of_curve( tangent1, pt_on_curve, surf_point, normal );
897 : : bool inside2 = inside_of_curve( tangent2, pt_on_curve, surf_point, normal );
898 : : if( cross % coe_normal > -CUBIT_RESABS )
899 : : return inside1 && inside2;
900 : : else
901 : : return inside1 || inside2;
902 : : }
903 : :
904 : : else // **** This is the normal, non-special case part ****
905 : : {
906 : : closest_coedge->closest_point( pt_on_curve, junk, &tangent1 );
907 : : if( closest_coedge->sense() == CUBIT_REVERSED )
908 : : tangent1 *= -1.0;
909 : :
910 : : return inside_of_curve( tangent1, pt_on_curve, surf_point, normal );
911 : : }
912 : : }
913 : : // Special case: closest point on loop at vertex
914 : : else
915 : : {
916 : : closest_coedge->get_curve()->closest_point( pt_on_curve, junk, &tangent1 );
917 : : other_coedge->get_curve()->closest_point( pt_on_curve, junk, &tangent2 );
918 : : if( closest_coedge->sense() == CUBIT_REVERSED )
919 : : tangent1 *= -1.0;
920 : : if( other_coedge->sense() == CUBIT_REVERSED )
921 : : tangent2 *= -1.0;
922 : :
923 : : closest_coedge->get_loop()->get_surface()->
924 : : closest_point( pt_on_curve, 0, &coe_normal );
925 : :
926 : : coe_cross = tangent1 * tangent2;
927 : : bool inside1 = inside_of_curve( tangent1, pt_on_curve, surf_point, normal );
928 : : bool inside2 = inside_of_curve( tangent2, pt_on_curve, surf_point, normal );
929 : :
930 : : if( coe_cross % coe_normal > -CUBIT_RESABS )
931 : : return inside1 && inside2;
932 : : else
933 : : return inside1 || inside2;
934 : : }
935 : : }
936 : :
937 : :
938 : : //-------------------------------------------------------------------------
939 : : // Purpose : Very rough approximation of the area bounded by a loop
940 : : //
941 : : // Special Notes :
942 : : //
943 : : // Creator : Jason Kraftcheck
944 : : //
945 : : // Creation Date : 08/14/02
946 : : //-------------------------------------------------------------------------
947 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
948 : : double VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
949 : : loop_area( COEDGE* first_coedge )
950 : : {
951 : : int i;
952 : :
953 : : DLIList<CubitVector*> polygon;
954 : : get_loop_polygon( first_coedge );
955 : :
956 : : // Get surface normal at each polygon point
957 : : DLIList<CubitVector*> normals;
958 : : polygon.reset();
959 : : for( i = polygon.size(); i--; )
960 : : {
961 : : CubitVector norm, *pt = polygon.get_and_step();
962 : : first_coedge->get_loop()->get_surface()->closest_point(*pt,0,&norm);
963 : : normals.append( new CubitVector(norm) );
964 : : }
965 : :
966 : : // Average surface normals
967 : : normal_list.reset();
968 : : CubitVector mean_normal(0.,0.,0.);
969 : : for( i = normals.size(); i--; )
970 : : mean_normal += *normals.get_and_step();
971 : : mean_normal /= normals.size();
972 : :
973 : : // Choose base point at which the surface normal
974 : : // is closest to the mean normal from above
975 : : point_list.reset();
976 : : normal_list.reset();
977 : : CubitVector* base_point = polygon.get_and_step();
978 : : CubitVector* base_normal = normals.get_and_step();
979 : : double largest_dot = mean_normal % *base_normal;
980 : :
981 : : for( i = polygon.size(); i > 1; i-- )
982 : : {
983 : : CubitVector* normal = normals.get_and_step();
984 : : double dot = mean_normal % *normal;
985 : : if( dot > largest_dot )
986 : : {
987 : : base_point = polygon.get();
988 : : base_normal = normal;
989 : : }
990 : : polygon.step();
991 : : }
992 : :
993 : : polygon.move_to( base_point );
994 : : normals.move_to( base_normal );
995 : : polygon.step();
996 : : normals.step();
997 : :
998 : : // Do simple 2-D area calculation and hope it isn't too
999 : : // inaccurate for the 3-D refface.
1000 : : double double_area = 0.0;
1001 : : CubitVector *prev_point = polygon.get_and_step(),
1002 : : *curr_point = polygon.get_and_step();
1003 : : CubitVector *prev_normal = normals.get_and_step(),
1004 : : *curr_normal = normals.get_and_step();
1005 : :
1006 : : while( curr_point != base_point )
1007 : : {
1008 : : CubitVector cross = (*prev_point - *base_point)*(*curr_point - *base_point);
1009 : : CubitVector normal = *base_normal + *prev_normal + *curr_normal;
1010 : : double dot_product = cross % normal;
1011 : : double_area += dot_product >= 0.0 ? cross.length() : -(cross.length());
1012 : :
1013 : : prev_point = curr_point;
1014 : : prev_normal = curr_normal;
1015 : : curr_point = polygon.get_and_step();
1016 : : curr_normal = normals.get_and_step();
1017 : : }
1018 : :
1019 : : while( polygon.size() > 0 ) delete polygon.pop();
1020 : : while( normals.size() > 0 ) delete normals.pop();
1021 : : return double_area / 2.0;
1022 : : }
1023 : :
1024 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
1025 : : CubitStatus VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
1026 : : closest_point_trimmed( DLIList<COEDGE*>& surface_coedges, const CubitVector& from_pt,
1027 : : CubitVector& result_pt, CubitPointContainment* containment )
1028 : : {
1029 : : CubitVector pt_on_surf, normal;
1030 : : if( ! surface->closest_point( from_pt, &pt_on_surf, &normal ) )
1031 : : return CUBIT_FAILURE;
1032 : :
1033 : :
1034 : : CubitVector pt_on_curve;
1035 : : COEDGE *closest_coedge = 0, *other_coedge = 0;
1036 : : if( ! closest_surface_coedge( surface, from_pt, closest_coedge,
1037 : : other_coedge, &pt_on_curve ) )
1038 : : return CUBIT_FAILURE;
1039 : :
1040 : : CubitVector coe_normal, coe_cross, tangent1, tangent2, junk;
1041 : : bool inside;
1042 : : if( ! other_coedge )
1043 : : {
1044 : : CURVE* curve_ptr = closest_coedge->get_curve();
1045 : : double u = curve_ptr->u_from_position( pt_on_curve );
1046 : :
1047 : : // **** Special case: closest point on loop at G1 discontinuity ****
1048 : : if( curve_ptr->G1_discontinuous( u, &tangent1, &tangent2 ) )
1049 : : {
1050 : : if( closest_coedge->sense() == CUBIT_REVERSED )
1051 : : {
1052 : : tangent1 *= -1.0;
1053 : : tangent2 *= -1.0;
1054 : : }
1055 : : surface->closest_point( pt_on_curve, NULL, &coe_normal );
1056 : : coe_cross = tangent1 * tangent2;
1057 : : double sum = (coe_cross + coe_normal).length_squared();
1058 : : double diff = (coe_cross - coe_normal).length_squared();
1059 : :
1060 : : CubitBoolean inside1 =
1061 : : inside_of_curve( tangent1, pt_on_curve, pt_on_surf, normal );
1062 : : CubitBoolean inside2 =
1063 : : inside_of_curve( tangent2, pt_on_curve, pt_on_surf, normal );
1064 : :
1065 : : if( (sum > diff) || (diff < CUBIT_DBL_MIN) )
1066 : : //discontinuity is at a convexity
1067 : : {
1068 : : //the point must be inside of both sub-edges
1069 : : inside = inside1 && inside2;
1070 : : }
1071 : : else //discontinuity is at a concavity
1072 : : {
1073 : : //the point must be inside of one of the sub-edges
1074 : : inside = inside1 || inside2;
1075 : : }
1076 : : }
1077 : :
1078 : : else // **** This is the normal, non-special case part ****
1079 : : {
1080 : : curve_ptr->closest_point( pt_on_curve, junk, &tangent1 );
1081 : : if( closest_coedge->sense() == CUBIT_REVERSED )
1082 : : tangent1 *= -1.0;
1083 : :
1084 : : inside = (inside_of_curve(tangent1, pt_on_curve, pt_on_surf, normal) == CUBIT_TRUE);
1085 : : }
1086 : : }
1087 : : // **** Special case: closest point on loop at vertex ****
1088 : : else
1089 : : {
1090 : : CURVE* curve1_ptr = closest_coedge->get_curve();
1091 : : CURVE* curve2_ptr = other_coedge->get_curve();
1092 : : curve1_ptr->closest_point( pt_on_curve, junk, &tangent1 );
1093 : : curve2_ptr->closest_point( pt_on_curve, junk, &tangent2 );
1094 : :
1095 : : if( closest_coedge->sense() == CUBIT_REVERSED )
1096 : : tangent1 *= -1.0;
1097 : : if( other_coedge->sense() == CUBIT_REVERSED )
1098 : : tangent2 *= -1.0;
1099 : :
1100 : : surface->closest_point( pt_on_curve, NULL, &coe_normal );
1101 : :
1102 : : coe_cross = tangent1 * tangent2;
1103 : : double sum = (coe_cross + coe_normal).length_squared();
1104 : : double diff = (coe_cross - coe_normal).length_squared();
1105 : :
1106 : : CubitBoolean inside1 =
1107 : : inside_of_curve( tangent1, pt_on_curve, pt_on_surf, normal );
1108 : : CubitBoolean inside2 =
1109 : : inside_of_curve( tangent2, pt_on_curve, pt_on_surf, normal );
1110 : :
1111 : : if( (sum > diff) || (diff < CUBIT_DBL_MIN) )
1112 : : //the common vertex is at a convexity
1113 : : {
1114 : : //the point must be inside of both coedges
1115 : : inside = inside1 && inside2;
1116 : : }
1117 : : else //the common vertex is at a concavity
1118 : : {
1119 : : //the point must be inside of one of the coedges
1120 : : inside = inside1 || inside2;
1121 : : }
1122 : : }
1123 : :
1124 : : result_pt = inside ? pt_on_surf : pt_on_curve;
1125 : : if( containment )
1126 : : {
1127 : : if( (pt_on_surf-pt_on_curve).length_squared() < (GEOMETRY_RESABS*GEOMETRY_RESABS) )
1128 : : *containment = CUBIT_PNT_BOUNDARY;
1129 : : else
1130 : : *containment = inside ? CUBIT_PNT_INSIDE : CUBIT_PNT_OUTSIDE;
1131 : : }
1132 : :
1133 : : return CUBIT_SUCCESS;
1134 : : }
1135 : :
1136 : : template <class SURFACE, class LOOP, class COEDGE,class CURVE, class POINT>
1137 : : CubitStatus VGLoopTool<SURFACE,LOOP,COEDGE,CURVE,POINT>::
1138 : : closest_surface_coedge( SURFACE* surface, const CubitVector& from_pt,
1139 : : COEDGE*& coedge1, COEDGE*& coedge2,
1140 : : CubitVector* pt_on_curve )
1141 : : {
1142 : : coedge1 = coedge2 = 0;
1143 : : LOOP* loop = 0;
1144 : : COEDGE* coedge;
1145 : : const double ressqr = CUBIT_RESABS * CUBIT_RESABS;
1146 : :
1147 : :
1148 : :
1149 : : //Find the first bounding box that the point is within, or if the
1150 : : // point isn't in any bounding box, the closest one
1151 : : closest_dst = CUBIT_DBL_MAX;
1152 : : while( loop = surface->next_loop( loop ) )
1153 : : {
1154 : : coedge = loop->first_coedge();
1155 : : do
1156 : : {
1157 : : if( odd_coedge_count( coedge ) )
1158 : : {
1159 : : double dist_sqr =
1160 : : coedge->get_curve()->bounding_box().distance_squared(from_pt);
1161 : : if( dist_sqr < closest_dst )
1162 : : {
1163 : : coedge1 = coedge;
1164 : : closest_dst = dist_sqr;
1165 : : if( dist_sqr < ressqr )
1166 : : break;
1167 : : }
1168 : : }
1169 : :
1170 : : coedge = coedge->next();
1171 : : } while( coedge != loop->first_coedge() );
1172 : :
1173 : : if( closest_dst < ressqr )
1174 : : break;
1175 : : }
1176 : :
1177 : : if( !coedge1 )
1178 : : return CUBIT_FAILURE;
1179 : :
1180 : : //Start by assuming that the curve we found above is the closest
1181 : : CubitVector closest_pt;
1182 : : coedge1->get_curve()->closest_point_trimmed( from_pt, closest_pt );
1183 : : closest_dst = ( from_pt - closest_pt ).length_squared();
1184 : :
1185 : : //Now look for a closer curve
1186 : : while( loop = surface->next_loop( loop ) )
1187 : : {
1188 : : coedge = loop->first_coedge();
1189 : : do
1190 : : {
1191 : : if( odd_coedge_count( coedge ) )
1192 : : {
1193 : : if( coedge->get_curve()->bounding_box().distance_squared(from_pt) <=
1194 : : closest_dst+GEOMETRY_RESABS )
1195 : : {
1196 : : CubitVector current_pt;
1197 : : coedge->get_curve()->closest_point_trimmed( from_pt, current_pt );
1198 : : double current_dst = (from_pt - current_pt).length_squared();
1199 : :
1200 : : if( (closest_pt = current_pt).length_squared() < ressqr )
1201 : : {
1202 : : if( current_dst < closest_dst )
1203 : : {
1204 : : closest_dst = current_dst;
1205 : : closest_pt = current_pt;
1206 : : coedge2 = coedge;
1207 : : }
1208 : : else
1209 : : {
1210 : : coedge2 = coedge;
1211 : : }
1212 : : }
1213 : : else if( current_dst < closest_dst )
1214 : : {
1215 : : coedge1 = coedge;
1216 : : closest_dst = current_dst;
1217 : : closest_pt = current_pt;
1218 : : coedge2 = 0;
1219 : : }
1220 : : }
1221 : : }
1222 : : coedge = coedge->next();
1223 : : } while( coedge != loop->first_coedge() );
1224 : : }
1225 : :
1226 : :
1227 : : //make sure we have things in the correct order
1228 : : if( coedge2 )
1229 : : {
1230 : : POINT* common = coedge1->get_curve()->common( coedge2->get_curve() );
1231 : : if( ! common )
1232 : : coedge2 = 0;
1233 : : else if( coedge1->start_point() == coedge2->end_point() )
1234 : : {
1235 : : COEDGE* tmp = coedge1;
1236 : : coedge1 = coedge2;
1237 : : coedge2 = tmp;
1238 : : }
1239 : : }
1240 : :
1241 : : if( pt_on_curve ) *pt_on_curve = closest_pt;
1242 : : return CUBIT_SUCCESS;
1243 : : }
1244 : : */
|