cgma
Loop.cpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Copyright Notice
00003 //
00004 // Copyright (c) 1996 
00005 // by Malcolm J. Panthaki, DBA, and the University of New Mexico.
00006 //-------------------------------------------------------------------------
00007 //
00008 //-------------------------------------------------------------------------
00009 // Filename      : Loop.C
00010 //
00011 // Purpose       : This file contains the implementation of the class
00012 //                  Loop. 
00013 //
00014 // Special Notes :
00015 //
00016 // Creator       : Xuechen Liu
00017 //
00018 // Creation Date : 08/02/96
00019 //
00020 // Owner         : Malcolm J. Panthaki
00021 //-------------------------------------------------------------------------
00022 
00023 // ********** BEGIN STANDARD INCLUDES      **********
00024 // ********** END STANDARD INCLUDES        **********
00025 
00026 // ********** BEGIN MOTIF INCLUDES         **********
00027 // ********** END MOTIF INCLUDES           **********
00028 
00029 // ********** BEGIN OPEN INVENTOR INCLUDES **********
00030 // ********** END OPEN INVENTOR INCLUDES   **********
00031 
00032 // ********** BEGIN CUBIT INCLUDES         **********
00033 
00034 #include "Loop.hpp"
00035 
00036 #include "CoEdge.hpp"
00037 #include "SenseEntity.hpp"
00038 #include "RefEdge.hpp"
00039 #include "RefFace.hpp"
00040 #include "RefVertex.hpp"
00041 #include "CubitUtil.hpp"
00042 
00043 #include "GeometryQueryEngine.hpp"
00044 
00045 #include "DLIList.hpp"
00046 #include "CastTo.hpp"
00047 
00048 #include "Curve.hpp"
00049 #include "LoopSM.hpp"
00050 
00051 // ********** END CUBIT INCLUDES           **********
00052 
00053 // ********** BEGIN STATIC DECLARATIONS    **********
00054 // ********** END STATIC DECLARATIONS      **********
00055 
00056 // ********** BEGIN PUBLIC FUNCTIONS       **********
00057 
00058 //-------------------------------------------------------------------------
00059 // Purpose       : Default constructor.
00060 //
00061 // Special Notes :
00062 //
00063 // Creator       : Xuechen Liu
00064 //
00065 // Creation Date : 08/06/96
00066 //-------------------------------------------------------------------------
00067 Loop::Loop()
00068 {
00069 }
00070 
00071 //-------------------------------------------------------------------------
00072 // Purpose       : A constructor woth a pointer to an other solid
00073 //                 model entity.
00074 //
00075 // Special Notes :
00076 //
00077 // Creator       : Xuechen Liu
00078 //
00079 // Creation Date : 08/06/96
00080 //-------------------------------------------------------------------------
00081 Loop::Loop(LoopSM* OSMEPtr)
00082 {
00083    set_topology_bridge(OSMEPtr) ;
00084 }
00085 
00086 LoopType Loop::loop_type() const
00087 {
00088     LoopSM* loop_sm = get_loop_sm_ptr();
00089     if (loop_sm)
00090     {
00091         return loop_sm->loop_type();
00092     }
00093     assert(0);
00094     return LOOP_TYPE_UNKNOWN;
00095 }
00096 
00097 //-------------------------------------------------------------------------
00098 // Purpose       : Gets the angle metric for this Loop.
00099 //                 
00100 // Special Notes : The actual computation is done by the underlying geometric
00101 //                 modeling engine as this is a geometric computation.
00102 //
00103 // Creator       : Malcolm J. Panthaki
00104 //
00105 // Creation Date : 1/10/97
00106 //-------------------------------------------------------------------------
00107 CubitStatus Loop::get_angle_metric(double& angle_metric)
00108 {
00109     // If the OSME knows its angle metric (some modelers cache
00110     // some data along these lines), return that value
00111   LoopSM* loop_sm = get_loop_sm_ptr();
00112   if (loop_sm && loop_sm->get_angle_metric(angle_metric))
00113     return CUBIT_SUCCESS;
00114   
00115     // First, get the list of coedges
00116   DLIList<CoEdge*> coedges;
00117   ordered_co_edges(coedges); 
00118   
00119     // Now build a polygon approximation of the curves in the loop.
00120     // The polygon is a straight-line approximation to and is
00121     // topologically equivalent to the loop. At any given point,
00122     // the polygon may be far from the actual loop, however.
00123     //  - samitch
00124   
00125     // If there are no coedges, this is an empty loop
00126   if (coedges.size() == 0)
00127   {
00128     angle_metric = 0;
00129     return CUBIT_FAILURE;
00130   }
00131 
00132   //catch hardpoint case
00133   if( coedges.size() == 1 && coedges[0]->ref_edge()->geometry_type() == POINT_CURVE_TYPE )
00134   {
00135     angle_metric = 2.0;
00136     return CUBIT_SUCCESS;  
00137   }
00138   
00139     // Loop through each coedge
00140   int i, j;
00141   DLIList<CubitVector*> polygon_points;
00142   DLIList<CubitVector*> interior_points;
00143   CoEdge* cur_coedge = NULL;
00144   coedges.reset();
00145   for (i = coedges.size(); i--; )
00146   {
00147       // Get the first point on this curve
00148     cur_coedge = coedges.get_and_step();
00149     RefEdge* cur_refedge = cur_coedge->get_ref_edge_ptr();
00150     polygon_points.append(new CubitVector
00151                           (cur_coedge->get_sense() == CUBIT_FORWARD ?
00152                            cur_refedge->start_vertex()->coordinates() :
00153                            cur_refedge->end_vertex()->coordinates()));
00154     
00155       // Get the interior points for approximation
00156     CubitSense return_sense = cur_coedge->get_sense();
00157     interior_points.clean_out();
00158     cur_refedge->get_interior_extrema(interior_points, return_sense);
00159       // Now put the points into the polygon.
00160       // We don't need to re-allocate any CubitVectors because we are just
00161       // copying pointers to dynamically allocated CubitVectors.
00162     if (cur_coedge->get_sense() == return_sense)
00163     {
00164       interior_points.reset();
00165       for (j = interior_points.size(); j--; )
00166         polygon_points.append(interior_points.get_and_step());
00167     }
00168     else
00169     {
00170       interior_points.last();
00171       for (j = interior_points.size(); j--; )
00172         polygon_points.append(interior_points.get_and_back());
00173     }
00174   }
00175   
00176     // Now that we have all of the points, compute and sum up
00177     // the internal angles on the polygon approximation.
00178   double angle, angle_sum = 0;
00179   RefFace* surface = cur_coedge->get_ref_face();
00180   CubitVector *point[3], t[2], normal;
00181   point[0] = polygon_points.get_and_step();
00182   point[1] = polygon_points.get_and_step();
00183   t[0] = *point[1] - *point[0];
00184   for (i = polygon_points.size(); i--; )
00185   {
00186       // Determine proper internal surface angle at point[1]
00187     point[2] = polygon_points.get_and_step();
00188     normal = surface->normal_at(*point[1]);
00189     t[1] = *point[1] - *point[2] ;
00190     angle = normal.vector_angle(t[1], t[0]);
00191     
00192       // Add up the total
00193     angle_sum += angle;
00194     
00195       // Iterate
00196     point[1] = point[2];
00197     t[0] = -t[1];
00198   }
00199   angle_metric = angle_sum / CUBIT_PI - polygon_points.size();
00200   
00201     // Clean up dynamically allocated vectors
00202   for (i = polygon_points.size(); i>0; i--) 
00203     delete polygon_points.get_and_step();
00204   
00205   return CUBIT_SUCCESS;
00206 }
00207 
00208 //-------------------------------------------------------------------------
00209 // Purpose       : gets the ref edges in order with respect to this Loop.
00210 //                 
00211 // Special Notes : appends the edges to the list, with respect to coedges.
00212 //
00213 // Creator       : David White
00214 //
00215 // Creation Date : 03/25/97
00216 //-------------------------------------------------------------------------
00217 CubitStatus Loop::ordered_ref_edges(DLIList<RefEdge*>& ordered_edge_list )
00218 {
00219   CubitStatus status = CUBIT_SUCCESS;
00220 
00221   DLIList<SenseEntity*> sense_entity_list;
00222 
00223   status = this->get_sense_entity_list(sense_entity_list);
00224   if ( status == CUBIT_FAILURE )
00225   {
00226     PRINT_ERROR("In Loop::ordered_ref_edges\n");
00227     PRINT_ERROR("       Problem getting the CoEdges of this Loop.\n");
00228     return CUBIT_FAILURE;
00229   }
00230   
00231     //Get the ref_edges associated with each co_edge.
00232   for ( int ii = sense_entity_list.size(); ii > 0; ii-- )
00233   {
00234     SenseEntity* se_ptr = sense_entity_list.get_and_step();
00235     BasicTopologyEntity* bte_ptr = se_ptr->get_basic_topology_entity_ptr();
00236     ordered_edge_list.append( dynamic_cast<RefEdge*>(bte_ptr) );
00237   }
00238 
00239   return CUBIT_SUCCESS;
00240 }
00241 //-------------------------------------------------------------------------
00242 // Purpose       : gets the ref edges in order with respect to this Loop.
00243 //                 
00244 // Special Notes : appends the edges to the list, with respect to coedges.
00245 //
00246 // Creator       : David White
00247 //
00248 // Creation Date : 03/25/97
00249 //-------------------------------------------------------------------------
00250 CubitStatus Loop::ordered_co_edges(DLIList<CoEdge*>& ordered_coedge_list )
00251 {
00252   CubitStatus status = CUBIT_SUCCESS;
00253   
00254   DLIList<SenseEntity*> sense_entity_list;
00255   
00256   status = this->get_sense_entity_list(sense_entity_list);
00257   if ( status == CUBIT_FAILURE )
00258   {
00259     PRINT_ERROR("In Loop::ordered_co_edges\n"
00260                 "       Problem getting the CoEdges of this Loop.\n");
00261     return CUBIT_FAILURE;
00262   }
00263   
00264     // Cast the SenseEntity list to a CoEdge list
00265   DLIList<CoEdge*> co_edge_list(sense_entity_list.size());
00266   CAST_LIST( sense_entity_list, co_edge_list , CoEdge);
00267   
00268   ordered_coedge_list += co_edge_list;
00269   return CUBIT_SUCCESS;
00270 }
00271 
00272 
00273 
00274 RefFace* Loop::get_ref_face_ptr()
00275 {
00276     return CAST_TO( get_basic_topology_entity_ptr(), RefFace );
00277 }
00278 
00279 //-------------------------------------------------------------------------
00280 // Purpose       : Get LoopSM
00281 //
00282 // Special Notes : 
00283 //
00284 // Creator       : Jason Kraftcheck
00285 //
00286 // Creation Date : 07/23/03
00287 //-------------------------------------------------------------------------
00288 LoopSM* Loop::get_loop_sm_ptr() const
00289 {
00290   return dynamic_cast<LoopSM*>(bridge_manager()->topology_bridge());
00291 }
00292 
00293 //-------------------------------------------------------------------------
00294 // Purpose       : Check if loops are spatially equal.
00295 //
00296 // Special Notes : 
00297 //
00298 // Creator       : Jason Kraftcheck
00299 //
00300 // Creation Date : 04/01/04
00301 //-------------------------------------------------------------------------
00302 CubitBoolean Loop::about_spatially_equal( DLIList<CoEdge*>& other_coedges,
00303                                           CubitSense relative_sense,
00304                                           double tolerance_factor,
00305                                           CubitBoolean notify_refEntity )
00306 {
00307   DLIList<CoEdge*> this_coedges(other_coedges.size());
00308   
00309     // Loops must have same number of coedges to match.
00310   this->ordered_co_edges( this_coedges );
00311   if (this_coedges.size() != other_coedges.size())
00312     return CUBIT_FALSE;
00313   
00314     // Want to compare coedges in order, so make sure we have
00315     // them in the correct order.
00316   if (relative_sense == CUBIT_REVERSED)
00317     this_coedges.reverse();
00318   
00319     // Try to match all coedges.  Begin with the first coedge
00320     // in this loop.  For each coedge in the other loop that 
00321     // it matches, check if all the other coedges match in the
00322     // correct order.
00323   int other_loop_index = 0;
00324   this_coedges.reset();
00325   other_coedges.reset();
00326   CoEdge* this_coedge = this_coedges.get_and_step();
00327   for (int i = other_coedges.size(); i--; )
00328   {
00329       // Loop until we find a matching CoEdge
00330     CoEdge* other_coedge = other_coedges.get_and_step();
00331     if (!this_coedge->about_spatially_equal( other_coedge,
00332                                              relative_sense,
00333                                              tolerance_factor,
00334                                              notify_refEntity ))
00335       continue;
00336     
00337       // Found a matching coedge.  Now try to match all the
00338       // others in the correct order.
00339     bool match = true;
00340     other_loop_index = other_coedges.get_index();
00341     for (int j = other_coedges.size() - 1; j-- && match; )
00342     {
00343       this_coedge = this_coedges.get_and_step();
00344       other_coedge = other_coedges.get_and_step();
00345       match = this_coedge->about_spatially_equal( other_coedge,
00346                                                   relative_sense,
00347                                                   tolerance_factor,
00348                                                   notify_refEntity );
00349     }
00350     
00351       // Matched all coedges, in order.  Done.
00352     if (match)
00353       return CUBIT_TRUE;
00354     
00355      // Try again, as perhaps the first coedge of this loop
00356      // also matches some other one in the second loop and
00357      // if we start with that one, the remaining coedges will
00358      // also match.
00359     this_coedges.reset();
00360     this_coedge = this_coedges.get_and_step();
00361     other_coedges.reset();
00362     other_coedges.step( other_loop_index );
00363   }
00364   
00365     // If here, loops didn't match.
00366   return CUBIT_FALSE;
00367 }
00368 
00369 
00370 
00371 // ********** END PUBLIC FUNCTIONS         **********
00372 
00373 // ********** BEGIN PROTECTED FUNCTIONS    **********
00374 // ********** END PROTECTED FUNCTIONS      **********
00375 
00376 // ********** BEGIN PRIVATE FUNCTIONS      **********
00377 // ********** END PRIVATE FUNCTIONS        **********
00378 
00379 // ********** BEGIN HELPER CLASSES         **********
00380 // ********** END HELPER CLASSES           **********
00381 
00382 // ********** BEGIN EXTERN FUNCTIONS       **********
00383 // ********** END EXTERN FUNCTIONS         **********
00384 
00385 // ********** BEGIN STATIC FUNCTIONS       **********
00386 // ********** END STATIC FUNCTIONS         **********
00387 
00388 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines