cgma
|
00001 //------------------------------------------------------------------------- 00002 // Filename : SimplifyTool.cpp 00003 // 00004 // Purpose : 00005 // 00006 // Simplify {Volume|Surface} <Range> [Angle <Value>] 00007 // [Respect {Surface <Range> | Curve <Range> | imprint}] 00008 // [Preview] 00009 // 00010 // Special Notes : 00011 // 00012 // Creator : Sam Showman 00013 // 00014 // Creation Date : 11/07/2005 00015 //------------------------------------------------------------------------- 00016 00017 #include "SimplifyTool.hpp" 00018 #include "RefVolume.hpp" 00019 #include "DLIList.hpp" 00020 #include "RefFace.hpp" 00021 #include "RefEdge.hpp" 00022 #include "RefVertex.hpp" 00023 #include "CompositeTool.hpp" 00024 #include "GfxDebug.hpp" 00025 #include "ProgressTool.hpp" 00026 #include "AppUtil.hpp" 00027 #include "GeometryFeatureTool.hpp" 00028 #include "GMem.hpp" 00029 #include "GeometryQueryEngine.hpp" 00030 00031 SimplifyTool::SimplifyTool() 00032 { 00033 } 00034 00035 SimplifyTool::~SimplifyTool() 00036 { 00037 } 00038 00039 CubitStatus SimplifyTool::simplify_volumes(DLIList<RefVolume*> ref_volume_list, 00040 double surf_angle_in, 00041 DLIList<RefFace*> respect_face_list, 00042 DLIList<RefEdge*> respect_edge_list, 00043 CubitBoolean respect_rounds, 00044 CubitBoolean respect_imprints, 00045 CubitBoolean local_normals, 00046 CubitBoolean preview) 00047 { 00048 ref_volume_list.uniquify_unordered(); 00049 for(int i = ref_volume_list.size();i--;) 00050 simplify_volume( 00051 ref_volume_list.get_and_step(), 00052 surf_angle_in, 00053 respect_face_list, 00054 respect_edge_list, 00055 respect_rounds, 00056 respect_imprints, 00057 local_normals, 00058 preview); 00059 00060 if(preview) 00061 GfxDebug::flush(); 00062 00063 return CUBIT_SUCCESS; 00064 } 00065 00066 CubitStatus SimplifyTool::simplify_surfaces(DLIList<RefFace*> ref_face_list, 00067 double angle_in, 00068 DLIList<RefFace*> respect_face_list, 00069 DLIList<RefEdge*> respect_edge_list, 00070 CubitBoolean respect_rounds, 00071 CubitBoolean respect_imprints, 00072 CubitBoolean local_normals, 00073 CubitBoolean preview) 00074 { 00075 CubitStatus status = CUBIT_FAILURE; 00076 ref_face_list.uniquify_unordered(); 00077 while(ref_face_list.size()) 00078 { 00079 DLIList<RefFace*> ref_faces_in_volume; 00080 ref_face_list.reset(); 00081 RefFace* cur_face = ref_face_list.get_and_step(); 00082 RefVolume* cur_vol = cur_face->ref_volume(); 00083 ref_faces_in_volume.append(cur_face); 00084 for(int i =1;i<ref_face_list.size();i++) 00085 { 00086 RefFace* face = ref_face_list.get_and_step(); 00087 if(face->ref_volume() == cur_vol) 00088 ref_faces_in_volume.append(face); 00089 } 00090 00091 if(ref_faces_in_volume.size()>1) 00092 { 00093 status = simplify_surfaces_in_volume( 00094 ref_faces_in_volume, 00095 angle_in, 00096 respect_face_list, 00097 respect_edge_list, 00098 respect_rounds, 00099 respect_imprints, 00100 local_normals, 00101 preview); 00102 } 00103 ref_face_list -= ref_faces_in_volume; 00104 } 00105 00106 if(preview) 00107 GfxDebug::flush(); 00108 00109 return CUBIT_SUCCESS; 00110 } 00111 00112 CubitStatus SimplifyTool::simplify_curves(DLIList<RefEdge*> ref_edge_list, 00113 double angle_in, 00114 DLIList<RefEdge*> respect_edge_list, 00115 DLIList<RefVertex*> respect_vertex_list, 00116 CubitBoolean respect_imprints, 00117 CubitBoolean local_normals, 00118 CubitBoolean preview) 00119 { 00120 CubitStatus status = CUBIT_FAILURE; 00121 ref_edge_list.uniquify_unordered(); 00122 while(ref_edge_list.size()) 00123 { 00124 DLIList<RefEdge*> ref_edges_in_volume; 00125 ref_edge_list.reset(); 00126 RefEdge* cur_edge = ref_edge_list.get_and_step(); 00127 RefVolume* cur_vol = cur_edge->ref_volume(); 00128 ref_edges_in_volume.append(cur_edge); 00129 for(int i =1;i<ref_edge_list.size();i++) 00130 { 00131 RefEdge* edge = ref_edge_list.get_and_step(); 00132 if(edge->ref_volume() == cur_vol) 00133 ref_edges_in_volume.append(edge); 00134 } 00135 00136 if(ref_edges_in_volume.size()>1) 00137 { 00138 status = simplify_curves_in_volume( 00139 ref_edges_in_volume, 00140 angle_in, 00141 respect_edge_list, 00142 respect_vertex_list, 00143 respect_imprints, 00144 local_normals, 00145 preview); 00146 } 00147 ref_edge_list -= ref_edges_in_volume; 00148 } 00149 00150 if(preview) 00151 GfxDebug::flush(); 00152 00153 return CUBIT_SUCCESS; 00154 } 00155 00156 CubitStatus SimplifyTool::simplify_volume(RefVolume* ref_volume, 00157 double angle_in, 00158 DLIList<RefFace*> respect_face_list, 00159 DLIList<RefEdge*> respect_edge_list, 00160 CubitBoolean respect_rounds, 00161 CubitBoolean respect_imprints, 00162 CubitBoolean local_normals, 00163 CubitBoolean preview) 00164 { 00165 DLIList<RefFace*> ref_face_list; 00166 ref_volume->ref_faces(ref_face_list); 00167 return simplify_surfaces_in_volume( 00168 ref_face_list, 00169 angle_in, 00170 respect_face_list, 00171 respect_edge_list, 00172 respect_rounds, 00173 respect_imprints, 00174 local_normals, 00175 preview); 00176 } 00177 00178 // main funciton 00179 // all of the input faces must be from the same volume 00180 CubitStatus SimplifyTool::simplify_surfaces_in_volume( 00181 DLIList<RefFace*> ref_face_list, 00182 double angle_in, 00183 DLIList<RefFace*> respect_face_list, 00184 DLIList<RefEdge*> respect_edge_list, 00185 CubitBoolean respect_rounds, 00186 CubitBoolean respect_imprints, 00187 CubitBoolean local_normals, 00188 CubitBoolean preview) 00189 { 00190 if(ref_face_list.size()==0) 00191 { 00192 PRINT_ERROR("No surfaces specified for simplification\n"); 00193 return CUBIT_FAILURE; 00194 } 00195 else if(ref_face_list.size() == 1) 00196 { 00197 PRINT_ERROR("Only one surface specified for simplification\n"); 00198 return CUBIT_FAILURE; 00199 } 00200 00201 DLIList<RefFace*> seed_faces; 00202 DLIList<RefEdge*> preview_edges; 00203 RefVolume* ref_volume = ref_face_list.get()->ref_volume(); 00204 DLIList<RefEdge*> preview_removed; 00205 00206 if(preview) 00207 ref_volume->ref_edges(preview_edges); 00208 00209 int j,k; 00210 00211 int new_face_count = 0; 00212 int combined_face_count = 0; 00213 ProgressTool *prog_ptr = 0; 00214 if(ref_face_list.size() > 100 ) 00215 { 00216 char title[200]; 00217 if(preview) 00218 sprintf(title, "Previewing Volume %d",ref_volume->id()); 00219 else 00220 sprintf(title, "Simplifying Surfaces in Volume %d",ref_volume->id()); 00221 00222 prog_ptr = AppUtil::instance()->progress_tool(); 00223 assert(prog_ptr != NULL); 00224 prog_ptr->start(0,100, title); 00225 } 00226 int start_face_count = ref_face_list.size(); 00227 while(ref_face_list.size()) 00228 { 00229 DLIList<RefFace*> composite_faces; 00230 seed_faces.append_unique(ref_face_list.pop()); 00231 00232 for ( j = ref_face_list.size(); j--; ) 00233 ref_face_list.get_and_step()->marked( CUBIT_FALSE ); 00234 00235 while(seed_faces.size()) 00236 { 00237 RefFace *seed_ref_face = seed_faces.pop(); 00238 seed_ref_face->marked(CUBIT_TRUE); 00239 00240 composite_faces.append(seed_ref_face); 00241 00242 // Get the edges 00243 DLIList<RefEdge*> ref_edge_list; 00244 seed_ref_face->ref_edges( ref_edge_list ); 00245 RefEdge *ref_edge_ptr; 00246 RefFace *ref_face_ptr; 00247 for( k = ref_edge_list.size(); k--; ) 00248 { 00249 ref_edge_ptr = ref_edge_list.get_and_step(); 00250 00251 // Don't propagate across merged entities (you can't create composites 00252 // across merged volumes) 00253 if( ref_edge_ptr->bridge_manager()->number_of_bridges() > 1) 00254 continue; 00255 00256 // Don't go propagate across surface splits if the user asks for it 00257 GeometryFeatureTool* gft = GeometryFeatureTool::instance(); 00258 if( respect_imprints && 00259 gft->feature_type(ref_edge_ptr) == GeometryFeatureEngine::FEATURE_IMPRINT) 00260 continue; 00261 00262 // Don't cross a curve if we want it respected 00263 if(respect_edge_list.is_in_list(ref_edge_ptr)) 00264 continue; 00265 00266 DLIList<RefFace*> attached_ref_faces; 00267 ref_edge_ptr->ref_faces( attached_ref_faces ); 00268 00269 attached_ref_faces.remove(seed_ref_face); 00270 ref_face_ptr = attached_ref_faces.size()!=0?attached_ref_faces.get():0; 00271 00272 // keep the face if we want it respected 00273 if(attached_ref_faces.size() == 1 && 00274 respect_face_list.is_in_list(attached_ref_faces.get())) 00275 continue; 00276 00277 // Don't consider ref_faces that are already in the list 00278 if( attached_ref_faces.size() == 1 && 00279 !ref_face_ptr->marked() && 00280 (!respect_rounds || 00281 ((gft->feature_type(ref_face_ptr) != GeometryFeatureEngine::FEATURE_ROUND && 00282 gft->feature_type(seed_ref_face) != GeometryFeatureEngine::FEATURE_ROUND) || 00283 (gft->feature_type(ref_face_ptr) == GeometryFeatureEngine::FEATURE_ROUND && 00284 gft->feature_type(seed_ref_face) == GeometryFeatureEngine::FEATURE_ROUND)))) 00285 { 00286 DLIList<RefVolume*> ref_volumes; 00287 ref_face_ptr->ref_volumes( ref_volumes ); 00288 if( !ref_volumes.size() || ref_volumes.size()==1 ) 00289 { 00290 // Only add the ref_face if it meets the feature angle criteria 00291 if(local_normals){ 00292 if(composite_surfaces_test_at_curves(seed_ref_face,ref_face_ptr,angle_in)) 00293 { 00294 ref_face_ptr->marked( CUBIT_TRUE ); 00295 seed_faces.append(ref_face_ptr); 00296 composite_faces.append(ref_face_ptr); 00297 } 00298 } 00299 else{ 00300 if(composite_surfaces(seed_ref_face,ref_face_ptr,angle_in)) 00301 { 00302 ref_face_ptr->marked( CUBIT_TRUE ); 00303 seed_faces.append(ref_face_ptr); 00304 composite_faces.append(ref_face_ptr); 00305 } 00306 } 00307 } 00308 } 00309 } 00310 } 00311 composite_faces.uniquify_unordered(); 00312 ref_face_list -= composite_faces; 00313 00314 if(!preview && 00315 composite_faces.size()>1) 00316 { 00317 DLIList<RefEdge*> result_edges; 00318 DLIList<RefFace*> result_faces; 00319 CompositeTool::instance()->composite( 00320 composite_faces, 00321 result_faces, 00322 result_edges); 00323 00324 combined_face_count +=composite_faces.size(); 00325 for(int m = result_faces.size();m--;) 00326 result_faces.get_and_step()->marked(CUBIT_TRUE); 00327 00328 new_face_count+=result_faces.size(); 00329 } 00330 else if(preview) 00331 { 00332 int face_count = composite_faces.size(); 00333 for(int i =0;i<face_count;i++) 00334 { 00335 RefFace* cur_comp_face = composite_faces[i]; 00336 DLIList<RefEdge*> refedges; 00337 for(int j =0;j<face_count;j++) 00338 { 00339 if(i==j) continue; 00340 composite_faces[j]->ref_edges(refedges); 00341 } 00342 00343 refedges.uniquify_unordered(); 00344 00345 DLIList<RefEdge*> temp_refedges; 00346 cur_comp_face->ref_edges(temp_refedges); 00347 refedges.intersect_unordered(temp_refedges); 00348 preview_removed+=refedges; 00349 } 00350 } 00351 00352 if(prog_ptr) 00353 { 00354 double frac = 1.0-(double)ref_face_list.size()/(double)start_face_count; 00355 prog_ptr->percent(frac); 00356 } 00357 } 00358 00359 if(prog_ptr) 00360 { 00361 prog_ptr->end(); 00362 prog_ptr = 0; 00363 } 00364 00365 if(preview) 00366 { 00367 preview_edges -=preview_removed; 00368 for(int c = preview_edges.size();c--;) 00369 GfxDebug::draw_ref_edge(preview_edges.get_and_step(),7); 00370 } 00371 else if(combined_face_count>new_face_count) 00372 { 00373 PRINT_INFO("Simplified %d surfaces into %d surfaces\n", 00374 combined_face_count, 00375 new_face_count); 00376 } 00377 00378 // make sure to set all of the surface markers to false 00379 DLIList<RefFace*> marked_face_list; 00380 ref_volume->ref_faces(marked_face_list); 00381 for(int i =0;i<marked_face_list.size();i++) 00382 marked_face_list[i]->marked(CUBIT_FALSE); 00383 00384 return CUBIT_SUCCESS; 00385 } 00386 00387 CubitStatus SimplifyTool::simplify_curves_in_volume( 00388 DLIList<RefEdge*> ref_edge_list, 00389 double angle_in, 00390 DLIList<RefEdge*> respect_edge_list, 00391 DLIList<RefVertex*> respect_vertex_list, 00392 CubitBoolean respect_imprints, 00393 CubitBoolean local_normals, 00394 CubitBoolean preview) 00395 { 00396 if(local_normals){ 00397 PRINT_WARNING("When simplifying curves, 'local_normals' is currently ignored.\n"); 00398 } 00399 00400 if(ref_edge_list.size()==0) 00401 { 00402 PRINT_ERROR("No curves specified for simplification\n"); 00403 return CUBIT_FAILURE; 00404 } 00405 else if(ref_edge_list.size() == 1) 00406 { 00407 PRINT_ERROR("Only one curve specified for simplification\n"); 00408 return CUBIT_FAILURE; 00409 } 00410 00411 RefVolume* ref_volume = ref_edge_list.get()->ref_volume(); 00412 if (NULL == ref_volume) 00413 { 00414 PRINT_WARNING("Simplifying free curves is not supported.\n"); 00415 return CUBIT_FAILURE; 00416 } 00417 00418 DLIList<RefEdge*> seed_edges; 00419 DLIList<RefVertex*> preview_vertices; 00420 DLIList<RefVertex*> preview_removed; 00421 00422 if(preview) 00423 ref_volume->ref_vertices(preview_vertices); 00424 00425 int j,k; 00426 00427 int new_edge_count = 0; 00428 int combined_edge_count = 0; 00429 ProgressTool *prog_ptr = 0; 00430 if(ref_edge_list.size() > 100 ) 00431 { 00432 char title[200]; 00433 if(preview) 00434 sprintf(title, "Previewing Volume %d",ref_volume->id()); 00435 else 00436 sprintf(title, "Simplifying Curves in Volume %d",ref_volume->id()); 00437 00438 prog_ptr = AppUtil::instance()->progress_tool(); 00439 assert(prog_ptr != NULL); 00440 prog_ptr->start(0,100, title); 00441 } 00442 int start_edge_count = ref_edge_list.size(); 00443 while(ref_edge_list.size()) 00444 { 00445 DLIList<RefEdge*> composite_edges; 00446 seed_edges.append_unique(ref_edge_list.pop()); 00447 00448 for ( j = ref_edge_list.size(); j--; ) 00449 ref_edge_list.get_and_step()->marked( CUBIT_FALSE ); 00450 00451 while(seed_edges.size()) 00452 { 00453 RefEdge *seed_ref_edge = seed_edges.pop(); 00454 seed_ref_edge->marked(CUBIT_TRUE); 00455 00456 composite_edges.append(seed_ref_edge); 00457 00458 // Get the vertices 00459 DLIList<RefVertex*> ref_vertex_list; 00460 seed_ref_edge->ref_vertices( ref_vertex_list ); 00461 RefVertex *ref_vertex_ptr; 00462 RefEdge *ref_edge_ptr; 00463 for( k = ref_vertex_list.size(); k--; ) 00464 { 00465 ref_vertex_ptr = ref_vertex_list.get_and_step(); 00466 00467 // Don't go propagate across surface splits if the user asks for it 00468 GeometryFeatureTool* gft = GeometryFeatureTool::instance(); 00469 if( respect_imprints && 00470 gft->feature_type(ref_vertex_ptr) == GeometryFeatureEngine::FEATURE_IMPRINT) 00471 continue; 00472 00473 // Don't cross a curve if we want it respected 00474 if(respect_vertex_list.is_in_list(ref_vertex_ptr)) 00475 continue; 00476 00477 DLIList<RefEdge*> attached_ref_edges; 00478 ref_vertex_ptr->ref_edges( attached_ref_edges ); 00479 00480 attached_ref_edges.remove(seed_ref_edge); 00481 ref_edge_ptr = attached_ref_edges.size()!=0?attached_ref_edges.get():0; 00482 00483 // keep the face if we want it respected 00484 if(attached_ref_edges.size() == 1 && 00485 respect_edge_list.is_in_list(attached_ref_edges.get())) 00486 continue; 00487 00488 // Don't consider ref_faces that are already in the list 00489 if( attached_ref_edges.size() == 1 && 00490 !ref_edge_ptr->marked()) 00491 { 00492 DLIList<RefVolume*> ref_volumes; 00493 ref_edge_ptr->ref_volumes( ref_volumes ); 00494 00495 if(composite_curves(seed_ref_edge,ref_edge_ptr,angle_in)) 00496 { 00497 ref_edge_ptr->marked( CUBIT_TRUE ); 00498 seed_edges.append(ref_edge_ptr); 00499 composite_edges.append(ref_edge_ptr); 00500 } 00501 } 00502 } 00503 } 00504 composite_edges.uniquify_unordered(); 00505 ref_edge_list -= composite_edges; 00506 00507 if(!preview && 00508 composite_edges.size()>1) 00509 { 00510 DLIList<RefVertex*> result_vertices; 00511 DLIList<RefEdge*> result_edges; 00512 CompositeTool::instance()->composite( 00513 composite_edges, 00514 result_edges, 00515 &result_vertices); 00516 00517 combined_edge_count +=composite_edges.size(); 00518 for(int m = result_edges.size();m--;) 00519 result_edges.get_and_step()->marked(CUBIT_TRUE); 00520 00521 new_edge_count+=result_edges.size(); 00522 } 00523 else if(preview) 00524 { 00525 int edge_count = composite_edges.size(); 00526 for(int i =0;i<edge_count;i++) 00527 { 00528 RefEdge* cur_comp_edge = composite_edges[i]; 00529 DLIList<RefVertex*> refvertices; 00530 for(int j =0;j<edge_count;j++) 00531 { 00532 if(i==j) continue; 00533 composite_edges[j]->ref_vertices(refvertices); 00534 } 00535 00536 refvertices.uniquify_unordered(); 00537 00538 DLIList<RefVertex*> temp_refvertices; 00539 cur_comp_edge->ref_vertices(temp_refvertices); 00540 refvertices.intersect_unordered(temp_refvertices); 00541 preview_removed+=refvertices; 00542 } 00543 } 00544 00545 if(prog_ptr) 00546 { 00547 double frac = 1.0-(double)ref_edge_list.size()/(double)start_edge_count; 00548 prog_ptr->percent(frac); 00549 } 00550 } 00551 00552 if(prog_ptr) 00553 { 00554 prog_ptr->end(); 00555 prog_ptr = 0; 00556 } 00557 00558 if(preview) 00559 { 00560 preview_vertices -=preview_removed; 00561 for(int c = preview_vertices.size();c--;) 00562 GfxDebug::draw_ref_vertex(preview_vertices.get_and_step(),7); 00563 } 00564 else if(combined_edge_count>new_edge_count) 00565 { 00566 PRINT_INFO("Simplified %d curves into %d curves\n", 00567 combined_edge_count, 00568 new_edge_count); 00569 } 00570 00571 // make sure to set all of the surface markers to false 00572 DLIList<RefEdge*> marked_edge_list; 00573 ref_volume->ref_edges(marked_edge_list); 00574 for(int i =0;i<marked_edge_list.size();i++) 00575 marked_edge_list[i]->marked(CUBIT_FALSE); 00576 00577 return CUBIT_SUCCESS; 00578 } 00579 00580 CubitBoolean SimplifyTool::composite_surfaces( 00581 RefFace* seed_ref_face, 00582 RefFace* ref_face_ptr, 00583 double angle_in) 00584 { 00585 double angle; 00586 CubitVector pos, norm1, norm2; 00587 00588 // Only add the ref_face if it meets the feature angle criteria 00589 double weight = 0.0; 00590 weighted_average_normal(seed_ref_face,norm1,weight); 00591 weighted_average_normal(ref_face_ptr,norm2,weight); 00592 00593 angle = norm1.interior_angle( norm2 ); 00594 00595 if( angle < angle_in) 00596 return CUBIT_TRUE; 00597 00598 return CUBIT_FALSE; 00599 } 00600 00601 CubitBoolean SimplifyTool::composite_curves( 00602 RefEdge* seed_ref_edge, 00603 RefEdge* ref_edge_ptr, 00604 double angle_in) 00605 { 00606 double angle; 00607 CubitVector pos, norm1, norm2; 00608 00609 // Only add the ref_face if it meets the feature angle criteria 00610 RefVertex* shared_vert = seed_ref_edge->common_ref_vertex( ref_edge_ptr ); 00611 00612 CubitVector seed_tangent; 00613 seed_ref_edge->tangent( shared_vert->coordinates(), seed_tangent ); 00614 // make this vector point away from the vertex along the edge 00615 if( shared_vert == seed_ref_edge->end_vertex() ) 00616 seed_tangent *= -1; 00617 00618 CubitVector edge2_tangent; 00619 ref_edge_ptr->tangent( shared_vert->coordinates(), edge2_tangent ); 00620 // make this vector point into the vertex along the edge 00621 if( shared_vert == ref_edge_ptr->start_vertex() ) 00622 edge2_tangent *= -1; 00623 00624 angle = seed_tangent.interior_angle( edge2_tangent ); 00625 00626 if( angle < angle_in) 00627 return CUBIT_TRUE; 00628 00629 return CUBIT_FALSE; 00630 } 00631 00632 void SimplifyTool::process_rounds(RefVolume* ref_volume, 00633 double min_radius, 00634 double max_radius) 00635 { 00636 DLIList<RefEdge*> edges; 00637 ref_volume->ref_edges(edges); 00638 00639 DLIList<RefFace*> rounds; 00640 00641 // a edge must have curvature within the tolerance 00642 for(int j = edges.size();j--;) 00643 { 00644 RefEdge* edge = edges.get_and_step(); 00645 CubitVector loc,tan,curv; 00646 edge->closest_point(edge->curve_center(),loc,&tan,&curv); 00647 00648 double curv_mag = curv.length(); 00649 00650 if(curv_mag > GEOMETRY_RESABS && 00651 1.0/curv_mag >= min_radius && 00652 1.0/curv_mag <= max_radius) 00653 { 00654 DLIList<RefFace*> new_rounds; 00655 edge->ref_faces(new_rounds); 00656 rounds+=new_rounds; 00657 } 00658 00659 } 00660 00661 rounds.uniquify_unordered(); 00662 for(int i = rounds.size();i--;) 00663 { 00664 // cull any flat surfaces 00665 RefFace* curr_face = rounds.get_and_step(); 00666 00667 double curve_0,curve_1; 00668 curr_face->get_principal_curvatures(curr_face->center_point(),curve_0,curve_1); 00669 curve_0 = fabs(curve_0); 00670 curve_1 = fabs(curve_1); 00671 00672 if((curve_0 > GEOMETRY_RESABS && 00673 1.0/curve_0 >= min_radius && 00674 1.0/curve_0 <= max_radius) || 00675 (curve_1 > GEOMETRY_RESABS && 00676 1.0/curve_1 >= min_radius && 00677 1.0/curve_1 <= max_radius)) 00678 { 00679 GfxDebug::highlight_ref_face(curr_face); 00680 } 00681 } 00682 } 00683 00684 CubitStatus 00685 SimplifyTool::weighted_average_normal(RefFace* ref_face, 00686 CubitVector &normal, 00687 double &weight ) 00688 { 00689 GMem g_mem; 00690 unsigned short norm_tol = 30; 00691 double dist_tol = -1.0; 00692 00693 ref_face->get_geometry_query_engine()-> 00694 get_graphics(ref_face->get_surface_ptr(), &g_mem, norm_tol, dist_tol ); 00695 00696 if(g_mem.fListCount < 1) 00697 { 00698 // Decrease tolerance and try again (we can get this for small features) 00699 norm_tol /= 2; 00700 ref_face->get_geometry_query_engine()-> 00701 get_graphics(ref_face->get_surface_ptr(), &g_mem, norm_tol, dist_tol ); 00702 } 00703 00704 if(g_mem.fListCount < 1) 00705 { 00706 // Lets give up 00707 PRINT_ERROR( "Unable to find average normal of a surface\n" ); 00708 return CUBIT_FAILURE; 00709 } 00710 00711 // Initialize 00712 weight = 0.0; 00713 normal.set( 0.0, 0.0, 0.0 ); 00714 00715 // Loop through the triangles 00716 double tri_weight, A, B, C; 00717 GPoint p[3]; 00718 GPoint* plist = g_mem.point_list(); 00719 int* facet_list = g_mem.facet_list(); 00720 int c = 0; 00721 for( ;c<g_mem.fListCount; ) 00722 { 00723 p[0] = plist[facet_list[++c]]; 00724 p[2] = plist[facet_list[++c]]; 00725 p[1] = plist[facet_list[++c]]; 00726 c++; 00727 00728 // Get centroid 00729 CubitVector p1( p[0].x, p[0].y, p[0].z ); 00730 CubitVector p2( p[2].x, p[2].y, p[2].z ); 00731 CubitVector p3( p[1].x, p[1].y, p[1].z ); 00732 00733 CubitVector center = (p1 + p2 + p3)/3.0; 00734 00735 CubitVector norm(ref_face->normal_at(center)); 00736 00737 // Get triangle area 00738 A = p1.y() * p2.z() + p1.z() * p3.y() + p2.y() * p3.z() - 00739 p2.z() * p3.y() - p1.y() * p3.z() - p1.z() * p2.y(); 00740 00741 B = p1.z() * p2.x() + p1.x() * p3.z() + p2.z() * p3.x() - 00742 p2.x() * p3.z() - p1.z() * p3.x() - p1.x() * p2.z(); 00743 00744 C = p1.x() * p2.y() + p1.y() * p3.x() + p2.x() * p3.y() - 00745 p2.y() * p3.x() - p1.x() * p3.y() - p1.y() * p2.x(); 00746 00747 //Note: triangle area = 0.5*(sqrt(A*A+B*B+C*C)); 00748 00749 tri_weight = 0.5*(A*A+B*B+C*C); 00750 00751 normal += tri_weight * norm; 00752 00753 weight += tri_weight; 00754 00755 } 00756 00757 normal.normalize(); 00758 00759 return CUBIT_SUCCESS; 00760 } 00761 00762 00763 00764 CubitBoolean SimplifyTool::composite_surfaces_test_at_curves( 00765 RefFace* seed_ref_face, 00766 RefFace* ref_face_ptr, 00767 double angle_in) 00768 { 00769 double angle; 00770 00771 if(!maximum_angle_deviation(seed_ref_face, ref_face_ptr, angle_in, angle)) 00772 return CUBIT_FALSE; 00773 00774 if( angle < angle_in) 00775 return CUBIT_TRUE; 00776 00777 return CUBIT_FALSE; 00778 } 00779 00780 00781 CubitBoolean SimplifyTool::maximum_angle_deviation( 00782 RefFace* seed_ref_face, 00783 RefFace* ref_face_ptr, 00784 double angle_in, 00785 double &angle_out) 00786 { 00787 double max_angle = -360; 00788 RefEdge* ref_edge = NULL; 00789 00790 double tol = angle_in / 2.0; 00791 00792 00793 DLIList<RefEdge*> common_edges; 00794 int num_edges = seed_ref_face->common_ref_edges(ref_face_ptr, common_edges); 00795 if(num_edges != common_edges.size()){ 00796 PRINT_ERROR("Unexpected results. List size incorrect.\n"); 00797 return CUBIT_FALSE; 00798 } 00799 00800 int i, j; 00801 for(i=0; i<num_edges; i++){ 00802 00803 GMem g_mem; 00804 ref_edge = common_edges.get_and_step(); 00805 00806 ref_edge->get_geometry_query_engine()-> 00807 get_graphics(ref_edge->get_curve_ptr(), &g_mem, tol); 00808 00809 if(g_mem.pointListCount < 2) 00810 { 00811 // Decrease tolerance and try again (we can get this for small features) 00812 tol /= 2.; 00813 00814 ref_edge->get_geometry_query_engine()-> 00815 get_graphics(ref_edge->get_curve_ptr(), &g_mem, tol); 00816 } 00817 00818 if(g_mem.pointListCount < 2) 00819 { 00820 // Lets give up 00821 PRINT_ERROR( "Unable to find average normal of a curve\n" ); 00822 return CUBIT_FAILURE; 00823 } 00824 00825 GPoint* plist = g_mem.point_list(); 00826 00827 for( j=0; j<g_mem.pointListCount; j++ ) 00828 { 00829 CubitVector p1(plist[j].x, plist[j].y, plist[j].z); 00830 00831 00832 CubitVector norm1(ref_face_ptr->normal_at(p1)); 00833 CubitVector norm2(seed_ref_face->normal_at(p1)); 00834 00835 double angle = norm1.interior_angle( norm2 ); 00836 if(angle > max_angle) 00837 max_angle=angle; 00838 } 00839 } 00840 if(max_angle < -.000001){ 00841 return CUBIT_FAILURE; 00842 } 00843 angle_out = max_angle; 00844 00845 return CUBIT_SUCCESS; 00846 } 00847 00848