Branch data Line data Source code
1 : : #include <map>
2 : : #include "CubitOctreeNode.hpp"
3 : : #include "CubitOctreeCell.hpp"
4 : : #include "CubitOctree.hpp"
5 : : #include "RefFace.hpp"
6 : : #include "CubitOctreeConstants.hpp"
7 : : #include "CubitFacet.hpp"
8 : : #include "CubitPoint.hpp"
9 : : #include "GfxDebug.hpp"
10 : : #include "PriorityQueue.hpp"
11 : : #include "CubitOctreeGenerator.hpp"
12 : : #include "GMem.hpp"
13 : : #include "RTree.hpp"
14 : : #include "RefEdge.hpp"
15 : : #include "GeometryQueryTool.hpp"
16 : : #include "DLIList.hpp"
17 : : #include "RefFace.hpp"
18 : : #include "GeomMeasureTool.hpp"
19 : : #include "OctreeIntersectionData.hpp"
20 : :
21 : :
22 : : //#include "SVDrawTool.hpp"
23 : :
24 : : int CubitOctreeNode::mCounter = -1;
25 : :
26 : 0 : int sort_by_size( CubitOctreeNode * &node1, CubitOctreeNode *&node2 )
27 : : {
28 [ # # ]: 0 : if (node1->get_size(OCTREE_SIZE_DEFAULT) <= node2->get_size(OCTREE_SIZE_DEFAULT)) {return -1;}
29 : 0 : else {return 1;}
30 : : }
31 : :
32 : :
33 : : /* --------------- Methods of CubitOctreeNode ------------- */
34 [ # # ][ # # ]: 0 : CubitOctreeNode::CubitOctreeNode( const CubitVector &cen, CubitOctreeCell *parent_cell, const int x_index, const int y_index, const int z_index )
35 : : {
36 [ # # ][ # # ]: 0 : initialize_constructor( cen.x(), cen.y(), cen.z() );
[ # # ][ # # ]
37 : 0 : adjCell[x_index][y_index][z_index] = parent_cell;
38 : 0 : }
39 : :
40 [ # # ][ # # ]: 0 : CubitOctreeNode::CubitOctreeNode( const double &x, const double &y, const double &z )
41 : : {
42 [ # # ]: 0 : initialize_constructor( x, y, z );
43 : 0 : }
44 : :
45 : 0 : CubitOctreeNode::~CubitOctreeNode(void)
46 : : {
47 : : int i;
48 : : OctreeIntersectionData *idata;
49 : :
50 [ # # ][ # # ]: 0 : for (i=0; i < octreeIntersectionDataList.size(); ++i)
51 : : {
52 [ # # ]: 0 : idata = octreeIntersectionDataList.get_and_step();
53 [ # # ]: 0 : if (idata != NULL)
54 : : {
55 [ # # ][ # # ]: 0 : delete idata;
56 : : }
57 : : }
58 : :
59 [ # # ]: 0 : octreeIntersectionDataList.clean_out();
60 : 0 : }
61 : :
62 : : /// in CubitOctree outside nodes are GREY, inside nodes are BLACK. And boundary nodes are WHITE.
63 : 0 : void CubitOctreeNode::initialize_constructor( const double &x, const double &y, const double &z ){
64 : :
65 : :
66 : : int i, j, k;
67 : 0 : color = CUBIT_GREY_INDEX; // boundary nodes are colored white and inside nodes black
68 : : // during facet intersection the white nodes dominates black
69 : 0 : visit = CUBIT_FALSE; // mat generation
70 : 0 : mark = CUBIT_FALSE;
71 : :
72 : 0 : halfspaceDirection = OCTREE_NEGATIVE;
73 : 0 : num = get_counter();
74 : :
75 : 0 : size = 0.0;
76 : :
77 : 0 : distance = CUBIT_DBL_MAX;
78 : :
79 : 0 : cellDepthDifference = 0;
80 : 0 : minDepthCell = NULL;
81 : :
82 : 0 : mNormal.x(0.0);
83 : 0 : mNormal.y(0.0);
84 : 0 : mNormal.z(0.0);
85 : :
86 : 0 : coord.x(x);
87 : 0 : coord.y(y);
88 : 0 : coord.z(z);
89 : :
90 [ # # ]: 0 : for( i = 0; i < 2; i++ ){
91 [ # # ]: 0 : for( j = 0; j < 2; j++ ){
92 [ # # ]: 0 : for( k = 0; k < 2; k++ ){
93 : 0 : adjCell[i][j][k] = NULL;
94 : : }
95 : : }
96 : : }
97 : :
98 : : // LRBTFN
99 [ # # ]: 0 : for( i = 0; i < 6; i++ ){
100 : 0 : adjGridNode[i] = NULL;
101 : 0 : adjNodeDistance[i] = -1; // ?
102 : : }
103 : :
104 : 0 : refFace = NULL;
105 : 0 : }
106 : :
107 : 0 : int CubitOctreeNode::get_counter()
108 : : {
109 : : //static int counter = -1;
110 : 0 : mCounter++;
111 : 0 : return(mCounter);
112 : : }
113 : :
114 : 0 : void CubitOctreeNode::display( OctreeNodeConstant type, float draw_size )
115 : : {
116 [ # # # # : 0 : switch( type ){
# ]
117 : : case NODE_SIZE:
118 [ # # ]: 0 : if (draw_size < 0)
119 : : {
120 : 0 : draw_size = size;
121 : : }
122 : : //SkeletonDebug::draw_point( coord, draw_size );
123 : 0 : break;
124 : :
125 : : case NODE_DISTANCE:
126 : 0 : if( color == CUBIT_BLACK_INDEX ){
127 : : //SkeletonDebug::draw_point( coord, (float)draw_size ) ;
128 : : }
129 : 0 : break;
130 : :
131 : : case NODE_FACE_NUM:
132 [ # # ]: 0 : if( refFace != NULL ){
133 : : //SkeletonDebug::draw_point( coord, (float)(( refFace->id() % 18) * 0.5) );
134 : : }
135 : : else{
136 [ # # ][ # # ]: 0 : PRINT_INFO("ERROR: Face Ptr Doesn't Exist in White Grid Node \n");
137 : : }
138 : 0 : break;
139 : :
140 : : case NODE_NORMAL:
141 : 0 : if( color == CUBIT_BLACK_INDEX ){
142 : : //SkeletonDebug::draw_line(coord, draw_size, coord+mNormal,draw_size);
143 : :
144 : : }
145 : 0 : break;
146 : :
147 : :
148 : :
149 : : default:
150 : : //SkeletonDebug::draw_point( coord, 1 );
151 : 0 : break;
152 : : }
153 : 0 : }
154 : :
155 : :
156 : :
157 : 0 : double CubitOctreeNode::get_size( OctreeSourceEntityType type ) const
158 : : {
159 : 0 : return size;
160 : :
161 : : }
162 : :
163 : 0 : void CubitOctreeNode::set_size( double s, int type ){
164 : :
165 : 0 : size = s;
166 : 0 : }
167 : :
168 : :
169 : 0 : CubitOctreeNode* CubitOctreeNode::get_adj_node(int select)
170 : : {
171 [ # # # # : 0 : switch (select)
# # # ]
172 : : {
173 : : case O_LEFT:
174 : 0 : return adjGridNode[O_LEFT];
175 : :
176 : : case O_RIGHT:
177 : 0 : return adjGridNode[O_RIGHT];
178 : :
179 : : case O_BOTTOM:
180 : 0 : return adjGridNode[O_BOTTOM];
181 : :
182 : : case O_TOP:
183 : 0 : return adjGridNode[O_TOP];
184 : :
185 : : case O_BACK:
186 : 0 : return adjGridNode[O_BACK];
187 : :
188 : : case O_FRONT:
189 : 0 : return adjGridNode[O_FRONT];
190 : :
191 : : default:
192 [ # # ][ # # ]: 0 : PRINT_INFO("ERROR: AdjNode index exceeded\n");
193 : 0 : return NULL;
194 : : }
195 : : }
196 : :
197 : 0 : void CubitOctreeNode::set_adj_node(enum OctreePosition select, CubitOctreeNode *ptr_node)
198 : : {
199 [ # # # # : 0 : switch( select )
# # # ]
200 : : {
201 : : case O_LEFT:
202 : 0 : adjGridNode[O_LEFT] = ptr_node;
203 : 0 : break;
204 : :
205 : : case O_RIGHT:
206 : 0 : adjGridNode[O_RIGHT] = ptr_node;
207 : 0 : break;
208 : :
209 : : case O_BOTTOM:
210 : 0 : adjGridNode[O_BOTTOM] = ptr_node;
211 : 0 : break;
212 : :
213 : : case O_TOP:
214 : 0 : adjGridNode[O_TOP] = ptr_node;
215 : 0 : break;
216 : :
217 : : case O_BACK:
218 : 0 : adjGridNode[O_BACK] = ptr_node;
219 : 0 : break;
220 : :
221 : : case O_FRONT:
222 : 0 : adjGridNode[O_FRONT] = ptr_node;
223 : 0 : break;
224 : :
225 : : default:
226 [ # # ][ # # ]: 0 : PRINT_INFO("ERROR: AdjNode index exceeded");
227 : :
228 : : }
229 : :
230 : 0 : }
231 : :
232 : :
233 : 0 : void CubitOctreeNode::set_adj_node_distance( enum OctreePosition select, int dist ){
234 : :
235 [ # # # # : 0 : switch( select ){
# # # ]
236 : :
237 : : case O_LEFT:
238 : 0 : adjNodeDistance[O_LEFT] = dist;
239 : 0 : break;
240 : :
241 : : case O_RIGHT:
242 : 0 : adjNodeDistance[O_RIGHT] = dist;
243 : 0 : break;
244 : :
245 : : case O_BOTTOM:
246 : 0 : adjNodeDistance[O_BOTTOM] = dist;
247 : 0 : break;
248 : :
249 : : case O_TOP:
250 : 0 : adjNodeDistance[O_TOP] = dist;
251 : 0 : break;
252 : :
253 : : case O_BACK:
254 : 0 : adjNodeDistance[O_BACK] = dist;
255 : 0 : break;
256 : :
257 : : case O_FRONT:
258 : 0 : adjNodeDistance[O_FRONT] = dist;
259 : 0 : break;
260 : :
261 : : default:
262 [ # # ][ # # ]: 0 : PRINT_INFO(" ERROR: AdjNode index exceeded");
263 : :
264 : : }
265 : :
266 : 0 : }
267 : :
268 : :
269 : 0 : double CubitOctreeNode::manhattan_distance_adj_node( int index ){
270 : :
271 [ # # # # : 0 : switch( index ){
# # # ]
272 : :
273 : : case O_FRONT:
274 : 0 : return fabs( coord.x() - adjGridNode[index]->coord.x() );
275 : :
276 : : case O_BACK:
277 : 0 : return fabs( coord.x() - adjGridNode[index]->coord.x() );
278 : :
279 : : case O_RIGHT:
280 : 0 : return fabs( coord.y() - adjGridNode[index]->coord.y() );
281 : :
282 : : case O_LEFT:
283 : 0 : return fabs( coord.y() - adjGridNode[index]->coord.y() );
284 : :
285 : : case O_TOP:
286 : 0 : return fabs( coord.z() - adjGridNode[index]->coord.z() );
287 : :
288 : : case O_BOTTOM:
289 : 0 : return fabs( coord.z() - adjGridNode[index]->coord.z() );
290 : :
291 : : default:
292 [ # # ][ # # ]: 0 : PRINT_INFO("WARNING: Adjacent grid node index doesn't exist");
293 : 0 : return 1.0;
294 : : }
295 : :
296 : : }
297 : :
298 : : double CubitOctreeNode::manhattan_distance_adj_node( CubitOctreeNode *ptr_adj_node ){
299 : : return fabs( coord.x() - ptr_adj_node->coord.x() ) + fabs(coord.y() - ptr_adj_node->coord.y()) + fabs(coord.z() - ptr_adj_node->coord.z());
300 : : }
301 : :
302 : 0 : int CubitOctreeNode::get_adj_node_distance( enum OctreePosition select){
303 : :
304 [ # # # # : 0 : switch( select ){
# # # ]
305 : :
306 : : case O_LEFT:
307 : 0 : return adjNodeDistance[O_LEFT];
308 : :
309 : : case O_RIGHT:
310 : 0 : return adjNodeDistance[O_RIGHT];
311 : :
312 : : case O_BOTTOM:
313 : 0 : return adjNodeDistance[O_BOTTOM];
314 : :
315 : : case O_TOP:
316 : 0 : return adjNodeDistance[O_TOP];
317 : :
318 : : case O_BACK:
319 : 0 : return adjNodeDistance[O_BACK];
320 : :
321 : : case O_FRONT:
322 : 0 : return adjNodeDistance[O_FRONT];
323 : :
324 : : default:
325 [ # # ][ # # ]: 0 : PRINT_INFO("ERROR: AdjNode index exceeded");
326 : 0 : return CUBIT_TRUE;
327 : :
328 : : }
329 : :
330 : : }
331 : :
332 : 0 : int CubitOctreeNode::find_min_depth_cell_and_depth_difference( void ){
333 : :
334 : : int i, j, k;
335 : 0 : int depth_min_depth_cell = CUBIT_INT_MAX;
336 : 0 : int depth_max_detph_cell = -CUBIT_INT_MAX;
337 : : int depth;
338 : :
339 [ # # ]: 0 : for( i = 0; i < 2; i++ ){
340 [ # # ]: 0 : for( j = 0; j < 2; j++ ){
341 [ # # ]: 0 : for( k = 0; k < 2; k++ ){
342 [ # # ]: 0 : if( adjCell[i][j][k] != NULL ){
343 : 0 : depth = adjCell[i][j][k]->get_depth();
344 [ # # ]: 0 : if( depth < depth_min_depth_cell ){
345 : 0 : depth_min_depth_cell = depth;
346 : 0 : minDepthCell = adjCell[i][j][k];
347 : : }
348 [ # # ]: 0 : if( depth > depth_max_detph_cell ){
349 : 0 : depth_max_detph_cell = depth;
350 : : }
351 : : }
352 : : }
353 : : }
354 : : }
355 : :
356 [ # # ][ # # ]: 0 : if( depth_min_depth_cell != CUBIT_INT_MAX && depth_max_detph_cell != -CUBIT_INT_MAX ){
357 : 0 : cellDepthDifference = depth_max_detph_cell - depth_min_depth_cell;
358 : : }
359 : : else{
360 : 0 : cellDepthDifference = 0;
361 : : }
362 : :
363 : 0 : return cellDepthDifference;
364 : : }
365 : :
366 : 0 : void CubitOctreeNode::calculate_size_based_on_cell_dimension( double bbox_dimension )
367 : : {
368 : : int i;
369 : 0 : int counter = 0;
370 : 0 : double sum = 0.0;
371 : :
372 [ # # ]: 0 : for( i = 0; i < 6; i++ ){
373 : :
374 [ # # ]: 0 : if( adjNodeDistance[i] >= 0 ){
375 : 0 : sum += 1.0 / pow( 2.0, adjNodeDistance[i] );
376 : 0 : counter++;
377 : : }
378 : : }
379 : :
380 : 0 : size = sum / counter * bbox_dimension;
381 : 0 : }
382 : :
383 : 0 : int CubitOctreeNode::find_half_space( CubitFacet *ptr_facet )
384 : : {
385 [ # # ][ # # ]: 0 : if( (coord - ptr_facet->point(0)->coordinates()) % (ptr_facet->normal()) >= 0 )
[ # # ][ # # ]
[ # # ]
386 : : {
387 : 0 : halfspaceDirection = OCTREE_POSITIVE;
388 : : }
389 : :
390 : 0 : return halfspaceDirection;
391 : : }
392 : :
393 : :
394 : :
395 : 0 : void CubitOctreeNode::calc_facet_patch_distance_normal(DLIList<OctreeIntersectionData*> &idatas, int num_use_idatas, double &patch_distance, CubitVector &patch_normal, CubitBoolean sort, CubitBoolean set_Refface)
396 : : {
397 : : int i, j;
398 : 0 : CubitBoolean duplicate = CUBIT_FALSE;
399 [ # # ]: 0 : for (i=0; i < idatas.size(); ++i)
400 : : {
401 : 0 : idatas.reset();
402 : 0 : idatas.step(i);
403 : 0 : OctreeIntersectionData *first = idatas.get();
404 : :
405 : :
406 [ # # ]: 0 : for (j=i+1; j < idatas.size(); ++j)
407 : : {
408 : 0 : idatas.reset();
409 : 0 : idatas.step(j);
410 [ # # ]: 0 : if (idatas.get() == first) {duplicate = CUBIT_TRUE;}
411 : 0 : break;
412 : : }
413 [ # # ]: 0 : if (duplicate == CUBIT_TRUE) {break;}
414 : :
415 : : }
416 [ # # ][ # # ]: 0 : if (duplicate) {PRINT_INFO("Duplicate idatas found for node %d\n", this->get_num());}
[ # # ]
417 : :
418 [ # # ]: 0 : if (sort) {idatas.sort(OctreeIntersectionData::compare_function);}
419 : :
420 : 0 : idatas.reset();
421 [ # # ]: 0 : if (sort)
422 : : {
423 : 0 : patch_distance = /*(coord - idatas.get()->get_int_point())%idatas.get()->get_facet_normal();*/ idatas.get()->get_length();
424 : : // CubitFacet *ptr_facet = idatas.get()->get_facet_ptr();
425 : : // CubitVector closest_point_on_facet = idatas.get()->get_int_point(), facet_normal = idatas.get()->get_facet_normal();
426 : :
427 : : /* if (fabs((coord - closest_point_on_facet)%facet_normal) != (coord-closest_point_on_facet).length())
428 : : {
429 : : SVDrawTool::clear_non_retained();
430 : : SVDrawTool::draw_vector(coord, closest_point_on_facet, CUBIT_YELLOW_INDEX);
431 : : PRINT_INFO("closest length is %lf\n", idatas.get()->get_length());
432 : : DLIList<CubitFacet*> temp_facets;
433 : : temp_facets.append(ptr_facet);
434 : :
435 : : SVDrawTool::draw_facets(temp_facets, CUBIT_YELLOW_INDEX);
436 : : temp_facets.clean_out();
437 : : for (i=0; i < idatas.size(); ++i)
438 : : {
439 : : CubitFacet *facet = idatas.get()->get_facet_ptr();
440 : : if (facet != ptr_facet)
441 : : {
442 : : SVDrawTool::draw_vector(coord, idatas.get()->get_int_point(), CUBIT_RED_INDEX);
443 : : PRINT_INFO("Other length is %lf\n", idatas.get()->get_length());
444 : : }
445 : :
446 : : idatas.step();
447 : : temp_facets.append(facet);
448 : : }
449 : : temp_facets.remove(ptr_facet);
450 : : SVDrawTool::draw_facets(temp_facets, CUBIT_RED_INDEX);
451 : : int j,k;
452 : :
453 : : for (i=0; i < 2; ++i)
454 : : {
455 : : for (j=0; j < 2; ++j)
456 : : {
457 : :
458 : : for (k=0; k < 2; ++k)
459 : : {
460 : :
461 : : CubitOctreeCell *CubitOctree_cell = adjCell[i][j][k];
462 : : if (CubitOctree_cell == NULL) {continue;}
463 : : double corners[3];
464 : : double half_edge_length = CubitOctree_cell->get_dimension()/2.0;
465 : : CubitVector center = CubitOctree_cell->get_center();
466 : : center.get_xyz(corners);
467 : : float box[6] = {corners[0]-half_edge_length, corners[1]-half_edge_length, corners[2]-half_edge_length,
468 : : corners[0]+half_edge_length, corners[1]+half_edge_length, corners[2]+half_edge_length};
469 : : SVDrawTool::draw_cube(box, CUBIT_GREEN_INDEX, SVDrawTool::WIRE);
470 : : }
471 : : }
472 : : }
473 : :
474 : : SVDrawTool::mouse_xforms();
475 : :
476 : : }*/
477 : : }
478 : 0 : else {patch_distance = -1;}
479 : :
480 [ # # ]: 0 : if (set_Refface) {refFace = idatas.get()->get_face();}
481 : :
482 [ # # ]: 0 : if (num_use_idatas == -1) {num_use_idatas = idatas.size();}
483 : :
484 [ # # ]: 0 : patch_normal = CubitVector(0,0,0);
485 : :
486 : : /*for (i=0; i < num_use_idatas; ++i)
487 : : {
488 : : double len = idatas.get()->get_length();
489 : : if (len < OCTREE_EPSILON) {len = OCTREE_EPSILON;}
490 : : normal += idatas.get()->get_facet_normal() * 1/(len);
491 : : idatas.step();
492 : : }
493 : : normal.normalize(); */
494 : :
495 : : OctreeIntersectionData *ptr_data;
496 : : //double denominator = 0.0;
497 : : double length;
498 : :
499 : : //distance = 0.0;
500 [ # # ]: 0 : for( i=0; i < num_use_idatas; i++ )
501 : : {
502 : 0 : ptr_data = idatas.get_and_step(); // VED: important
503 : :
504 : 0 : length = ptr_data->get_length();
505 [ # # ]: 0 : if( length < OCTREE_EPSILON ){
506 [ # # ][ # # ]: 0 : patch_normal += ptr_data->get_normal() * (1/(OCTREE_EPSILON*OCTREE_EPSILON));
507 : : //distance += ( ptr_data->get_normal()%( coord - ptr_data->get_int_point() ) ) * (1/OCTREE_EPSILON)/denominator;
508 : : }
509 : : else{
510 [ # # ][ # # ]: 0 : patch_normal += ptr_data->get_normal() * (1/(length*length));
511 : : //distance += ( ptr_data->get_normal()%( coord - ptr_data->get_int_point() ) ) * (1/length)/denominator;
512 : : }
513 : : }
514 : 0 : patch_normal.normalize();
515 : 0 : }
516 : :
517 : :
518 : 0 : void CubitOctreeNode::SAT_find_face_distance_average_normal ()
519 : : {
520 : : // three cases:
521 : : // 1) One facet (one RefFace) => use facet's normal and distance to facet, RefFace is set to facet's owning face
522 : : // 2) Multiple facets, one refFace => use distance to closest facet and its owning RefFace, IDW normal from N closest facets
523 : : // 3) Multiple facets, multiple RefFaces => use distance to closest facet and its owning RefFace, IDW normal from N closest facets
524 : :
525 : : //int i, j, k;
526 : :
527 : : // case: no intersection datas, this should not happen. I should prolly put an cassertere.
528 [ # # ]: 0 : if (octreeIntersectionDataList.size() == 0)
529 : : {
530 [ # # ][ # # ]: 0 : PRINT_ERROR("No OctreeIntersectionDatas attached to black grid node in queue for MAT generation!\n");
531 : 0 : return;
532 : : }
533 : :
534 : : // case: one facet, just get distance, normal, and face from facet
535 [ # # ]: 0 : if (octreeIntersectionDataList.size() == 1)
536 : : {
537 : 0 : distance = octreeIntersectionDataList.get()->get_length();
538 [ # # ]: 0 : mNormal = octreeIntersectionDataList.get()->get_facet_normal();
539 : 0 : refFace = octreeIntersectionDataList.get()->get_face();
540 : :
541 : :
542 : : // remember to delete the idata - check if this is ok
543 [ # # ]: 0 : delete octreeIntersectionDataList.get();
544 : 0 : octreeIntersectionDataList.clean_out();
545 : 0 : return;
546 : : }
547 : :
548 : :
549 : :
550 : : // case: multiple facets, one face
551 : : // just initialize normal, distance, and Refface
552 : :
553 : : // case: two faces
554 : : // determine if disconnected and if normals diverge => EWC case 1
555 : : // else check angle
556 : :
557 : :
558 : :
559 : : // now find N closest facets (keep list of idatas though)
560 : : // choose closest one, use distance to it and use its RefFace
561 : : // then use all and IDW to get normal
562 : :
563 : : int num_facets_to_use;
564 : : if (N_CLOSEST_FACETS_FACTOR_FOR_FRONT_NORMALS == 0.00) {num_facets_to_use = 1;}
565 : 0 : else if (N_CLOSEST_FACETS_FACTOR_FOR_FRONT_NORMALS == 1.00) {num_facets_to_use = octreeIntersectionDataList.size();}
566 : : else {num_facets_to_use = (int)(N_CLOSEST_FACETS_FACTOR_FOR_FRONT_NORMALS * octreeIntersectionDataList.size());}
567 [ # # ]: 0 : if (num_facets_to_use == 0) {num_facets_to_use = 1;}
568 [ # # ]: 0 : else if (num_facets_to_use > octreeIntersectionDataList.size()) {num_facets_to_use = octreeIntersectionDataList.size();}
569 : :
570 : : /*DLIList<OctreeIntersectionData*> n_closest_idatas;
571 : :
572 : : RTree<OctreeIntersectionData*> *rtree = new RTree<OctreeIntersectionData*>;
573 : : double closest = CUBIT_DBL_MAX;
574 : : for (i=0; i < octreeIntersectionDataList.size(); ++i)
575 : : {
576 : : rtree->add(octreeIntersectionDataList.get_and_step());
577 : : }
578 : : rtree->k_nearest_neighbor(coord, num_facets_to_use, closest, n_closest_idatas, OctreeIntersectionData::dist_sqr_to_vec);
579 : : delete rtree;
580 : :
581 : : normal = CubitVector(0,0,0);
582 : : // calc_facet_patch_distance_normal(octreeIntersectionDataList, num_facets_to_use, distance, normal, CUBIT_TRUE, CUBIT_TRUE);
583 : :
584 : :
585 : : refFace = n_closest_idatas.get()->get_face();
586 : :
587 : :
588 : : distance = n_closest_idatas.get()->get_length();
589 : :
590 : : for (i=0; i < num_facets_to_use; ++i)
591 : : {
592 : : double len = n_closest_idatas.get()->get_length();
593 : : normal += n_closest_idatas.get_and_step()->get_facet_normal() * 1/(len);
594 : : }
595 : :
596 : : normal.normalize();*/
597 : :
598 : :
599 [ # # ]: 0 : mNormal = CubitVector(0,0,0);
600 : 0 : calc_facet_patch_distance_normal(octreeIntersectionDataList, num_facets_to_use, distance, mNormal, CUBIT_TRUE, CUBIT_TRUE);
601 : :
602 : : /*
603 : : octreeIntersectionDataList.sort(OctreeIntersectionData::compare_function);
604 : : octreeIntersectionDataList.reset();
605 : :
606 : :
607 : :
608 : :
609 : : refFace = octreeIntersectionDataList.get()->get_face();
610 : :
611 : :
612 : : distance = octreeIntersectionDataList.get()->get_length();
613 : :
614 : : for (i=0; i < num_facets_to_use; ++i)
615 : : {
616 : : double len = octreeIntersectionDataList.get()->get_length();
617 : : normal += octreeIntersectionDataList.get_and_step()->get_facet_normal() * 1/(len);
618 : : }
619 : :
620 : : normal.normalize();
621 : : */
622 : : // now normal, distance to boundary, and Refface have been set
623 : :
624 : : }
625 : :
626 : :
627 : : // checks intesection between the lines joining grid node and adjacent nodes with the facet.
628 : :
629 : 0 : void CubitOctreeNode::find_intersection_with_facet( CubitOctreeType type, RefFace *ptr_face, CubitFacet *ptr_facet, DLIList<CubitOctreeNode*> &boundary_white_node_list )
630 : : {
631 : :
632 : : int i;
633 : : CubitBoolean result;
634 [ # # ]: 0 : CubitVector int_point;
635 [ # # ]: 0 : CubitVector facet_normal;
636 : : double para;
637 : :
638 [ # # ][ # # ]: 0 : facet_normal = ptr_facet->normal();
639 : :
640 [ # # ]: 0 : for( i = 0; i < 6; i++ ){
641 : :
642 : 0 : result = CUBIT_FALSE;
643 : :
644 [ # # ]: 0 : if( adjGridNode[i] != NULL ){
645 [ # # ][ # # ]: 0 : if( adjGridNode[i]->halfspaceDirection == OCTREE_NEGATIVE && adjGridNode[i]->mark == CUBIT_TRUE ){
646 : : //- adj_node[0] = O_FRONT Node
647 : : //- adj_node[1] = O_BACK Node
648 : : //- adj_node[2] = O_RIGHT Node
649 : : //- adj_node[3] = O_LEFT Node
650 : : //- adj_node[4] = O_TOP Node
651 : : //- adj_node[5] = O_BOTTOM Node
652 : :
653 [ # # # # : 0 : switch( i ){
# # # ]
654 : :
655 : : case O_FRONT:
656 [ # # ][ # # ]: 0 : result = find_intersection_point( OCTREE_X, coord, adjGridNode[i]->coord, facet_normal, ptr_facet->point(0)->coordinates(), ptr_facet->point(1)->coordinates(), ptr_facet->point(2)->coordinates(), int_point, para );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
657 : 0 : break;
658 : :
659 : : case O_BACK:
660 [ # # ][ # # ]: 0 : result = find_intersection_point( OCTREE_X, coord, adjGridNode[i]->coord, facet_normal, ptr_facet->point(0)->coordinates(), ptr_facet->point(1)->coordinates(), ptr_facet->point(2)->coordinates(), int_point, para );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
661 : 0 : break;
662 : :
663 : :
664 : : case O_RIGHT:
665 [ # # ][ # # ]: 0 : result = find_intersection_point( OCTREE_Y, coord, adjGridNode[i]->coord, facet_normal, ptr_facet->point(0)->coordinates(), ptr_facet->point(1)->coordinates(), ptr_facet->point(2)->coordinates(), int_point, para );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
666 : 0 : break;
667 : :
668 : :
669 : : case O_LEFT:
670 [ # # ][ # # ]: 0 : result = find_intersection_point( OCTREE_Y, coord, adjGridNode[i]->coord, facet_normal, ptr_facet->point(0)->coordinates(), ptr_facet->point(1)->coordinates(), ptr_facet->point(2)->coordinates(), int_point, para );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
671 : 0 : break;
672 : :
673 : :
674 : : case O_TOP:
675 [ # # ][ # # ]: 0 : result = find_intersection_point( OCTREE_Z, coord, adjGridNode[i]->coord, facet_normal, ptr_facet->point(0)->coordinates(), ptr_facet->point(1)->coordinates(), ptr_facet->point(2)->coordinates(), int_point, para );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
676 : 0 : break;
677 : :
678 : :
679 : : case O_BOTTOM:
680 [ # # ][ # # ]: 0 : result = find_intersection_point( OCTREE_Z, coord, adjGridNode[i]->coord, facet_normal, ptr_facet->point(0)->coordinates(), ptr_facet->point(1)->coordinates(), ptr_facet->point(2)->coordinates(), int_point, para );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
681 : 0 : break;
682 : :
683 : : default:
684 : 0 : break;
685 : :
686 : : }
687 : : }
688 : : }
689 : :
690 : :
691 [ # # ]: 0 : if( result == CUBIT_TRUE ){
692 : : OctreeIntersectionData * ptr_data;
693 : :
694 [ # # # ]: 0 : switch( type ){
695 : : case CUBIT_OCTREE_VOLUME:
696 : : // update color of boundary node
697 [ # # ]: 0 : if( color != CUBIT_WHITE_INDEX ){
698 : 0 : if( color == CUBIT_BLACK_INDEX ){
699 : : // Mark the common cells incident on both end points of the edge as GREY
700 : : // To resolve the intersection problems I added the SAT intersection code -ved
701 : : }
702 : :
703 [ # # ]: 0 : boundary_white_node_list.push( this );
704 : 0 : refFace = ptr_face;
705 : : //PRINT_DEBUG_157(" Testing: Face Num = %d\n", RefFace->id() );
706 : 0 : color = CUBIT_WHITE_INDEX;
707 : 0 : distance = -1;
708 : : }
709 : : // WARNING: devided by zero.
710 [ # # ][ # # ]: 0 : ptr_data = new OctreeIntersectionData( this, facet_normal * -1, int_point, (adjGridNode[i]->coord - int_point).length(), ptr_face );
[ # # ][ # # ]
[ # # ][ # # ]
711 [ # # ]: 0 : adjGridNode[i]->append_list_item( ptr_data );
712 : 0 : break;
713 : :
714 : : case CUBIT_OCTREE_FACE:
715 : 0 : refFace = ptr_face;
716 : 0 : color = CUBIT_BLACK_INDEX;
717 : 0 : distance = -1;
718 : 0 : adjGridNode[i]->color = CUBIT_BLACK_INDEX;
719 : 0 : break;
720 : :
721 : : default:
722 [ # # ][ # # ]: 0 : PRINT_INFO("This case not yet implemented \n");
[ # # ][ # # ]
723 : 0 : break;
724 : : }
725 : : }
726 : : }
727 : 0 : }
728 : :
729 : :
730 : :
731 : :
732 : :
733 : : // returns true if the intersection between the line segment and facet takes place
734 : : // para stores the parameter of intersection point int_point
735 : 0 : CubitBoolean CubitOctreeNode::find_intersection_point( int axis, CubitVector grid_node0, CubitVector grid_node1, CubitVector &facet_normal, CubitVector facet_vert0, CubitVector facet_vert1, CubitVector facet_vert2, CubitVector &int_point, double ¶ ){
736 : :
737 : : double A, B, C, D;
738 : : double nominator, denominator;
739 : :
740 [ # # ]: 0 : D = - ( facet_normal%(facet_vert1 - grid_node0) );
741 : 0 : A = facet_normal.x();
742 : 0 : B = facet_normal.y();
743 : 0 : C = facet_normal.z();
744 : :
745 [ # # # # ]: 0 : switch( axis ){
746 : :
747 : : case OCTREE_X:
748 [ # # ]: 0 : if( fabs(A) < OCTREE_EPSILON ){
749 : : //line parallel to facet
750 : : // both end points are intersection points
751 : :
752 : 0 : return CUBIT_FALSE;
753 : : }
754 : : else{
755 : 0 : nominator = D;
756 : 0 : denominator = A * ( grid_node0.x() - grid_node1.x() );
757 : 0 : para = nominator / denominator;
758 : : }
759 : 0 : break;
760 : :
761 : :
762 : : case OCTREE_Y:
763 [ # # ]: 0 : if( fabs(B) < OCTREE_EPSILON ){
764 : : //line parallel to facet
765 : : // both end points are intersection points
766 : :
767 : 0 : return CUBIT_FALSE;
768 : : }
769 : : else{
770 : 0 : nominator = D;
771 : 0 : denominator = B * ( grid_node0.y() - grid_node1.y() );
772 : 0 : para = nominator / denominator;
773 : : }
774 : 0 : break;
775 : :
776 : :
777 : : case OCTREE_Z:
778 [ # # ]: 0 : if( fabs(C) < OCTREE_EPSILON ){
779 : : //line parallel to facet
780 : : // both end points are intersection points
781 : :
782 : 0 : return CUBIT_FALSE;
783 : : }
784 : : else{
785 : 0 : nominator = D;
786 : 0 : denominator = C * ( grid_node0.z() - grid_node1.z() );
787 : 0 : para = nominator / denominator;
788 : : }
789 : 0 : break;
790 : :
791 : : default:
792 : 0 : break;
793 : : }
794 : :
795 [ # # ][ # # ]: 0 : int_point = grid_node0 + para * ( grid_node1 - grid_node0 );
[ # # ]
796 : 0 : return( is_intersection_point_contained_inside_facet( int_point, facet_vert0, facet_vert1, facet_vert2 ) );
797 : :
798 : :
799 : : }
800 : :
801 : :
802 : 0 : CubitBoolean CubitOctreeNode::is_same_side(const CubitVector &p1, const CubitVector &p2, const CubitVector &a, const CubitVector &b)
803 : : {
804 [ # # ][ # # ]: 0 : static CubitVector edge;
[ # # ][ # # ]
805 [ # # ]: 0 : edge = b-a;
806 : : //cp1 = edge*(p1-a);
807 : : //cp2 = edge*(p2-a);
808 [ # # ][ # # ]: 0 : if ( (edge*(p1-a)) % (edge*(p2-a)) >= 0) {return CUBIT_TRUE;}
[ # # ][ # # ]
[ # # ]
809 : 0 : return CUBIT_FALSE;
810 : : }
811 : :
812 : :
813 : : // returns true if intersection point is contained inside the facet
814 : : // interior angle at the intersecton point should add up to 360 deg.
815 : 0 : CubitBoolean CubitOctreeNode::is_intersection_point_contained_inside_facet( const CubitVector &int_point, const CubitVector &facet_vert0, const CubitVector &facet_vert1, const CubitVector &facet_vert2 ){
816 [ # # ][ # # ]: 0 : if ( fabs((int_point-facet_vert0)%( (facet_vert1-facet_vert0) * (facet_vert2-facet_vert0) )) > OCTREE_EPSILON)
[ # # ][ # # ]
[ # # ]
817 : : {
818 : 0 : return CUBIT_FALSE;
819 : : }
820 : :
821 [ # # ][ # # ]: 0 : if (is_same_side(int_point,facet_vert0, facet_vert1,facet_vert2) && is_same_side(int_point,facet_vert1, facet_vert0,facet_vert2) && is_same_side(int_point,facet_vert2, facet_vert0,facet_vert1)) {return CUBIT_TRUE;}
[ # # ][ # # ]
822 : 0 : return CUBIT_FALSE;
823 : :
824 : : /*CubitVector line0, line1, line2;
825 : : double ang0, ang1, ang2;
826 : :
827 : : line0 = facet_vert0 - int_point ;
828 : : line0 = line0 / line0.length();
829 : :
830 : :
831 : : line1 = facet_vert1 - int_point ;
832 : : line1 = line1 / line1.length();
833 : :
834 : : line2 = facet_vert2 - int_point ;
835 : : line2 = line2 / line2.length();
836 : : //Added (M. Brewer) to check for an invalid number passed to acos
837 : : //compute ang0
838 : : double temp_double = line0 % line1;
839 : : if(temp_double>1.0)
840 : : temp_double=1.0;
841 : : else if (temp_double<-1.0)
842 : : temp_double=-1.0;
843 : : ang0 = acos( temp_double );
844 : : //compute ang1
845 : : temp_double = line1 % line2;
846 : : if(temp_double>1.0)
847 : : temp_double=1.0;
848 : : else if (temp_double<-1.0)
849 : : temp_double=-1.0;
850 : : ang1 = acos( temp_double );
851 : : //compute ang2
852 : : temp_double = line2 % line0;
853 : : if(temp_double>1.0)
854 : : temp_double=1.0;
855 : : else if (temp_double<-1.0)
856 : : temp_double=-1.0;
857 : : ang2 = acos( temp_double );
858 : :
859 : : if( fabs ( ( ang0 + ang1 + ang2 ) - CUBIT_PI * 2 ) < OCTREE_EPSILON ){
860 : : return CUBIT_TRUE;
861 : : }
862 : : else{
863 : : return CUBIT_FALSE;
864 : : }*/
865 : : }
866 : :
867 : :
868 : :
869 : :
870 : :
871 : 0 : CubitBoolean CubitOctreeNode::find_size_using_adj_node()
872 : : {
873 : : int i;
874 : 0 : double sum = 0.0;
875 : 0 : int count = 0;
876 [ # # ]: 0 : for( i = 0; i < 6; i ++ ){
877 [ # # ]: 0 : if( adjGridNode[i] != NULL ){
878 : : // WARNING: Why we need to check for -1
879 : : //if( adjGridNode[i]->size != -1 && adjGridNode[i]->size != CUBIT_DBL_MAX && adjGridNode[i]->size != 0){
880 : : //if( adjGridNode[i]->size != CUBIT_DBL_MAX && adjGridNode[i]->size != 0.0 ){
881 [ # # ]: 0 : if( adjGridNode[i]->size != 0.0 ){
882 : 0 : sum += adjGridNode[i]->size;
883 : 0 : count++;
884 : : }
885 : : }
886 : : }
887 : :
888 [ # # ]: 0 : if( sum != 0.0 ){
889 : 0 : size = sum / count;
890 : 0 : return CUBIT_TRUE;
891 : : }
892 : : else
893 : 0 : return CUBIT_FALSE;
894 : : }
895 : :
896 : :
897 : :
898 : 0 : CubitBoolean CubitOctreeNode::compare_function( CubitOctreeNode *&a, CubitOctreeNode *&b ){
899 : :
900 [ # # ]: 0 : if( a->get_distance() < b->get_distance() )
901 : 0 : return CUBIT_TRUE;
902 : : else
903 : 0 : return CUBIT_FALSE;
904 : :
905 : : }
906 : :
907 : 0 : void CubitOctreeNode::find_distance_at_adj_node(PriorityQueue<CubitOctreeNode *> *heap )
908 : : {
909 : : int i;
910 [ # # ]: 0 : CubitVector mat_pnt_center;
911 : : double new_node_distance;
912 : :
913 : : // PRINT_INFO("Testing: Face id = %d\n", mrefFace->id());
914 : 0 : visit = CUBIT_TRUE;
915 : :
916 [ # # ]: 0 : for( i = 0; i < 6; i++ ){
917 : :
918 : : // at the boundary of solid
919 [ # # ]: 0 : if( adjGridNode[i] == NULL )
920 : 0 : continue;
921 : :
922 : :
923 : : // *************** WARNING *********
924 : :
925 : :
926 : : // if the adjGridNode is on boundary or outside don't do anything
927 : : // Just testing white node is enough because we assume the facet and the grid
928 : : // intersection done during octree generation is correct
929 : : // At this point only at the boundary there is white and black nodes because of facet/octree intersection
930 : : // and both at interior and outside we grey node
931 : : //if( adjGridNode[i]->get_color() == CUBIT_WHITE_INDEX || adjGridNode[i]->get_color() == CUBIT_GREY_INDEX )
932 [ # # ][ # # ]: 0 : if( adjGridNode[i]->get_color() == CUBIT_WHITE_INDEX || adjGridNode[i]->get_color() == CUBIT_YELLOW_INDEX)
[ # # ][ # # ]
[ # # ]
933 : 0 : continue;
934 : :
935 : : // meeting of the front should be the major
936 : : // criteria not the size value. check for null of
937 : : // grid_node->face. then check for adjacency, black_white, and size...
938 [ # # ][ # # ]: 0 : new_node_distance = distance + ( adjGridNode[i]->coord - coord )%mNormal;
939 : :
940 : : // WARNING: The below condition is very important.
941 : : // Therefore I think the normal calculation is wrong
942 : : // Front should always go forward.
943 : :
944 [ # # ]: 0 : if(new_node_distance <= distance)
945 : : {
946 : :
947 : : // OPEN IT
948 : : // this happens at the concave region containing many surfaces.
949 : : //PRINT_DEBUG_157(" Distance Calculation is wrong (discresing)\n");
950 : :
951 : :
952 [ # # ]: 0 : if (adjGridNode[i]->refFace != NULL)
953 : : {
954 : : //if (adjGridNode[i]->mrefFace != mrefFace)
955 : : // {
956 : 0 : continue;
957 : : //}
958 : : }
959 : :
960 : :
961 : : //if (adjGridNode[i]->mrefFace != mrefFace)
962 : : //{
963 : 0 : adjGridNode[i]->color = CUBIT_BLACK_INDEX;
964 : : //new_node_distance = distance;
965 : 0 : continue;
966 : : //}
967 : :
968 : :
969 : : //SVDrawTool::draw_vector(adjGridNode[i]->coord, closest, CUBIT_RED_INDEX);
970 : :
971 : :
972 : : }
973 : : //if( adjGridNode[i]->mrefFace != mrefFace )
974 : : //{
975 : 0 : adjGridNode[i]->color = CUBIT_BLACK_INDEX;
976 : : //}
977 : :
978 [ # # ]: 0 : if( adjGridNode[i]->refFace == NULL ){
979 : : // internal black nodes
980 : : // not near skeleton
981 : 0 : adjGridNode[i]->distance = new_node_distance;
982 : 0 : adjGridNode[i]->refFace = refFace;
983 [ # # ]: 0 : adjGridNode[i]->mNormal = mNormal;
984 [ # # ]: 0 : heap->push( adjGridNode[i] );
985 : : }
986 : : else{
987 : :
988 : :
989 : : }
990 : : }
991 : :
992 [ + - ][ + - ]: 6540 : }
993 : :
994 : :
995 : :
996 : :
997 : :
998 : : //EOF
|