Branch data Line data Source code
1 : : //- Class: FacetEvalTool
2 : : //- Description: The FacetEvalTool is a tool to perform generic geometric
3 : : //- operations on a set of facets.
4 : : //- Assumptions: All of the facets are connected topologically correct.
5 : : //-
6 : : //- Owner: Steve J. Owen
7 : : //- Checked by:
8 : :
9 : : #include <float.h>
10 : : #include "CastTo.hpp"
11 : : #include "CubitVector.hpp"
12 : : #include "CubitPoint.hpp"
13 : : #include "CubitFacet.hpp"
14 : : #include "CubitFacetEdge.hpp"
15 : : #include "CubitFacetEdgeData.hpp"
16 : : #include "CpuTimer.hpp"
17 : : #include "CubitMessage.hpp"
18 : : #include "CubitBox.hpp"
19 : : #include "DLIList.hpp"
20 : : #include "FacetEvalTool.hpp"
21 : : #include "GeometryDefines.h"
22 : : #include "CubitTransformMatrix.hpp"
23 : : #include "ChollaDebug.hpp"
24 : : #include "TDFacetBoundaryEdge.hpp"
25 : : #include "TDFacetBoundaryPoint.hpp"
26 : : #include "GfxDebug.hpp"
27 : : //#include "FacetParamTool.hpp"
28 : : #include "KDDTree.hpp"
29 : : #include "AbstractTree.hpp"
30 : : #include "CubitFileIOWrapper.hpp"
31 : : #include "FacetDataUtil.hpp"
32 : :
33 : : double FacetEvalTool::timeGridSearch = 0.0;
34 : : double FacetEvalTool::timeFacetProject = 0.0;
35 : : int FacetEvalTool::numEvals = 0;
36 : : #define GRID_SEARCH_THRESHOLD 20
37 : :
38 : : //===========================================================================
39 : : //Function Name: FacetEvalTool
40 : : //
41 : : //Member Type: PUBLIC
42 : : //Description: constructor
43 : : //===========================================================================
44 : 341 : CubitStatus FacetEvalTool::initialize(
45 : : DLIList<CubitFacet*> &facet_list,
46 : : DLIList<CubitPoint*> &point_list, // if this isn't filled in, I'll do it here
47 : : int interp_order, // 0 = linear or 4 = Bezier only for now
48 : : double min_dot ) // from feature angle
49 : : {
50 : 341 : myFacetList = facet_list;
51 : 341 : myPointList = point_list;
52 : 341 : isParameterized = CUBIT_FALSE;
53 : 341 : minDot = min_dot;
54 : 341 : output_id = -1;
55 : :
56 : : // mark all of the facets on this surface with the toolID
57 : :
58 : : int i;
59 [ + + ]: 1397 : for (i = 0; i< myFacetList.size(); i++)
60 : 1056 : myFacetList.get_and_step()->set_tool_id( toolID );
61 : :
62 : : // generate the list of points, if not already defined
63 : :
64 [ - + ]: 341 : if (myPointList.size() == 0)
65 : : {
66 : 0 : get_points_from_facets( facet_list, myPointList );
67 : : }
68 : 341 : interpOrder = 0; // default to project to linear facet
69 : :
70 : : // set the bounding box and compareTol and setup grid search
71 : 341 : myBBox = NULL;
72 : 341 : aTree = NULL;
73 : :
74 : 341 : reset_bounding_box();
75 : :
76 : :
77 : 341 : lastFacet = NULL;
78 : 341 : isFlat = -999;
79 : 341 : isFlat = is_flat();
80 : :
81 [ - + ]: 341 : if (interp_order == -1) {
82 : 0 : interpOrder = 0; // use linear as default interp order
83 : : }
84 : : else {
85 : 341 : interpOrder = interp_order;
86 : : }
87 : :
88 : : // generate edges
89 : :
90 [ + - - + ]: 682 : if ( CUBIT_SUCCESS != get_edges_from_facets( facet_list, myEdgeList ) ||
[ - + ]
91 : 341 : CUBIT_SUCCESS != get_loops_from_facets( myEdgeList, myLoopList ) )
92 : : {
93 [ # # ][ # # ]: 0 : PRINT_ERROR("Unable to initialize Facet Evaluation Tool.\n");
94 : 0 : return CUBIT_FAILURE;
95 : : }
96 : :
97 [ + + ]: 341 : if (interpOrder > 0) {
98 : 66 : init_gradient();
99 [ - + ]: 66 : if (interpOrder == 3) { // least_squares
100 : 0 : init_quadrics();
101 : : }
102 [ + - ]: 66 : else if(interpOrder == 4) { // spline
103 : 66 : init_bezier_surface();
104 : : }
105 : : }
106 : :
107 : : // compute the area of all facets
108 : :
109 : 341 : myArea = -1.0;
110 : 341 : myArea = area();
111 : :
112 : :
113 : 341 : int mydebug = 0;
114 [ - + ]: 341 : if (mydebug)
115 : : {
116 : 0 : debug_draw_eval_bezier_facet( myFacetList.get_and_step() );
117 : 0 : debug_draw_facets();
118 : 0 : debug_draw_facet_normals();
119 [ # # ]: 0 : if (interpOrder > 0) debug_draw_point_normals();
120 : 0 : GfxDebug::flush();
121 : 0 : GfxDebug::mouse_xforms();
122 : : }
123 : :
124 : : //parameterize();
125 : 341 : return CUBIT_SUCCESS;
126 : : }
127 : :
128 : : //===========================================================================
129 : : //Function Name: FacetEvalTool
130 : : //Member Type: PUBLIC
131 : : //Descriptoin: constructor. This one is an empty constructor
132 : : // sed with restore method
133 : : //===========================================================================
134 [ + - ][ + - ]: 946 : FacetEvalTool::FacetEvalTool()
[ + - ][ + - ]
135 : : {
136 : : static int counter = 1;
137 : 473 : toolID = counter++;
138 : 473 : myBBox = NULL;
139 : 473 : aTree = NULL;
140 : 473 : lastFacet = NULL;
141 : 473 : isFlat = -999;
142 : 473 : myArea = -1.0;
143 : 473 : interpOrder = 0;
144 : 473 : minDot = 0;
145 : 473 : isParameterized = CUBIT_FALSE;
146 : 473 : }
147 : :
148 : : //===========================================================================
149 : : //Function Name: ~FacetEvalTool
150 : : //
151 : : //Member Type: PUBLIC
152 : : //Descriptoin: destructor
153 : : //===========================================================================
154 [ # # ][ # # ]: 0 : FacetEvalTool::~FacetEvalTool()
[ # # ][ # # ]
155 : : {
156 [ # # ][ # # ]: 0 : if ( DEBUG_FLAG(110) )
[ # # ]
157 : : {
158 [ # # ][ # # ]: 0 : PRINT_INFO("num facets = %d\n",myFacetList.size());
[ # # ][ # # ]
[ # # ]
159 [ # # ][ # # ]: 0 : PRINT_INFO("numEvals = %d\n",numEvals);
[ # # ][ # # ]
160 [ # # ][ # # ]: 0 : PRINT_INFO("timeFacetProject = %f\n",timeFacetProject);
[ # # ][ # # ]
161 [ # # ][ # # ]: 0 : PRINT_INFO("timeGridSearch = %f\n",timeGridSearch);
[ # # ][ # # ]
162 : : }
163 : :
164 [ # # ]: 0 : if (aTree != NULL)
165 [ # # ][ # # ]: 0 : delete aTree;
166 : :
167 [ # # ][ # # ]: 0 : if (myBBox) delete myBBox;
[ # # ]
168 [ # # ]: 0 : destroy_facets();
169 : :
170 [ # # ]: 0 : myLoopList.reset();
171 : : int i;
172 [ # # ][ # # ]: 0 : for (i=myLoopList.size(); i>0; i--)
173 : : {
174 [ # # ][ # # ]: 0 : delete myLoopList.get_and_step();
[ # # ]
175 : : }
176 [ # # ]: 0 : myLoopList.clean_out();
177 : 0 : }
178 : :
179 : 0 : void FacetEvalTool::remove_facets( DLIList<CubitFacet*>& facets )
180 : : {
181 : 0 : facets = myFacetList;
182 [ # # ]: 0 : for ( int i = facets.size(); i--; )
183 : 0 : facets.step_and_get()->set_tool_id(0);
184 : 0 : myFacetList.clean_out();
185 : 0 : myEdgeList.clean_out();
186 : 0 : myPointList.clean_out();
187 : 0 : }
188 : :
189 : 0 : CubitStatus FacetEvalTool::reverse_facets( )
190 : : {
191 : : int i;
192 : : CubitFacet* temp_facet;
193 : :
194 [ # # ]: 0 : for(i=0; i<myFacetList.size(); i++){
195 : 0 : temp_facet=myFacetList.get_and_step();
196 [ # # ]: 0 : if(!temp_facet){
197 [ # # ][ # # ]: 0 : PRINT_ERROR("Unexpected NULL pointer for facet.\n");
198 : 0 : return CUBIT_FAILURE;
199 : : }
200 : 0 : temp_facet->flip();
201 : : }
202 : :
203 : 0 : return CUBIT_SUCCESS;
204 : : }
205 : :
206 : 0 : CubitStatus FacetEvalTool::reverse_facets( DLIList<CubitFacet *> &facets )
207 : : {
208 : : int i;
209 : : CubitFacet* temp_facet;
210 : :
211 [ # # ]: 0 : for(i=0; i<facets.size(); i++){
212 : 0 : temp_facet=facets.get_and_step();
213 [ # # ]: 0 : if(!temp_facet){
214 [ # # ][ # # ]: 0 : PRINT_ERROR("Unexpected NULL pointer for facet.\n");
215 : 0 : return CUBIT_FAILURE;
216 : : }
217 : 0 : temp_facet->flip();
218 : : }
219 : :
220 : 0 : return CUBIT_SUCCESS;
221 : : }
222 : :
223 : :
224 : 0 : void FacetEvalTool::replace_facets( DLIList<CubitFacet *> &facet_list )
225 : : {
226 : 0 : myFacetList.clean_out();
227 : 0 : myEdgeList.clean_out();
228 : 0 : myPointList.clean_out();
229 : 0 : FacetDataUtil::get_points( facet_list, myPointList );
230 : 0 : FacetDataUtil::get_edges( facet_list, myEdgeList );
231 : 0 : myFacetList = facet_list;
232 [ # # ]: 0 : for ( int i = myFacetList.size(); i--; )
233 : 0 : myFacetList.step_and_get()->set_tool_id(toolID);
234 : 0 : reset_bounding_box();
235 : 0 : }
236 : :
237 : :
238 : : //===========================================================================
239 : : //Function Name: set_up_grid_search
240 : : //
241 : : //Member Type: PUBLIC
242 : : //Descriptoin: set up grid search if we have a lot of facets
243 : : //===========================================================================
244 : 473 : void FacetEvalTool::set_up_grid_search(
245 : : double geom_factor )
246 : : {
247 [ - + ]: 473 : if(aTree)
248 [ # # ]: 0 : delete aTree;
249 : :
250 [ + - ]: 473 : if (myFacetList.size() < GRID_SEARCH_THRESHOLD)
251 : : {
252 : 473 : aTree = NULL;
253 : : }
254 : : else
255 : : {
256 [ # # ]: 0 : aTree = new KDDTree<CubitFacet*> (GEOMETRY_RESABS*geom_factor, false/*self-balancing off*/);
257 [ # # ]: 0 : for ( int ii = myFacetList.size(); ii > 0; ii-- )
258 : : {
259 : 0 : aTree->add(myFacetList.get_and_step());
260 : : }
261 : 0 : aTree->balance();
262 : : }
263 : 473 : }
264 : :
265 : : //===========================================================================
266 : : //Function Name: is_flat
267 : : //
268 : : //Member Type: PUBLIC
269 : : //Descriptoin: Determine if the facets are all in the same plane
270 : : //===========================================================================
271 : 1221 : int FacetEvalTool::is_flat()
272 : : {
273 : : int ii;
274 [ + + ]: 1221 : if (isFlat != -999) {
275 : 880 : return isFlat;
276 : : }
277 : : else {
278 : 341 : isFlat = CUBIT_TRUE;
279 [ + - ][ + - ]: 341 : CubitVector firstnormal = myFacetList.get_and_step()->normal();
280 [ + - ]: 341 : firstnormal.normalize();
281 [ + - ]: 341 : CubitVector normal;
282 [ + - ][ + + ]: 1034 : for ( ii = myFacetList.size(); ii > 1 &&isFlat; ii-- ){
[ + + ]
283 [ + - ][ + - ]: 693 : normal = myFacetList.get_and_step()->normal();
[ + - ]
284 [ + - ]: 693 : normal.normalize();
285 [ + - ][ + + ]: 693 : if (fabs(normal%firstnormal) < 0.9987654321) {
286 : 33 : isFlat = CUBIT_FALSE;
287 : : }
288 : : }
289 : : }
290 : 1221 : return isFlat;
291 : : }
292 : :
293 : : //===========================================================================
294 : : //Function Name: init_gradient
295 : : //
296 : : //Member Type: PRIVATE
297 : : //Descriptoin: initialize the gradients for order 1 interpolation
298 : : //===========================================================================
299 : 66 : CubitStatus FacetEvalTool::init_gradient()
300 : : {
301 : : int i,j;
302 : :
303 : : // retrieve all faces attached to the points in point_list
304 : :
305 [ + + ]: 330 : for (i = 0; i < myPointList.size(); i++)
306 : : {
307 [ + - ]: 264 : CubitPoint* point = myPointList.get_and_step();
308 : :
309 [ + - ]: 264 : DLIList<CubitFacet*> adj_facet_list;
310 [ + - ]: 264 : point->facets(adj_facet_list);
311 [ + - ][ + - ]: 264 : if (adj_facet_list.size() > 0) {
312 [ + - ]: 264 : CubitVector avg_normal(0.0e0, 0.0e0, 0.0e0);
313 : 264 : double totangle = 0.0e0;
314 : :
315 : : // weight the normal by the spanning angle at the point
316 : :
317 [ + - ][ + + ]: 1452 : for (j = 0; j < adj_facet_list.size(); j++)
318 : : {
319 [ + - ]: 1188 : CubitFacet* facet = adj_facet_list.get_and_step();
320 [ + - ]: 1188 : double angle = facet->angle( point );
321 [ + - ]: 1188 : facet->weight( angle );
322 : 1188 : totangle += angle;
323 : : }
324 [ + - ][ + + ]: 1452 : for (j = 0; j < adj_facet_list.size(); j++)
325 : : {
326 [ + - ]: 1188 : CubitFacet* facet = adj_facet_list.get_and_step();
327 [ + - ]: 1188 : CubitVector normal = facet->normal();
328 [ + - ]: 1188 : normal.normalize();
329 [ + - ][ + - ]: 1188 : avg_normal += (facet->weight() / totangle) * normal;
[ + - ]
330 : : }
331 [ + - ]: 264 : avg_normal.normalize();
332 [ + - ]: 264 : point->normal(avg_normal);
333 [ + - ][ + - ]: 264 : double coefd = -(point->coordinates()%avg_normal);
334 [ + - ]: 264 : point->d_coef( coefd );
335 : : }
336 [ + - ]: 264 : }
337 : 66 : return CUBIT_SUCCESS;
338 : : }
339 : :
340 : : //===========================================================================
341 : : //Function Name: init_quadrics
342 : : // NOTE: I (Roshan) fixed couple of bugs on Aug 02, 2010. See BUGFIX comments below. I didn't test this function; however, I have tested CMLSmoothTool::init_quadric().
343 : : //Member Type: PRIVATE
344 : : //Descriptoin: initialize the quadrics at the facet vertices for order 2
345 : : // interpolation
346 : : //===========================================================================
347 : 0 : CubitStatus FacetEvalTool::init_quadrics()
348 : : {
349 : : // use the normal at the vertices as a local space with which to do
350 : : // interpolation. A quadric will be approximated from the surrounding
351 : : // vertices. Interpolation will provide a "z" deviation from the tangent
352 : : // plane at the vertex
353 : :
354 : : // define a basis set of vectors at each point (assumes the gradients
355 : : // have already been approximated
356 : :
357 : : int i,j;
358 : : CubitPoint* point;
359 [ # # ][ # # ]: 0 : for (i = 0; i < myPointList.size(); i++)
360 : : {
361 [ # # ]: 0 : point = myPointList.get_and_step();
362 [ # # ]: 0 : point->define_tangent_vectors();
363 : : }
364 : :
365 : : // set up for least squares
366 : :
367 : : CubitStatus status;
368 : : #define MAX_CLOSE_POINTS 100
369 : : CubitPoint *close_points[MAX_CLOSE_POINTS];
370 [ # # ][ # # ]: 0 : CubitVector coords[MAX_CLOSE_POINTS], cp;
[ # # ]
371 : : double weight[MAX_CLOSE_POINTS];
372 : : int num_close;
373 [ # # ]: 0 : CubitMatrix lhs(5,5);
374 [ # # ][ # # ]: 0 : CubitMatrix rhs(5,1);
375 [ # # ][ # # ]: 0 : CubitMatrix coef(5,1);
376 [ # # ][ # # ]: 0 : for (i = 0; i < myPointList.size(); i++)
377 : : {
378 [ # # ]: 0 : point = myPointList.get_and_step();
379 : : status = get_close_points( point, close_points, num_close,
380 [ # # ]: 0 : MAX_CLOSE_POINTS, 5 );
381 [ # # ]: 0 : if (status != CUBIT_SUCCESS) {
382 : 0 : return status;
383 : : }
384 : :
385 : : // transform to local system in x-y
386 : : // determine weights based on inverse distance
387 : :
388 : 0 : weight[0] = 0.0e0;
389 : 0 : double maxdist = -1e100;
390 : 0 : double totweight = 0.0e0;
391 [ # # ]: 0 : for(j=0; j<num_close; j++) {
392 [ # # ][ # # ]: 0 : cp = close_points[j]->coordinates();
393 [ # # ]: 0 : point->transform_to_local( cp, coords[j] );
394 [ # # ][ # # ]: 0 : weight[j] = sqrt( FacetEvalToolUtils::sqr(coords[j].x()) + FacetEvalToolUtils::sqr(coords[j].y()) );
[ # # ][ # # ]
395 [ # # ]: 0 : if (weight[j] > maxdist) maxdist = weight[j];
396 : : }
397 : 0 : maxdist *= 1.1e0;
398 [ # # ]: 0 : for (j=0; j<num_close; j++) {
399 [ # # ]: 0 : weight[j] = FacetEvalToolUtils::sqr((maxdist-weight[j])/(maxdist*weight[j]));
400 : 0 : totweight += weight[j];
401 : : }
402 : :
403 : : // fill up the matrices
404 : :
405 : : //lhs.set_to_identity();
406 : : //rhs.set_to_identity();
407 : : //coef.set_to_identity();
408 : :
409 : : double dx, dy, wjdx, wjdy, dx2, dy2, dxdy, dz;
410 [ # # ]: 0 : for (j=0; j<num_close; j++) {
411 : 0 : weight[j] /= totweight;
412 : 0 : weight[j] = 1; // BUGFIX: ignore weights for now and reset weights to 1
413 [ # # ]: 0 : dx = /*-*/ coords[j].x(); //BUGFIX: Why we need -ve coords?
414 [ # # ]: 0 : dy = /*-*/ coords[j].y(); //BUGFIX: Why we need -ve coords?
415 : 0 : wjdx = weight[j] * dx;
416 : 0 : wjdy = weight[j] * dy;
417 [ # # ]: 0 : dx2 = FacetEvalToolUtils::sqr( dx );
418 [ # # ]: 0 : dy2 = FacetEvalToolUtils::sqr( dy );
419 : 0 : dxdy = dx * dy;
420 [ # # ]: 0 : dz = coords[j].z();
421 : :
422 [ # # ]: 0 : lhs.add( 0, 0, wjdx * dx );
423 [ # # ]: 0 : lhs.add( 0, 1, wjdx * dy );
424 [ # # ]: 0 : lhs.add( 0, 2, wjdx * dx2 );
425 [ # # ]: 0 : lhs.add( 0, 3, wjdx * dxdy );
426 [ # # ]: 0 : lhs.add( 0, 4, wjdx * dy2 );
427 [ # # ]: 0 : rhs.add( 0, 0, wjdx * dz ); // BUGFIX: dz was missing
428 : :
429 [ # # ]: 0 : lhs.add( 1, 1, wjdy * dy );
430 [ # # ]: 0 : lhs.add( 1, 2, wjdy * dx2 );
431 [ # # ]: 0 : lhs.add( 1, 3, wjdy * dxdy );
432 [ # # ]: 0 : lhs.add( 1, 4, wjdy * dx * dy2 );
433 [ # # ]: 0 : rhs.add( 1, 0, wjdy * dz ); // BUGFIX: dz was missing
434 : :
435 [ # # ]: 0 : lhs.add( 2, 2, wjdx * dx2 * dx );
436 [ # # ]: 0 : lhs.add( 2, 3, wjdx * dx2 * dy );
437 [ # # ]: 0 : lhs.add( 2, 4, wjdx * dx * dy2 );
438 [ # # ]: 0 : rhs.add( 2, 0, wjdx * dx * dz );// BUGFIX: dz was missing
439 : :
440 [ # # ]: 0 : lhs.add( 3, 3, wjdx * dx * dy2 );
441 [ # # ]: 0 : lhs.add( 3, 4, wjdx * dy * dy2 );
442 [ # # ]: 0 : rhs.add( 3, 0, wjdx * dy * dz ); // BUGFIX: dz was missing
443 : :
444 [ # # ]: 0 : lhs.add( 4, 4, wjdy * dy * dy2 );
445 [ # # ]: 0 : rhs.add( 4, 0, wjdy * dy * dz ); // BUGFIX: dz was missing
446 : : }
447 [ # # ][ # # ]: 0 : lhs.set( 1, 0, lhs.get(0,1) );
448 [ # # ][ # # ]: 0 : lhs.set( 2, 0, lhs.get(0,2) );
449 [ # # ][ # # ]: 0 : lhs.set( 2, 1, lhs.get(1,2) );
450 [ # # ][ # # ]: 0 : lhs.set( 3, 0, lhs.get(0,3) );
451 [ # # ][ # # ]: 0 : lhs.set( 3, 1, lhs.get(1,3) );
452 [ # # ][ # # ]: 0 : lhs.set( 3, 2, lhs.get(2,3) );
453 [ # # ][ # # ]: 0 : lhs.set( 4, 0, lhs.get(0,4) );
454 [ # # ][ # # ]: 0 : lhs.set( 4, 1, lhs.get(1,4) );
455 [ # # ][ # # ]: 0 : lhs.set( 4, 2, lhs.get(2,4) );
456 [ # # ][ # # ]: 0 : lhs.set( 4, 3, lhs.get(3,4) );
457 : :
458 : : // solve the system
459 : :
460 [ # # ]: 0 : status = lhs.solveNxN( rhs, coef );
461 [ # # ]: 0 : if (status != CUBIT_SUCCESS) {
462 : 0 : return status;
463 : : }
464 : :
465 : : // store the quadric coefficents with the point
466 : :
467 [ # # ]: 0 : point->coef_vector( coef );
468 : : }
469 [ # # ]: 0 : return CUBIT_SUCCESS;
470 : : }
471 : :
472 : : //===========================================================================
473 : : //Function Name: get_close_points
474 : : //
475 : : //Member Type: PRIVATE
476 : : //Descriptoin: get a list of points close to the current point on the facets
477 : : // return a minimum of min_close and a maximum of max_close points
478 : : //===========================================================================
479 : 0 : CubitStatus FacetEvalTool::get_close_points(
480 : : CubitPoint *point,
481 : : CubitPoint **close_point,
482 : : int &num_close,
483 : : int max_close,
484 : : int min_close )
485 : : {
486 : :
487 : : // get the points immediately adjacent
488 : :
489 [ # # ]: 0 : DLIList<CubitFacet*> adj_facet_list;
490 [ # # ]: 0 : point->facets(adj_facet_list);
491 [ # # ][ # # ]: 0 : if (adj_facet_list.size() > max_close) {
492 : 0 : return CUBIT_FAILURE;
493 : : }
494 [ # # ]: 0 : point->adjacent_points(close_point, num_close);
495 : :
496 : : // if we don't have enough yet, then go to the next level
497 : :
498 [ # # ]: 0 : if (num_close < min_close) {
499 : : CubitPoint *cpoint[100];
500 : : CubitPoint *cur_point;
501 : : CubitBoolean found;
502 : : int nclose, cnclose;
503 : 0 : nclose = num_close;
504 [ # # ]: 0 : for(int i=0; i<num_close; i++) {
505 : 0 : cur_point = close_point[i];
506 [ # # ]: 0 : DLIList<CubitFacet*> cadj_facet_list;
507 [ # # ]: 0 : cur_point->facets(cadj_facet_list);
508 [ # # ][ # # ]: 0 : if (cadj_facet_list.size() + nclose > max_close) {
509 : 0 : return CUBIT_FAILURE;
510 : : }
511 [ # # ]: 0 : cur_point->adjacent_points(cpoint,cnclose);
512 [ # # ][ # # ]: 0 : for(int k=0; k<cnclose; k++) {
[ # # ]
513 : :
514 : : // check that it is not already on the list
515 : :
516 : 0 : found = CUBIT_FALSE;
517 [ # # ][ # # ]: 0 : for(int l=0; l<nclose && !found; l++) {
518 [ # # ][ # # ]: 0 : if (close_point[l] == cpoint[k] ||
519 : 0 : cpoint[k] == point) {
520 : 0 : found = CUBIT_TRUE;
521 : : }
522 : : }
523 [ # # ]: 0 : if (!found) {
524 : :
525 : : // make sure the normal at this point is not more than 90 degrees
526 : : // from the normal at the point
527 : :
528 [ # # ][ # # ]: 0 : double dot = cpoint[k]->normal() % point->normal();
[ # # ]
529 [ # # ]: 0 : if (dot > GEOMETRY_RESABS) {
530 : :
531 : : // add the point to the list
532 : :
533 : 0 : close_point[nclose++] = cpoint[k];
534 : : }
535 : : }
536 : : }
537 : 0 : }
538 : 0 : num_close = nclose;
539 [ # # ]: 0 : if (num_close < min_close) {
540 : 0 : return CUBIT_FAILURE;
541 : : }
542 : : }
543 [ # # ]: 0 : return CUBIT_SUCCESS;
544 : : }
545 : :
546 : : //===========================================================================
547 : : //Function Name: mark edge pairs
548 : : //
549 : : //Member Type: PRIVATE
550 : : //Descriptoin: For the given point, we loop over the attached boundary
551 : : // edges and figure out which pairs should be C1 continuous.
552 : : // A given edge is paired with at most two other edges. The
553 : : // other edges (or the other edge) is stored on a tool data
554 : : // to be used later.
555 : : //===========================================================================
556 : 264 : CubitStatus FacetEvalTool::mark_edge_pairs(CubitPoint* point)
557 : : {
558 : : int i,j;
559 [ + - ]: 264 : DLIList<CubitFacetEdge*> edge_list;
560 [ + - ][ + - ]: 528 : DLIList<CubitFacetEdge*> edge_list_init;
561 : 264 : CubitPoint* prev_point = NULL;
562 : 264 : CubitPoint* next_point = NULL;
563 : 264 : CubitFacetEdge* prev_edge = NULL;
564 : 264 : CubitFacetEdge* next_edge = NULL;
565 [ + - ][ + - ]: 264 : CubitVector e0, e1;
566 : : double current_dot;
567 [ + - ]: 264 : point->edges(edge_list_init);
568 : 264 : TDFacetBoundaryEdge *td_fbe = NULL;
569 : :
570 : : // make a list with only the boundary edges
571 [ + - ][ + + ]: 1452 : for(i=0; i< edge_list_init.size(); i++){
572 [ + - ]: 1188 : prev_edge = edge_list_init.get_and_step();
573 [ + - ]: 1188 : td_fbe = TDFacetBoundaryEdge::get_facet_boundary_edge(prev_edge);
574 [ + + ]: 1188 : if(td_fbe)
575 [ + - ]: 792 : edge_list.append(prev_edge);
576 : : }
577 : 264 : prev_edge=NULL;
578 : : //if there is one or none, we don't need to bother looking
579 : : // for pairs.
580 [ + - ][ - + ]: 264 : if(edge_list.size() < 2)
581 : 0 : return CUBIT_SUCCESS;
582 [ + - ]: 264 : int num_edges=edge_list.size();
583 [ + - ][ + - ]: 528 : std::vector<int> other_index(num_edges);
584 [ + - ][ + - ]: 528 : std::vector<double> dot_array(num_edges);
585 : 264 : bool pair_exists = false;
586 : : // loop over the edges. For each edge, find the edge that would
587 : : // make the best other edge to pair this one with
588 [ + + ]: 1056 : for(i = 0; i<num_edges; i++){
589 [ + - ]: 792 : other_index[i]=-1;
590 [ + - ]: 792 : dot_array[i]=-1.0;
591 : :
592 [ + - ]: 792 : prev_edge=edge_list[i];
593 [ + - ]: 792 : prev_point = prev_edge->other_point(point);
594 : : // now figure out which other edge would be the best pair with
595 : : // this one. This could be sped up by only looking at the edges
596 : : // i+1 to num_edges, but ever this more exhaustive search is not
597 : : // guaranteed to make an optimal pairing... we take the longer
598 : : // approach hoping it will give slightly better results for
599 : : // hard problems...
600 [ + + ]: 3168 : for(j = 0; j<num_edges; j++){
601 [ + + ]: 2376 : if(j!=i){
602 [ + - ]: 1584 : next_edge = edge_list[j];
603 [ + - ]: 1584 : next_point = next_edge->other_point(point);
604 [ + - ][ + - ]: 1584 : e0 = point->coordinates() - next_point->coordinates();
[ + - ][ + - ]
605 [ + - ][ + - ]: 1584 : e1 = prev_point->coordinates() - point->coordinates();
[ + - ][ + - ]
606 [ + - ]: 1584 : e0.normalize();
607 [ + - ]: 1584 : e1.normalize();
608 [ + - ]: 1584 : current_dot = e0%e1;
609 : : //if the current dot satisfies the feature angle criterion
610 : : // and is better than any other we've seen so far for this
611 : : // given edge, save it.
612 [ - + ][ # # ]: 1584 : if(current_dot >= minDot && current_dot > dot_array[i]){
[ # # ][ - + ]
613 [ # # ]: 0 : dot_array[i]=current_dot;
614 [ # # ]: 0 : other_index[i]=j;
615 : 0 : pair_exists=true;//keep track of whether a pair has been saved
616 : : }
617 : : }
618 : : }
619 : : }
620 : : //if there aren't any pairs, don't bother moving forward.
621 [ + - ]: 264 : if(!pair_exists)
622 : 264 : return CUBIT_SUCCESS;
623 : : //now find the best pair. That is the pair with biggest
624 : : // dot product. Then find the next, and so on until we
625 : : // are done.
626 : 0 : double best_this_time = CUBIT_DBL_MAX;
627 : 0 : int best_index=-1;
628 : : // given num_edges > 2 and each edge is paired with at most
629 : : // one other edge at this node, there can't be more than
630 : : // num_edges - 1 pairs. Actually, num_edges / 2, but
631 : : // it is just a safety check anyway, so num_edges-1 will work.
632 [ # # ][ # # ]: 0 : for(i=0;i<num_edges-1 && best_this_time >= minDot; i++){
633 : 0 : best_this_time = -1.0;
634 : 0 : best_index = -1;
635 : : //loop over and find the biggest dot
636 [ # # ]: 0 : for(j=0;j<num_edges; j++){
637 [ # # ][ # # ]: 0 : if(dot_array[j] > best_this_time){
638 [ # # ]: 0 : best_this_time = dot_array[j];
639 : 0 : best_index = j;
640 : : }
641 : : }
642 : : //if we found a pair that we can make C1
643 [ # # ]: 0 : if(best_index >= 0){
644 : : //Don't let the above loop find either of these again
645 : : // (unless they are the 'other' in the pair).
646 [ # # ]: 0 : dot_array[best_index] = -1.0;
647 [ # # ][ # # ]: 0 : dot_array[other_index[best_index]] = -1.0;
648 : :
649 : : //First, make sure the other in the pair hasn't already
650 : : // been used.
651 [ # # ]: 0 : CubitFacetEdge* edge_1 = edge_list[best_index];
652 [ # # ][ # # ]: 0 : CubitFacetEdge* edge_2 = edge_list[other_index[best_index]];
653 [ # # ]: 0 : td_fbe = TDFacetBoundaryEdge::get_facet_boundary_edge( edge_2 );
654 [ # # ]: 0 : if(!td_fbe){
655 [ # # ][ # # ]: 0 : PRINT_ERROR("Expected a tool data.\n");
[ # # ][ # # ]
656 : 0 : return CUBIT_FAILURE;
657 : : }
658 : : //figure out whether it should be stored as prev or next
659 [ # # ][ # # ]: 0 : if(point == edge_2->point(0)){
660 : : //if something has already been stored here, then
661 : : // need to skip this pair
662 [ # # ][ # # ]: 0 : if(td_fbe->get_prev_edge())
663 : 0 : edge_1 = NULL;
664 : : else
665 [ # # ]: 0 : td_fbe->set_prev_edge(edge_1);
666 : : }
667 : : else{
668 [ # # ][ # # ]: 0 : if(td_fbe->get_next_edge())
669 : 0 : edge_1 = NULL;
670 : : else
671 [ # # ]: 0 : td_fbe->set_next_edge(edge_1);
672 : : }
673 : : //edge_1 will be NULL if we decided above to skip this pair
674 [ # # ]: 0 : if(edge_1){//otherwise save edge_2 in the appropriate spot
675 : : // for edge_1's tool data.
676 [ # # ]: 0 : td_fbe = TDFacetBoundaryEdge::get_facet_boundary_edge( edge_1 );
677 [ # # ]: 0 : if(!td_fbe){
678 [ # # ][ # # ]: 0 : PRINT_ERROR("Expected another tool data.\n");
[ # # ][ # # ]
679 : 0 : return CUBIT_FAILURE;
680 : : }
681 : :
682 [ # # ][ # # ]: 0 : if(point == edge_1->point(0))
683 [ # # ]: 0 : td_fbe->set_prev_edge(edge_2);
684 : : else
685 [ # # ]: 0 : td_fbe->set_next_edge(edge_2);
686 : : }
687 : : }
688 : :
689 : : }
690 [ + - ]: 264 : return CUBIT_SUCCESS;
691 : : }
692 : :
693 : :
694 : :
695 : : //===========================================================================
696 : : //Function Name: pair_edges
697 : : //
698 : : //Member Type: PRIVATE
699 : : //Descriptoin: Basically, loops over the points and calls
700 : : // mark_edge_pairs
701 : : //===========================================================================
702 : 66 : CubitStatus FacetEvalTool::pair_edges()
703 : : {
704 : 66 : CubitStatus status = CUBIT_SUCCESS;
705 : : int i;
706 : 66 : CubitPoint* point = NULL;
707 [ + + ]: 330 : for( i=0;i<myPointList.size(); i++){
708 : 264 : point = myPointList.get_and_step();
709 : 264 : status = mark_edge_pairs(point);
710 [ - + ]: 264 : if(status!=CUBIT_SUCCESS)
711 : 0 : return status;
712 : : }
713 : 66 : return status;
714 : : }
715 : :
716 : : //===========================================================================
717 : : //Function Name: init_bezier_surface
718 : : //
719 : : //Member Type: PRIVATE
720 : : //Descriptoin: compute the surface control points
721 : : //===========================================================================
722 : 66 : CubitStatus FacetEvalTool::init_bezier_surface()
723 : : {
724 : : // initialize the edges
725 : :
726 : : int i;
727 : 66 : CubitStatus status = CUBIT_SUCCESS;
728 : : CubitFacetEdge *edge;
729 : : // figure out which edges should be paired for C1 continuity.
730 : 66 : status = pair_edges();
731 [ - + ]: 66 : if(status!=CUBIT_SUCCESS)
732 : 0 : return status;
733 : :
734 [ + + ][ + - ]: 396 : for (i=0; i<myEdgeList.size() && status == CUBIT_SUCCESS; i++) {
[ + + ]
735 : 330 : edge = myEdgeList.get_and_step();
736 : 330 : status = init_bezier_edge( edge, minDot );
737 [ - + ]: 330 : if (status != CUBIT_SUCCESS)
738 : 0 : return status;
739 : : }
740 : 66 : int mydebug = 0;
741 [ - + ]: 66 : if (mydebug)
742 : : {
743 : 0 : debug_draw_bezier_edges();
744 : 0 : dview();
745 : : }
746 : :
747 : : // initialize the facets
748 : :
749 [ + - ]: 66 : if (status == CUBIT_SUCCESS) {
750 : : CubitFacet *facet;
751 [ + + ][ + - ]: 198 : for (i=0; i<myFacetList.size() && status == CUBIT_SUCCESS; i++) {
[ + + ]
752 : 132 : facet = myFacetList.get_and_step();
753 : 132 : status = init_bezier_facet( facet );
754 : : }
755 : : }
756 [ - + ]: 66 : if(status != CUBIT_SUCCESS){
757 [ # # ][ # # ]: 0 : PRINT_ERROR("Problem initializing bezier facet.\n");
758 : 0 : return status;
759 : : }
760 : :
761 : : // reset the bounding box to account for new control points
762 : :
763 : 66 : reset_bounding_box();
764 : :
765 : : //draw_eval_bezier_facet( myFacetList.get_and_step() );
766 : : // draw_bezier_facet( myFacetList.get_and_step() );
767 : :
768 : 66 : return status;
769 : : }
770 : :
771 : : //===========================================================================
772 : : //Function Name: init_bezier_edge
773 : : //
774 : : //Member Type: PRIVATE
775 : : //Descriptoin: compute the control points for an edge
776 : : //===========================================================================
777 : 330 : CubitStatus FacetEvalTool::init_bezier_edge( CubitFacetEdge *edge,
778 : : double min_dot )
779 : : {
780 : 330 : CubitStatus stat = CUBIT_SUCCESS;
781 : :
782 : : TDFacetBoundaryEdge *td_bfe =
783 : 330 : TDFacetBoundaryEdge::get_facet_boundary_edge( edge );
784 [ + + ]: 330 : if (td_bfe)
785 : : {
786 : 264 : stat = td_bfe->init_control_points( min_dot );
787 [ - + ]: 264 : if (stat != CUBIT_SUCCESS)
788 : 0 : return stat;
789 : 264 : stat = td_bfe->merge_control_points();
790 : : }
791 : : else
792 : : {
793 [ + - ][ + + ]: 264 : CubitVector ctrl_pts[3];
794 [ + - ][ + - ]: 66 : CubitVector P0 = edge->point(0)->coordinates();
795 [ + - ][ + - ]: 66 : CubitVector P3 = edge->point(1)->coordinates();
796 [ + - ][ + - ]: 66 : CubitVector N0 = edge->point(0)->normal( edge );
797 [ + - ][ + - ]: 66 : CubitVector N3 = edge->point(1)->normal( edge );
798 [ + - ][ + - ]: 66 : CubitVector T0, T3;
799 [ + - ][ - + ]: 66 : if (edge->num_adj_facets() <= 1)
800 : : {
801 [ # # ]: 0 : stat = compute_curve_tangent( edge, min_dot, T0, T3 );
802 [ # # ]: 0 : if (stat != CUBIT_SUCCESS)
803 : 0 : return stat;
804 : : }
805 : : else
806 : : {
807 [ + - ][ + - ]: 66 : T0 = P3 - P0;
808 [ + - ]: 66 : T0.normalize();
809 [ + - ]: 66 : T3 = T0;
810 : : }
811 [ + - ]: 66 : stat = init_edge_control_points( P0, P3, N0, N3, T0, T3, ctrl_pts );
812 [ - + ]: 66 : if (stat != CUBIT_SUCCESS)
813 : 0 : return stat;
814 [ + - ]: 66 : edge->control_points( ctrl_pts, 4 );
815 : : }
816 : 330 : return stat;
817 : : }
818 : :
819 : :
820 : : //===========================================================================
821 : : //Function Name: init_edge_control_points
822 : : //
823 : : //Member Type: PRIVATE
824 : : //Descriptoin: compute the control points for an edge
825 : : //===========================================================================
826 : 594 : CubitStatus FacetEvalTool::init_edge_control_points( CubitVector &P0,
827 : : CubitVector &P3,
828 : : CubitVector &N0,
829 : : CubitVector &N3,
830 : : CubitVector &T0,
831 : : CubitVector &T3,
832 : : CubitVector Pi[3] )
833 : : {
834 [ + - ][ + + ]: 2970 : CubitVector Vi[4];
835 [ + - ]: 594 : Vi[0] = P0;
836 [ + - ]: 594 : Vi[3] = P3;
837 [ + - ]: 594 : double di = P0.distance_between( P3 );
838 [ + - ]: 594 : double ai = N0 % N3;
839 [ + - ]: 594 : double ai0 = N0 % T0;
840 [ + - ]: 594 : double ai3 = N3 % T3;
841 [ + - ]: 594 : double denom = 4 - FacetEvalToolUtils::sqr(ai);
842 [ - + ]: 594 : if (fabs(denom) < 1e-20) {
843 : 0 : return CUBIT_FAILURE;
844 : : }
845 : 594 : double row = 6.0e0 * (2.0e0 * ai0 + ai * ai3) / denom;
846 : 594 : double omega = 6.0e0 * (2.0e0 * ai3 + ai * ai0) / denom;
847 [ + - ][ + - ]: 594 : Vi[1] = Vi[0] + (di * (((6.0e0 * T0) - ((2.0e0 * row) * N0) + (omega * N3)) / 18.0e0));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
848 [ + - ][ + - ]: 594 : Vi[2] = Vi[3] - (di * (((6.0e0 * T3) + (row * N0) - ((2.0e0 * omega) * N3)) / 18.0e0));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
849 [ + - ][ + + ]: 2376 : CubitVector Wi[3];
850 [ + - ][ + - ]: 594 : Wi[0] = Vi[1] - Vi[0];
851 [ + - ][ + - ]: 594 : Wi[1] = Vi[2] - Vi[1];
852 [ + - ][ + - ]: 594 : Wi[2] = Vi[3] - Vi[2];
853 : :
854 [ + - ][ + - ]: 594 : Pi[0] = 0.25 * Vi[0] + 0.75 * Vi[1];
[ + - ][ + - ]
855 [ + - ][ + - ]: 594 : Pi[1] = 0.50 * Vi[1] + 0.50 * Vi[2];
[ + - ][ + - ]
856 [ + - ][ + - ]: 594 : Pi[2] = 0.75 * Vi[2] + 0.25 * Vi[3];
[ + - ][ + - ]
857 : :
858 : 594 : return CUBIT_SUCCESS;
859 : : }
860 : :
861 : : //===========================================================================
862 : : //Function Name: init_edge_control_points_single
863 : : //
864 : : //Member Type: PRIVATE
865 : : //Descriptoin: compute the control points for an edge without normals
866 : : //===========================================================================
867 : 0 : CubitStatus FacetEvalTool::init_edge_control_points_single(
868 : : CubitVector &P0,
869 : : CubitVector &P3,
870 : : CubitVector &T0,
871 : : CubitVector &T3,
872 : : CubitVector Pi[3] )
873 : : {
874 [ # # ][ # # ]: 0 : CubitVector Vi[4];
875 [ # # ]: 0 : Vi[0] = P0;
876 [ # # ]: 0 : Vi[3] = P3;
877 [ # # ]: 0 : double di = P0.distance_between( P3 );
878 [ # # ]: 0 : double ai = T0 % T3;
879 [ # # ]: 0 : double denom = 4 - FacetEvalToolUtils::sqr(ai);
880 [ # # ]: 0 : if (fabs(denom) < 1e-20) {
881 : 0 : return CUBIT_FAILURE;
882 : : }
883 [ # # ][ # # ]: 0 : Vi[1] = Vi[0] + (di * (((6.0e0 * T0)) / 18.0e0));
[ # # ][ # # ]
[ # # ]
884 [ # # ][ # # ]: 0 : Vi[2] = Vi[3] - (di * (((6.0e0 * T3)) / 18.0e0));
[ # # ][ # # ]
[ # # ]
885 : :
886 [ # # ][ # # ]: 0 : Pi[0] = 0.25 * Vi[0] + 0.75 * Vi[1];
[ # # ][ # # ]
887 [ # # ][ # # ]: 0 : Pi[1] = 0.50 * Vi[1] + 0.50 * Vi[2];
[ # # ][ # # ]
888 [ # # ][ # # ]: 0 : Pi[2] = 0.75 * Vi[2] + 0.25 * Vi[3];
[ # # ][ # # ]
889 : :
890 : 0 : return CUBIT_SUCCESS;
891 : : }
892 : :
893 : : //===========================================================================
894 : : //Function Name: init_bezier_facet
895 : : //
896 : : //Member Type: PRIVATE
897 : : //Descriptoin: compute the control points for a facet
898 : : //===========================================================================
899 : 264 : CubitStatus FacetEvalTool::init_bezier_facet( CubitFacet *facet )
900 : : {
901 : :
902 : 264 : CubitStatus stat = CUBIT_SUCCESS;
903 [ + - ][ + + ]: 5016 : CubitVector P[3][5];
[ + + ]
904 [ + - ][ + + ]: 3432 : CubitVector N[6], G[6];
[ + - ][ + + ]
905 [ + - ]: 264 : stat = facet->get_edge_control_points( P );
906 [ - + ]: 264 : if (stat != CUBIT_SUCCESS)
907 : 0 : return stat;
908 : :
909 : : // retreive the normals from the edge points. Note we duplicate the
910 : : // pointer data here only because of the edge_use
911 : :
912 : 264 : int mydebug = 0;
913 [ - + ]: 264 : if (mydebug)
914 : : {
915 [ # # ]: 0 : dcolor(CUBIT_RED_INDEX);
916 [ # # ]: 0 : dfdraw(facet);
917 [ # # ]: 0 : dview();
918 : : }
919 [ + + ]: 1056 : for (int i=0; i<3; i++) {
920 [ + - ]: 792 : CubitFacetEdge *edge = facet->edge(i);
921 [ + - ][ + + ]: 792 : if (facet->edge_use(i) == 1) {
922 [ + - ][ + - ]: 396 : N[i*2] = edge->point(0)->normal( facet );
[ + - ]
923 [ + - ][ + - ]: 396 : N[i*2+1] = edge->point(1)->normal( facet );
[ + - ]
924 : : }
925 : : else {
926 [ + - ][ + - ]: 396 : N[i*2] = edge->point(1)->normal( facet );
[ + - ]
927 [ + - ][ + - ]: 396 : N[i*2+1] = edge->point(0)->normal( facet );
[ + - ]
928 : : }
929 : : }
930 : :
931 : : // init the facet control points.
932 : :
933 [ + - ]: 264 : stat = init_facet_control_points( N, P, G );
934 [ - + ]: 264 : if (stat != CUBIT_SUCCESS)
935 : 0 : return stat;
936 [ + - ]: 264 : facet->set_control_points ( G );
937 [ + - ]: 264 : facet->update_bezier_bounding_box();
938 : 264 : return stat;
939 : : }
940 : :
941 : : //===========================================================================
942 : : //Function Name: init_facet_control_points
943 : : //
944 : : //Member Type: PRIVATE
945 : : //Descriptoin: compute the control points for a facet
946 : : //===========================================================================
947 : 264 : CubitStatus FacetEvalTool::init_facet_control_points(
948 : : CubitVector N[6], // vertex normals (per edge)
949 : : CubitVector P[3][5], // edge control points
950 : : CubitVector G[6] ) // return internal control points
951 : : {
952 [ + - ][ + + ]: 3960 : CubitVector Di[4], Ai[3], N0, N3, Vi[4], Wi[3];
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ][ + + ]
953 : : double denom;
954 : : double lambda[2], mu[2];
955 : :
956 : 264 : CubitStatus stat = CUBIT_SUCCESS;
957 : :
958 [ + + ]: 1056 : for (int i=0; i<3; i++) {
959 [ + - ]: 792 : N0 = N[i*2];
960 [ + - ]: 792 : N3 = N[i*2+1];
961 [ + - ]: 792 : Vi[0] = P[i][0];
962 [ + - ][ + - ]: 792 : Vi[1] = (P[i][1] - 0.25 * P[i][0]) / 0.75;
[ + - ][ + - ]
963 [ + - ][ + - ]: 792 : Vi[2] = (P[i][3] - 0.25 * P[i][4]) / 0.75;
[ + - ][ + - ]
964 [ + - ]: 792 : Vi[3] = P[i][4];
965 [ + - ][ + - ]: 792 : Wi[0] = Vi[1] - Vi[0];
966 [ + - ][ + - ]: 792 : Wi[1] = Vi[2] - Vi[1];
967 [ + - ][ + - ]: 792 : Wi[2] = Vi[3] - Vi[2];
968 [ + - ][ + - ]: 792 : Di[0] = P[(i+2)%3][3] - 0.5*(P[i][1] + P[i][0]);
[ + - ][ + - ]
969 [ + - ][ + - ]: 792 : Di[3] = P[(i+1)%3][1] - 0.5*(P[i][4] + P[i][3]);
[ + - ][ + - ]
970 [ + - ][ - + ]: 792 : if(Wi[0].length() == 0.0)
971 : : {
972 [ # # ][ # # ]: 0 : Ai[0] = N0 * Wi[0];
973 [ # # ]: 0 : lambda[0] = Di[0] % Wi[0];
974 : : }
975 : : else
976 : : {
977 [ + - ][ + - ]: 792 : Ai[0] = (N0 * Wi[0]) / Wi[0].length();
[ + - ][ + - ]
978 [ + - ][ + - ]: 792 : lambda[0] = (Di[0] % Wi[0]) / (Wi[0] % Wi[0]);
979 : : }
980 : :
981 [ + - ][ - + ]: 792 : if(Wi[2].length() == 0.0)
982 : : {
983 [ # # ][ # # ]: 0 : Ai[2] = N3 * Wi[2];
984 [ # # ]: 0 : lambda[1] = Di[3] % Wi[2];
985 : : }
986 : : else
987 : : {
988 [ + - ][ + - ]: 792 : Ai[2] = (N3 * Wi[2]) / Wi[2].length();
[ + - ][ + - ]
989 [ + - ][ + - ]: 792 : lambda[1] = (Di[3] % Wi[2]) / (Wi[2] % Wi[2]);
990 : : }
991 [ + - ][ + - ]: 792 : Ai[1] = Ai[0] + Ai[2];
992 [ + - ]: 792 : denom = Ai[1].length();
993 [ + - ]: 792 : if (denom > 0)
994 [ + - ]: 792 : Ai[1] /= denom;
995 [ + - ]: 792 : mu[0] = (Di[0] % Ai[0]);
996 [ + - ]: 792 : mu[1] = (Di[3] % Ai[2]);
997 [ + - ][ + - ]: 792 : G[i*2] = 0.5 * (P[i][1] + P[i][2]) +
[ + - ]
998 [ + - ][ + - ]: 1584 : 0.66666666666666 * lambda[0] * Wi[1] +
999 [ + - ][ + - ]: 1584 : 0.33333333333333 * lambda[1] * Wi[0] +
1000 [ + - ][ + - ]: 1584 : 0.66666666666666 * mu[0] * Ai[1] +
1001 [ + - ][ + - ]: 1584 : 0.33333333333333 * mu[1] * Ai[0];
1002 [ + - ][ + - ]: 792 : G[i*2+1] = 0.5 * (P[i][2] + P[i][3]) +
[ + - ]
1003 [ + - ][ + - ]: 1584 : 0.33333333333333 * lambda[0] * Wi[2] +
1004 [ + - ][ + - ]: 1584 : 0.66666666666666 * lambda[1] * Wi[1] +
1005 [ + - ][ + - ]: 1584 : 0.33333333333333 * mu[0] * Ai[2] +
1006 [ + - ][ + - ]: 1584 : 0.66666666666666 * mu[1] * Ai[1];
1007 : : }
1008 : 264 : return stat;
1009 : : }
1010 : :
1011 : : //===========================================================================
1012 : : //Function Name: eval_bezier_patch
1013 : : //
1014 : : //Member Type: PRIVATE
1015 : : //Descriptoin: evaluate the bezier patch defined at a facet
1016 : : //===========================================================================
1017 : 0 : CubitStatus FacetEvalTool::eval_bezier_patch( CubitFacet *facet,
1018 : : CubitVector &areacoord,
1019 : : CubitVector &pt)
1020 : : {
1021 : : // interpolate internal control points
1022 : :
1023 [ # # ][ # # ]: 0 : CubitVector gctrl_pts[6];
1024 [ # # ]: 0 : facet->get_control_points( gctrl_pts );
1025 [ # # ][ # # ]: 0 : CubitVector P_facet[3];
1026 [ # # ][ # # ]: 0 : if (fabs(areacoord.y() + areacoord.z()) < 1.0e-6) {
[ # # ]
1027 [ # # ][ # # ]: 0 : pt = facet->point(0)->coordinates();
[ # # ]
1028 : 0 : return CUBIT_SUCCESS;
1029 : : }
1030 [ # # ][ # # ]: 0 : if (fabs(areacoord.x() + areacoord.z()) < 1.0e-6) {
[ # # ]
1031 [ # # ][ # # ]: 0 : pt = facet->point(1)->coordinates();
[ # # ]
1032 : 0 : return CUBIT_SUCCESS;
1033 : : }
1034 [ # # ][ # # ]: 0 : if (fabs(areacoord.x() + areacoord.y()) < 1.0e-6) {
[ # # ]
1035 [ # # ][ # # ]: 0 : pt = facet->point(2)->coordinates();
[ # # ]
1036 : 0 : return CUBIT_SUCCESS;
1037 : : }
1038 : :
1039 : : //2,1,1
1040 [ # # ][ # # ]: 0 : P_facet[0] = (1.0e0 / (areacoord.y() + areacoord.z())) *
[ # # ]
1041 [ # # ][ # # ]: 0 : (areacoord.y() * gctrl_pts[3] +
[ # # ]
1042 [ # # ][ # # ]: 0 : areacoord.z() * gctrl_pts[4]);
[ # # ]
1043 : : //1,2,1
1044 [ # # ][ # # ]: 0 : P_facet[1] = (1.0e0 / (areacoord.x() + areacoord.z())) *
[ # # ]
1045 [ # # ][ # # ]: 0 : (areacoord.x() * gctrl_pts[0] +
[ # # ]
1046 [ # # ][ # # ]: 0 : areacoord.z() * gctrl_pts[5]);
[ # # ]
1047 : : //1,1,2
1048 [ # # ][ # # ]: 0 : P_facet[2] = (1.0e0 / (areacoord.x() + areacoord.y())) *
[ # # ]
1049 [ # # ][ # # ]: 0 : (areacoord.x() * gctrl_pts[1] +
[ # # ]
1050 [ # # ][ # # ]: 0 : areacoord.y() * gctrl_pts[2]);
[ # # ]
1051 : :
1052 : : // sum the contribution from each of the control points
1053 : :
1054 [ # # ]: 0 : pt.set(0.0e0, 0.0e0, 0.0e0);
1055 : : CubitFacetEdge *edge;
1056 [ # # ]: 0 : edge = facet->edge( 2 );
1057 [ # # ][ # # ]: 0 : CubitVector ctrl_pts[5];
1058 [ # # ]: 0 : edge->control_points(facet, ctrl_pts);
1059 : :
1060 : : //i=4; j=0; k=0;
1061 [ # # ][ # # ]: 0 : double B = FacetEvalToolUtils::quart(areacoord.x());
1062 [ # # ][ # # ]: 0 : pt += B * ctrl_pts[0];
1063 : :
1064 : : //i=3; j=1; k=0;
1065 [ # # ][ # # ]: 0 : B = 4.0 * FacetEvalToolUtils::cube(areacoord.x()) * areacoord.y();
[ # # ]
1066 [ # # ][ # # ]: 0 : pt += B * ctrl_pts[1];
1067 : :
1068 : : //i=2; j=2; k=0;
1069 [ # # ][ # # ]: 0 : B = 6.0 * FacetEvalToolUtils::sqr(areacoord.x()) * FacetEvalToolUtils::sqr(areacoord.y());
[ # # ][ # # ]
1070 [ # # ][ # # ]: 0 : pt += B * ctrl_pts[2];
1071 : :
1072 : : //i=1; j=3; k=0;
1073 [ # # ][ # # ]: 0 : B = 4.0 * areacoord.x() * FacetEvalToolUtils::cube(areacoord.y());
[ # # ]
1074 [ # # ][ # # ]: 0 : pt += B * ctrl_pts[3];
1075 : :
1076 [ # # ]: 0 : edge = facet->edge( 0 );
1077 [ # # ]: 0 : edge->control_points(facet, ctrl_pts);
1078 : :
1079 : : //i=0; j=4; k=0;
1080 [ # # ][ # # ]: 0 : B = FacetEvalToolUtils::quart(areacoord.y());
1081 [ # # ][ # # ]: 0 : pt += B * ctrl_pts[0];
1082 : :
1083 : : //i=0; j=3; k=1;
1084 [ # # ][ # # ]: 0 : B = 4.0 * FacetEvalToolUtils::cube(areacoord.y()) * areacoord.z();
[ # # ]
1085 [ # # ][ # # ]: 0 : pt += B * ctrl_pts[1];
1086 : :
1087 : : //i=0; j=2; k=2;
1088 [ # # ][ # # ]: 0 : B = 6.0 * FacetEvalToolUtils::sqr(areacoord.y()) * FacetEvalToolUtils::sqr(areacoord.z());
[ # # ][ # # ]
1089 [ # # ][ # # ]: 0 : pt += B * ctrl_pts[2];
1090 : :
1091 : : //i=0; j=1; k=3;
1092 [ # # ][ # # ]: 0 : B = 4.0 * areacoord.y() * FacetEvalToolUtils::cube(areacoord.z());
[ # # ]
1093 [ # # ][ # # ]: 0 : pt += B * ctrl_pts[3];
1094 : :
1095 [ # # ]: 0 : edge = facet->edge( 1 );
1096 [ # # ]: 0 : edge->control_points(facet, ctrl_pts);
1097 : :
1098 : : //i=0; j=0; k=4;
1099 [ # # ][ # # ]: 0 : B = FacetEvalToolUtils::quart(areacoord.z());
1100 [ # # ][ # # ]: 0 : pt += B * ctrl_pts[0];
1101 : :
1102 : : //i=1; j=0; k=3;
1103 [ # # ][ # # ]: 0 : B = 4.0 * areacoord.x() * FacetEvalToolUtils::cube(areacoord.z());
[ # # ]
1104 [ # # ][ # # ]: 0 : pt += B * ctrl_pts[1];
1105 : :
1106 : : //i=2; j=0; k=2;
1107 [ # # ][ # # ]: 0 : B = 6.0 * FacetEvalToolUtils::sqr(areacoord.x()) * FacetEvalToolUtils::sqr(areacoord.z());
[ # # ][ # # ]
1108 [ # # ][ # # ]: 0 : pt += B * ctrl_pts[2];
1109 : :
1110 : : //i=3; j=0; k=1;
1111 [ # # ][ # # ]: 0 : B = 4.0 * FacetEvalToolUtils::cube(areacoord.x()) * areacoord.z();
[ # # ]
1112 [ # # ][ # # ]: 0 : pt += B * ctrl_pts[3];
1113 : :
1114 : : //i=2; j=1; k=1;
1115 [ # # ][ # # ]: 0 : B = 12.0 * FacetEvalToolUtils::sqr(areacoord.x()) * areacoord.y() * areacoord.z();
[ # # ][ # # ]
1116 [ # # ][ # # ]: 0 : pt += B * P_facet[0];
1117 : :
1118 : : //i=1; j=2; k=1;
1119 [ # # ][ # # ]: 0 : B = 12.0 * areacoord.x() * FacetEvalToolUtils::sqr(areacoord.y()) * areacoord.z();
[ # # ][ # # ]
1120 [ # # ][ # # ]: 0 : pt += B * P_facet[1];
1121 : :
1122 : : //i=1; j=1; k=2;
1123 [ # # ][ # # ]: 0 : B = 12.0 * areacoord.x() * areacoord.y() * FacetEvalToolUtils::sqr(areacoord.z());
[ # # ][ # # ]
1124 [ # # ][ # # ]: 0 : pt += B * P_facet[2];
1125 : :
1126 : 0 : return CUBIT_SUCCESS;
1127 : : }
1128 : :
1129 : : //===========================================================================
1130 : : //Function Name: eval_bezier_patch_normal
1131 : : //
1132 : : //Member Type: PRIVATE
1133 : : //Descriptoin: evaluate the bezier patch defined at a facet
1134 : : //===========================================================================
1135 : 0 : CubitStatus FacetEvalTool::eval_bezier_patch_normal( CubitFacet *facet,
1136 : : CubitVector &areacoord,
1137 : : CubitVector &normal )
1138 : : {
1139 : : // interpolate internal control points
1140 : :
1141 [ # # ][ # # ]: 0 : CubitVector gctrl_pts[6];
1142 [ # # ]: 0 : facet->get_control_points( gctrl_pts );
1143 [ # # ][ # # ]: 0 : if (fabs(areacoord.y() + areacoord.z()) < 1.0e-6) {
[ # # ]
1144 [ # # ][ # # ]: 0 : normal = facet->point(0)->normal(facet);
[ # # ]
1145 : 0 : return CUBIT_SUCCESS;
1146 : : }
1147 [ # # ][ # # ]: 0 : if (fabs(areacoord.x() + areacoord.z()) < 1.0e-6) {
[ # # ]
1148 [ # # ][ # # ]: 0 : normal = facet->point(1)->normal(facet);
[ # # ]
1149 : 0 : return CUBIT_SUCCESS;
1150 : : }
1151 [ # # ][ # # ]: 0 : if (fabs(areacoord.x() + areacoord.y()) < 1.0e-6) {
[ # # ]
1152 [ # # ][ # # ]: 0 : normal = facet->point(2)->normal(facet);
[ # # ]
1153 : 0 : return CUBIT_SUCCESS;
1154 : : }
1155 : :
1156 : : // compute the hodograph of the quartic Gregory patch
1157 : :
1158 [ # # ][ # # ]: 0 : CubitVector Nijk[10];
1159 [ # # ]: 0 : hodograph(facet,areacoord,Nijk);
1160 : :
1161 : : // sum the contribution from each of the control points
1162 : :
1163 [ # # ]: 0 : normal.set(0.0e0, 0.0e0, 0.0e0);
1164 : :
1165 : : //i=3; j=0; k=0;
1166 : 0 : double Bsum = 0.0;
1167 [ # # ][ # # ]: 0 : double B = FacetEvalToolUtils::cube(areacoord.x());
1168 : 0 : Bsum += B;
1169 [ # # ][ # # ]: 0 : normal += B * Nijk[0];
1170 : :
1171 : : //i=2; j=1; k=0;
1172 [ # # ][ # # ]: 0 : B = 3.0 * FacetEvalToolUtils::sqr(areacoord.x()) * areacoord.y();
[ # # ]
1173 : 0 : Bsum += B;
1174 [ # # ][ # # ]: 0 : normal += B * Nijk[1];
1175 : :
1176 : : //i=1; j=2; k=0;
1177 [ # # ][ # # ]: 0 : B = 3.0 * areacoord.x() * FacetEvalToolUtils::sqr(areacoord.y());
[ # # ]
1178 : 0 : Bsum += B;
1179 [ # # ][ # # ]: 0 : normal += B * Nijk[2];
1180 : :
1181 : : //i=0; j=3; k=0;
1182 [ # # ][ # # ]: 0 : B = FacetEvalToolUtils::cube(areacoord.y());
1183 : 0 : Bsum += B;
1184 [ # # ][ # # ]: 0 : normal += B * Nijk[3];
1185 : :
1186 : : //i=2; j=0; k=1;
1187 [ # # ][ # # ]: 0 : B = 3.0 * FacetEvalToolUtils::sqr(areacoord.x()) * areacoord.z();
[ # # ]
1188 : 0 : Bsum += B;
1189 [ # # ][ # # ]: 0 : normal += B * Nijk[4];
1190 : :
1191 : : //i=1; j=1; k=1;
1192 [ # # ][ # # ]: 0 : B = 6.0 * areacoord.x() * areacoord.y() * areacoord.z();
[ # # ]
1193 : 0 : Bsum += B;
1194 [ # # ][ # # ]: 0 : normal += B * Nijk[5];
1195 : :
1196 : : //i=0; j=2; k=1;
1197 [ # # ][ # # ]: 0 : B = 3.0 * FacetEvalToolUtils::sqr(areacoord.y()) * areacoord.z();
[ # # ]
1198 : 0 : Bsum += B;
1199 [ # # ][ # # ]: 0 : normal += B * Nijk[6];
1200 : :
1201 : : //i=1; j=0; k=2;
1202 [ # # ][ # # ]: 0 : B = 3.0 * areacoord.x() * FacetEvalToolUtils::sqr(areacoord.z());
[ # # ]
1203 : 0 : Bsum += B;
1204 [ # # ][ # # ]: 0 : normal += B * Nijk[7];
1205 : :
1206 : : //i=0; j=1; k=2;
1207 [ # # ][ # # ]: 0 : B = 3.0 * areacoord.y() * FacetEvalToolUtils::sqr(areacoord.z());
[ # # ]
1208 : 0 : Bsum += B;
1209 [ # # ][ # # ]: 0 : normal += B * Nijk[8];
1210 : :
1211 : : //i=0; j=0; k=3;
1212 [ # # ][ # # ]: 0 : B = FacetEvalToolUtils::cube(areacoord.z());
1213 : 0 : Bsum += B;
1214 [ # # ][ # # ]: 0 : normal += B * Nijk[9];
1215 : :
1216 [ # # ]: 0 : assert(fabs(Bsum - 1.0) < 1e-9);
1217 : :
1218 [ # # ]: 0 : normal.normalize();
1219 : :
1220 : 0 : return CUBIT_SUCCESS;
1221 : : }
1222 : :
1223 : : //===========================================================================
1224 : : //Function Name: hodograph
1225 : : //
1226 : : //Member Type: PUBLIC
1227 : : //Description: get the hodograph control points for the facet
1228 : : //Note: This is a triangle cubic patch that is defined by the
1229 : : // normals of quartic facet control point lattice. Returned coordinates
1230 : : // in Nijk are defined by the following diagram
1231 : : //
1232 : : //
1233 : : // *9 index polar
1234 : : // / \ 0 300 point(0)
1235 : : // / \ 1 210
1236 : : // 7*-----*8 2 120
1237 : : // / \ / \ 3 030 point(1)
1238 : : // / \ / \ 4 201
1239 : : // 4*----5*-----*6 5 111
1240 : : // / \ / \ / \ 6 021
1241 : : // / \ / \ / \ 7 102
1242 : : // *-----*-----*-----* 8 012
1243 : : // 0 1 2 3 9 003 point(2)
1244 : : //
1245 : : //===========================================================================
1246 : 0 : CubitStatus FacetEvalTool::hodograph( CubitFacet *facet,
1247 : : CubitVector &areacoord,
1248 : : CubitVector Nijk[10] )
1249 : : {
1250 : :
1251 : : // compute the control points on the interior of the patch based on areacoord
1252 : :
1253 [ # # ][ # # ]: 0 : CubitVector gctrl_pts[6];
1254 [ # # ]: 0 : facet->get_control_points( gctrl_pts );
1255 [ # # ][ # # ]: 0 : CubitVector P_facet[3];
1256 : :
1257 : : //2,1,1
1258 [ # # ][ # # ]: 0 : P_facet[0] = (1.0e0 / (areacoord.y() + areacoord.z())) *
[ # # ]
1259 [ # # ][ # # ]: 0 : (areacoord.y() * gctrl_pts[3] +
[ # # ]
1260 [ # # ][ # # ]: 0 : areacoord.z() * gctrl_pts[4]);
[ # # ]
1261 : : //1,2,1
1262 [ # # ][ # # ]: 0 : P_facet[1] = (1.0e0 / (areacoord.x() + areacoord.z())) *
[ # # ]
1263 [ # # ][ # # ]: 0 : (areacoord.x() * gctrl_pts[0] +
[ # # ]
1264 [ # # ][ # # ]: 0 : areacoord.z() * gctrl_pts[5]);
[ # # ]
1265 : : //1,1,2
1266 [ # # ][ # # ]: 0 : P_facet[2] = (1.0e0 / (areacoord.x() + areacoord.y())) *
[ # # ]
1267 [ # # ][ # # ]: 0 : (areacoord.x() * gctrl_pts[1] +
[ # # ]
1268 [ # # ][ # # ]: 0 : areacoord.y() * gctrl_pts[2]);
[ # # ]
1269 : :
1270 : : // corner control points are just the normals at the points
1271 : :
1272 : : //3, 0, 0
1273 [ # # ][ # # ]: 0 : Nijk[0] = facet->point(0)->normal(facet);
[ # # ]
1274 : : //0, 3, 0
1275 [ # # ][ # # ]: 0 : Nijk[3] = facet->point(1)->normal(facet);
[ # # ]
1276 : : //0, 0, 3
1277 [ # # ][ # # ]: 0 : Nijk[9] = facet->point(2)->normal(facet);
[ # # ]
1278 : :
1279 : : // fill in the boundary control points. Define as the normal to the local
1280 : : // triangle formed by the quartic control point lattice
1281 : :
1282 : : CubitFacetEdge *edge;
1283 [ # # ]: 0 : edge = facet->edge( 2 );
1284 [ # # ][ # # ]: 0 : CubitVector ctrl_pts[5];
1285 [ # # ]: 0 : edge->control_points(facet, ctrl_pts);
1286 : :
1287 : : //2, 1, 0
1288 [ # # ][ # # ]: 0 : Nijk[1] = (ctrl_pts[2] - ctrl_pts[1]) * (P_facet[0] - ctrl_pts[1]);
[ # # ][ # # ]
1289 [ # # ]: 0 : Nijk[1].normalize();
1290 : :
1291 : : //1, 2, 0
1292 [ # # ][ # # ]: 0 : Nijk[2] = (ctrl_pts[3] - ctrl_pts[2]) * (P_facet[1] - ctrl_pts[2]);
[ # # ][ # # ]
1293 [ # # ]: 0 : Nijk[2].normalize();
1294 : :
1295 [ # # ]: 0 : edge = facet->edge( 0 );
1296 [ # # ]: 0 : edge->control_points(facet, ctrl_pts);
1297 : :
1298 : : //0, 2, 1
1299 [ # # ][ # # ]: 0 : Nijk[6] = (ctrl_pts[1] - P_facet[1]) * (ctrl_pts[2] - P_facet[1]);
[ # # ][ # # ]
1300 [ # # ]: 0 : Nijk[6].normalize();
1301 : :
1302 : : //0, 1, 2
1303 [ # # ][ # # ]: 0 : Nijk[8] = (ctrl_pts[2] - P_facet[2]) * (ctrl_pts[3] - P_facet[2]);
[ # # ][ # # ]
1304 [ # # ]: 0 : Nijk[8].normalize();
1305 : :
1306 [ # # ]: 0 : edge = facet->edge( 1 );
1307 [ # # ]: 0 : edge->control_points(facet, ctrl_pts);
1308 : :
1309 : : //1, 0, 2
1310 [ # # ][ # # ]: 0 : Nijk[7] = (P_facet[2] - ctrl_pts[2]) * (ctrl_pts[1] - ctrl_pts[2]);
[ # # ][ # # ]
1311 [ # # ]: 0 : Nijk[7].normalize();
1312 : :
1313 : : //2, 0, 1
1314 [ # # ][ # # ]: 0 : Nijk[4] = (P_facet[0] - ctrl_pts[3]) * (ctrl_pts[2] - ctrl_pts[3]);
[ # # ][ # # ]
1315 [ # # ]: 0 : Nijk[4].normalize();
1316 : :
1317 : : //1, 1, 1
1318 [ # # ][ # # ]: 0 : Nijk[5] = (P_facet[1] - P_facet[0]) * (P_facet[2] - P_facet[0]);
[ # # ][ # # ]
1319 [ # # ]: 0 : Nijk[5].normalize();
1320 : :
1321 : 0 : int mydebug = 0;
1322 [ # # ]: 0 : if (mydebug)
1323 : : {
1324 : : #define ONE_THIRD 0.33333333333333333333333333333333333
1325 : : #define TWO_THIRDS .666666666666666666666666666666666666667
1326 : : int ii;
1327 [ # # ][ # # ]: 0 : CubitVector ac, pt;
1328 [ # # ]: 0 : for(ii=0; ii<10; ii++)
1329 : : {
1330 [ # # # # : 0 : switch(ii)
# # # # #
# # ]
1331 : : {
1332 [ # # ]: 0 : case 0: ac.set(1.0, 0.0, 0.0 ); break;
1333 [ # # ]: 0 : case 1: ac.set(TWO_THIRDS, ONE_THIRD, 0.0 ); break;
1334 [ # # ]: 0 : case 2: ac.set(ONE_THIRD, TWO_THIRDS, 0.0 ); break;
1335 [ # # ]: 0 : case 3: ac.set(0.0, 1.0, 0.0 ); break;
1336 [ # # ]: 0 : case 4: ac.set(TWO_THIRDS, 0.0, ONE_THIRD ); break;
1337 [ # # ]: 0 : case 5: ac.set(ONE_THIRD, ONE_THIRD, ONE_THIRD ); break;
1338 [ # # ]: 0 : case 6: ac.set(0.0, TWO_THIRDS, ONE_THIRD ); break;
1339 [ # # ]: 0 : case 7: ac.set(ONE_THIRD, 0.0, TWO_THIRDS); break;
1340 [ # # ]: 0 : case 8: ac.set(0.0, ONE_THIRD, TWO_THIRDS); break;
1341 [ # # ]: 0 : case 9: ac.set(0.0, 0.0, 1.0 ); break;
1342 : : }
1343 [ # # ]: 0 : eval_bezier_patch(facet, ac, pt);
1344 [ # # ]: 0 : dray(pt,Nijk[ii],1.0);
1345 : : }
1346 [ # # ]: 0 : dview();
1347 : : }
1348 : :
1349 : 0 : return CUBIT_SUCCESS;
1350 : : }
1351 : :
1352 : :
1353 : : //===========================================================================
1354 : : //Function Name: project_to_patch
1355 : : //
1356 : : //Member Type: PUBLIC
1357 : : //Descriptoin: Project a point to a bezier patch. Pass in the area
1358 : : // of the point projected to the linear facet. Function
1359 : : // assumes that the point is contained within the patch -
1360 : : // if not, it will project to one of its edges.
1361 : : //===========================================================================
1362 : 0 : CubitStatus FacetEvalTool::project_to_patch(
1363 : : CubitFacet *facet, // (IN) the facet where the patch is defined
1364 : : CubitVector &ac, // (IN) area coordinate initial guess (from linear facet)
1365 : : const CubitVector &pt, // (IN) point we are projecting to patch
1366 : : CubitVector &eval_pt, // (OUT) The projected point
1367 : : CubitVector *eval_norm, // (OUT) normal at evaluated point
1368 : : CubitBoolean &outside, // (OUT) the closest point on patch to pt is on an edge
1369 : : double compare_tol, // (IN) comparison tolerance
1370 : : int edge_id ) // (IN) only used if this is to be projected to one
1371 : : // of the edges. Otherwise, should be -1
1372 : : {
1373 : 0 : CubitStatus status = CUBIT_SUCCESS;
1374 : :
1375 : : // see if we are at a vertex
1376 : :
1377 : : #define INCR 0.01
1378 : 0 : const double tol = compare_tol;
1379 : :
1380 [ # # ][ # # ]: 0 : if (is_at_vertex( facet, pt, ac, compare_tol, eval_pt, eval_norm ))
1381 : : {
1382 : 0 : outside = CUBIT_FALSE;
1383 : 0 : return CUBIT_SUCCESS;
1384 : : }
1385 : :
1386 : : // check if the start ac is inside the patch -if not, then move it there
1387 : :
1388 : 0 : int nout = 0;
1389 : 0 : const double atol = 0.001;
1390 [ # # ][ # # ]: 0 : if(move_ac_inside( ac, atol ))
1391 : 0 : nout++;
1392 : :
1393 : 0 : int diverge = 0;
1394 : 0 : int iter = 0;
1395 [ # # ]: 0 : CubitVector newpt;
1396 [ # # ]: 0 : eval_bezier_patch(facet, ac, newpt);
1397 [ # # ]: 0 : CubitVector move = pt - newpt;
1398 [ # # ]: 0 : double lastdist = move.length();
1399 : 0 : double bestdist = lastdist;
1400 [ # # ]: 0 : CubitVector bestac = ac;
1401 [ # # ]: 0 : CubitVector bestpt = newpt;
1402 [ # # ]: 0 : CubitVector bestnorm;
1403 : :
1404 : : // If we are already close enough, then return now
1405 : :
1406 [ # # ][ # # ]: 0 : if (lastdist <= tol && !eval_norm && nout == 0) {
[ # # ]
1407 [ # # ]: 0 : eval_pt = pt;
1408 : 0 : outside = CUBIT_FALSE;
1409 : 0 : return status;
1410 : : }
1411 : :
1412 : : double ratio, mag, umove, vmove, det, distnew, movedist;
1413 [ # # ]: 0 : CubitVector lastpt = newpt;
1414 [ # # ]: 0 : CubitVector lastac = ac;
1415 [ # # ]: 0 : CubitVector norm;
1416 [ # # ][ # # ]: 0 : CubitVector xpt, ypt, zpt, xac, yac, zac, xvec, yvec, zvec;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1417 [ # # ][ # # ]: 0 : CubitVector du, dv, newac;
[ # # ]
1418 : 0 : CubitBoolean done = CUBIT_FALSE;
1419 [ # # ]: 0 : while (!done) {
1420 : :
1421 : : // We will be locating the projected point within the u,v,w coordinate
1422 : : // system of the triangular bezier patch. Since u+v+w=1, the components
1423 : : // are not linearly independant. We will choose only two of the
1424 : : // coordinates to use and compute the third.
1425 : :
1426 : : int system;
1427 [ # # ][ # # ]: 0 : if (lastac.x() >= lastac.y() && lastac.x() >= lastac.z()) {
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1428 : 0 : system = 0;
1429 : : }
1430 [ # # ][ # # ]: 0 : else if (lastac.y() >= lastac.z()) {
[ # # ]
1431 : 0 : system = 1;
1432 : : }
1433 : : else {
1434 : 0 : system = 2;
1435 : : }
1436 : :
1437 : : // compute the surface derivatives with respect to each
1438 : : // of the barycentric coordinates
1439 : :
1440 : :
1441 [ # # ][ # # ]: 0 : if (system == 1 || system == 2) {
1442 [ # # ][ # # ]: 0 : xac.x( lastac.x() + INCR );
1443 [ # # ][ # # ]: 0 : if (lastac.y() + lastac.z() == 0.0)
[ # # ]
1444 : 0 : return CUBIT_FAILURE;
1445 [ # # ][ # # ]: 0 : ratio = lastac.z() / (lastac.y() + lastac.z());
[ # # ]
1446 [ # # ][ # # ]: 0 : xac.y( (1.0 - xac.x()) * (1.0 - ratio) );
1447 [ # # ][ # # ]: 0 : xac.z( 1.0 - xac.x() - xac.y() );
[ # # ]
1448 [ # # ]: 0 : eval_bezier_patch(facet, xac, xpt);
1449 [ # # ][ # # ]: 0 : xvec = xpt - lastpt;
1450 [ # # ]: 0 : xvec /= INCR;
1451 : : }
1452 [ # # ][ # # ]: 0 : if (system == 0 || system == 2) {
1453 [ # # ][ # # ]: 0 : yac.y( lastac.y() + INCR );
1454 [ # # ][ # # ]: 0 : if (lastac.x() + lastac.z() == 0.0)
[ # # ]
1455 : 0 : return CUBIT_FAILURE;
1456 [ # # ][ # # ]: 0 : ratio = lastac.z() / (lastac.x() + lastac.z());
[ # # ]
1457 [ # # ][ # # ]: 0 : yac.x( (1.0 - yac.y()) * (1.0 - ratio) );
1458 [ # # ][ # # ]: 0 : yac.z( 1.0 - yac.x() - yac.y() );
[ # # ]
1459 [ # # ]: 0 : eval_bezier_patch(facet, yac, ypt);
1460 [ # # ][ # # ]: 0 : yvec = ypt - lastpt;
1461 [ # # ]: 0 : yvec /= INCR;
1462 : : }
1463 [ # # ][ # # ]: 0 : if (system == 0 || system == 1) {
1464 [ # # ][ # # ]: 0 : zac.z( lastac.z() + INCR );
1465 [ # # ][ # # ]: 0 : if (lastac.x() + lastac.y() == 0.0)
[ # # ]
1466 : 0 : return CUBIT_FAILURE;
1467 [ # # ][ # # ]: 0 : ratio = lastac.y() / (lastac.x() + lastac.y());
[ # # ]
1468 [ # # ][ # # ]: 0 : zac.x( (1.0 - zac.z()) * (1.0 - ratio) );
1469 [ # # ][ # # ]: 0 : zac.y( 1.0 - zac.x() - zac.z() );
[ # # ]
1470 [ # # ]: 0 : eval_bezier_patch(facet, zac, zpt);
1471 [ # # ][ # # ]: 0 : zvec = zpt - lastpt;
1472 [ # # ]: 0 : zvec /= INCR;
1473 : : }
1474 : :
1475 : : // compute the surface normal
1476 : :
1477 [ # # # # ]: 0 : switch (system) {
1478 : : case 0:
1479 [ # # ]: 0 : du = yvec;
1480 [ # # ]: 0 : dv = zvec;
1481 : 0 : break;
1482 : : case 1:
1483 [ # # ]: 0 : du = zvec;
1484 [ # # ]: 0 : dv = xvec;
1485 : 0 : break;
1486 : : case 2:
1487 [ # # ]: 0 : du = xvec;
1488 [ # # ]: 0 : dv = yvec;
1489 : 0 : break;
1490 : : }
1491 [ # # ][ # # ]: 0 : norm = du * dv;
1492 [ # # ]: 0 : mag = norm.length();
1493 [ # # ]: 0 : if (mag < DBL_EPSILON) {
1494 : 0 : return CUBIT_FAILURE;
1495 : : // do something else here (it is likely a flat triangle -
1496 : : // so try evaluating just an edge of the bezier patch)
1497 : : }
1498 [ # # ]: 0 : norm /= mag;
1499 [ # # ]: 0 : if (iter == 0)
1500 [ # # ]: 0 : bestnorm = norm;
1501 : :
1502 : : // project the move vector to the tangent plane
1503 : :
1504 [ # # ][ # # ]: 0 : move = (norm * move) * norm;
[ # # ]
1505 : :
1506 : : // compute an equivalent u-v-w vector
1507 : :
1508 [ # # ][ # # ]: 0 : CubitVector absnorm( fabs(norm.x()), fabs(norm.y()), fabs(norm.z()) );
[ # # ][ # # ]
1509 [ # # ][ # # ]: 0 : if (absnorm.z() >= absnorm.y() && absnorm.z() >= absnorm.x()) {
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1510 [ # # ][ # # ]: 0 : det = du.x() * dv.y() - dv.x() * du.y();
[ # # ][ # # ]
1511 [ # # ]: 0 : if (fabs(det) <= DBL_EPSILON) {
1512 : 0 : return CUBIT_FAILURE; // do something else here
1513 : : }
1514 [ # # ][ # # ]: 0 : umove = (move.x() * dv.y() - dv.x() * move.y()) / det;
[ # # ][ # # ]
1515 [ # # ][ # # ]: 0 : vmove = (du.x() * move.y() - move.x() * du.y()) / det;
[ # # ][ # # ]
1516 : : }
1517 [ # # ][ # # ]: 0 : else if (absnorm.y() >= absnorm.z() && absnorm.y() >= absnorm.x()) {
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1518 [ # # ][ # # ]: 0 : det = du.x() * dv.z() - dv.x() * du.z();
[ # # ][ # # ]
1519 [ # # ]: 0 : if (fabs(det) <= DBL_EPSILON) {
1520 : 0 : return CUBIT_FAILURE;
1521 : : }
1522 [ # # ][ # # ]: 0 : umove = (move.x() * dv.z() - dv.x() * move.z()) / det;
[ # # ][ # # ]
1523 [ # # ][ # # ]: 0 : vmove = (du.x() * move.z() - move.x() * du.z()) / det;
[ # # ][ # # ]
1524 : : }
1525 : : else {
1526 [ # # ][ # # ]: 0 : det = du.y() * dv.z() - dv.y() * du.z();
[ # # ][ # # ]
1527 [ # # ]: 0 : if (fabs(det) <= DBL_EPSILON) {
1528 : 0 : return CUBIT_FAILURE;
1529 : : }
1530 [ # # ][ # # ]: 0 : umove = (move.y() * dv.z() - dv.y() * move.z()) / det;
[ # # ][ # # ]
1531 [ # # ][ # # ]: 0 : vmove = (du.y() * move.z() - move.y() * du.z()) / det;
[ # # ][ # # ]
1532 : : }
1533 : :
1534 : : /* === compute the new u-v coords and evaluate surface at new location */
1535 : :
1536 [ # # # # ]: 0 : switch (system) {
1537 : : case 0:
1538 [ # # ][ # # ]: 0 : newac.y( lastac.y() + umove );
1539 [ # # ][ # # ]: 0 : newac.z( lastac.z() + vmove );
1540 [ # # ][ # # ]: 0 : newac.x( 1.0 - newac.y() - newac.z() );
[ # # ]
1541 : 0 : break;
1542 : : case 1:
1543 [ # # ][ # # ]: 0 : newac.z( lastac.z() + umove );
1544 [ # # ][ # # ]: 0 : newac.x( lastac.x() + vmove );
1545 [ # # ][ # # ]: 0 : newac.y( 1.0 - newac.z() - newac.x() );
[ # # ]
1546 : 0 : break;
1547 : : case 2:
1548 [ # # ][ # # ]: 0 : newac.x( lastac.x() + umove );
1549 [ # # ][ # # ]: 0 : newac.y( lastac.y() + vmove );
1550 [ # # ][ # # ]: 0 : newac.z( 1.0 - newac.x() - newac.y() );
[ # # ]
1551 : 0 : break;
1552 : : }
1553 : :
1554 : : // Keep it inside the patch
1555 : :
1556 [ # # ][ # # ]: 0 : if ( newac.x() >= -atol &&
[ # # ]
1557 [ # # ][ # # ]: 0 : newac.y() >= -atol &&
[ # # ]
1558 [ # # ]: 0 : newac.z() >= -atol) {
1559 : 0 : nout = 0;
1560 : : }
1561 : : else {
1562 [ # # ][ # # ]: 0 : if (move_ac_inside( newac, atol ) == CUBIT_TRUE)
1563 : 0 : nout++;
1564 : : }
1565 : :
1566 : : // Evaluate at the new location
1567 : :
1568 [ # # ]: 0 : if (edge_id != -1)
1569 [ # # ]: 0 : ac_at_edge( newac, newac, edge_id ); // move to edge first
1570 [ # # ]: 0 : eval_bezier_patch(facet, newac, newpt);
1571 : :
1572 : : // Check for convergence
1573 : :
1574 [ # # ]: 0 : distnew = pt.distance_between(newpt);
1575 [ # # ][ # # ]: 0 : move = newpt - lastpt;
1576 [ # # ]: 0 : movedist = move.length();
1577 [ # # ][ # # ]: 0 : if (movedist < tol ||
1578 : : distnew < tol ) {
1579 : 0 : done = CUBIT_TRUE;
1580 [ # # ]: 0 : if (distnew < bestdist)
1581 : : {
1582 : 0 : bestdist = distnew;
1583 [ # # ]: 0 : bestac = newac;
1584 [ # # ]: 0 : bestpt = newpt;
1585 [ # # ]: 0 : bestnorm = norm;
1586 : : }
1587 : : }
1588 : : else {
1589 : :
1590 : : // don't allow more than 30 iterations
1591 : :
1592 : 0 : iter++;
1593 [ # # ]: 0 : if (iter > 30) {
1594 : : //if (movedist > tol * 100.0) nout=1;
1595 : 0 : done = CUBIT_TRUE;
1596 : : }
1597 : :
1598 : : // Check for divergence - don't allow more than 5 divergent
1599 : : // iterations
1600 : :
1601 [ # # ]: 0 : if (distnew > lastdist) {
1602 : 0 : diverge++;
1603 [ # # ]: 0 : if (diverge > 10) {
1604 : 0 : done = CUBIT_TRUE;
1605 : : //if (movedist > tol * 100.0) nout=1;
1606 : : }
1607 : : }
1608 : :
1609 : : // Check if we are continuing to project outside the facet.
1610 : : // If so, then stop now
1611 : :
1612 [ # # ]: 0 : if (nout > 3) {
1613 : 0 : done = CUBIT_TRUE;
1614 : : }
1615 : :
1616 : : // set up for next iteration
1617 : :
1618 [ # # ]: 0 : if (!done) {
1619 [ # # ]: 0 : if (distnew < bestdist)
1620 : : {
1621 : 0 : bestdist = distnew;
1622 [ # # ]: 0 : bestac = newac;
1623 [ # # ]: 0 : bestpt = newpt;
1624 [ # # ]: 0 : bestnorm = norm;
1625 : : }
1626 : 0 : lastdist = distnew;
1627 [ # # ]: 0 : lastpt = newpt;
1628 [ # # ]: 0 : lastac = newac;
1629 [ # # ][ # # ]: 0 : move = pt - lastpt;
1630 : : }
1631 : : }
1632 : : }
1633 : :
1634 [ # # ]: 0 : eval_pt = bestpt;
1635 [ # # ]: 0 : if (eval_norm) {
1636 [ # # ]: 0 : *eval_norm = bestnorm;
1637 : : }
1638 [ # # ]: 0 : outside = (nout > 0) ? CUBIT_TRUE : CUBIT_FALSE;
1639 [ # # ]: 0 : ac = bestac;
1640 : :
1641 : 0 : return status;
1642 : : }
1643 : :
1644 : : //===========================================================================
1645 : : //Function Name: is_at_vertex
1646 : : //
1647 : : //Member Type: PRIVATE
1648 : : //Description: determine if the point is at one of the facet's vertices
1649 : : //===========================================================================
1650 : 0 : CubitBoolean FacetEvalTool::is_at_vertex(
1651 : : CubitFacet *facet, // (IN) facet we are evaluating
1652 : : const CubitVector &pt, // (IN) the point
1653 : : CubitVector &ac, // (IN) the ac of the point on the facet plane
1654 : : double compare_tol, // (IN) return TRUE of closer than this
1655 : : CubitVector &eval_pt, // (OUT) location at vertex if TRUE
1656 : : CubitVector *eval_norm_ptr ) // (OUT) normal at vertex if TRUE
1657 : : {
1658 : : double dist;
1659 [ # # ]: 0 : CubitVector vert_loc;
1660 : 0 : const double actol = 0.1;
1661 [ # # ][ # # ]: 0 : if (fabs(ac.x()) < actol && fabs(ac.y()) < actol) {
[ # # ][ # # ]
[ # # ]
1662 [ # # ][ # # ]: 0 : vert_loc = facet->point(2)->coordinates();
[ # # ]
1663 [ # # ]: 0 : dist = pt.distance_between( vert_loc );
1664 [ # # ]: 0 : if (dist <= compare_tol)
1665 : : {
1666 [ # # ]: 0 : eval_pt = vert_loc;
1667 [ # # ]: 0 : if (eval_norm_ptr)
1668 : : {
1669 [ # # ][ # # ]: 0 : *eval_norm_ptr = facet->point(2)->normal( facet );
[ # # ]
1670 : : }
1671 : 0 : return CUBIT_TRUE;
1672 : : }
1673 : : }
1674 : :
1675 [ # # ][ # # ]: 0 : if (fabs(ac.x()) < actol && fabs(ac.z()) < actol) {
[ # # ][ # # ]
[ # # ]
1676 [ # # ][ # # ]: 0 : vert_loc = facet->point(1)->coordinates();
[ # # ]
1677 [ # # ]: 0 : dist = pt.distance_between( vert_loc );
1678 [ # # ]: 0 : if (dist <= compare_tol)
1679 : : {
1680 [ # # ]: 0 : eval_pt = vert_loc;
1681 [ # # ]: 0 : if (eval_norm_ptr)
1682 : : {
1683 [ # # ][ # # ]: 0 : *eval_norm_ptr = facet->point(1)->normal( facet );
[ # # ]
1684 : : }
1685 : 0 : return CUBIT_TRUE;
1686 : : }
1687 : : }
1688 : :
1689 [ # # ][ # # ]: 0 : if (fabs(ac.y()) < actol && fabs(ac.z()) < actol) {
[ # # ][ # # ]
[ # # ]
1690 [ # # ][ # # ]: 0 : vert_loc = facet->point(0)->coordinates();
[ # # ]
1691 [ # # ]: 0 : dist = pt.distance_between( vert_loc );
1692 [ # # ]: 0 : if (dist <= compare_tol)
1693 : : {
1694 [ # # ]: 0 : eval_pt = vert_loc;
1695 [ # # ]: 0 : if (eval_norm_ptr)
1696 : : {
1697 [ # # ][ # # ]: 0 : *eval_norm_ptr = facet->point(0)->normal( facet );
[ # # ]
1698 : : }
1699 : 0 : return CUBIT_TRUE;
1700 : : }
1701 : : }
1702 : :
1703 : 0 : return CUBIT_FALSE;
1704 : : }
1705 : :
1706 : : //===========================================================================
1707 : : //Function Name: ac_at_edge
1708 : : //
1709 : : //Member Type: PRIVATE
1710 : : //Description: determine the area coordinate of the facet at the edge
1711 : : //===========================================================================
1712 : 0 : void FacetEvalTool::ac_at_edge( CubitVector &fac, // facet area coordinate
1713 : : CubitVector &eac, // edge area coordinate
1714 : : int edge_id ) // id of edge
1715 : : {
1716 : 0 : double u = 0.0, v = 0.0, w = 0.0;
1717 [ # # # # ]: 0 : switch (edge_id)
1718 : : {
1719 : : case 0:
1720 : 0 : u = 0.0;
1721 : 0 : v = fac.y() / (fac.y() + fac.z());
1722 : 0 : w = 1.0 - v;
1723 : 0 : break;
1724 : : case 1:
1725 : 0 : u = fac.x() / (fac.x() + fac.z());
1726 : 0 : v = 0.0;
1727 : 0 : w = 1.0 - u;
1728 : 0 : break;
1729 : : case 2:
1730 : 0 : u = fac.x() / (fac.x() + fac.y());
1731 : 0 : v = 1.0 - u;
1732 : 0 : w = 0.0;
1733 : 0 : break;
1734 : : default:
1735 : 0 : assert(0);
1736 : : break;
1737 : : }
1738 : 0 : eac.set(u, v, w);
1739 : 0 : }
1740 : :
1741 : : //===========================================================================
1742 : : //Function Name: move_ac_inside
1743 : : //
1744 : : //Member Type: PRIVATE
1745 : : //Description: find the closest area coordinate to the boundary of the
1746 : : // patch if any of its components are < 0
1747 : : // Return if the ac was modified.
1748 : : //===========================================================================
1749 : 0 : CubitBoolean FacetEvalTool::move_ac_inside( CubitVector &ac, double tol )
1750 : : {
1751 : 0 : int nout = 0;
1752 [ # # ]: 0 : if (ac.x() < -tol) {
1753 : 0 : ac.x( 0.0 );
1754 : 0 : ac.y( ac.y() / (ac.y() + ac.z()) );
1755 : 0 : ac.z( 1.0 - ac.y() );
1756 : 0 : nout++;
1757 : : }
1758 [ # # ]: 0 : if (ac.y() < -tol) {
1759 : 0 : ac.y( 0.0 );
1760 : 0 : ac.x( ac.x() / (ac.x() + ac.z()) );
1761 : 0 : ac.z( 1.0 - ac.x() );
1762 : 0 : nout++;
1763 : : }
1764 [ # # ]: 0 : if (ac.z() < -tol) {
1765 : 0 : ac.z( 0.0 );
1766 : 0 : ac.x( ac.x() / (ac.x() + ac.y()) );
1767 : 0 : ac.y( 1.0 - ac.x() );
1768 : 0 : nout++;
1769 : : }
1770 [ # # ]: 0 : return (nout > 0) ? CUBIT_TRUE : CUBIT_FALSE;
1771 : : }
1772 : :
1773 : 473 : bool FacetEvalTool::have_data_to_calculate_bbox(void)
1774 : : {
1775 [ - + ][ # # ]: 473 : if(myPointList.size() > 0 ||
[ + - ]
1776 [ # # ]: 0 : (interpOrder == 4 &&
1777 [ # # ]: 0 : (myEdgeList.size() > 0 ||
1778 : 0 : myFacetList.size() > 0)))
1779 : : {
1780 : 473 : return true;
1781 : : }
1782 : 0 : return false;
1783 : : }
1784 : :
1785 : : //===========================================================================
1786 : : //Function Name: reset_bounding_box
1787 : : //
1788 : : //Member Type: PUBLIC
1789 : : //Description: Calculates the bounding box of the surface (also sets
1790 : : // the compareTol and grid search).
1791 : : //===========================================================================
1792 : 473 : void FacetEvalTool::reset_bounding_box()
1793 : : {
1794 [ + - ]: 473 : if(have_data_to_calculate_bbox())
1795 : : {
1796 [ + + ]: 473 : if (myBBox != NULL)
1797 : : {
1798 [ + - ]: 132 : delete myBBox;
1799 : 132 : myBBox = NULL;
1800 : : }
1801 : :
1802 : 473 : bounding_box();
1803 : :
1804 : 473 : double diag = sqrt(FacetEvalToolUtils::sqr(myBBox->x_range()) +
1805 : 473 : FacetEvalToolUtils::sqr(myBBox->y_range()) +
1806 : 473 : FacetEvalToolUtils::sqr(myBBox->z_range()));
1807 : 473 : compareTol = 1.0e-3 * diag;
1808 : :
1809 : 473 : set_up_grid_search( diag );
1810 : : }
1811 : 473 : }
1812 : :
1813 : :
1814 : : //===========================================================================
1815 : : //Function Name: bounding_box
1816 : : //
1817 : : //Member Type: PUBLIC
1818 : : //Descriptoin: Calculates the bounding box of the surface.
1819 : : //===========================================================================
1820 : 2838 : CubitBox FacetEvalTool::bounding_box()
1821 : : {
1822 [ + + ]: 2838 : if ( !myBBox )
1823 : : {
1824 : : int ii;
1825 : : CubitPoint *point_ptr;
1826 : : double x, y, z;
1827 : 605 : double x_min = CUBIT_DBL_MAX, x_max = -CUBIT_DBL_MAX;
1828 : 605 : double y_min = CUBIT_DBL_MAX, y_max = -CUBIT_DBL_MAX;
1829 : 605 : double z_min = CUBIT_DBL_MAX, z_max = -CUBIT_DBL_MAX;
1830 [ + - ][ + + ]: 3377 : for ( ii = myPointList.size(); ii > 0; ii-- )
1831 : : {
1832 [ + - ]: 2772 : point_ptr = myPointList.get_and_step();
1833 [ + - ]: 2772 : x = point_ptr->x();
1834 [ + - ]: 2772 : y = point_ptr->y();
1835 [ + - ]: 2772 : z = point_ptr->z();
1836 [ + + ]: 2772 : if ( x < x_min )
1837 : 825 : x_min = x;
1838 [ + + ]: 2772 : if ( y < y_min )
1839 : 715 : y_min = y;
1840 [ + + ]: 2772 : if ( z < z_min )
1841 : 759 : z_min = z;
1842 [ + + ]: 2772 : if ( x > x_max )
1843 : 880 : x_max = x;
1844 [ + + ]: 2772 : if ( y > y_max )
1845 : 1056 : y_max = y;
1846 [ + + ]: 2772 : if ( z > z_max )
1847 : 1067 : z_max = z;
1848 : : }
1849 [ + + ]: 605 : if (interpOrder == 4)
1850 : : {
1851 : : CubitFacetEdge *edge_ptr;
1852 [ + - ][ + + ]: 462 : CubitVector ctrl_pts[6];
1853 : : int jj;
1854 [ + - ][ + + ]: 396 : for ( ii = myEdgeList.size(); ii > 0; ii-- )
1855 : : {
1856 [ + - ]: 330 : edge_ptr = myEdgeList.get_and_step();
1857 [ + - ]: 330 : edge_ptr->control_points(ctrl_pts);
1858 [ + + ]: 1320 : for (jj=1; jj<4; jj++)
1859 : : {
1860 [ + - ]: 990 : x = ctrl_pts[jj].x();
1861 [ + - ]: 990 : y = ctrl_pts[jj].y();
1862 [ + - ]: 990 : z = ctrl_pts[jj].z();
1863 [ - + ]: 990 : if ( x < x_min )
1864 : 0 : x_min = x;
1865 [ - + ]: 990 : if ( y < y_min )
1866 : 0 : y_min = y;
1867 [ - + ]: 990 : if ( z < z_min )
1868 : 0 : z_min = z;
1869 [ - + ]: 990 : if ( x > x_max )
1870 : 0 : x_max = x;
1871 [ - + ]: 990 : if ( y > y_max )
1872 : 0 : y_max = y;
1873 [ - + ]: 990 : if ( z > z_max )
1874 : 0 : z_max = z;
1875 : : }
1876 : : }
1877 : : CubitFacet *facet_ptr;
1878 [ + - ][ + + ]: 198 : for ( ii = myFacetList.size(); ii > 0; ii-- )
1879 : : {
1880 [ + - ]: 132 : facet_ptr = myFacetList.get_and_step();
1881 [ + - ]: 132 : facet_ptr->get_control_points(ctrl_pts);
1882 [ + + ]: 924 : for (jj=0; jj<6; jj++)
1883 : : {
1884 [ + - ]: 792 : x = ctrl_pts[jj].x();
1885 [ + - ]: 792 : y = ctrl_pts[jj].y();
1886 [ + - ]: 792 : z = ctrl_pts[jj].z();
1887 [ - + ]: 792 : if ( x < x_min )
1888 : 0 : x_min = x;
1889 [ - + ]: 792 : if ( y < y_min )
1890 : 0 : y_min = y;
1891 [ - + ]: 792 : if ( z < z_min )
1892 : 0 : z_min = z;
1893 [ - + ]: 792 : if ( x > x_max )
1894 : 0 : x_max = x;
1895 [ - + ]: 792 : if ( y > y_max )
1896 : 0 : y_max = y;
1897 [ - + ]: 792 : if ( z > z_max )
1898 : 0 : z_max = z;
1899 : : }
1900 : : }
1901 : : }
1902 [ + - ]: 605 : CubitVector min_v(x_min, y_min, z_min );
1903 [ + - ]: 605 : CubitVector max_v(x_max, y_max, z_max );
1904 [ + - ][ + - ]: 605 : myBBox = new CubitBox( min_v, max_v );
1905 : : }
1906 : 2838 : return *(myBBox);
1907 : : }
1908 : :
1909 : : //===========================================================================
1910 : : //Function Name: closest_point
1911 : : //
1912 : : //Member Type: PUBLIC
1913 : : //Description: Finds the closest point from the vector (this_point) to the
1914 : : // set of facets that lies on the set of facets. If the point
1915 : : // lies outside this set, the closest point will be on the plane
1916 : : // of the closest facet. The closest_point is set to be that point.
1917 : : //===========================================================================
1918 : 2167 : CubitStatus FacetEvalTool::closest_point(CubitVector &this_point,
1919 : : CubitVector *closest_point_ptr,
1920 : : CubitVector *normal_ptr)
1921 : : {
1922 : 2167 : CubitBoolean trim = CUBIT_FALSE;
1923 : : CubitBoolean outside;
1924 : 2167 : CubitStatus rv = CUBIT_SUCCESS;
1925 : 2167 : static int count = 0; count++;
1926 : :
1927 : 2167 : int mydebug = 0;
1928 [ - + ]: 2167 : if (mydebug)
1929 : : {
1930 [ # # ]: 0 : debug_draw_vec( this_point, CUBIT_RED_INDEX );
1931 : : }
1932 : :
1933 : : rv = project_to_facets( this_point, trim, &outside,
1934 [ + - ]: 2167 : closest_point_ptr, normal_ptr );
1935 : :
1936 [ + - ][ + - ]: 2167 : if (DEBUG_FLAG(49))
[ - + ]
1937 : : {
1938 [ # # ]: 0 : if (closest_point_ptr)
1939 : : {
1940 [ # # ]: 0 : double dist = closest_point_ptr->distance_between( this_point );
1941 [ # # ]: 0 : if (dist > 1.0)
1942 : : {
1943 [ # # ][ # # ]: 0 : PRINT_ERROR("Appears to be bad projection in FacetEvalTool::project_to_facets\n");
[ # # ][ # # ]
1944 : : }
1945 : : }
1946 : : }
1947 : :
1948 [ - + ][ # # ]: 2167 : if (mydebug && closest_point_ptr)
1949 : : {
1950 [ # # ]: 0 : debug_draw_vec( *closest_point_ptr, CUBIT_GREEN_INDEX );
1951 : : }
1952 : 2167 : return rv;
1953 : : }
1954 : :
1955 : :
1956 : 0 : CubitFacet* FacetEvalTool::closest_facet( const CubitVector& point )
1957 : : {
1958 [ # # ]: 0 : CubitVector non_const(point);
1959 : : CubitBoolean junk;
1960 [ # # ]: 0 : CubitStatus result = project_to_facets( non_const, true, &junk, 0, 0 );
1961 [ # # ]: 0 : return result ? lastFacet : 0;
1962 : : }
1963 : :
1964 : : //===========================================================================
1965 : : //Function Name: facets_from_search_grid
1966 : : //
1967 : : //Member Type: PRIVATE
1968 : : //Description: find the closest facets to the point in the search grid
1969 : : // by starting with a default tolerance and expanding until facets are found
1970 : : //===========================================================================
1971 : 0 : void FacetEvalTool::facets_from_search_grid(
1972 : : CubitVector &this_point,
1973 : : DLIList<CubitFacet *> &facet_list,
1974 : : double &tol_used)
1975 : : {
1976 : 0 : double tol = compareTol * 10;
1977 [ # # ]: 0 : while (facet_list.size() == 0)
1978 : : {
1979 [ # # ]: 0 : CubitVector ptmin( this_point.x() - tol,
1980 [ # # ]: 0 : this_point.y() - tol,
1981 [ # # ][ # # ]: 0 : this_point.z() - tol );
1982 [ # # ]: 0 : CubitVector ptmax( this_point.x() + tol,
1983 [ # # ]: 0 : this_point.y() + tol,
1984 [ # # ][ # # ]: 0 : this_point.z() + tol );
1985 [ # # ]: 0 : CubitBox ptbox(ptmin,ptmax);
1986 [ # # ]: 0 : aTree->find(ptbox,facet_list);
1987 : :
1988 [ # # ][ # # ]: 0 : if (0 == facet_list.size())
1989 : 0 : tol *= 2.0;
1990 [ # # ]: 0 : }
1991 : :
1992 : 0 : tol_used = tol;
1993 : 0 : }
1994 : :
1995 : : //===========================================================================
1996 : : //Function Name: facets_from_search_grid
1997 : : //
1998 : : //Member Type: PRIVATE
1999 : : //Description: find the closest facets to the point in the search grid
2000 : : // for a given tolerance
2001 : : //===========================================================================
2002 : 0 : void FacetEvalTool::facets_from_search_grid(
2003 : : CubitVector &this_point,
2004 : : double compare_tol,
2005 : : DLIList<CubitFacet *> &facet_list )
2006 : : {
2007 : 0 : double tol = compare_tol;
2008 : :
2009 [ # # ]: 0 : CubitVector ptmin( this_point.x() - tol,
2010 [ # # ]: 0 : this_point.y() - tol,
2011 [ # # ][ # # ]: 0 : this_point.z() - tol );
2012 [ # # ]: 0 : CubitVector ptmax( this_point.x() + tol,
2013 [ # # ]: 0 : this_point.y() + tol,
2014 [ # # ][ # # ]: 0 : this_point.z() + tol );
2015 [ # # ]: 0 : CubitBox ptbox(ptmin,ptmax);
2016 [ # # ][ # # ]: 0 : aTree->find(ptbox,facet_list);
2017 : 0 : }
2018 : :
2019 : : //===========================================================================
2020 : : //Function Name: project_to_facets
2021 : : //
2022 : : //Member Type: PRIVATE
2023 : : //Description: Project a point to the facets. Use the interpOrder.
2024 : : // if trim is set, then trim the point to the boundary.
2025 : : // This is a non-static version. it uses the facets
2026 : : // in the evaltool
2027 : : //===========================================================================
2028 : : CubitStatus
2029 : 2178 : FacetEvalTool::project_to_facets(CubitVector &this_point,
2030 : : CubitBoolean trim,
2031 : : CubitBoolean *outside,
2032 : : CubitVector *closest_point_ptr,
2033 : : CubitVector *normal_ptr)
2034 : : {
2035 [ + - ]: 2178 : CpuTimer function_time;
2036 [ + - ][ + - ]: 2178 : if (DEBUG_FLAG(110))
[ - + ]
2037 : : {
2038 [ # # ]: 0 : function_time.cpu_secs();
2039 : 0 : numEvals++;
2040 : : }
2041 : :
2042 : 2178 : CubitStatus rv = CUBIT_SUCCESS;
2043 : :
2044 : : // if there are a lot of facets on this surface - use the grid search first
2045 : : // to narrow the selection
2046 : :
2047 [ - + ]: 2178 : if (aTree != NULL)
2048 : : {
2049 [ # # ]: 0 : DLIList<CubitFacet *> facet_list;
2050 : 0 : double search_tol = DBL_MAX;
2051 [ # # ]: 0 : facets_from_search_grid( this_point, facet_list, search_tol );
2052 [ # # ][ # # ]: 0 : if ( DEBUG_FLAG(110) )
[ # # ]
2053 [ # # ]: 0 : timeGridSearch += function_time.cpu_secs();
2054 : :
2055 [ # # ][ # # ]: 0 : if (facet_list.size())
2056 : : {
2057 [ # # ]: 0 : CubitVector grid_close_pt;
2058 : : rv = project_to_facets(facet_list,lastFacet,interpOrder,compareTol,
2059 : : this_point,trim,outside, &grid_close_pt,
2060 [ # # ]: 0 : normal_ptr);
2061 : :
2062 [ # # ]: 0 : if (CUBIT_SUCCESS == rv)
2063 : : {
2064 [ # # ]: 0 : if (closest_point_ptr)
2065 : : {
2066 [ # # ]: 0 : *closest_point_ptr = grid_close_pt;
2067 : : }
2068 : :
2069 : : // when we do the projection, if we end up with the closest point being farther
2070 : : // away than the grid search tolerance, we may have missed a closer facet
2071 : : // so redo the grid search using the distance as a tolerance
2072 [ # # ]: 0 : double distance = grid_close_pt.distance_between( this_point );
2073 [ # # ]: 0 : if (distance > search_tol)
2074 : : {
2075 [ # # ]: 0 : DLIList<CubitFacet*> facets_within_distance;
2076 [ # # ]: 0 : CubitVector grid_close_pt2;
2077 [ # # ]: 0 : facets_from_search_grid(this_point, distance, facets_within_distance);
2078 [ # # ][ # # ]: 0 : if (facets_within_distance.size() &&
[ # # ][ # # ]
2079 [ # # ]: 0 : (facets_within_distance != facet_list) )
2080 : : {
2081 : : rv = project_to_facets(facets_within_distance, lastFacet, interpOrder, compareTol,
2082 : : this_point, trim, outside, &grid_close_pt2,
2083 [ # # ]: 0 : normal_ptr);
2084 [ # # ]: 0 : if (CUBIT_SUCCESS == rv)
2085 : : {
2086 [ # # ]: 0 : double distance2 = grid_close_pt2.distance_between( this_point );
2087 [ # # ]: 0 : if (distance2 < distance)
2088 : : {
2089 [ # # ]: 0 : if (closest_point_ptr)
2090 : : {
2091 [ # # ]: 0 : *closest_point_ptr = grid_close_pt2;
2092 : : }
2093 : : }
2094 : : }
2095 [ # # ]: 0 : }
2096 : : }
2097 : : }
2098 : :
2099 [ # # ][ # # ]: 0 : if ( DEBUG_FLAG(110) )
[ # # ]
2100 : : {
2101 [ # # ]: 0 : timeFacetProject += function_time.cpu_secs();
2102 [ # # ]: 0 : if (closest_point_ptr)
2103 : : {
2104 [ # # ]: 0 : double dist = closest_point_ptr->distance_between( this_point );
2105 [ # # ]: 0 : if (dist > compareTol * 100)
2106 : : {
2107 [ # # ][ # # ]: 0 : PRINT_ERROR("Appears to be bad projection in FacetEvalTool::project_to_facets\n");
[ # # ][ # # ]
2108 [ # # ]: 0 : dcolor(CUBIT_GREEN_INDEX);
2109 [ # # ]: 0 : dpoint(this_point);
2110 [ # # ]: 0 : dcolor(CUBIT_RED_INDEX);
2111 [ # # ]: 0 : dpoint(*closest_point_ptr);
2112 [ # # ]: 0 : dcolor(CUBIT_YELLOW_INDEX);
2113 [ # # ]: 0 : dfldraw(facet_list);
2114 [ # # ]: 0 : dview();
2115 : 0 : rv = CUBIT_FAILURE;
2116 : : }
2117 : : }
2118 : : }
2119 [ # # ]: 0 : }
2120 : : }
2121 : :
2122 : : // otherwise just use the complete list of facets
2123 : :
2124 : : else
2125 : : {
2126 : : rv = project_to_facets(myFacetList,lastFacet,interpOrder,compareTol,
2127 : : this_point,trim,outside,closest_point_ptr,
2128 [ + - ]: 2178 : normal_ptr);
2129 [ + - ][ + - ]: 2178 : if ( DEBUG_FLAG(110) )
[ - + ]
2130 [ # # ]: 0 : timeFacetProject += function_time.cpu_secs();
2131 : : }
2132 : :
2133 : 2178 : return rv;
2134 : : }
2135 : :
2136 : : //===========================================================================
2137 : : //Function Name: project_to_facets
2138 : : //
2139 : : //Member Type: PRIVATE
2140 : : //Description: Project a point to the facets. Use the interpOrder.
2141 : : // if trim is set, then trim the point to the boundary.
2142 : : // This is a static version of the above. Any list of facets
2143 : : // can be passed to this function
2144 : : //===========================================================================
2145 : : CubitStatus
2146 : 2178 : FacetEvalTool::project_to_facets(
2147 : : DLIList <CubitFacet *> &facet_list, // (IN) facets that we can project to
2148 : : CubitFacet *&last_facet, // (IN/OUT) last facet projected to -
2149 : : // it will try this one first
2150 : : int interp_order, // (IN) 0 = linear facets,
2151 : : // 4 = b-spline patches
2152 : : double compare_tol, // (IN) tolerance for projection -
2153 : : // should be about 1e-3*edge
2154 : : const CubitVector &this_point, // (IN) point we are projecting
2155 : : CubitBoolean trim, // (IN) trim to facet (always trimmed
2156 : : // if b-spline patch)
2157 : : CubitBoolean *outside, // (OUT) TRUE if projected outside
2158 : : // the facet
2159 : : CubitVector *closest_point_ptr, // (OUT) resulting projection point
2160 : : // (NULL if only want normal)
2161 : : CubitVector *normal_ptr) // (OUT) resulting normal at projected
2162 : : // point (NULL if not required)
2163 : : {
2164 : 2178 : int ncheck, ii, nincr=0;
2165 : : static int calls=0;
2166 : : static int nncheck=0;
2167 : : static int ntol=0;
2168 : : static int mydebug=0;
2169 : : CubitBoolean outside_facet, best_outside_facet;
2170 [ + - ][ + - ]: 2178 : CubitVector close_point, best_point, best_areacoord;
[ + - ]
2171 : 2178 : CubitFacet *best_facet = NULL;
2172 : : CubitFacet *facet;
2173 [ + - ][ - + ]: 2178 : assert (facet_list.size() > 0);
2174 : 2178 : double big_dist = compare_tol * 1.0e3;
2175 : :
2176 : : // set the first facet to be checked as the last one located
2177 : :
2178 [ + + ]: 2178 : if (last_facet) {
2179 [ + - ][ - + ]: 1958 : if (!facet_list.move_to(last_facet)) {
2180 [ # # ]: 0 : facet_list.reset();
2181 : : }
2182 : : }
2183 : : else {
2184 [ + - ]: 220 : facet_list.reset();
2185 : : }
2186 : :
2187 : : // so we don't evaluate a facet more than once - mark the facets
2188 : : // as we evaluate them. Put the evaluated facets on a used_facet_list
2189 : : // so we clear the marks off when we are done. Note: this assumes
2190 : : // theat marks are initially cleared.
2191 : :
2192 [ + - ]: 2178 : DLIList<CubitFacet *>used_facet_list;
2193 [ + - ][ + + ]: 10890 : for(ii=0; ii<facet_list.size(); ii++)
2194 [ + - ][ + - ]: 8712 : facet_list.get_and_step()->marked(0);
2195 : :
2196 [ + - ]: 2178 : int nfacets = facet_list.size();
2197 : 2178 : int nevald = 0;
2198 : 2178 : double tol = compare_tol * 10;
2199 : 2178 : const double atol = 0.001;
2200 : 2178 : double mindist = CUBIT_DBL_MAX;
2201 : 2178 : CubitBoolean eval_all = CUBIT_FALSE;
2202 : 2178 : CubitBoolean done = CUBIT_FALSE;
2203 : 2178 : best_outside_facet = CUBIT_TRUE;
2204 : :
2205 [ + + ]: 7062 : while(!done) {
2206 : :
2207 : : // define a bounding box around the point
2208 : :
2209 [ + - ]: 4884 : double ptmin_x = this_point.x() - tol;
2210 [ + - ]: 4884 : double ptmin_y = this_point.y() - tol;
2211 [ + - ]: 4884 : double ptmin_z = this_point.z() - tol;
2212 [ + - ]: 4884 : double ptmax_x = this_point.x() + tol;
2213 [ + - ]: 4884 : double ptmax_y = this_point.y() + tol;
2214 [ + - ]: 4884 : double ptmax_z = this_point.z() + tol;
2215 : :
2216 : 4884 : bool debug = false;
2217 : :
2218 [ - + ]: 4884 : if( debug )
2219 : : {
2220 [ # # ]: 0 : GfxDebug::clear();
2221 [ # # ][ # # ]: 0 : for( int i=used_facet_list.size(); i--; )
2222 [ # # ][ # # ]: 0 : used_facet_list.get_and_step()->debug_draw(CUBIT_GREEN_INDEX, 0 );
2223 : : }
2224 : :
2225 : 4884 : ncheck = 0;
2226 [ + - ][ + + ]: 19833 : for ( ii = facet_list.size(); ii > 0 && !done; ii-- )
[ + + ]
2227 : : {
2228 [ + - ]: 14949 : facet = facet_list.get_and_step();
2229 [ + - ][ + + ]: 14949 : if (facet->marked())
2230 : 11121 : continue;
2231 : :
2232 : : // Try to trivially reject this facet with a bounding box test
2233 : : // (Does the bounding box of the facet intersect with the
2234 : : // bounding box of the point)
2235 : :
2236 [ - + ]: 14553 : if( debug )
2237 : : {
2238 [ # # ]: 0 : facet->debug_draw( CUBIT_RED_INDEX );
2239 [ # # ]: 0 : GfxDebug::flush();
2240 [ # # ]: 0 : GfxDebug::mouse_xforms();
2241 : : }
2242 : :
2243 : :
2244 [ + - ]: 14553 : if (!eval_all)
2245 : : {
2246 [ + - ]: 14553 : const CubitBox &bbox = facet->bounding_box();
2247 [ + - ][ + + ]: 23111 : if (ptmax_x < bbox.min_x() ||
[ + + ][ + + ]
2248 [ + - ]: 8558 : ptmin_x > bbox.max_x()) {
2249 : 7227 : continue;
2250 : : }
2251 [ + - ][ + + ]: 12826 : if (ptmax_y < bbox.min_y() ||
[ + + ][ + + ]
2252 [ + - ]: 5500 : ptmin_y > bbox.max_y()) {
2253 : 2607 : continue;
2254 : : }
2255 [ + - ][ + + ]: 8822 : if (ptmax_z < bbox.min_z() ||
[ + + ][ + + ]
2256 [ + - ]: 4103 : ptmin_z > bbox.max_z()) {
2257 : 4719 : continue;
2258 : : }
2259 : : }
2260 : :
2261 : : // skip zero area facets
2262 [ + - ][ - + ]: 3828 : if(facet->area() <= 0.0)
2263 : : {
2264 [ # # ]: 0 : facet->marked(1);
2265 : 0 : nfacets--;
2266 : 0 : continue;
2267 : : }
2268 : :
2269 : : // Only facets that pass the bounding box test will get past here!
2270 : :
2271 : : // Project point to plane of the facet and determine its area coordinates
2272 : :
2273 : 3828 : ncheck++; nevald++;
2274 [ + - ]: 3828 : CubitVector pt_on_plane;
2275 : : double dist_to_plane;
2276 [ + - ]: 3828 : project_to_facet_plane( facet, this_point, pt_on_plane, dist_to_plane );
2277 : :
2278 [ + - ]: 3828 : CubitVector areacoord;
2279 [ + - ]: 3828 : facet_area_coordinate( facet, pt_on_plane, areacoord );
2280 [ - + ]: 3828 : if (interp_order != 0)
2281 : : {
2282 : :
2283 : : // modify the areacoord - project to the bezier patch- snaps to the
2284 : : // edge of the patch if necessary
2285 : :
2286 [ # # ]: 0 : if (project_to_facet( facet, this_point, areacoord,
2287 [ # # ]: 0 : close_point, outside_facet, compare_tol ) != CUBIT_SUCCESS)
2288 : : {
2289 : 0 : return CUBIT_FAILURE;
2290 : : }
2291 : : }
2292 : : else
2293 : : {
2294 : :
2295 : : // If sign of areacoords are all positive then its inside the triangle
2296 : : // and we are done - go interpolate the point. (use an absolute
2297 : : // tolerance since the coordinates arenormalized)
2298 [ + - ][ + + ]: 10516 : if (areacoord.x() > -atol &&
[ + + ]
2299 [ + + ][ + - ]: 6688 : areacoord.y() > -atol &&
[ + + ]
2300 [ + - ]: 2211 : areacoord.z() > -atol) {
2301 [ + + ][ + + ]: 2079 : if (dist_to_plane < compare_tol && !trim)
2302 : : {
2303 [ + - ]: 1738 : close_point = this_point;
2304 : : }
2305 : : else
2306 : : {
2307 [ + - ]: 341 : close_point = pt_on_plane;
2308 : : }
2309 : 2079 : outside_facet = CUBIT_FALSE;
2310 : : }
2311 : :
2312 : : // otherwise find the closest vertex or edge to the projected point
2313 : :
2314 [ + - ][ + + ]: 1749 : else if (areacoord.x() < atol)
2315 : : {
2316 : 968 : outside_facet = CUBIT_TRUE;
2317 [ + - ][ + + ]: 968 : if (areacoord.y() < atol)
2318 : : {
2319 [ + - ][ - + ]: 429 : if (eval_point( facet, 2, close_point ) != CUBIT_SUCCESS)
2320 : : {
2321 : 0 : return CUBIT_FAILURE;
2322 : : }
2323 : : }
2324 [ + - ][ + + ]: 539 : else if(areacoord.z() < atol)
2325 : : {
2326 [ + - ][ - + ]: 44 : if (eval_point( facet, 1, close_point ) != CUBIT_SUCCESS)
2327 : : {
2328 : 0 : return CUBIT_FAILURE;
2329 : : }
2330 : : }
2331 : : else
2332 : : {
2333 [ - + ]: 495 : if(project_to_facetedge( facet, 1, 2, this_point, pt_on_plane,
2334 [ + - ]: 495 : close_point, outside_facet, trim ) !=CUBIT_SUCCESS)
2335 : : {
2336 : 0 : return CUBIT_FAILURE;
2337 : : }
2338 : : }
2339 : : }
2340 [ + - ][ + + ]: 781 : else if (areacoord.y() < atol)
2341 : : {
2342 : 649 : outside_facet = CUBIT_TRUE;
2343 [ + - ][ + + ]: 649 : if (areacoord.z() < atol)
2344 : : {
2345 [ + - ][ - + ]: 44 : if (eval_point( facet, 0, close_point )!= CUBIT_SUCCESS)
2346 : : {
2347 : 0 : return CUBIT_FAILURE;
2348 : : }
2349 : : }
2350 : : else
2351 : : {
2352 [ - + ]: 605 : if(project_to_facetedge( facet, 2, 0, this_point, pt_on_plane,
2353 [ + - ]: 605 : close_point, outside_facet, trim ) !=CUBIT_SUCCESS)
2354 : : {
2355 : 0 : return CUBIT_FAILURE;
2356 : : }
2357 : : }
2358 : : }
2359 : : else
2360 : : {
2361 : 132 : outside_facet = CUBIT_TRUE;
2362 [ - + ]: 132 : if(project_to_facetedge( facet, 0, 1, this_point, pt_on_plane,
2363 [ + - ]: 132 : close_point, outside_facet, trim ) !=CUBIT_SUCCESS)
2364 : : {
2365 : 0 : return CUBIT_FAILURE;
2366 : : }
2367 : : }
2368 : : }
2369 : :
2370 : : // keep track of the minimum distance
2371 [ + - ]: 3828 : double dist = close_point.distance_between( this_point );
2372 : :
2373 [ + + ]: 3828 : if( trim )
2374 : : {
2375 [ + + ]: 44 : if( dist < mindist )
2376 : : {
2377 : 11 : mindist = dist;
2378 [ + - ]: 11 : best_point = close_point;
2379 : 11 : best_facet = facet;
2380 [ + - ]: 11 : best_areacoord = areacoord;
2381 : 11 : best_outside_facet = outside_facet;
2382 : : }
2383 : : }
2384 [ + + ][ + + ]: 3784 : else if ( (best_outside_facet == outside_facet && dist < mindist) ||
[ + + ]
2385 [ + + ][ - + ]: 2706 : (best_outside_facet && !outside_facet && (dist < big_dist || !best_facet)) )
[ # # ]
2386 : : {
2387 : 2662 : mindist = dist;
2388 [ + - ]: 2662 : best_point = close_point;
2389 : 2662 : best_facet = facet;
2390 [ + - ]: 2662 : best_areacoord = areacoord;
2391 : 2662 : best_outside_facet = outside_facet;
2392 : :
2393 [ + + ][ + - ]: 2662 : if (dist < compare_tol && !trim) {
2394 : 1738 : done = CUBIT_TRUE;
2395 : : }
2396 : 2662 : big_dist = 10.0 * mindist;
2397 : : }
2398 [ + - ]: 3828 : facet->marked(1);
2399 [ + - ]: 3828 : used_facet_list.append(facet);
2400 : : }
2401 : :
2402 : : // We are done if we found at least one triangle. Otherwise
2403 : : // increase the tolerance and try again
2404 : :
2405 [ + + ]: 4884 : if (!done)
2406 : : {
2407 [ + + ]: 3146 : if (nevald == nfacets)
2408 : : {
2409 : 440 : done = CUBIT_TRUE;
2410 : : }
2411 : : else
2412 : : {
2413 : 2706 : nincr++;
2414 [ + + ]: 2706 : if (ncheck > 0) {
2415 [ + - ]: 132 : if (best_outside_facet) {
2416 [ + - ]: 132 : if (nincr < 10)
2417 : : {
2418 : 132 : tol *= 2.0;
2419 : 132 : ntol++;
2420 : : }
2421 : : else
2422 : : // getting here means that the compare_tol probably is too small
2423 : : // just try all the remaining facets
2424 : : {
2425 : 132 : eval_all = CUBIT_TRUE;
2426 : : }
2427 : : }
2428 : : else
2429 : : {
2430 : 132 : done = CUBIT_TRUE;
2431 : : }
2432 : : }
2433 : : else {
2434 [ - + ]: 2574 : if (nincr >= 10)
2435 : : {
2436 : 0 : eval_all = CUBIT_TRUE;
2437 : : }
2438 : : else
2439 : : {
2440 : 2574 : tol *= 2.0e0;
2441 : 3146 : ntol++;
2442 : : }
2443 : : }
2444 : : }
2445 : : }
2446 : : } // while(!done)
2447 [ - + ]: 2178 : if(best_facet == NULL){
2448 [ # # ][ # # ]: 0 : PRINT_ERROR("Unable to determine facet correctly.\n");
[ # # ][ # # ]
2449 : 0 : return CUBIT_FAILURE;
2450 : : }
2451 : : // make sure we actually got something
2452 [ - + ]: 2178 : assert(best_facet != NULL);
2453 : :
2454 : : // if the closest point is outside of a facet, then evaluate the point
2455 : : // on the facet using its area coordinates (otherwise it would be
2456 : : // trimmed to an edge or point)
2457 : :
2458 : :
2459 [ + + ][ + + ]: 2178 : if ( !trim && best_outside_facet && interp_order != 4) {
[ + - ]
2460 [ - + ]: 132 : if (project_to_facet( best_facet, this_point, best_areacoord,
2461 [ + - ]: 132 : best_point, best_outside_facet, compare_tol )
2462 : : != CUBIT_SUCCESS) {
2463 : 0 : return CUBIT_FAILURE;
2464 : : }
2465 : :
2466 : : // see if its really outside (it could just be on an edge where the
2467 : : // curvature is convex)
2468 : :
2469 [ + - ]: 132 : best_outside_facet = is_outside( best_facet, best_areacoord );
2470 : : }
2471 : :
2472 : : // evaluate the normal if required
2473 : :
2474 [ + + ]: 2178 : if (normal_ptr) {
2475 [ + - ]: 924 : CubitVector normal;
2476 [ + - ][ - + ]: 924 : if (eval_facet_normal( best_facet, best_areacoord, normal )
2477 : : != CUBIT_SUCCESS) {
2478 : 0 : return CUBIT_FAILURE;
2479 : : }
2480 [ + - ]: 924 : *normal_ptr = normal;
2481 : : }
2482 : :
2483 [ + + ]: 2178 : if (closest_point_ptr) {
2484 [ + - ]: 1276 : *closest_point_ptr = best_point;
2485 : : }
2486 : :
2487 : 2178 : *outside = best_outside_facet;
2488 : 2178 : last_facet = best_facet;
2489 : :
2490 : :
2491 : : // clear the marks from the used facets
2492 : :
2493 [ + - ][ + + ]: 6006 : for (ii=0; ii<used_facet_list.size(); ii++)
2494 : : {
2495 [ + - ]: 3828 : facet = used_facet_list.get_and_step();
2496 [ + - ]: 3828 : facet->marked( 0 );
2497 : : }
2498 : :
2499 [ - + ]: 2178 : if (mydebug) {
2500 : 0 : nncheck+= ncheck;
2501 : 0 : calls++;
2502 [ # # ]: 0 : if (calls%100==0){
2503 [ # # ][ # # ]: 0 : PRINT_INFO("calls = %d, ckecks = %d, ntol = %d\n",calls,nncheck,ntol);
[ # # ][ # # ]
2504 : : }
2505 : : }
2506 : :
2507 [ + - ]: 2178 : return CUBIT_SUCCESS;
2508 : : }
2509 : :
2510 : :
2511 : : //===========================================================================
2512 : : //Function Name: eval_facet
2513 : : //
2514 : : //Member Type: PUBLIC
2515 : : //Descriptoin: Evaluate the location and normal of a set of area coordinates
2516 : : // on a facet. Use the interpOrder to evaluate.
2517 : : // Static function
2518 : : //===========================================================================
2519 : 0 : CubitStatus FacetEvalTool::eval_facet( CubitFacet *facet,
2520 : : CubitVector &areacoord,
2521 : : CubitVector *eval_point,
2522 : : CubitVector *eval_normal )
2523 : : {
2524 : 0 : CubitStatus rv = CUBIT_SUCCESS;
2525 : 0 : int mydebug = 0;
2526 [ # # ]: 0 : if (mydebug)
2527 : : {
2528 [ # # ]: 0 : dcolor( CUBIT_RED_INDEX );
2529 [ # # ]: 0 : dfdraw( facet );
2530 [ # # ]: 0 : dview();
2531 [ # # ]: 0 : dcolor( CUBIT_YELLOW_INDEX );
2532 : : }
2533 : :
2534 [ # # ]: 0 : CubitPoint *pt0 = facet->point(0);
2535 [ # # ]: 0 : CubitPoint *pt1 = facet->point(1);
2536 [ # # ]: 0 : CubitPoint *pt2 = facet->point(2);
2537 [ # # ]: 0 : CubitVector close_point;
2538 : :
2539 [ # # ]: 0 : CubitVector this_point;
2540 [ # # ][ # # ]: 0 : this_point.x( areacoord.x() * pt0->x() +
2541 [ # # ][ # # ]: 0 : areacoord.y() * pt1->x() +
2542 [ # # ][ # # ]: 0 : areacoord.z() * pt2->x() );
[ # # ]
2543 [ # # ][ # # ]: 0 : this_point.y( areacoord.x() * pt0->y() +
2544 [ # # ][ # # ]: 0 : areacoord.y() * pt1->y() +
2545 [ # # ][ # # ]: 0 : areacoord.z() * pt2->y() );
[ # # ]
2546 [ # # ][ # # ]: 0 : this_point.z( areacoord.x() * pt0->z() +
2547 [ # # ][ # # ]: 0 : areacoord.y() * pt1->z() +
2548 [ # # ][ # # ]: 0 : areacoord.z() * pt2->z() );
[ # # ]
2549 : :
2550 [ # # ]: 0 : int eval_order = facet->eval_order();
2551 [ # # ]: 0 : if (eval_order != 0)
2552 : : {
2553 [ # # ][ # # ]: 0 : if (facet->is_flat())
2554 : 0 : eval_order = 0;
2555 : : }
2556 : :
2557 [ # # # ]: 0 : switch(eval_order) {
2558 : : case 0:
2559 [ # # ]: 0 : if (eval_point)
2560 [ # # ]: 0 : *eval_point = this_point;
2561 [ # # ]: 0 : if (eval_normal)
2562 [ # # ]: 0 : eval_facet_normal(facet, areacoord, *eval_normal);
2563 : 0 : break;
2564 : :
2565 : : case 4:
2566 : : eval_bezier_patch( facet,
2567 : : areacoord,
2568 [ # # ]: 0 : close_point );
2569 : : //project_to_patch(facet, areacoord, this_point, close_point,
2570 : : // eval_normal, outside );
2571 : :
2572 : : //for now over-ride the normal from project_to_patch -- it is bogus
2573 [ # # ]: 0 : if (eval_normal)
2574 [ # # ]: 0 : eval_facet_normal(facet, areacoord, *eval_normal);
2575 [ # # ]: 0 : if (eval_point)
2576 [ # # ]: 0 : *eval_point = close_point;
2577 : :
2578 : 0 : break;
2579 : : default:
2580 : : // the interpolation order for now is limited to 0 and 4
2581 : : // something other than that is being attempted (or eval_order is not
2582 : : // returning the correct value)
2583 : 0 : assert(0);
2584 : : break;
2585 : : }
2586 : :
2587 : 0 : return rv;
2588 : : }
2589 : :
2590 : : //===========================================================================
2591 : : //Function Name: eval_facet
2592 : : //
2593 : : //Member Type: PUBLIC
2594 : : //Descriptoin: Evaluate the location of a set of area coordinates
2595 : : // on a facet. Use the interpOrder to evaluate.
2596 : : //===========================================================================
2597 : 0 : CubitStatus FacetEvalTool::eval_facet( CubitFacet *facet,
2598 : : CubitVector &pt,
2599 : : CubitVector &areacoord,
2600 : : CubitVector &close_point,
2601 : : CubitBoolean &outside_facet )
2602 : : {
2603 : :
2604 : 0 : CubitPoint *pt0 = facet->point(0);
2605 : 0 : CubitPoint *pt1 = facet->point(1);
2606 : 0 : CubitPoint *pt2 = facet->point(2);
2607 : :
2608 : 0 : int interp_order = facet->eval_order();
2609 [ # # ][ # # ]: 0 : if (interp_order != 0 && facet->is_flat())
[ # # ]
2610 : : {
2611 : 0 : interp_order = 0;
2612 : : }
2613 : :
2614 [ # # # # : 0 : switch(interp_order) {
# # ]
2615 : : case 0:
2616 : 0 : close_point.x( areacoord.x() * pt0->x() +
2617 : 0 : areacoord.y() * pt1->x() +
2618 : 0 : areacoord.z() * pt2->x() );
2619 : 0 : close_point.y( areacoord.x() * pt0->y() +
2620 : 0 : areacoord.y() * pt1->y() +
2621 : 0 : areacoord.z() * pt2->y() );
2622 : 0 : close_point.z( areacoord.x() * pt0->z() +
2623 : 0 : areacoord.y() * pt1->z() +
2624 : 0 : areacoord.z() * pt2->z() );
2625 : 0 : outside_facet = CUBIT_FALSE;
2626 : 0 : break;
2627 : : case 1:
2628 : : {
2629 [ # # ]: 0 : CubitVector tp0 = pt0->project_to_tangent_plane( pt );
2630 [ # # ]: 0 : CubitVector tp1 = pt1->project_to_tangent_plane( pt );
2631 [ # # ]: 0 : CubitVector tp2 = pt2->project_to_tangent_plane( pt );
2632 [ # # ][ # # ]: 0 : close_point.x( areacoord.x() * tp0.x() +
2633 [ # # ][ # # ]: 0 : areacoord.y() * tp1.x() +
2634 [ # # ][ # # ]: 0 : areacoord.z() * tp2.x() );
[ # # ]
2635 [ # # ][ # # ]: 0 : close_point.y( areacoord.x() * tp0.y() +
2636 [ # # ][ # # ]: 0 : areacoord.y() * tp1.y() +
2637 [ # # ][ # # ]: 0 : areacoord.z() * tp2.y() );
[ # # ]
2638 [ # # ][ # # ]: 0 : close_point.z( areacoord.x() * tp0.z() +
2639 [ # # ][ # # ]: 0 : areacoord.y() * tp1.z() +
2640 [ # # ][ # # ]: 0 : areacoord.z() * tp2.z() );
[ # # ]
2641 : 0 : outside_facet = CUBIT_FALSE;
2642 : : }
2643 : 0 : break;
2644 : : case 2:
2645 : : {
2646 [ # # ][ # # ]: 0 : CubitVector qp0, qp1, qp2, qn0, qn1, qn2;
[ # # ][ # # ]
[ # # ][ # # ]
2647 [ # # ]: 0 : eval_quadratic( facet, 0, pt, qp0, qn0 );
2648 [ # # ]: 0 : eval_quadratic( facet, 1, pt, qp1, qn1 );
2649 [ # # ]: 0 : eval_quadratic( facet, 2, pt, qp2, qn2 );
2650 : :
2651 [ # # ][ # # ]: 0 : close_point.x( areacoord.x() * qp0.x() +
2652 [ # # ][ # # ]: 0 : areacoord.y() * qp1.x() +
2653 [ # # ][ # # ]: 0 : areacoord.z() * qp2.x() );
[ # # ]
2654 [ # # ][ # # ]: 0 : close_point.y( areacoord.x() * qp0.y() +
2655 [ # # ][ # # ]: 0 : areacoord.y() * qp1.y() +
2656 [ # # ][ # # ]: 0 : areacoord.z() * qp2.y() );
[ # # ]
2657 [ # # ][ # # ]: 0 : close_point.z( areacoord.x() * qp0.z() +
2658 [ # # ][ # # ]: 0 : areacoord.y() * qp1.z() +
2659 [ # # ][ # # ]: 0 : areacoord.z() * qp2.z() );
[ # # ]
2660 : 0 : outside_facet = CUBIT_FALSE;
2661 : : }
2662 : 0 : break;
2663 : : case 3:
2664 : : {
2665 [ # # ][ # # ]: 0 : CubitVector qp0, qp1, qp2;
[ # # ]
2666 [ # # ]: 0 : eval_quadric( facet, 0, pt, qp0 );
2667 [ # # ]: 0 : eval_quadric( facet, 1, pt, qp1 );
2668 [ # # ]: 0 : eval_quadric( facet, 2, pt, qp2 );
2669 : :
2670 [ # # ][ # # ]: 0 : close_point.x( areacoord.x() * qp0.x() +
2671 [ # # ][ # # ]: 0 : areacoord.y() * qp1.x() +
2672 [ # # ][ # # ]: 0 : areacoord.z() * qp2.x() );
[ # # ]
2673 [ # # ][ # # ]: 0 : close_point.y( areacoord.x() * qp0.y() +
2674 [ # # ][ # # ]: 0 : areacoord.y() * qp1.y() +
2675 [ # # ][ # # ]: 0 : areacoord.z() * qp2.y() );
[ # # ]
2676 [ # # ][ # # ]: 0 : close_point.z( areacoord.x() * qp0.z() +
2677 [ # # ][ # # ]: 0 : areacoord.y() * qp1.z() +
2678 [ # # ][ # # ]: 0 : areacoord.z() * qp2.z() );
[ # # ]
2679 : 0 : outside_facet = CUBIT_FALSE;
2680 : : }
2681 : 0 : break;
2682 : : case 4:
2683 : : {
2684 : : //CubitStatus stat = eval_bezier_patch( facet, areacoord, pt );
2685 : : //close_point = pt;
2686 : : //outside_facet = CUBIT_FALSE;
2687 : 0 : double compare_tol = /*sqrt(facet->area()) **/ 1.0e-3;
2688 : 0 : int edge_id = -1;
2689 : : project_to_patch(facet, areacoord, pt, close_point, NULL,
2690 : 0 : outside_facet, compare_tol, edge_id );
2691 : : }
2692 : 0 : break;
2693 : : }
2694 : :
2695 : 0 : return CUBIT_SUCCESS;
2696 : : }
2697 : :
2698 : : //===========================================================================
2699 : : //Function Name: project_to_facet
2700 : : //
2701 : : //Member Type: PUBLIC
2702 : : //Description: project to a single facet. Uses the input areacoord as
2703 : : // a starting guess.
2704 : : //===========================================================================
2705 : 132 : CubitStatus FacetEvalTool::project_to_facet( CubitFacet *facet,
2706 : : const CubitVector &pt,
2707 : : CubitVector &areacoord,
2708 : : CubitVector &close_point,
2709 : : CubitBoolean &outside_facet,
2710 : : double compare_tol)
2711 : : {
2712 : :
2713 : 132 : CubitStatus stat = CUBIT_SUCCESS;
2714 : 132 : CubitPoint *pt0 = facet->point(0);
2715 : 132 : CubitPoint *pt1 = facet->point(1);
2716 : 132 : CubitPoint *pt2 = facet->point(2);
2717 : :
2718 : 132 : int interp_order = facet->eval_order();
2719 [ - + ]: 132 : if (facet->is_flat())
2720 : : {
2721 : 0 : interp_order = 0;
2722 : : }
2723 : :
2724 [ + - - - ]: 132 : switch(interp_order) {
2725 : : case 0:
2726 : 132 : close_point.x( areacoord.x() * pt0->x() +
2727 : 132 : areacoord.y() * pt1->x() +
2728 : 132 : areacoord.z() * pt2->x() );
2729 : 132 : close_point.y( areacoord.x() * pt0->y() +
2730 : 132 : areacoord.y() * pt1->y() +
2731 : 132 : areacoord.z() * pt2->y() );
2732 : 132 : close_point.z( areacoord.x() * pt0->z() +
2733 : 132 : areacoord.y() * pt1->z() +
2734 : 132 : areacoord.z() * pt2->z() );
2735 : 132 : outside_facet = CUBIT_FALSE;
2736 : 132 : break;
2737 : : case 1:
2738 : : case 2:
2739 : : case 3:
2740 : 0 : assert(0); // not available from this function
2741 : : break;
2742 : : case 4:
2743 : : {
2744 : 0 : int edge_id = -1;
2745 : : stat = project_to_patch(facet, areacoord, pt, close_point, NULL,
2746 : 0 : outside_facet, compare_tol, edge_id );
2747 : : }
2748 : 0 : break;
2749 : : }
2750 : :
2751 : 132 : return stat;
2752 : : }
2753 : :
2754 : : //===========================================================================
2755 : : //Function Name: project_to_facetedge
2756 : : //
2757 : : //Member Type: PUBLIC
2758 : : //Description: Project a point to the facet edge.
2759 : : // Use the interpOrder to evaluate.
2760 : : //===========================================================================
2761 : 1232 : CubitStatus FacetEvalTool::project_to_facetedge( CubitFacet *facet,
2762 : : int vert0, int vert1,
2763 : : const CubitVector &the_point,
2764 : : CubitVector &pt_on_plane,
2765 : : CubitVector &close_point,
2766 : : CubitBoolean &outside_facet,
2767 : : CubitBoolean must_be_on_edge)
2768 : : {
2769 [ + - ]: 1232 : CubitPoint *pt0 = facet->point(vert0);
2770 [ + - ]: 1232 : CubitPoint *pt1 = facet->point(vert1);
2771 : :
2772 : : // the edge vector
2773 : :
2774 [ + - ][ + - ]: 1232 : CubitVector e0 ( pt1->x() - pt0->x(),
2775 [ + - ][ + - ]: 1232 : pt1->y() - pt0->y(),
2776 [ + - ][ + - ]: 2464 : pt1->z() - pt0->z() );
[ + - ]
2777 [ + - ]: 1232 : e0.normalize();
2778 : :
2779 : : // vector from vert0 to point
2780 : :
2781 [ + - ][ + - ]: 1232 : CubitVector v0 ( pt_on_plane.x() - pt0->x(),
2782 [ + - ][ + - ]: 1232 : pt_on_plane.y() - pt0->y(),
2783 [ + - ][ + - ]: 2464 : pt_on_plane.z() - pt0->z() );
[ + - ]
2784 : :
2785 [ + - ][ + - ]: 1232 : CubitVector v1 ( pt_on_plane.x() - pt1->x(),
2786 [ + - ][ + - ]: 1232 : pt_on_plane.y() - pt1->y(),
2787 [ + - ][ + - ]: 2464 : pt_on_plane.z() - pt1->z() );
[ + - ]
2788 : :
2789 : : // project to edge
2790 : :
2791 [ + - ]: 1232 : double projection1 = v0%e0;
2792 [ + - ][ + - ]: 1232 : double projection2 = v1%(-e0);
2793 : :
2794 [ - + ][ # # ]: 1232 : if( !must_be_on_edge || (projection1 > 0 && projection2 > 0 ))
[ # # ]
2795 : : {
2796 [ + - ][ + - ]: 1232 : close_point.x ( pt0->x() + e0.x() * projection1 );
[ + - ]
2797 [ + - ][ + - ]: 1232 : close_point.y ( pt0->y() + e0.y() * projection1 );
[ + - ]
2798 [ + - ][ + - ]: 1232 : close_point.z ( pt0->z() + e0.z() * projection1 );
[ + - ]
2799 : : }
2800 : : else //we are closer to one a facet vertex than to the edge
2801 : : {
2802 [ # # ][ # # ]: 0 : if( the_point.distance_between( pt0->coordinates() )
[ # # ]
2803 [ # # ][ # # ]: 0 : < the_point.distance_between( pt1->coordinates()))
2804 [ # # ][ # # ]: 0 : close_point = pt0->coordinates();
2805 : : else
2806 [ # # ][ # # ]: 0 : close_point = pt1->coordinates();
2807 : : }
2808 : :
2809 : : // project the point on the facet (if the order is higher than 0)
2810 : :
2811 : 1232 : outside_facet = CUBIT_TRUE;
2812 [ + - ][ - + ]: 1232 : if (facet->eval_order() > 0 && !facet->is_flat()) {
[ # # ][ # # ]
[ - + ]
2813 [ # # ]: 0 : CubitVector areacoord;
2814 [ # # ]: 0 : facet_area_coordinate( facet, close_point, areacoord );
2815 : 0 : int edge_id = -1;
2816 [ # # ][ # # ]: 0 : if ((vert0 == 0 && vert1 == 1) ||
[ # # ]
2817 [ # # ]: 0 : (vert0 == 1 && vert1 == 0))
2818 : : {
2819 : 0 : edge_id = 2;
2820 : : }
2821 [ # # ][ # # ]: 0 : else if ((vert0 == 1 && vert1 == 2) ||
[ # # ]
2822 [ # # ]: 0 : (vert0 == 2 && vert1 == 1))
2823 : : {
2824 : 0 : edge_id = 0;
2825 : : }
2826 [ # # ][ # # ]: 0 : else if ((vert0 == 2 && vert1 == 0) ||
[ # # ]
2827 [ # # ]: 0 : (vert0 == 0 && vert1 == 2))
2828 : : {
2829 : 0 : edge_id = 1;
2830 : : }
2831 : : else
2832 : : {
2833 : 0 : assert(0); //edge_id wasn't set
2834 : : }
2835 : :
2836 : 0 : double compare_tol = projection1 * 1.0e-3;
2837 [ # # ]: 0 : if (project_to_patch( facet, areacoord, the_point, close_point,
2838 [ # # ]: 0 : NULL, outside_facet, compare_tol, edge_id )!= CUBIT_SUCCESS) {
2839 : 0 : return CUBIT_FAILURE;
2840 : : }
2841 : : }
2842 : :
2843 : 1232 : return CUBIT_SUCCESS;
2844 : : }
2845 : :
2846 : : //===========================================================================
2847 : : //Function Name: eval_edge
2848 : : //
2849 : : //Member Type: PUBLIC
2850 : : //Description: Evaluate the location of a point projected to a
2851 : : // linear edge.
2852 : : //===========================================================================
2853 : 0 : CubitStatus FacetEvalTool::eval_edge( CubitFacet *facet,
2854 : : int vert0, int vert1,
2855 : : CubitVector &pt_on_plane,
2856 : : CubitVector &close_point )
2857 : : {
2858 [ # # ]: 0 : CubitPoint *pt0 = facet->point(vert0);
2859 [ # # ]: 0 : CubitPoint *pt1 = facet->point(vert1);
2860 : :
2861 : : // the edge vector
2862 : :
2863 [ # # ][ # # ]: 0 : CubitVector e0 ( pt1->x() - pt0->x(),
2864 [ # # ][ # # ]: 0 : pt1->y() - pt0->y(),
2865 [ # # ][ # # ]: 0 : pt1->z() - pt0->z() );
[ # # ]
2866 [ # # ]: 0 : e0.normalize();
2867 : :
2868 : : // vector from vert0 to point
2869 : :
2870 [ # # ][ # # ]: 0 : CubitVector v0 ( pt_on_plane.x() - pt0->x(),
2871 [ # # ][ # # ]: 0 : pt_on_plane.y() - pt0->y(),
2872 [ # # ][ # # ]: 0 : pt_on_plane.z() - pt0->z() );
[ # # ]
2873 : :
2874 : : // project to edge
2875 : :
2876 [ # # ]: 0 : double len = v0%e0;
2877 [ # # ][ # # ]: 0 : close_point.x ( pt0->x() + e0.x() * len );
[ # # ]
2878 [ # # ][ # # ]: 0 : close_point.y ( pt0->y() + e0.y() * len );
[ # # ]
2879 [ # # ][ # # ]: 0 : close_point.z ( pt0->z() + e0.z() * len );
[ # # ]
2880 : :
2881 : 0 : return CUBIT_SUCCESS;
2882 : : }
2883 : :
2884 : : //===========================================================================
2885 : : //Function Name: eval_point
2886 : : //
2887 : : //Member Type: PUBLIC
2888 : : //Descriptoin: Evaluate the location and normal of a set of area coordinates
2889 : : // on a facet.
2890 : : //===========================================================================
2891 : 517 : CubitStatus FacetEvalTool::eval_point( CubitFacet *facet,
2892 : : int vertex_id,
2893 : : CubitVector &close_point )
2894 : : {
2895 : 517 : close_point.x (facet->point(vertex_id)->x());
2896 : 517 : close_point.y (facet->point(vertex_id)->y());
2897 : 517 : close_point.z (facet->point(vertex_id)->z());
2898 : :
2899 : 517 : return CUBIT_SUCCESS;
2900 : : }
2901 : :
2902 : : //===========================================================================
2903 : : //Function Name: eval_facet_normal
2904 : : //
2905 : : //Member Type: PUBLIC
2906 : : //Descriptoin: Evaluate the normal of the facet (use the interpOrder)
2907 : : // return normalized normal
2908 : : //===========================================================================
2909 : 924 : CubitStatus FacetEvalTool::eval_facet_normal( CubitFacet *facet,
2910 : : CubitVector &areacoord,
2911 : : CubitVector &normal )
2912 : : {
2913 [ + - - - ]: 924 : switch(facet->eval_order()) {
2914 : : case 0:
2915 [ + - ]: 924 : normal = facet->normal();
2916 : 924 : break;
2917 : : case 1: case 2: case 3:
2918 : : {
2919 [ # # ][ # # ]: 0 : CubitVector norm0 = facet->point(0)->normal( facet );
2920 [ # # ][ # # ]: 0 : CubitVector norm1 = facet->point(1)->normal( facet );
2921 [ # # ][ # # ]: 0 : CubitVector norm2 = facet->point(2)->normal( facet );
2922 [ # # ][ # # ]: 0 : normal.x( areacoord.x() * norm0.x() +
2923 [ # # ][ # # ]: 0 : areacoord.y() * norm1.x() +
2924 [ # # ][ # # ]: 0 : areacoord.z() * norm2.x() );
[ # # ]
2925 [ # # ][ # # ]: 0 : normal.y( areacoord.x() * norm0.y() +
2926 [ # # ][ # # ]: 0 : areacoord.y() * norm1.y() +
2927 [ # # ][ # # ]: 0 : areacoord.z() * norm2.y() );
[ # # ]
2928 [ # # ][ # # ]: 0 : normal.z( areacoord.x() * norm0.z() +
2929 [ # # ][ # # ]: 0 : areacoord.y() * norm1.z() +
2930 [ # # ][ # # ]: 0 : areacoord.z() * norm2.z() );
[ # # ]
2931 [ # # ]: 0 : normal.normalize();
2932 : : }
2933 : 0 : break;
2934 : : case 4:
2935 [ # # ]: 0 : if(facet->is_flat())
2936 : : {
2937 [ # # ]: 0 : normal = facet->normal();
2938 : : }
2939 : : else
2940 : : {
2941 : 0 : eval_bezier_patch_normal(facet, areacoord, normal);
2942 : :
2943 : : // check for reasonableness of the normal
2944 : :
2945 : : #if 0
2946 : : if (DEBUG_FLAG(110))
2947 : : {
2948 : : CubitVector norm0 = facet->point(0)->normal( facet );
2949 : : CubitVector norm1 = facet->point(1)->normal( facet );
2950 : : CubitVector norm2 = facet->point(2)->normal( facet );
2951 : : CubitVector lin_normal;
2952 : : lin_normal.x( areacoord.x() * norm0.x() +
2953 : : areacoord.y() * norm1.x() +
2954 : : areacoord.z() * norm2.x() );
2955 : : lin_normal.y( areacoord.x() * norm0.y() +
2956 : : areacoord.y() * norm1.y() +
2957 : : areacoord.z() * norm2.y() );
2958 : : lin_normal.z( areacoord.x() * norm0.z() +
2959 : : areacoord.y() * norm1.z() +
2960 : : areacoord.z() * norm2.z() );
2961 : : lin_normal.normalize();
2962 : :
2963 : : PRINT_INFO("(facet %4d) ac=%7.5lf %7.5lf %7.5lf\n",
2964 : : facet->id(), areacoord.x(), areacoord.y(), areacoord.z());
2965 : : PRINT_INFO(" bn=%7.5lf %7.5lf %7.5lf\n",
2966 : : normal.x(), normal.y(), normal.z());
2967 : : PRINT_INFO(" ln=%7.5lf %7.5lf %7.5lf\n",
2968 : : lin_normal.x(), lin_normal.y(), lin_normal.z());
2969 : :
2970 : : const double tol = 1e-2;
2971 : : if (fabs(lin_normal.x() - normal.x()) > tol ||
2972 : : fabs(lin_normal.y() - normal.y()) > tol ||
2973 : : fabs(lin_normal.z() - normal.z()) > tol)
2974 : : {
2975 : : int mydebug = 0;
2976 : : if (mydebug)
2977 : : {
2978 : : CubitVector pt;
2979 : : eval_bezier_patch(facet, areacoord, pt);
2980 : : dcolor(CUBIT_GREEN_INDEX);
2981 : : dray(pt,normal,1.0);
2982 : : dcolor(CUBIT_RED_INDEX);
2983 : : dray(pt,lin_normal,1.0);
2984 : : dview();
2985 : : }
2986 : :
2987 : : PRINT_INFO("^=============^==============^=============^=============^\n");
2988 : : }
2989 : : }
2990 : : #endif
2991 : : }
2992 : :
2993 : 0 : break;
2994 : : }
2995 : :
2996 : 924 : return CUBIT_SUCCESS;
2997 : : }
2998 : :
2999 : :
3000 : : //===========================================================================
3001 : : //Function Name: eval_quadratic
3002 : : //
3003 : : //Member Type: PRIVATE
3004 : : //Descriptoin: Evaluate the point based on a quadratic approximation
3005 : : //===========================================================================
3006 : 0 : CubitStatus FacetEvalTool::eval_quadratic( CubitFacet *facet,
3007 : : int pt_idx,
3008 : : CubitVector &eval_pt,
3009 : : CubitVector &qpoint,
3010 : : CubitVector &qnorm )
3011 : : {
3012 : : // interpolate a point on a circle that is defined by two points and
3013 : : // two normals. The first pont is a vertex on the facet, the second
3014 : : // is a point on the opposite edge. The point to be interpolated lies
3015 : : // somewhere between the two
3016 : :
3017 [ # # ][ # # ]: 0 : CubitVector normA = facet->point(pt_idx)->normal( facet );
3018 [ # # ][ # # ]: 0 : CubitVector ptA = facet->point(pt_idx)->coordinates();
3019 : 0 : int idx0 = -1, idx1 = -1;
3020 [ # # # # ]: 0 : switch(pt_idx) {
3021 : : case 0:
3022 : 0 : idx0 = 1;
3023 : 0 : idx1 = 2;
3024 : 0 : break;
3025 : : case 1:
3026 : 0 : idx0 = 2;
3027 : 0 : idx1 = 0;
3028 : 0 : break;
3029 : : case 2:
3030 : 0 : idx0 = 0;
3031 : 0 : idx1 = 1;
3032 : 0 : break;
3033 : : }
3034 [ # # ][ # # ]: 0 : CubitVector ptB, normB, pt0, pt1, norm0, norm1;
[ # # ][ # # ]
[ # # ][ # # ]
3035 [ # # ][ # # ]: 0 : pt0 = facet->point(idx0)->coordinates();
[ # # ]
3036 [ # # ][ # # ]: 0 : pt1 = facet->point(idx1)->coordinates();
[ # # ]
3037 [ # # ][ # # ]: 0 : norm0 = facet->point(idx0)->normal( facet );
[ # # ]
3038 [ # # ][ # # ]: 0 : norm1 = facet->point(idx1)->normal( facet );
[ # # ]
3039 : : on_circle( pt0, norm0, pt1, norm1,
3040 [ # # ]: 0 : eval_pt, ptB, normB );
3041 : : on_circle( ptA, normA, ptB, normB,
3042 [ # # ]: 0 : eval_pt, qpoint, qnorm );
3043 : :
3044 : 0 : return CUBIT_SUCCESS;
3045 : :
3046 : : }
3047 : :
3048 : : //===========================================================================
3049 : : //Function Name: on_circle
3050 : : //
3051 : : //Member Type: PRIVATE
3052 : : //Description: compute a projection of a point onto a circle. The circle
3053 : : // is defined by two points and two normals. Return the
3054 : : // projected point and its normal
3055 : : //===========================================================================
3056 : 0 : void FacetEvalTool::on_circle( CubitVector &ptA,
3057 : : CubitVector &normA,
3058 : : CubitVector &ptB,
3059 : : CubitVector &normB,
3060 : : CubitVector &eval_pt,
3061 : : CubitVector &pt_on_circle,
3062 : : CubitVector &normal )
3063 : : {
3064 : : // angle between the normals
3065 : :
3066 : 0 : double cosang = normA%normB;
3067 : :
3068 : : // check for flat surfaces - project to the segment
3069 : :
3070 [ # # ][ # # ]: 0 : if (cosang >= 0.99999 || cosang <= -0.99999) {
3071 [ # # ]: 0 : CubitVector vAB = ptB - ptA;
3072 [ # # ]: 0 : vAB.normalize();
3073 [ # # ]: 0 : CubitVector vAeval_pt = eval_pt - ptA;
3074 [ # # ]: 0 : double len = vAB%vAeval_pt;
3075 [ # # ][ # # ]: 0 : pt_on_circle = ptA + len * vAB;
[ # # ]
3076 [ # # ]: 0 : if (cosang <= -0.99999) { // this is bad! (facet spans 180 degrees)
3077 [ # # ]: 0 : normal = normA;
3078 : : }
3079 : : else {
3080 [ # # ][ # # ]: 0 : normal = 0.5e0 * (normA + normB);
[ # # ]
3081 : 0 : }
3082 : : }
3083 : : else {
3084 : :
3085 : : // curved surface
3086 : : // define a common plane at eval_pt
3087 : :
3088 [ # # ]: 0 : CubitVector pnorm = normA*normB;
3089 [ # # ]: 0 : pnorm.normalize();
3090 [ # # ][ # # ]: 0 : double pcoefd = -pnorm%eval_pt;
3091 : :
3092 : : // project everything to common plane
3093 : :
3094 [ # # ]: 0 : double pdist = pnorm%ptA + pcoefd;
3095 [ # # ][ # # ]: 0 : CubitVector pptA = ptA - pnorm * pdist;
3096 [ # # ]: 0 : pdist = pnorm%ptB + pcoefd;
3097 [ # # ][ # # ]: 0 : CubitVector pptB = ptB - pnorm * pdist;
3098 : :
3099 : 0 : double angle = acos(cosang);
3100 [ # # ]: 0 : double dist = pptA.distance_between(pptB);
3101 : :
3102 : : // kradius is the radius of curvature
3103 : : // center is the center of curvature
3104 : : // centerA and centerB should be the same within tol
3105 : :
3106 : 0 : double kradius = dist / (2.0e0 * sin( angle * 0.5e0 ));
3107 [ # # ][ # # ]: 0 : CubitVector centerA = pptA - kradius * normA;
3108 [ # # ][ # # ]: 0 : CubitVector centerB = pptB - kradius * normB;
3109 [ # # ][ # # ]: 0 : CubitVector center = (centerA + centerB) * 0.5e0;
3110 : :
3111 [ # # ][ # # ]: 0 : normal = eval_pt - center;
3112 [ # # ]: 0 : normal.normalize();
3113 [ # # ][ # # ]: 0 : pt_on_circle = center + kradius * normal;
[ # # ]
3114 : : }
3115 : 0 : }
3116 : :
3117 : : //===========================================================================
3118 : : //Function Name: eval_quadric
3119 : : //
3120 : : //Member Type: PRIVATE
3121 : : //Description: evaluate a point on an interpolated quadric surface
3122 : : //===========================================================================
3123 : 0 : void FacetEvalTool::eval_quadric( CubitFacet *facet,
3124 : : int pt_index,
3125 : : CubitVector &eval_pt,
3126 : : CubitVector &qpt )
3127 : : {
3128 : : // transform the point to the local system
3129 : :
3130 [ # # ]: 0 : CubitPoint *point = facet->point(pt_index);
3131 [ # # ]: 0 : CubitVector loc_eval_pt;
3132 [ # # ]: 0 : point->transform_to_local( eval_pt, loc_eval_pt );
3133 : : // point->transform_to_local( point->coordinates(), loc_pt );
3134 : :
3135 : : // interpolate a "z" value in the local coordinate system
3136 : :
3137 [ # # ]: 0 : double *coef = point->coef_vector();
3138 [ # # ]: 0 : loc_eval_pt.z( coef[0] * loc_eval_pt.x() +
3139 [ # # ]: 0 : coef[1] * loc_eval_pt.y() +
3140 [ # # ][ # # ]: 0 : coef[2] * FacetEvalToolUtils::sqr(loc_eval_pt.x()) +
3141 [ # # ][ # # ]: 0 : coef[3] * loc_eval_pt.x() * loc_eval_pt.y() +
3142 [ # # ][ # # ]: 0 : coef[4] * FacetEvalToolUtils::sqr(loc_eval_pt.y()) );
[ # # ]
3143 : :
3144 : :
3145 : : // loc_eval_pt.z( point->z() -
3146 : : // coef[0] * loc_eval_pt.x() -
3147 : : // coef[1] * loc_eval_pt.y() +
3148 : : // coef[2] * sqr(loc_eval_pt.x()) +
3149 : : // coef[3] * loc_eval_pt.x() * loc_eval_pt.y() +
3150 : : // coef[4] * sqr(loc_eval_pt.y()) );
3151 : :
3152 : : // transform back to global system
3153 : :
3154 [ # # ]: 0 : point->transform_to_global( loc_eval_pt, qpt );
3155 : :
3156 : 0 : }
3157 : :
3158 : : //===========================================================================
3159 : : //Function Name: project_to_facet_plane
3160 : : //
3161 : : //Member Type: PUBLIC
3162 : : //Descriptoin: Project a point to the plane of a facet
3163 : : //===========================================================================
3164 : 3828 : void FacetEvalTool::project_to_facet_plane(
3165 : : CubitFacet *facet,
3166 : : const CubitVector &pt,
3167 : : CubitVector &point_on_plane,
3168 : : double &dist_to_plane)
3169 : : {
3170 [ + - ]: 3828 : CubitVector normal = facet->normal();
3171 [ + - ]: 3828 : normal.normalize();
3172 [ + - ]: 3828 : CubitPoint *facPoint = facet->point(0);
3173 [ + - ][ + - ]: 3828 : double coefd = -(normal.x() * facPoint->x() +
3174 [ + - ][ + - ]: 3828 : normal.y() * facPoint->y() +
3175 [ + - ][ + - ]: 3828 : normal.z() * facPoint->z());
3176 [ + - ][ + - ]: 3828 : double dist = normal.x() * pt.x() +
3177 [ + - ][ + - ]: 3828 : normal.y() * pt.y() +
3178 [ + - ][ + - ]: 3828 : normal.z() * pt.z() + coefd;
3179 : 3828 : dist_to_plane = fabs(dist);
3180 : :
3181 [ + - ][ + - ]: 3828 : point_on_plane.set( pt.x() - normal.x() * dist,
3182 [ + - ][ + - ]: 3828 : pt.y() - normal.y() * dist,
3183 [ + - ][ + - ]: 7656 : pt.z() - normal.z() * dist );
[ + - ]
3184 : :
3185 : 3828 : }
3186 : :
3187 : : //===========================================================================
3188 : : //Function Name: facet_area_coordinate
3189 : : //
3190 : : //Member Type: PUBLIC
3191 : : //Descriptoin: Determine the area coordinates of a point on the plane
3192 : : // of a facet
3193 : : //===========================================================================
3194 : 3828 : void FacetEvalTool::facet_area_coordinate(
3195 : : CubitFacet *facet,
3196 : : const CubitVector &pt_on_plane,
3197 : : CubitVector &areacoord )
3198 : : {
3199 : : double area2;
3200 [ + - ]: 3828 : CubitVector normal = facet->normal();
3201 [ + - ]: 3828 : CubitPoint *pt0 = facet->point(0);
3202 [ + - ]: 3828 : CubitPoint *pt1 = facet->point(1);
3203 [ + - ]: 3828 : CubitPoint *pt2 = facet->point(2);
3204 : 3828 : double tol = GEOMETRY_RESABS * 1.e-5;
3205 [ + - ][ + - ]: 3828 : CubitVector v1( pt1->x() - pt0->x(),
3206 [ + - ][ + - ]: 3828 : pt1->y() - pt0->y(),
3207 [ + - ][ + - ]: 7656 : pt1->z() - pt0->z());//(*p1-*p0);
[ + - ]
3208 [ + - ][ + - ]: 3828 : CubitVector v2( pt2->x() - pt0->x(),
3209 [ + - ][ + - ]: 3828 : pt2->y() - pt0->y(),
3210 [ + - ][ + - ]: 7656 : pt2->z() - pt0->z());// = (*p2-*p0);
[ + - ]
3211 [ + - ][ + - ]: 3828 : area2 = (v1*v2).length_squared();
3212 [ - + ]: 3828 : if(area2 < 100 * tol){
3213 : 0 : tol = .01 * area2;
3214 : : }
3215 [ + - ][ + - ]: 3828 : CubitVector absnorm( fabs(normal.x()), fabs(normal.y()), fabs(normal.z()) );
[ + - ][ + - ]
3216 : :
3217 : : // project to the closest coordinate plane so we only have to do this in 2D
3218 : :
3219 [ + - ][ + - ]: 3828 : if (absnorm.x() >= absnorm.y() && absnorm.x() >= absnorm.z()) {
[ + + ][ + - ]
[ + - ][ + + ]
[ + + ]
3220 : 2420 : area2 = FacetEvalToolUtils::determ3(pt0->y(), pt0->z(),
3221 : 2420 : pt1->y(), pt1->z(),
3222 [ + - ][ + - ]: 1210 : pt2->y(), pt2->z());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
3223 [ - + ]: 1210 : if (fabs(area2) < tol) {
3224 [ # # ]: 0 : areacoord.set( -CUBIT_DBL_MAX, -CUBIT_DBL_MAX, -CUBIT_DBL_MAX );
3225 : : }
3226 [ + - ][ + - ]: 1210 : else if ( pt_on_plane.within_tolerance( pt0->coordinates(), GEOMETRY_RESABS ) )
[ + + ]
3227 : : {
3228 [ + - ]: 99 : areacoord.set( 1.0, 0.0, 0.0 );
3229 : : }
3230 [ + - ][ + - ]: 1111 : else if ( pt_on_plane.within_tolerance( pt1->coordinates(), GEOMETRY_RESABS ) )
[ + + ]
3231 : : {
3232 [ + - ]: 77 : areacoord.set( 0.0, 1.0, 0.0 );
3233 : : }
3234 [ + - ][ + - ]: 1034 : else if ( pt_on_plane.within_tolerance( pt2->coordinates(), GEOMETRY_RESABS ) )
[ + + ]
3235 : : {
3236 [ + - ]: 264 : areacoord.set( 0.0, 0.0, 1.0 );
3237 : : }
3238 : : else {
3239 : : areacoord.x(
3240 : : FacetEvalToolUtils::determ3( pt_on_plane.y(), pt_on_plane.z(),
3241 [ + - ][ + - ]: 770 : pt1->y(), pt1->z(), pt2->y(), pt2->z() ) / area2 );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3242 : : areacoord.y(
3243 : 1540 : FacetEvalToolUtils::determ3( pt0->y(), pt0->z(),
3244 : : pt_on_plane.y(), pt_on_plane.z(),
3245 [ + - ][ + - ]: 770 : pt2->y(), pt2->z() ) / area2 );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3246 : : areacoord.z(
3247 : 3080 : FacetEvalToolUtils::determ3( pt0->y(), pt0->z(), pt1->y(), pt1->z(),
3248 [ + - ][ + - ]: 1210 : pt_on_plane.y(), pt_on_plane.z() ) / area2 );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3249 : : }
3250 : : }
3251 [ + - ][ + - ]: 2618 : else if(absnorm.y() >= absnorm.x() && absnorm.y() >= absnorm.z()) {
[ + - ][ + - ]
[ + - ][ + + ]
[ + + ]
3252 : 2772 : area2 = FacetEvalToolUtils::determ3(pt0->x(), pt0->z(),
3253 : 2772 : pt1->x(), pt1->z(),
3254 [ + - ][ + - ]: 1386 : pt2->x(), pt2->z());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
3255 [ - + ]: 1386 : if (fabs(area2) < tol) {
3256 [ # # ]: 0 : areacoord.set( -CUBIT_DBL_MAX, -CUBIT_DBL_MAX, -CUBIT_DBL_MAX );
3257 : : }
3258 [ + - ][ + - ]: 1386 : else if ( pt_on_plane.within_tolerance( pt0->coordinates(), GEOMETRY_RESABS ) )
[ + + ]
3259 : : {
3260 [ + - ]: 55 : areacoord.set( 1.0, 0.0, 0.0 );
3261 : : }
3262 [ + - ][ + - ]: 1331 : else if ( pt_on_plane.within_tolerance( pt1->coordinates(), GEOMETRY_RESABS ) )
[ + + ]
3263 : : {
3264 [ + - ]: 121 : areacoord.set( 0.0, 1.0, 0.0 );
3265 : : }
3266 [ + - ][ + - ]: 1210 : else if ( pt_on_plane.within_tolerance( pt2->coordinates(), GEOMETRY_RESABS ) )
[ + + ]
3267 : : {
3268 [ + - ]: 286 : areacoord.set( 0.0, 0.0, 1.0 );
3269 : : }
3270 : : else {
3271 : : areacoord.x(
3272 : : FacetEvalToolUtils::determ3( pt_on_plane.x(), pt_on_plane.z(),
3273 [ + - ][ + - ]: 924 : pt1->x(), pt1->z(), pt2->x(), pt2->z() ) / area2 );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3274 : : areacoord.y(
3275 : 1848 : FacetEvalToolUtils::determ3( pt0->x(), pt0->z(),
3276 : : pt_on_plane.x(), pt_on_plane.z(),
3277 [ + - ][ + - ]: 924 : pt2->x(), pt2->z() ) / area2 );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3278 : : areacoord.z(
3279 : 3696 : FacetEvalToolUtils::determ3( pt0->x(), pt0->z(), pt1->x(), pt1->z(),
3280 [ + - ][ + - ]: 1386 : pt_on_plane.x(), pt_on_plane.z() ) / area2 );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3281 : : }
3282 : : }
3283 : : else {
3284 : 2464 : area2 = FacetEvalToolUtils::determ3(pt0->x(), pt0->y(),
3285 : 2464 : pt1->x(), pt1->y(),
3286 [ + - ][ + - ]: 1232 : pt2->x(), pt2->y());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
3287 [ - + ]: 1232 : if (fabs(area2) < tol) {
3288 [ # # ]: 0 : areacoord.set( -CUBIT_DBL_MAX, -CUBIT_DBL_MAX, -CUBIT_DBL_MAX );
3289 : : }
3290 [ + - ][ + - ]: 1232 : else if ( pt_on_plane.within_tolerance( pt0->coordinates(), GEOMETRY_RESABS ) )
[ + + ]
3291 : : {
3292 [ + - ]: 110 : areacoord.set( 1.0, 0.0, 0.0 );
3293 : : }
3294 [ + - ][ + - ]: 1122 : else if ( pt_on_plane.within_tolerance( pt1->coordinates(), GEOMETRY_RESABS ) )
[ + + ]
3295 : : {
3296 [ + - ]: 66 : areacoord.set( 0.0, 1.0, 0.0 );
3297 : : }
3298 [ + - ][ + - ]: 1056 : else if ( pt_on_plane.within_tolerance( pt2->coordinates(), GEOMETRY_RESABS ) )
[ + + ]
3299 : : {
3300 [ + - ]: 440 : areacoord.set( 0.0, 0.0, 1.0 );
3301 : : }
3302 : : else {
3303 : : areacoord.x(
3304 : : FacetEvalToolUtils::determ3( pt_on_plane.x(), pt_on_plane.y(),
3305 [ + - ][ + - ]: 616 : pt1->x(), pt1->y(), pt2->x(), pt2->y() ) / area2 );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3306 : : areacoord.y(
3307 : 1232 : FacetEvalToolUtils::determ3( pt0->x(), pt0->y(),
3308 : : pt_on_plane.x(), pt_on_plane.y(),
3309 [ + - ][ + - ]: 616 : pt2->x(), pt2->y() ) / area2 );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3310 : : areacoord.z(
3311 : 2464 : FacetEvalToolUtils::determ3( pt0->x(), pt0->y(), pt1->x(), pt1->y(),
3312 [ + - ][ + - ]: 616 : pt_on_plane.x(), pt_on_plane.y() ) / area2 );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3313 : : }
3314 : : }
3315 : 3828 : }
3316 : :
3317 : : //===========================================================================
3318 : : //Function Name: is_outside
3319 : : //
3320 : : //Member Type: PRIVATE
3321 : : //Descriptoin: Determines if the areacoord is actually outside the range
3322 : : // of the surface facets.
3323 : : //===========================================================================
3324 : 132 : CubitBoolean FacetEvalTool::is_outside(
3325 : : CubitFacet *facet,
3326 : : CubitVector &areacoord)
3327 : : {
3328 [ - + ]: 132 : if (areacoord.x() < -GEOMETRY_RESABS) {
3329 [ # # ]: 0 : if (NULL == facet->shared_facet_on_surf( facet->point(1),
3330 : 0 : facet->point(2),
3331 : 0 : facet->tool_id() )) {
3332 : 0 : return CUBIT_TRUE;
3333 : : }
3334 : : }
3335 [ + + ]: 132 : if (areacoord.y() < -GEOMETRY_RESABS) {
3336 [ - + ]: 22 : if (NULL == facet->shared_facet_on_surf( facet->point(2),
3337 : 22 : facet->point(0),
3338 : 22 : facet->tool_id() )) {
3339 : 0 : return CUBIT_TRUE;
3340 : : }
3341 : : }
3342 [ + + ]: 132 : if (areacoord.z() < -GEOMETRY_RESABS) {
3343 [ + - ]: 110 : if (NULL == facet->shared_facet_on_surf( facet->point(0),
3344 : 110 : facet->point(1),
3345 : 110 : facet->tool_id() )) {
3346 : 110 : return CUBIT_TRUE;
3347 : : }
3348 : : }
3349 : 22 : return CUBIT_FALSE;
3350 : : }
3351 : :
3352 : : //===========================================================================
3353 : : //Function Name: closest_point_trimmed
3354 : : //
3355 : : //Member Type: PUBLIC
3356 : : //Descriptoin: Finds the closest point from the vector (this_point) to the
3357 : : // set of facets that lies on the set of facets. If the point
3358 : : // lies outside this set, the closest point will be on the edge
3359 : : // of the closest facet.
3360 : : // This function also determines if the point is outside or
3361 : : // inside the current set of facets. You should call
3362 : : // a bounding box test first before this...
3363 : : //===========================================================================
3364 : 11 : CubitStatus FacetEvalTool::closest_point_trimmed(
3365 : : CubitVector &this_point,
3366 : : CubitVector *closest_point_ptr,
3367 : : CubitBoolean &lies_outside,
3368 : : CubitVector *normal_ptr)
3369 : : {
3370 : :
3371 : 11 : CubitBoolean trim = CUBIT_TRUE;
3372 : : return project_to_facets ( this_point, trim, &lies_outside,
3373 : 11 : closest_point_ptr, normal_ptr );
3374 : : }
3375 : :
3376 : : //===========================================================================
3377 : : //Function Name: destroy_facets
3378 : : //
3379 : : //Member Type: PRIVATE
3380 : : //Descriptoin: Deletes the points and facets.
3381 : : //===========================================================================
3382 : 0 : void FacetEvalTool::destroy_facets()
3383 : : {
3384 : : int i, j;
3385 : : CubitPoint *point;
3386 : : CubitFacet *facet;
3387 : : CubitFacetEdge *edge;
3388 : 0 : myFacetList.last();
3389 : 0 : CubitFacetEdgeData *cfe_data = NULL;
3390 [ # # ]: 0 : for( i = myFacetList.size(); i > 0; i-- )
3391 : : {
3392 : 0 : facet = myFacetList.pop();
3393 [ # # ]: 0 : for (j = 0; j<3; j++)
3394 : : {
3395 : 0 : point = facet->point( j );
3396 : 0 : point->remove_facet( facet );
3397 : 0 : edge = facet->edge( j );
3398 [ # # ]: 0 : cfe_data = CAST_TO( edge, CubitFacetEdgeData );
3399 [ # # ]: 0 : if (cfe_data)
3400 : 0 : cfe_data->remove_facet( facet );
3401 : : }
3402 [ # # ]: 0 : delete facet;
3403 : : }
3404 [ # # ]: 0 : for( i = myEdgeList.size(); i > 0; i-- )
3405 : : {
3406 : 0 : edge = myEdgeList.pop();
3407 [ # # ][ # # ]: 0 : if (edge && edge->num_adj_facets() == 0)
[ # # ]
3408 : : {
3409 [ # # ]: 0 : delete edge;
3410 : : }
3411 : : }
3412 [ # # ]: 0 : for( i = myPointList.size(); i > 0; i-- )
3413 : : {
3414 : 0 : point = myPointList.pop();
3415 [ # # ][ # # ]: 0 : if (point && point->num_adj_facets() == 0)
[ # # ]
3416 : : {
3417 [ # # ]: 0 : delete point;
3418 : : }
3419 : : }
3420 : 0 : }
3421 : :
3422 : : //===========================================================================
3423 : : //Function Name: get_points_from_facets
3424 : : //
3425 : : //Member Type: PRIVATE
3426 : : //Descriptoin: Gets the set of points contained in the list of facets.
3427 : : // Populates the point_list with those points.
3428 : : //===========================================================================
3429 : 0 : CubitStatus FacetEvalTool::get_points_from_facets(
3430 : : DLIList<CubitFacet*> &facet_list,
3431 : : DLIList<CubitPoint*> &point_list )
3432 : : {
3433 : : int i, j;
3434 : :
3435 [ # # ]: 0 : DLIList<CubitPoint*> all_points;
3436 : :
3437 [ # # ][ # # ]: 0 : for ( i = 0; i < facet_list.size(); i++)
3438 : : {
3439 [ # # ]: 0 : CubitFacet* facet = facet_list.get_and_step();
3440 [ # # ]: 0 : facet->points(all_points);
3441 : : }
3442 [ # # ][ # # ]: 0 : for ( i = 0; i < all_points.size(); i++)
3443 : : {
3444 [ # # ][ # # ]: 0 : all_points.get_and_step()->marked( CUBIT_FALSE );
3445 : : }
3446 : :
3447 [ # # ][ # # ]: 0 : for ( j = 0; j < all_points.size(); j++)
3448 : : {
3449 [ # # ]: 0 : CubitPoint* point = all_points.get_and_step();
3450 [ # # ][ # # ]: 0 : if (!point->marked())
3451 : : {
3452 [ # # ]: 0 : point->marked(CUBIT_TRUE);
3453 [ # # ]: 0 : point_list.append(point);
3454 : : }
3455 : : }
3456 : :
3457 : : // unmark the found points
3458 : :
3459 [ # # ][ # # ]: 0 : for (i = 0; i < point_list.size(); i++)
3460 : : {
3461 [ # # ][ # # ]: 0 : point_list.get_and_step()->marked(CUBIT_FALSE);
3462 : : }
3463 [ # # ]: 0 : return CUBIT_SUCCESS;
3464 : : }
3465 : :
3466 : : //===========================================================================
3467 : : //Function Name: get_loops_from_facets
3468 : : //
3469 : : //Member Type: PRIVATE
3470 : : //Descriptoin: generate an ordered list of facetedge lists representing the
3471 : : // boundary loops for this set of facets
3472 : : //===========================================================================
3473 : 341 : CubitStatus FacetEvalTool::get_loops_from_facets(
3474 : : DLIList<CubitFacetEdge*> &all_edge_list, // all the edges on the facets
3475 : : DLIList<DLIList<CubitFacetEdge*>*> &loop_list ) // return a list of edge lists
3476 : : {
3477 : : int i;
3478 : 341 : int mydebug = 0;
3479 : : CubitFacetEdge* edge, *startedge;
3480 : : CubitFacet *facet, *nextfacet;
3481 : : CubitBoolean found;
3482 : :
3483 [ - + ]: 341 : if (mydebug)
3484 : : {
3485 [ # # ]: 0 : GfxDebug::clear();
3486 [ # # ][ # # ]: 0 : for (i = 0; i< myFacetList.size(); i++)
3487 [ # # ][ # # ]: 0 : myFacetList.get_and_step()->debug_draw( CUBIT_GREEN_INDEX, false);
3488 [ # # ]: 0 : GfxDebug::flush();
3489 [ # # ]: 0 : GfxDebug::mouse_xforms();
3490 : : }
3491 : :
3492 [ + - ][ + + ]: 2563 : for ( i = 0; i < all_edge_list.size(); i++)
3493 : : {
3494 [ + - ]: 2222 : startedge = all_edge_list.get_and_step();
3495 [ + - ][ + + ]: 2222 : if (startedge->get_flag() == 0) {
3496 [ + - ]: 858 : startedge->set_flag( 1 );
3497 : :
3498 : : // Find an edge without a neighboring facet or a facet that
3499 : : // is not on the current surface to start a loop
3500 : :
3501 [ + - ][ + + ]: 858 : if (startedge->num_adj_facets_on_surf(toolID) == 1)
3502 : : {
3503 : :
3504 : : // Start a new loop
3505 : :
3506 [ + - ][ + - ]: 330 : DLIList<CubitFacetEdge*> *edge_list = new DLIList<CubitFacetEdge*>;
3507 [ + - ]: 330 : loop_list.append( edge_list );
3508 [ + - ]: 330 : edge_list->append( startedge );
3509 [ - + ][ # # ]: 330 : if (mydebug) debug_draw_edge(startedge);
3510 : :
3511 : : // find the next ccw edge on the loop. Edges are placed on the
3512 : : // list based on ccw order wrt the orientation of the facets
3513 : : // (ie. same orientation as facets)
3514 : :
3515 : 330 : edge = startedge;
3516 [ + - ]: 330 : facet = edge->adj_facet_on_surf(toolID);
3517 : 330 : int num_failures = 0;
3518 [ + + ]: 1276 : do {
3519 : 1276 : found = CUBIT_FALSE;
3520 [ + + ]: 2244 : do {
3521 [ + - ]: 2244 : edge = facet->next_edge( edge );
3522 [ - + ]: 2244 : assert(edge != NULL);
3523 [ + - ]: 2244 : edge->set_flag( 1 );
3524 : :
3525 [ + - ]: 2244 : nextfacet = edge->other_facet_on_surf(facet);
3526 : :
3527 [ + + ]: 2244 : if (nextfacet == NULL) {
3528 [ + + ]: 1276 : if (edge != startedge) {
3529 : 946 : num_failures = 0;
3530 [ + - ]: 946 : edge_list->append( edge );
3531 : : }
3532 : 1276 : found = CUBIT_TRUE;
3533 : : }
3534 : : else {
3535 : 968 : num_failures++;
3536 : 968 : facet = nextfacet;
3537 : : }
3538 [ + + ][ + - ]: 2244 : } while (!found && num_failures < myFacetList.size() );
[ + - ]
3539 [ + + ][ + - ]: 1276 : } while (edge != startedge && num_failures < myFacetList.size() );
[ + - ]
3540 : :
3541 [ - + ]: 330 : if( edge != startedge )
3542 : 858 : return CUBIT_FAILURE;
3543 : : }
3544 : : }
3545 : : }
3546 : :
3547 : : // reset the flags
3548 : :
3549 [ + - ][ + + ]: 2563 : for ( i = 0; i < all_edge_list.size(); i++) {
3550 [ + - ][ + - ]: 2222 : all_edge_list.get_and_step()->set_flag( 0 );
3551 : : }
3552 : 341 : return CUBIT_SUCCESS;
3553 : : }
3554 : :
3555 : : //===========================================================================
3556 : : //Function Name: get_edges_from_facets
3557 : : //
3558 : : //Member Type: PRIVATE
3559 : : //Descriptoin: Populates the edge list from the list of facets
3560 : : //===========================================================================
3561 : 341 : CubitStatus FacetEvalTool::get_edges_from_facets(
3562 : : DLIList<CubitFacet*> &facet_list,
3563 : : DLIList<CubitFacetEdge*> &edge_list )
3564 : : {
3565 : : int i, j, k;
3566 : : CubitPoint *p0, *p1;
3567 : : CubitFacet *facet, *adj_facet;
3568 : : CubitFacetEdge *edge;
3569 [ + - ][ + + ]: 1397 : for ( i = 0; i < facet_list.size(); i++) {
3570 [ + - ]: 1056 : facet = facet_list.get_and_step();
3571 [ + + ]: 4224 : for (j=0; j<3; j++) {
3572 [ + - ][ - + ]: 3168 : if (!(edge = facet->edge(j)))
3573 : : {
3574 [ # # ]: 0 : facet->get_edge_pts( j, p0, p1 );
3575 : 0 : edge = NULL;
3576 : 0 : k = -1;
3577 : : //find another facet on this surface sharing these two points
3578 [ # # ]: 0 : adj_facet = facet->shared_facet( p0, p1 );
3579 : :
3580 [ # # ]: 0 : if (adj_facet) {
3581 [ # # ]: 0 : edge = adj_facet->edge_from_pts(p0, p1, k);
3582 : : }
3583 : :
3584 [ # # ]: 0 : if (!edge) {
3585 : : edge = (CubitFacetEdge *)
3586 [ # # ][ # # ]: 0 : new CubitFacetEdgeData( p0, p1, facet, adj_facet, j, k );
3587 : : }
3588 : : else{
3589 [ # # ]: 0 : facet->add_edge( edge );
3590 : : }
3591 : : }
3592 [ + - ]: 3168 : edge->set_flag( 0 );
3593 : : }
3594 : : }
3595 : : // create a unique list of edges
3596 : :
3597 [ + - ][ + + ]: 1397 : for ( i = 0; i < facet_list.size(); i++)
3598 : : {
3599 [ + - ]: 1056 : facet = facet_list.get_and_step();
3600 [ + + ]: 4224 : for (j=0; j<3; j++)
3601 : : {
3602 [ + - ]: 3168 : edge = facet->edge(j);
3603 [ - + ]: 3168 : if ( !edge )
3604 : 0 : return CUBIT_FAILURE;
3605 [ + - ][ + + ]: 3168 : if (0 == edge->get_flag())
3606 : : {
3607 [ + - ]: 2222 : edge->set_flag( 1 );
3608 [ + - ]: 2222 : edge_list.append( edge );
3609 : : }
3610 : : }
3611 : : }
3612 : :
3613 : : // reset the flags on the edges
3614 : :
3615 [ + - ][ + + ]: 2563 : for ( i = 0; i < edge_list.size(); i++)
3616 : : {
3617 [ + - ]: 2222 : edge = edge_list.get_and_step();
3618 [ + - ]: 2222 : edge->set_flag( 0 );
3619 : : }
3620 : 341 : return CUBIT_SUCCESS;
3621 : : }
3622 : :
3623 : :
3624 : : //===========================================================================
3625 : : //Function Name: check_faceting
3626 : : //
3627 : : //Member Type: PRIVATE
3628 : : //Descriptoin: check the edge/face orientations
3629 : : //===========================================================================
3630 : 0 : void FacetEvalTool::check_faceting()
3631 : : {
3632 : : int ii;
3633 [ # # ][ # # ]: 0 : for (ii = 0; ii< myFacetList.size(); ii++)
3634 [ # # ][ # # ]: 0 : myFacetList.get_and_step()->debug_draw( CUBIT_YELLOW_INDEX );
3635 [ # # ]: 0 : GfxDebug::flush();
3636 [ # # ]: 0 : GfxDebug::mouse_xforms();
3637 : :
3638 [ # # ]: 0 : CubitFacet *facet = myFacetList.get_and_step();
3639 [ # # ]: 0 : CubitVector snorm = facet->normal();
3640 [ # # ]: 0 : snorm.normalize();
3641 [ # # ][ # # ]: 0 : for (ii=1; ii<myFacetList.size(); ii++)
3642 : : {
3643 [ # # ]: 0 : facet = myFacetList.get_and_step();
3644 [ # # ]: 0 : CubitVector norm = facet->normal();
3645 [ # # ]: 0 : norm.normalize();
3646 [ # # ][ # # ]: 0 : if (norm % snorm < 0.8)
3647 : : {
3648 [ # # ]: 0 : facet->debug_draw( CUBIT_RED_INDEX );
3649 : : }
3650 : : else
3651 : : {
3652 [ # # ]: 0 : facet->debug_draw( CUBIT_BLUE_INDEX );
3653 : : }
3654 : : }
3655 : 0 : }
3656 : :
3657 : :
3658 : : //===========================================================================
3659 : : //Function Name: draw_facets
3660 : : //
3661 : : //Member Type: PRIVATE
3662 : : //Descriptoin: draw the facets for debug
3663 : : //===========================================================================
3664 : 0 : void FacetEvalTool::debug_draw_facets( int color )
3665 : : {
3666 : : int ii;
3667 [ # # ]: 0 : if ( color == -1 )
3668 : 0 : color = CUBIT_YELLOW_INDEX;
3669 : 0 : CubitBoolean flush_it = CUBIT_FALSE;
3670 [ # # ]: 0 : for ( ii = myFacetList.size(); ii > 0; ii-- )
3671 : : {
3672 : 0 : myFacetList.get_and_step()->debug_draw(color, flush_it);
3673 : : }
3674 : 0 : GfxDebug::flush();
3675 : 0 : }
3676 : :
3677 : : //===========================================================================
3678 : : //Function Name: draw_vec
3679 : : //
3680 : : //Member Type: PRIVATE
3681 : : //Descriptoin: draw a single point
3682 : : //===========================================================================
3683 : 0 : void FacetEvalTool::debug_draw_vec( CubitVector &vec, int color )
3684 : : {
3685 [ # # ]: 0 : if ( color == -1 )
3686 : 0 : color = CUBIT_YELLOW_INDEX;
3687 : 0 : GfxDebug::draw_point(vec, color);
3688 : 0 : GfxDebug::flush();
3689 : 0 : }
3690 : :
3691 : : //===========================================================================
3692 : : //Function Name: draw_facet_normals
3693 : : //
3694 : : //Member Type: PRIVATE
3695 : : //Descriptoin: the the normal at the centroid of the facets
3696 : : //===========================================================================
3697 : 0 : void FacetEvalTool::debug_draw_facet_normals(int color)
3698 : : {
3699 : : int ii,jj;
3700 [ # # ]: 0 : if ( color == -1 )
3701 : 0 : color = CUBIT_RED_INDEX;
3702 [ # # ]: 0 : for ( ii = myFacetList.size(); ii > 0; ii-- )
3703 : : {
3704 [ # # ]: 0 : CubitFacet *facet = myFacetList.get_and_step();
3705 [ # # ]: 0 : CubitVector center(0.0e0, 0.0e0, 0.0e0);
3706 [ # # ]: 0 : for (jj = 0; jj < 3; jj++)
3707 : : {
3708 [ # # ][ # # ]: 0 : center += facet->point(jj)->coordinates();
[ # # ]
3709 : : }
3710 [ # # ]: 0 : center /= 3.0;
3711 [ # # ]: 0 : CubitVector normal = facet->normal();
3712 [ # # ][ # # ]: 0 : double mag = sqrt(FacetEvalToolUtils::sqr(normal.x()) + FacetEvalToolUtils::sqr(normal.y()) + FacetEvalToolUtils::sqr(normal.z()));
[ # # ][ # # ]
[ # # ][ # # ]
3713 : 0 : mag = sqrt(mag);
3714 [ # # ]: 0 : normal.normalize();
3715 [ # # ][ # # ]: 0 : CubitVector end = center + normal*mag;
3716 [ # # ][ # # ]: 0 : GfxDebug::draw_line(center.x(), center.y(), center.z(),
[ # # ]
3717 [ # # ][ # # ]: 0 : end.x(), end.y(), end.z(), color);
[ # # ][ # # ]
3718 : : }
3719 : 0 : GfxDebug::flush();
3720 : 0 : }
3721 : :
3722 : : //===========================================================================
3723 : : //Function Name: draw_point_normals
3724 : : //
3725 : : //Member Type: PRIVATE
3726 : : //Descriptoin: the the normal at the points
3727 : : //===========================================================================
3728 : 0 : void FacetEvalTool::debug_draw_point_normals(int color)
3729 : : {
3730 : : int ii;
3731 [ # # ]: 0 : if ( color == -1 )
3732 : 0 : color = CUBIT_RED_INDEX;
3733 : 0 : double len = 0.1 * sqrt(FacetEvalToolUtils::sqr(myBBox->x_range()) +
3734 : 0 : FacetEvalToolUtils::sqr(myBBox->y_range()) +
3735 : 0 : FacetEvalToolUtils::sqr(myBBox->z_range()));
3736 [ # # ]: 0 : for ( ii = myPointList.size(); ii > 0; ii-- )
3737 : : {
3738 [ # # ]: 0 : CubitPoint *point = myPointList.get_and_step();
3739 [ # # ]: 0 : CubitVector normal = point->normal();
3740 [ # # ][ # # ]: 0 : CubitVector end = point->coordinates() + normal*len;
[ # # ]
3741 [ # # ][ # # ]: 0 : GfxDebug::draw_line(point->x(), point->y(), point->z(),
[ # # ]
3742 [ # # ][ # # ]: 0 : end.x(), end.y(), end.z(), color);
[ # # ][ # # ]
3743 : : }
3744 : 0 : GfxDebug::flush();
3745 : 0 : }
3746 : :
3747 : : //===========================================================================
3748 : : //Function Name: draw_edges
3749 : : //
3750 : : //Member Type: PRIVATE
3751 : : //Descriptoin: draw the facet edges
3752 : : //===========================================================================
3753 : 0 : void FacetEvalTool::debug_draw_edges(int color)
3754 : : {
3755 : : int ii;
3756 [ # # ]: 0 : if ( color == -1 )
3757 : 0 : color = CUBIT_BLUE_INDEX;
3758 [ # # ]: 0 : for ( ii = myEdgeList.size(); ii > 0; ii-- )
3759 : : {
3760 : 0 : CubitFacetEdge *edge = myEdgeList.get_and_step();
3761 : 0 : CubitPoint *begin_point = edge->point(0);
3762 : 0 : CubitPoint *end_point = edge->point(1);
3763 : 0 : GfxDebug::draw_line(begin_point->x(),
3764 : 0 : begin_point->y(),
3765 : 0 : begin_point->z(),
3766 : 0 : end_point->x(),
3767 : 0 : end_point->y(),
3768 : 0 : end_point->z(),
3769 : 0 : color);
3770 : : }
3771 : 0 : GfxDebug::flush();
3772 : 0 : }
3773 : :
3774 : : //===========================================================================
3775 : : //Function Name: draw_edge
3776 : : //
3777 : : //Member Type: PRIVATE
3778 : : //Descriptoin: draw the facet edge
3779 : : //===========================================================================
3780 : 0 : void FacetEvalTool::debug_draw_edge(CubitFacetEdge *edge, int color)
3781 : : {
3782 [ # # ]: 0 : if ( color == -1 ) {
3783 : 0 : color = CUBIT_YELLOW_INDEX;
3784 : : }
3785 : 0 : CubitPoint *begin_point = edge->point(0);
3786 : 0 : CubitPoint *end_point = edge->point(1);
3787 : 0 : GfxDebug::draw_line(begin_point->x(),
3788 : 0 : begin_point->y(),
3789 : 0 : begin_point->z(),
3790 : 0 : end_point->x(),
3791 : 0 : end_point->y(),
3792 : 0 : end_point->z(),
3793 : 0 : color);
3794 : 0 : GfxDebug::flush();
3795 : 0 : }
3796 : :
3797 : : //===========================================================================
3798 : : //Function Name: draw_bezier_edges
3799 : : //
3800 : : //Member Type: PRIVATE
3801 : : //Descriptoin: draw the control polygons from the bezier control points on
3802 : : // the edges
3803 : : //===========================================================================
3804 : 0 : void FacetEvalTool::debug_draw_bezier_edges(int color)
3805 : : {
3806 : : int ii, i;
3807 [ # # ][ # # ]: 0 : CubitVector ctrl_pts[5], begin, end;
[ # # ][ # # ]
3808 [ # # ]: 0 : if ( color == -1 )
3809 : 0 : color = CUBIT_RED_INDEX;
3810 [ # # ][ # # ]: 0 : for ( ii = myEdgeList.size(); ii > 0; ii-- )
3811 : : {
3812 [ # # ]: 0 : CubitFacetEdge *edge = myEdgeList.get_and_step();
3813 [ # # ]: 0 : edge->control_points( ctrl_pts );
3814 [ # # ]: 0 : for (i=1; i<5; i++) {
3815 [ # # ]: 0 : begin = ctrl_pts[i-1];
3816 [ # # ]: 0 : end = ctrl_pts[i];
3817 [ # # ][ # # ]: 0 : GfxDebug::draw_line(begin.x(), begin.y(), begin.z(),
[ # # ]
3818 [ # # ][ # # ]: 0 : end.x(), end.y(), end.z(), color);
[ # # ][ # # ]
3819 : : }
3820 : : }
3821 [ # # ]: 0 : GfxDebug::flush();
3822 : 0 : }
3823 : :
3824 : : //===========================================================================
3825 : : //Function Name: draw_bezier_facets
3826 : : //
3827 : : //Member Type: PRIVATE
3828 : : //Descriptoin: draw the control polygons from the bezier control points on
3829 : : // the facets
3830 : : //===========================================================================
3831 : 0 : void FacetEvalTool::debug_draw_bezier_facets(int color)
3832 : : {
3833 : : int ii;
3834 [ # # ]: 0 : if ( color == -1 )
3835 : 0 : color = CUBIT_WHITE_INDEX;
3836 [ # # ]: 0 : for ( ii = myFacetList.size(); ii > 0; ii-- )
3837 : : {
3838 : 0 : debug_draw_bezier_facet( myFacetList.get_and_step(), color );
3839 : : }
3840 : :
3841 : 0 : }
3842 : :
3843 : : //===========================================================================
3844 : : //Function Name: draw_bezier_facet
3845 : : //
3846 : : //Member Type: PRIVATE
3847 : : //Descriptoin: draw the control polygons from the bezier control points on
3848 : : // a facet
3849 : : //===========================================================================
3850 : 0 : void FacetEvalTool::debug_draw_bezier_facet(CubitFacet *facet, int color)
3851 : : {
3852 : : CubitVector areacoord( 0.3333333333333333333,
3853 : : 0.3333333333333333333,
3854 [ # # ]: 0 : 0.3333333333333333333 );
3855 : :
3856 : : // interpolate internal control points
3857 : :
3858 [ # # ][ # # ]: 0 : CubitVector gctrl_pts[6];
3859 [ # # ]: 0 : facet->get_control_points( gctrl_pts );
3860 [ # # ][ # # ]: 0 : CubitVector P_facet[3];
3861 : :
3862 : : //2,1,1
3863 [ # # ][ # # ]: 0 : P_facet[0] = (1.0e0 / (areacoord.y() + areacoord.z())) *
[ # # ]
3864 [ # # ][ # # ]: 0 : (areacoord.y() * gctrl_pts[3] +
[ # # ]
3865 [ # # ][ # # ]: 0 : areacoord.z() * gctrl_pts[4]);
[ # # ]
3866 : : //1,2,1
3867 [ # # ][ # # ]: 0 : P_facet[1] = (1.0e0 / (areacoord.x() + areacoord.z())) *
[ # # ]
3868 [ # # ][ # # ]: 0 : (areacoord.x() * gctrl_pts[0] +
[ # # ]
3869 [ # # ][ # # ]: 0 : areacoord.z() * gctrl_pts[5]);
[ # # ]
3870 : : //1,1,2
3871 [ # # ][ # # ]: 0 : P_facet[2] = (1.0e0 / (areacoord.x() + areacoord.y())) *
[ # # ]
3872 [ # # ][ # # ]: 0 : (areacoord.x() * gctrl_pts[1] +
[ # # ]
3873 [ # # ][ # # ]: 0 : areacoord.y() * gctrl_pts[2]);
[ # # ]
3874 : :
3875 [ # # ][ # # ]: 0 : CubitVector cp0[5], cp1[5], cp2[5];
[ # # ][ # # ]
[ # # ][ # # ]
3876 : :
3877 [ # # ][ # # ]: 0 : facet->edge(0)->control_points(facet,cp0);
3878 [ # # ][ # # ]: 0 : facet->edge(1)->control_points(facet,cp1);
3879 [ # # ][ # # ]: 0 : facet->edge(2)->control_points(facet,cp2);
3880 : :
3881 : 0 : color = CUBIT_WHITE_INDEX;
3882 [ # # ]: 0 : debug_draw_line(cp0[1], cp2[3], color);
3883 [ # # ]: 0 : debug_draw_line(cp0[2], P_facet[1], color);
3884 [ # # ]: 0 : debug_draw_line(P_facet[1], cp2[2], color);
3885 [ # # ]: 0 : debug_draw_line(cp0[3], P_facet[2], color);
3886 [ # # ]: 0 : debug_draw_line(P_facet[2], P_facet[0], color);
3887 [ # # ]: 0 : debug_draw_line(P_facet[0], cp2[1], color);
3888 : :
3889 : 0 : color = CUBIT_GREEN_INDEX;
3890 [ # # ]: 0 : debug_draw_line(cp1[1], P_facet[2], color);
3891 [ # # ]: 0 : debug_draw_line(P_facet[2], P_facet[1], color);
3892 [ # # ]: 0 : debug_draw_line(P_facet[1], cp2[3], color);
3893 [ # # ]: 0 : debug_draw_line(cp1[2], P_facet[0], color);
3894 [ # # ]: 0 : debug_draw_line(P_facet[0], cp2[2], color);
3895 [ # # ]: 0 : debug_draw_line(cp1[3], cp2[1], color);
3896 : :
3897 : 0 : color = CUBIT_BLUE_INDEX;
3898 [ # # ]: 0 : debug_draw_line(cp0[1], P_facet[1], color);
3899 [ # # ]: 0 : debug_draw_line(P_facet[1], P_facet[0], color);
3900 [ # # ]: 0 : debug_draw_line(P_facet[0], cp1[3], color);
3901 [ # # ]: 0 : debug_draw_line(cp0[2], P_facet[2], color);
3902 [ # # ]: 0 : debug_draw_line(P_facet[2], cp1[2], color);
3903 [ # # ]: 0 : debug_draw_line(cp0[3], cp1[1], color);
3904 : 0 : }
3905 : :
3906 : : //===========================================================================
3907 : : //Function Name: draw_eval_bezier_facet
3908 : : //
3909 : : //Member Type: PRIVATE
3910 : : //Descriptoin: draw points on the evaluated bezier patch
3911 : : //===========================================================================
3912 : 0 : void FacetEvalTool::debug_draw_eval_bezier_facet( CubitFacet *facet )
3913 : : {
3914 [ # # ][ # # ]: 0 : CubitVector areacoord, pt, loc;
[ # # ]
3915 : : double u, v, w;
3916 : : CubitBoolean outside;
3917 : : #if 0
3918 : : for (int i=0; i<=10; i++) {
3919 : : v = w = 0.5 * (double)i/10.0;
3920 : : u = 1.0 - v - w;
3921 : : areacoord.set(u, v, w);
3922 : : eval_facet(facet, pt, areacoord, loc, outside);
3923 : : draw_location(loc);
3924 : : v = 0.25 * (double)i/10.0;
3925 : : w = 0.75 * (double)i/10.0;
3926 : : u = 1.0 - v - w;
3927 : : areacoord.set(u, v, w);
3928 : : eval_facet(facet, pt, areacoord, loc, outside);
3929 : : draw_location(loc);
3930 : : w = 0.25 * (double)i/10.0;
3931 : : v = 0.75 * (double)i/10.0;
3932 : : u = 1.0 - v - w;
3933 : : areacoord.set(u, v, w);
3934 : : eval_facet(facet, pt, areacoord, loc, outside);
3935 : : debug_draw_location(loc);
3936 : : }
3937 : : #endif
3938 [ # # ]: 0 : for (int j=0; j<=10; j++) {
3939 [ # # ]: 0 : for (int i=0; i<=20; i++) {
3940 : 0 : u = ((double)j/10.0) * (double)i/20.0;
3941 : 0 : w = (1.0 - ((double)j/10.0)) * (double)i/20.0;
3942 : 0 : v = 1.0 - u - w;
3943 [ # # ]: 0 : areacoord.set(u, v, w);
3944 [ # # ]: 0 : eval_facet(facet, pt, areacoord, loc, outside);
3945 [ # # ]: 0 : debug_draw_location(loc);
3946 : : }
3947 : : }
3948 : :
3949 : : #if 0
3950 : : for (i=0; i<=10; i++) {
3951 : : u = v = 0.5 * (double)i/10.0;
3952 : : w = 1.0 - u - v;
3953 : : areacoord.set(u, v, w);
3954 : : eval_facet(facet, pt, areacoord, loc, outside);
3955 : : draw_location(loc);
3956 : : u = 0.25 * (double)i/10.0;
3957 : : v = 0.75 * (double)i/10.0;
3958 : : w = 1.0 - u - v;
3959 : : areacoord.set(u, v, w);
3960 : : eval_facet(facet, pt, areacoord, loc, outside);
3961 : : draw_location(loc);
3962 : : v = 0.25 * (double)i/10.0;
3963 : : u = 0.75 * (double)i/10.0;
3964 : : w = 1.0 - u - v;
3965 : : areacoord.set(u, v, w);
3966 : : eval_facet(facet, pt, areacoord, loc, outside);
3967 : : draw_location(loc);
3968 : : }
3969 : : #endif
3970 : :
3971 : 0 : }
3972 : :
3973 : : //===========================================================================
3974 : : //Function Name: draw_line
3975 : : //
3976 : : //Member Type: PRIVATE
3977 : : //===========================================================================
3978 : 0 : void FacetEvalTool::debug_draw_line(CubitVector &begin, CubitVector &end, int color)
3979 : : {
3980 : 0 : GfxDebug::draw_line(begin.x(), begin.y(), begin.z(),
3981 : 0 : end.x(), end.y(), end.z(), color);
3982 : 0 : GfxDebug::flush();
3983 : 0 : }
3984 : :
3985 : : //===========================================================================
3986 : : //Function Name: draw_location
3987 : : //
3988 : : //Member Type: PRIVATE
3989 : : //===========================================================================
3990 : 0 : void FacetEvalTool::debug_draw_location(CubitVector &loc, int color )
3991 : : {
3992 [ # # ]: 0 : if ( color == -1 )
3993 : 0 : color = CUBIT_YELLOW_INDEX;
3994 : 0 : GfxDebug::draw_point(loc, color);
3995 : 0 : GfxDebug::flush();
3996 : 0 : }
3997 : :
3998 : :
3999 : : //===========================================================================
4000 : : //Function Name: write_loops
4001 : : //
4002 : : //Member Type: PRIVATE
4003 : : //===========================================================================
4004 : 0 : void FacetEvalTool::write_loops()
4005 : : {
4006 : : int ii, jj;
4007 [ # # ]: 0 : for (ii=0; ii<myLoopList.size(); ii++)
4008 : : {
4009 : 0 : DLIList<CubitFacetEdge*> *loop = myLoopList.get_and_step();
4010 [ # # ][ # # ]: 0 : PRINT_INFO("======= Loop %d =========\n", ii);
4011 [ # # ]: 0 : for (jj=0; jj<loop->size(); jj++)
4012 : : {
4013 : 0 : CubitFacetEdge *edge = loop->get_and_step();
4014 : 0 : CubitPoint *point0 = edge->point( 0 );
4015 : 0 : CubitPoint *point1 = edge->point( 1 );
4016 [ # # ]: 0 : PRINT_INFO(" (%d) %f, %f, %f (%d) %f, %f, %f\n",
4017 : : point0->id(), point0->x(), point0->y(), point0->z(),
4018 [ # # ]: 0 : point1->id(), point1->x(), point1->y(), point1->z());
4019 : : }
4020 : : }
4021 : 0 : }
4022 : :
4023 : : //===========================================================================
4024 : : //Function Name: transform_control_points
4025 : : //
4026 : : //Member Type: PUBLIC
4027 : : //===========================================================================
4028 : 0 : void FacetEvalTool::transform_control_points( CubitTransformMatrix &tfmat )
4029 : : {
4030 [ # # ]: 0 : if (interpOrder != 4)
4031 : 0 : return;
4032 : :
4033 [ # # ][ # # ]: 0 : CubitVector control_points[6];
4034 : : CubitFacet *facet;
4035 : : int ii, jj;
4036 [ # # ][ # # ]: 0 : for (ii=0; ii<myFacetList.size(); ii++)
4037 : : {
4038 [ # # ]: 0 : facet = myFacetList.get_and_step();
4039 [ # # ]: 0 : facet->get_control_points( control_points );
4040 [ # # ]: 0 : for (jj=0; jj<6; jj++)
4041 : : {
4042 [ # # ][ # # ]: 0 : control_points[jj] = tfmat * control_points[jj];
4043 : : }
4044 [ # # ]: 0 : facet->set_control_points( control_points );
4045 : : }
4046 : :
4047 : : CubitFacetEdge *edge;
4048 [ # # ][ # # ]: 0 : for (ii=0; ii<myEdgeList.size(); ii++)
4049 : : {
4050 [ # # ]: 0 : edge = myEdgeList.get_and_step();
4051 [ # # ][ # # ]: 0 : if (!edge->get_flag())
4052 : : {
4053 [ # # ]: 0 : edge->set_flag(1);
4054 [ # # ]: 0 : edge->control_points( control_points );
4055 : :
4056 : : // assumes the end control points (the vertices) have already
4057 : : // been transformed
4058 : :
4059 [ # # ][ # # ]: 0 : control_points[0] = tfmat * control_points[1];
4060 [ # # ][ # # ]: 0 : control_points[1] = tfmat * control_points[2];
4061 [ # # ][ # # ]: 0 : control_points[2] = tfmat * control_points[3];
4062 [ # # ]: 0 : edge->control_points( control_points, 4 );
4063 : : }
4064 : : }
4065 : : }
4066 : :
4067 : : //===========================================================================
4068 : : //Function Name: area
4069 : : //
4070 : : //Member Type: PUBLIC
4071 : : //===========================================================================
4072 : 341 : double FacetEvalTool::area()
4073 : : {
4074 [ + - ]: 341 : if (myArea < 0.0)
4075 : 341 : calculate_area();
4076 : :
4077 : 341 : return myArea;
4078 : : }
4079 : : //===========================================================================
4080 : : //Function Name: calcualte_area
4081 : : //
4082 : : //Member Type: Public
4083 : : //===========================================================================
4084 : 407 : void FacetEvalTool::calculate_area()
4085 : : {
4086 : 407 : myArea = 0.0;
4087 : : int ii;
4088 : : CubitFacet *facet;
4089 [ + + ]: 1727 : for (ii=0; ii<myFacetList.size(); ii++)
4090 : : {
4091 : 1320 : facet = myFacetList.get_and_step();
4092 : 1320 : myArea += facet->area();
4093 : : }
4094 : 407 : }
4095 : :
4096 : : //===========================================================================
4097 : : //Function Name: parameterize
4098 : : //Description: compute the parameterization of the facetted representation
4099 : : //Member Type: PUBLIC
4100 : : //===========================================================================
4101 : 0 : CubitStatus FacetEvalTool::parameterize()
4102 : : {
4103 : :
4104 [ # # ][ # # ]: 0 : if (myLoopList.size() != 1)
4105 : : {
4106 [ # # ][ # # ]: 0 : PRINT_WARNING("Cannot parameterize surface. Multiple loops detected\n");
[ # # ][ # # ]
4107 : 0 : isParameterized = CUBIT_FALSE;
4108 : 0 : return CUBIT_FAILURE;
4109 : : }
4110 : :
4111 : : // make arrays out of the points and facets
4112 : :
4113 [ # # ][ # # ]: 0 : double *points = new double [3 * myPointList.size()];
[ # # ]
4114 [ # # ][ # # ]: 0 : int *facets = new int [3 * myFacetList.size()];
[ # # ]
4115 [ # # ][ # # ]: 0 : if (!points || !facets)
4116 : : {
4117 [ # # ][ # # ]: 0 : PRINT_ERROR("Could not define parameterization for surface (out of memory)\n");
[ # # ][ # # ]
4118 : 0 : return CUBIT_FAILURE;
4119 : : }
4120 : : int ii;
4121 : : CubitPoint *pt;
4122 [ # # ]: 0 : myPointList.reset();
4123 [ # # ][ # # ]: 0 : for (ii=0; ii<myPointList.size(); ii++)
4124 : : {
4125 [ # # ]: 0 : pt = myPointList.get_and_step();
4126 [ # # ]: 0 : points[ii*3] = pt->x();
4127 [ # # ]: 0 : points[ii*3+1] = pt->y();
4128 [ # # ]: 0 : points[ii*3+2] = pt->z();
4129 [ # # ]: 0 : pt->marked(ii);
4130 : : }
4131 : : CubitFacet *facet;
4132 : : CubitPoint *pts[3];
4133 [ # # ][ # # ]: 0 : for (ii=0; ii<myFacetList.size(); ii++)
4134 : : {
4135 [ # # ]: 0 : facet = myFacetList.get_and_step();
4136 [ # # ]: 0 : facet->points( pts[0], pts[1], pts[2] );
4137 [ # # ]: 0 : facets[ii*3] = pts[0]->marked();
4138 [ # # ]: 0 : facets[ii*3+1] = pts[1]->marked();
4139 [ # # ]: 0 : facets[ii*3+2] = pts[2]->marked();
4140 : : }
4141 : :
4142 : : // do the parameterization
4143 : :
4144 : : // comment out for now
4145 : : // Note to sjowen: this depends on FacetParamTool and facetParamTool is a ParamTool
4146 : : // (which is in geom directory). We ned a solution that breaks that dependency.
4147 : : // FacetParamTool facetparamtool( myPointList.size(), myFacetList.size(),
4148 : : // points, facets );
4149 : : if(1)//!facetparamtool.flatten())
4150 : : {
4151 [ # # ][ # # ]: 0 : PRINT_ERROR("Surface Parameterizer Failed\n");
[ # # ][ # # ]
4152 : 0 : isParameterized = CUBIT_FALSE;
4153 : : }
4154 : : else
4155 : : {
4156 : : double *sizes = NULL;
4157 : : double *uv = NULL;//facetparamtool.get_uvs_sizing( ratio, sizes );
4158 : :
4159 : : // update the points with uv values
4160 : :
4161 : : TDFacetBoundaryPoint *td_fbp;
4162 : : CubitBoolean on_internal_boundary;
4163 : : myPointList.reset();
4164 : : for (ii=0; ii<myPointList.size(); ii++)
4165 : : {
4166 : : pt = myPointList.get_and_step();
4167 : : DLIList <CubitFacet *> facet_list;
4168 : : pt->facets_on_surf( toolID, facet_list, on_internal_boundary );
4169 : : if (on_internal_boundary)
4170 : : {
4171 : : td_fbp = TDFacetBoundaryPoint::get_facet_boundary_point( pt );
4172 : : if (!td_fbp)
4173 : : {
4174 : : TDFacetBoundaryPoint::add_facet_boundary_point( pt );
4175 : : td_fbp = TDFacetBoundaryPoint::get_facet_boundary_point( pt );
4176 : : td_fbp->add_surf_facets( facet_list );
4177 : : td_fbp->set_uv( facet_list.get(), uv[ii*2], uv[ii*2+1] );
4178 : : }
4179 : : else
4180 : : {
4181 : : if (td_fbp->set_uv( facet_list.get(),
4182 : : uv[ii*2], uv[ii*2+1] ) != CUBIT_SUCCESS)
4183 : : {
4184 : : td_fbp->add_surf_facets( facet_list );
4185 : : td_fbp->set_uv( facet_list.get(), uv[ii*2], uv[ii*2+1] );
4186 : : }
4187 : : }
4188 : : }
4189 : : else
4190 : : {
4191 : : pt->set_uv( uv[ii*2], uv[ii*2+1] );
4192 : : }
4193 : : }
4194 : : isParameterized = CUBIT_TRUE;
4195 : : PRINT_INFO("Surface Parameterization succeeded\n");
4196 : : delete [] sizes;
4197 : : delete [] uv;
4198 : : }
4199 : :
4200 : : // clean up
4201 : :
4202 [ # # ]: 0 : delete [] points;
4203 [ # # ]: 0 : delete [] facets;
4204 : 0 : return CUBIT_SUCCESS;
4205 : : }
4206 : :
4207 : : //===========================================================================
4208 : : //Function Name: compute_curve_tangent
4209 : : //
4210 : : //Member Type: PRIVATE
4211 : : //Descriptoin: compute the tangents to the endpoints of a boundary edge.
4212 : : //===========================================================================
4213 : 0 : CubitStatus FacetEvalTool::compute_curve_tangent(
4214 : : CubitFacetEdge *edge,
4215 : : double min_dot,
4216 : : CubitVector &T0,
4217 : : CubitVector &T3 )
4218 : : {
4219 : :
4220 : 0 : CubitPoint *p0 = edge->point( 0 );
4221 : 0 : CubitPoint *p1 = edge->point( 1 );
4222 : 0 : CubitFacetEdge *prev_edge = next_boundary_edge( edge, p0 );
4223 [ # # ]: 0 : if (prev_edge == NULL) // could be end of a hard line
4224 : : {
4225 [ # # ][ # # ]: 0 : T0 = p1->coordinates() - p0->coordinates();
[ # # ]
4226 : 0 : T0.normalize();
4227 : : }
4228 : : else
4229 : : {
4230 [ # # ]: 0 : CubitPoint *p2 = prev_edge->other_point( p0 );
4231 [ # # ][ # # ]: 0 : CubitVector e0 = p0->coordinates() - p2->coordinates();
[ # # ]
4232 [ # # ][ # # ]: 0 : CubitVector e1 = p1->coordinates() - p0->coordinates();
[ # # ]
4233 [ # # ]: 0 : e0.normalize();
4234 [ # # ]: 0 : e1.normalize();
4235 [ # # ][ # # ]: 0 : if (e0 % e1 >= min_dot)
4236 : : {
4237 [ # # ][ # # ]: 0 : T0 = (p0->coordinates() - p2->coordinates()) +
[ # # ][ # # ]
4238 [ # # ][ # # ]: 0 : (p1->coordinates() - p0->coordinates());
[ # # ][ # # ]
4239 [ # # ]: 0 : T0.normalize();
4240 : : }
4241 : : else
4242 : : {
4243 [ # # ]: 0 : T0 = e1;
4244 : : }
4245 : : }
4246 : :
4247 : :
4248 : 0 : CubitFacetEdge *next_edge = next_boundary_edge( edge, p1 );
4249 [ # # ]: 0 : if (next_edge == NULL) // could be end of a hard line
4250 : : {
4251 [ # # ][ # # ]: 0 : T3 = p1->coordinates() - p0->coordinates();
[ # # ]
4252 : 0 : T3.normalize();
4253 : : }
4254 : : else
4255 : : {
4256 [ # # ]: 0 : CubitPoint *p2 = next_edge->other_point( p1 );
4257 [ # # ][ # # ]: 0 : CubitVector e0 = p2->coordinates() - p1->coordinates();
[ # # ]
4258 [ # # ][ # # ]: 0 : CubitVector e1 = p1->coordinates() - p0->coordinates();
[ # # ]
4259 [ # # ]: 0 : e0.normalize();
4260 [ # # ]: 0 : e1.normalize();
4261 [ # # ][ # # ]: 0 : if (e0 % e1 >= min_dot)
4262 : : {
4263 [ # # ][ # # ]: 0 : T3 = (p2->coordinates() - p1->coordinates()) +
[ # # ][ # # ]
4264 [ # # ][ # # ]: 0 : (p1->coordinates() - p0->coordinates());
[ # # ][ # # ]
4265 [ # # ]: 0 : T3.normalize();
4266 : : }
4267 : : else
4268 : : {
4269 [ # # ]: 0 : T3 = e1;
4270 : : }
4271 : : }
4272 : :
4273 : 0 : return CUBIT_SUCCESS;
4274 : : }
4275 : :
4276 : :
4277 : : //===========================================================================
4278 : : //Function Name: next_boundary_edge
4279 : : //
4280 : : //Member Type: PRIVATE
4281 : : //Descriptoin: given a facet boundary edge and one of its nodes, find the
4282 : : // next edge on the same surface
4283 : : //===========================================================================
4284 : 0 : CubitFacetEdge *FacetEvalTool::next_boundary_edge(
4285 : : CubitFacetEdge *this_edge,
4286 : : CubitPoint *p0 )
4287 : : {
4288 : 0 : CubitFacetEdge *next_edge = NULL;
4289 : :
4290 [ # # ]: 0 : DLIList<CubitFacetEdge*> edge_list;
4291 [ # # ]: 0 : p0->edges( edge_list );
4292 : : int ii;
4293 : :
4294 : 0 : CubitFacetEdge *edge_ptr = NULL;
4295 [ # # ][ # # ]: 0 : for (ii=0; ii<edge_list.size() && next_edge == NULL; ii++)
[ # # ][ # # ]
4296 : : {
4297 [ # # ]: 0 : edge_ptr = edge_list.get_and_step();
4298 [ # # ]: 0 : if (edge_ptr != this_edge)
4299 : : {
4300 [ # # ][ # # ]: 0 : if (edge_ptr->num_adj_facets() <= 1)
4301 : : {
4302 : 0 : next_edge = edge_ptr;
4303 : : }
4304 : : }
4305 : : }
4306 : :
4307 [ # # ]: 0 : return next_edge;
4308 : : }
4309 : :
4310 : : //===========================================================================
4311 : : //Function Name: save
4312 : : //
4313 : : //Member Type: PRIVATE
4314 : : //Description: save the facet eval tool to a cubit file
4315 : : // Assumption: contained facets have been previuosly saved. This function
4316 : : // saves only the facet ids.
4317 : : //===========================================================================
4318 : 275 : CubitStatus FacetEvalTool::save(
4319 : : FILE *fp )
4320 : : {
4321 [ + - ]: 275 : NCubitFile::CIOWrapper cio(fp);
4322 : : typedef NCubitFile::UnsignedInt32 int32;
4323 : :
4324 [ + - ]: 275 : cio.Write(reinterpret_cast<int32*>(&interpOrder), 1);
4325 [ + - ]: 275 : cio.Write(reinterpret_cast<int32*>(&isFlat), 1);
4326 [ - + ]: 275 : int32 is_param = isParameterized ? 1 : 0;
4327 [ + - ]: 275 : cio.Write(&is_param, 1);
4328 : :
4329 [ + - ]: 275 : cio.Write(&myArea, 1);
4330 [ + - ]: 275 : cio.Write(&minDot, 1);
4331 : :
4332 : : // write ids of facets that belong to this tool
4333 : : int32 ii;
4334 : : CubitFacet *facet_ptr;
4335 [ + - ]: 275 : int32 nfacets = myFacetList.size();
4336 [ + - ][ + - ]: 275 : int32* facet_id = new int32 [nfacets];
4337 [ + - ]: 275 : myFacetList.reset();
4338 [ + + ]: 1067 : for (ii=0; ii<nfacets; ii++)
4339 : : {
4340 [ + - ]: 792 : facet_ptr = myFacetList.get_and_step();
4341 [ + - ]: 792 : facet_id[ii] = facet_ptr->id();
4342 : : }
4343 [ + - ]: 275 : cio.Write(&nfacets, 1);
4344 [ + - ]: 275 : if (nfacets > 0)
4345 : : {
4346 [ + - ]: 275 : cio.Write(facet_id, nfacets);
4347 : : }
4348 [ + - ]: 275 : delete [] facet_id;
4349 : :
4350 : : // write ids of edges that belong to this tool
4351 : : CubitFacetEdge *edge_ptr;
4352 [ + - ]: 275 : int32 nedges = myEdgeList.size();
4353 [ + - ][ + - ]: 275 : int32* edge_id = new int32 [nedges];
4354 [ + - ]: 275 : myEdgeList.reset();
4355 [ + + ]: 1969 : for (ii=0; ii<nedges; ii++)
4356 : : {
4357 [ + - ]: 1694 : edge_ptr = myEdgeList.get_and_step();
4358 [ + - ]: 1694 : edge_id[ii] = edge_ptr->id();
4359 : : //volatile int test_int = edge_id[ii] + 1; // this is a test line to look for uninitialized data rjm
4360 : : }
4361 [ + - ]: 275 : cio.Write( &nedges, 1);
4362 [ + - ]: 275 : if (nedges > 0)
4363 : : {
4364 [ + - ]: 275 : cio.Write(edge_id, nedges);
4365 : : }
4366 [ + - ]: 275 : delete [] edge_id;
4367 : :
4368 : : // write ids of points that belong to this tool
4369 : : CubitPoint *point_ptr;
4370 [ + - ]: 275 : int32 npoints = myPointList.size();
4371 [ + - ][ + - ]: 275 : int32* point_id = new int32 [npoints];
4372 [ + - ]: 275 : myPointList.reset();
4373 [ + + ]: 1463 : for (ii=0; ii<npoints; ii++)
4374 : : {
4375 [ + - ]: 1188 : point_ptr = myPointList.get_and_step();
4376 [ + - ]: 1188 : point_id[ii] = point_ptr->id();
4377 : : }
4378 [ + - ]: 275 : cio.Write(&npoints, 1);
4379 [ + - ]: 275 : if (npoints > 0)
4380 : : {
4381 [ + - ]: 275 : cio.Write(point_id, npoints);
4382 : : }
4383 [ + - ]: 275 : delete [] point_id;
4384 : :
4385 [ + - ]: 275 : return CUBIT_SUCCESS;
4386 : : }
4387 : :
4388 : : //===========================================================================
4389 : : //Function Name: restore
4390 : : //
4391 : : //Member Type: PRIVATE
4392 : : //Description: restore a facetevaltool from a CUB file
4393 : : //===========================================================================
4394 : 132 : CubitStatus FacetEvalTool::restore(
4395 : : FILE *fp,
4396 : : unsigned int endian,
4397 : : int num_facets,
4398 : : int num_edges,
4399 : : int num_points,
4400 : : CubitFacet **facets,
4401 : : CubitFacetEdge **edges,
4402 : : CubitPoint **points )
4403 : : {
4404 [ + - ]: 132 : NCubitFile::CIOWrapper cio(endian, fp);
4405 : : typedef NCubitFile::UnsignedInt32 int32;
4406 : :
4407 : : // read interpOrder, isFlat, isParameterized
4408 : : int int_data[3];
4409 [ + - ]: 132 : cio.Read(reinterpret_cast<int32*>(int_data), 3);
4410 : 132 : interpOrder = int_data[0];
4411 : 132 : isFlat = int_data[1];
4412 : 132 : isParameterized = (int_data[2] != 0);
4413 : :
4414 : : // read myArea, minDot
4415 : : double double_data[2];
4416 [ + - ]: 132 : cio.Read( double_data, 2);
4417 : 132 : myArea = double_data[0];
4418 : 132 : minDot = double_data[1];
4419 : :
4420 : 132 : lastFacet = NULL;
4421 : :
4422 : : // read the facet ids and assign facets to this eval tool
4423 : : int nfacets;
4424 [ + - ]: 132 : cio.Read(reinterpret_cast<int32*>(&nfacets), 1);
4425 : 132 : int32 *facet_id = NULL;
4426 [ + - ]: 132 : if (nfacets > 0)
4427 : : {
4428 [ + - ][ + - ]: 132 : facet_id = new int32 [nfacets];
4429 [ + - ]: 132 : cio.Read(facet_id, nfacets);
4430 : : int ii, id;
4431 [ + + ]: 660 : for(ii=0; ii<nfacets; ii++)
4432 : : {
4433 : 528 : id = facet_id[ii];
4434 [ + - ][ - + ]: 528 : if (ii < 0 || ii >= num_facets)
4435 : : {
4436 [ # # ]: 0 : delete [] facet_id;
4437 : 0 : return CUBIT_FAILURE;
4438 : : }
4439 [ + - ]: 528 : myFacetList.append( facets[id] );
4440 [ + - ]: 528 : facets[id]->set_tool_id( toolID );
4441 : : }
4442 [ + - ]: 132 : delete [] facet_id;
4443 : : }
4444 : :
4445 : : // read the edges
4446 : : int nedges;
4447 [ + - ]: 132 : cio.Read(reinterpret_cast<int32*>(&nedges), 1);
4448 : 132 : int32 *edge_id = NULL;
4449 [ + - ]: 132 : if (nedges > 0)
4450 : : {
4451 [ + - ][ + - ]: 132 : edge_id = new int32 [nedges];
4452 [ + - ]: 132 : cio.Read(edge_id, nedges);
4453 : : int ii, id;
4454 [ + + ]: 1188 : for(ii=0; ii<nedges; ii++)
4455 : : {
4456 : 1056 : id = edge_id[ii];
4457 [ + - ][ - + ]: 1056 : if (ii < 0 || ii >= num_edges)
4458 : : {
4459 [ # # ]: 0 : delete [] edge_id;
4460 : 0 : return CUBIT_FAILURE;
4461 : : }
4462 [ + - ]: 1056 : myEdgeList.append( edges[id] );
4463 : : }
4464 [ + - ]: 132 : delete [] edge_id;
4465 : : }
4466 : :
4467 : : // read the points
4468 : : int npoints;
4469 [ + - ]: 132 : cio.Read(reinterpret_cast<int32*>(&npoints), 1);
4470 : 132 : int32 *point_id = NULL;
4471 [ + - ]: 132 : if (npoints > 0)
4472 : : {
4473 [ + - ][ + - ]: 132 : point_id = new int32 [npoints];
4474 [ + - ]: 132 : cio.Read(point_id, npoints);
4475 : : int ii, id;
4476 [ + + ]: 792 : for(ii=0; ii<npoints; ii++)
4477 : : {
4478 : 660 : id = point_id[ii];
4479 [ + - ][ - + ]: 660 : if (ii < 0 || ii >= num_points)
4480 : : {
4481 [ # # ]: 0 : delete [] point_id;
4482 : 0 : return CUBIT_FAILURE;
4483 : : }
4484 [ + - ]: 660 : myPointList.append( points[id] );
4485 : : }
4486 [ + - ]: 132 : delete [] point_id;
4487 : : }
4488 : :
4489 [ + - ][ + - ]: 132 : bounding_box();
4490 [ + - ][ + - ]: 132 : double diag = sqrt(FacetEvalToolUtils::sqr(myBBox->x_range()) +
4491 [ + - ][ + - ]: 132 : FacetEvalToolUtils::sqr(myBBox->y_range()) +
4492 [ + - ][ + - ]: 132 : FacetEvalToolUtils::sqr(myBBox->z_range()));
4493 : 132 : compareTol = 1.0e-3 * diag;
4494 : :
4495 [ + - ]: 132 : return CUBIT_SUCCESS;
4496 : : }
4497 : :
4498 : 0 : CubitStatus FacetEvalTool::get_intersections(CubitVector point1,
4499 : : CubitVector point2,
4500 : : DLIList<CubitVector*>& intersection_list,
4501 : : bool bounded)
4502 : : {
4503 : : //Find the points were the line intersects the bounding box.
4504 [ # # ]: 0 : CubitVector intersect_1;
4505 [ # # ]: 0 : CubitVector intersect_2;
4506 [ # # ]: 0 : CubitBox bbox = *myBBox;
4507 : :
4508 : : //Increase the size of the box in each direction.
4509 : : //Don't use scale because the box may be too thin (planar surface).
4510 [ # # ][ # # ]: 0 : double offset = 2.0 * (point1 - point2).length();
4511 : :
4512 [ # # ]: 0 : CubitVector min;
4513 [ # # ][ # # ]: 0 : min.x( bbox.min_x() - offset );
4514 [ # # ][ # # ]: 0 : min.y( bbox.min_y() - offset );
4515 [ # # ][ # # ]: 0 : min.z( bbox.min_z() - offset );
4516 [ # # ]: 0 : CubitVector max;
4517 [ # # ][ # # ]: 0 : max.x( bbox.max_x() + offset );
4518 [ # # ][ # # ]: 0 : max.y( bbox.max_y() + offset );
4519 [ # # ][ # # ]: 0 : max.z( bbox.max_z() + offset );
4520 : :
4521 [ # # ]: 0 : bbox.reset( min, max );
4522 : : int box_intersections = FacetDataUtil::get_bbox_intersections( point1, point2, bbox,
4523 [ # # ]: 0 : intersect_1, intersect_2 );
4524 : :
4525 : : //The bounding box is larger than the surface we are checking.
4526 : : //This means that if there are less than two intersections
4527 : : //the line will not intersect the surface.
4528 [ # # ]: 0 : if( 2 > box_intersections )
4529 : 0 : return CUBIT_SUCCESS;
4530 : :
4531 [ # # ]: 0 : bbox.reset( intersect_1 );
4532 [ # # ]: 0 : bbox |= intersect_2;
4533 : :
4534 : : //Find the facets that are intersected by the bbox that was just created.
4535 [ # # ][ # # ]: 0 : DLIList<CubitFacet*> search_facets;
4536 [ # # ]: 0 : if( aTree )
4537 : : {
4538 : : //Get the facets from the tree.
4539 [ # # ]: 0 : aTree->find( bbox, search_facets );
4540 : : }
4541 : : else
4542 [ # # ]: 0 : search_facets = myFacetList;
4543 : :
4544 : : int ii;
4545 [ # # ][ # # ]: 0 : for( ii = search_facets.size(); ii > 0; ii-- )
4546 : : {
4547 [ # # ]: 0 : CubitFacet* test_facet = search_facets.get_and_step();
4548 : :
4549 [ # # ]: 0 : CubitVector intersection;
4550 [ # # ]: 0 : CubitVector area_coord;
4551 : : CubitPointContainment contain = FacetDataUtil::intersect_facet( intersect_1, intersect_2, test_facet,
4552 [ # # ]: 0 : intersection, area_coord );
4553 : :
4554 [ # # ]: 0 : if( bounded )
4555 : : {
4556 [ # # ]: 0 : CubitVector dir1 = point2 - point1;
4557 [ # # ]: 0 : CubitVector dir2 = intersection - point1;
4558 : :
4559 [ # # ][ # # ]: 0 : if( dir2.length_squared() > (GEOMETRY_RESABS * GEOMETRY_RESABS) )
4560 : : {
4561 [ # # ][ # # ]: 0 : if( dir1 % dir2 < 0 ||
[ # # ][ # # ]
4562 [ # # ][ # # ]: 0 : ( ( dir2.length_squared() - dir1.length_squared() ) >
4563 : : ( GEOMETRY_RESABS * GEOMETRY_RESABS ) ) )
4564 : : {
4565 : : //The inserction point is not between the two end points.
4566 : 0 : contain = CUBIT_PNT_OUTSIDE;
4567 : : }
4568 : : }
4569 : : }
4570 : :
4571 [ # # ][ # # ]: 0 : if( CUBIT_PNT_BOUNDARY == contain ||
4572 : : CUBIT_PNT_INSIDE == contain )
4573 : : {
4574 : : //The point intersects the facets.
4575 [ # # ][ # # ]: 0 : CubitVector* new_intersection = new CubitVector;
4576 [ # # ]: 0 : *new_intersection = intersection;
4577 [ # # ]: 0 : intersection_list.append( new_intersection );
4578 : : }
4579 : : }
4580 : :
4581 : : //Remove duplicate intersections.
4582 [ # # ]: 0 : intersection_list.reset();
4583 [ # # ][ # # ]: 0 : for( ii = 0; ii < intersection_list.size(); ii++ )
4584 : : {
4585 [ # # ]: 0 : CubitVector* base_vec = intersection_list.next(ii);
4586 [ # # ]: 0 : if( NULL == base_vec )
4587 : 0 : continue;
4588 : :
4589 : : int jj;
4590 [ # # ][ # # ]: 0 : for( jj = ii+1; jj < intersection_list.size(); jj++ )
4591 : : {
4592 [ # # ]: 0 : CubitVector* compare_vec = intersection_list.next(jj);
4593 [ # # ]: 0 : if( NULL != compare_vec )
4594 : : {
4595 [ # # ][ # # ]: 0 : if( base_vec->distance_between_squared( *compare_vec ) < GEOMETRY_RESABS * GEOMETRY_RESABS )
4596 : : {
4597 [ # # ]: 0 : intersection_list.step(jj);
4598 [ # # ]: 0 : delete intersection_list.get();
4599 [ # # ]: 0 : intersection_list.change_to( NULL );
4600 [ # # ]: 0 : intersection_list.reset();
4601 : : }
4602 : : }
4603 : : }
4604 : : }
4605 [ # # ]: 0 : intersection_list.remove_all_with_value( NULL );
4606 : :
4607 [ # # ]: 0 : return CUBIT_SUCCESS;
4608 : : }
4609 : :
4610 : 0 : int FacetEvalTool::intersect_ray( CubitVector &origin, CubitVector &direction, CubitFacet* facet, CubitVector* point, double &distance )
4611 : : {
4612 : : // This algorithm can be found at http://geometryalgorithms.com/
4613 : :
4614 [ # # ]: 0 : CubitVector n; // triangle vectors
4615 [ # # ][ # # ]: 0 : CubitVector w0, w; // ray vectors
4616 : : double a, b; // params to calc ray-plane intersect
4617 : :
4618 : : // get triangle edge vectors and plane normal
4619 : : //CubitVector normal = facet->normal();
4620 [ # # ]: 0 : CubitPoint *pt0 = facet->point(0);
4621 [ # # ]: 0 : CubitPoint *pt1 = facet->point(1);
4622 [ # # ]: 0 : CubitPoint *pt2 = facet->point(2);
4623 : 0 : double tol = GEOMETRY_RESABS;
4624 : :
4625 [ # # ][ # # ]: 0 : CubitVector u( pt1->x() - pt0->x(),
4626 [ # # ][ # # ]: 0 : pt1->y() - pt0->y(),
4627 [ # # ][ # # ]: 0 : pt1->z() - pt0->z()); //(*p1-*p0);
[ # # ]
4628 [ # # ][ # # ]: 0 : CubitVector v( pt2->x() - pt0->x(),
4629 [ # # ][ # # ]: 0 : pt2->y() - pt0->y(),
4630 [ # # ][ # # ]: 0 : pt2->z() - pt0->z()); // = (*p2-*p0);
[ # # ]
4631 : :
4632 : : //u = T.V1 - T.V0;
4633 : : //v = T.V2 - T.V0;
4634 [ # # ][ # # ]: 0 : n = u * v; // cross product
4635 [ # # ][ # # ]: 0 : if (n.length_squared() == 0) // triangle is degenerate
4636 : 0 : return -1; // do not deal with this case
4637 : :
4638 : : //dir = R.P1 - R.P0; // ray direction vector
4639 : : //w0 = R.P0 - T.V0;
4640 [ # # ][ # # ]: 0 : w0 = CubitVector(origin.x() - pt0->x(),
[ # # ]
4641 [ # # ][ # # ]: 0 : origin.y() - pt0->y(),
4642 [ # # ][ # # ]: 0 : origin.z() - pt0->z());
[ # # ]
4643 : :
4644 [ # # ]: 0 : a = -(n%w0);
4645 [ # # ]: 0 : b = (n%direction);
4646 [ # # ]: 0 : if (fabs(b) < tol) { // ray is parallel to triangle plane
4647 [ # # ]: 0 : if (a == 0) // ray lies in triangle plane
4648 : 0 : return 2;
4649 : 0 : else return 0; // ray disjoint from plane
4650 : : }
4651 : :
4652 : : // get intersect point of ray with triangle plane
4653 : 0 : distance = a / b;
4654 [ # # ]: 0 : if (distance < 0.0) // ray goes away from triangle
4655 : 0 : return 0; // => no intersect
4656 : : // for a segment, also test if (r > 1.0) => no intersect
4657 : :
4658 [ # # ][ # # ]: 0 : point->set(origin + distance * direction); // intersect point of ray and plane
[ # # ]
4659 : :
4660 : : // the distance we want to return is real distance, not distance/magnitude
4661 [ # # ]: 0 : distance *= direction.length();
4662 : :
4663 : : // is point inside facet?
4664 : : double uu, uv, vv, wu, wv, D;
4665 [ # # ]: 0 : uu = u%u;
4666 [ # # ]: 0 : uv = u%v;
4667 [ # # ]: 0 : vv = v%v;
4668 : : //w = *I - T.V0;
4669 [ # # ][ # # ]: 0 : w = CubitVector(point->x() - pt0->x(),
[ # # ]
4670 [ # # ][ # # ]: 0 : point->y() - pt0->y(),
4671 [ # # ][ # # ]: 0 : point->z() - pt0->z());
[ # # ]
4672 [ # # ]: 0 : wu = w%u;
4673 [ # # ]: 0 : wv = w%v;
4674 : 0 : D = uv * uv - uu * vv;
4675 : :
4676 : : // get and test parametric coords
4677 : : double s, t;
4678 : 0 : s = (uv * wv - vv * wu) / D;
4679 [ # # ][ # # ]: 0 : if (s < 0.0 || s > 1.0) // point is outside facet
4680 : 0 : return 0;
4681 : 0 : t = (uv * wu - uu * wv) / D;
4682 [ # # ][ # # ]: 0 : if (t < 0.0 || (s + t) > 1.0) // point is outside facet
4683 : 0 : return 0;
4684 : :
4685 : 0 : return 1; // point is in facet
4686 : :
4687 : : }
4688 : :
4689 : 0 : int FacetEvalTool::intersect_ray( CubitVector &origin, CubitVector &direction, CubitFacetEdge* facet_edge, CubitVector* point, double &hit_distance )
4690 : : {
4691 : : // This algorithm can be found at http://geometryalgorithms.com/
4692 : 0 : double tol = GEOMETRY_RESABS;
4693 : :
4694 [ # # ]: 0 : CubitPoint* p0 = facet_edge->point(0);
4695 [ # # ]: 0 : CubitPoint* p1 = facet_edge->point(1);
4696 [ # # ][ # # ]: 0 : CubitVector u0 = CubitVector(p0->x(), p0->y(), p0->z());
[ # # ][ # # ]
4697 [ # # ][ # # ]: 0 : CubitVector u1 = CubitVector(p1->x(), p1->y(), p1->z());
[ # # ][ # # ]
4698 : :
4699 [ # # ]: 0 : CubitVector u = CubitVector(u0, u1);
4700 [ # # ]: 0 : CubitVector v = direction;
4701 [ # # ]: 0 : v.normalize();
4702 : :
4703 [ # # ]: 0 : CubitVector w = CubitVector(origin, u0);
4704 : :
4705 : : double sc, tc; // sc is fraction along facet edge, tc is distance along ray
4706 : :
4707 [ # # ]: 0 : double a = u%u; // always >= 0
4708 [ # # ]: 0 : double b = u%v;
4709 [ # # ]: 0 : double c = v%v; // always >= 0
4710 [ # # ]: 0 : double d = u%w;
4711 [ # # ]: 0 : double e = v%w;
4712 : 0 : double D = a*c - b*b; // always >= 0
4713 : :
4714 : : // compute the line parameters of the two closest points
4715 [ # # ]: 0 : if (D < tol)
4716 : : {
4717 : : // the lines are almost parallel
4718 : 0 : sc = 0.0;
4719 [ # # ]: 0 : tc = (b>c ? d/b : e/c); // use the largest denominator
4720 : : }
4721 : : else
4722 : : {
4723 : 0 : sc = (b*e - c*d) / D;
4724 : 0 : tc = (a*e - b*d) / D;
4725 : : }
4726 : :
4727 : : // get the difference of the two closest points
4728 [ # # ][ # # ]: 0 : CubitVector dP = CubitVector(w + (sc * u) - (tc * v)); // = <0 0 0> if intersection
[ # # ][ # # ]
4729 : :
4730 [ # # ]: 0 : double distance = sqrt(dP % dP); // return the closest distance (0 if intersection)
4731 : :
4732 [ # # ][ # # ]: 0 : point->set(u0 + (sc * u));
[ # # ]
4733 : 0 : hit_distance = tc; //distance from origin to intersection point
4734 : :
4735 [ # # ]: 0 : if (distance < tol)
4736 : : {
4737 : : //check if parallel (infinite intersection)
4738 [ # # ]: 0 : if (D < tol)
4739 : 0 : return 2;
4740 : : //check if on edge
4741 [ # # ][ # # ]: 0 : if (sc <= 1.0 && sc >= 0.0)
4742 : 0 : return 1;
4743 : : else
4744 : 0 : return 0;
4745 : : }
4746 : :
4747 : 0 : return 0;
4748 : : }
4749 : :
4750 : 11 : double FacetEvalTool::contained_volume( DLIList<CubitFacet *> &facets )
4751 : : {
4752 [ + - ][ + - ]: 11 : CubitVector p0, p1, p2, p3, normal;
[ + - ][ + - ]
[ + - ]
4753 : 11 : double volume = 0.0;
4754 : :
4755 [ + - ]: 11 : facets.reset();
4756 [ + - ][ + + ]: 143 : for (int i = facets.size(); i--; )
4757 : : {
4758 [ + - ]: 132 : CubitFacet* facet = facets.get_and_step();
4759 [ + - ][ + - ]: 132 : p1 = facet->point(0)->coordinates();
[ + - ]
4760 [ + - ][ + - ]: 132 : p2 = facet->point(1)->coordinates();
[ + - ]
4761 [ + - ][ + - ]: 132 : p3 = facet->point(2)->coordinates();
[ + - ]
4762 [ + - ][ + - ]: 132 : normal = (p3 - p1) * (p2 - p1);
[ + - ][ + - ]
4763 : :
4764 [ + - ]: 132 : double two_area = normal.length();
4765 [ + - ]: 132 : if (two_area > CUBIT_RESABS )
4766 : : {
4767 [ + - ]: 132 : normal /= two_area;
4768 : :
4769 [ + - ][ + - ]: 132 : double height = normal % (p0 - p1);
4770 : 132 : double vol = two_area * height;
4771 : 132 : volume += vol;
4772 : : }
4773 : : }
4774 : :
4775 : 11 : volume /= 6.0;
4776 : 11 : return volume;
4777 [ + - ][ + - ]: 6540 : }
4778 : :
|