cgma
SimplifyTool.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines