cgma
|
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