cgma
|
00001 #include "RemoveBlends.hpp" 00002 #include "CubitUtil.hpp" 00003 //#include "Model.hpp" 00004 #include "GeometryQueryTool.hpp" 00005 00006 //#include "SVDrawTool.hpp" 00007 #include "GMem.hpp" 00008 #include "GfxDebug.hpp" 00009 00010 #include "VirtualQueryEngine.hpp" 00011 #include "PartitionEngine.hpp" 00012 00013 00014 #include "CompositeTool.hpp" 00015 #include "PartitionTool.hpp" 00016 #include "PartSurfFacetTool.hpp" 00017 00018 #include "RefFace.hpp" 00019 #include "RefEdge.hpp" 00020 #include "RefVertex.hpp" 00021 00022 #include "CompositeLump.hpp" 00023 #include "PartitionCurve.hpp" 00024 #include "SubSurface.hpp" 00025 #include "SplitSurfaceTool.hpp" 00026 00027 namespace RemoveBlends 00028 { 00029 CubitStatus remove_blend(RefFace* ref_face, 00030 DLIList<CubitVector>& locations, 00031 DLIList<RefFace*>& composite_faces) 00032 { 00033 CubitStatus result = CUBIT_SUCCESS; 00034 int i; 00035 00036 locations.reset(); 00037 RefFace* the_face = ref_face; 00038 if (the_face && VirtualQueryEngine::is_virtual(the_face)) 00039 { 00040 PRINT_WARNING ("Can not collapse a virtual surface.\n"); 00041 return CUBIT_FAILURE; 00042 } 00043 00044 // Find the curve to split along. 00045 SplitSurfaceTool sst; 00046 DLIList<DLIList<CubitVector*>*> vec_lists; 00047 DLIList<Curve*> curve_list; 00048 00049 DLIList<CubitVector*> *vec_list = new DLIList<CubitVector*>; 00050 00051 vec_list->append( new CubitVector( locations.get_and_step() ) ); 00052 vec_list->append( new CubitVector( locations.get_and_step() ) ); 00053 00054 vec_lists.append( vec_list ); 00055 00056 sst.calculate_split_curves(the_face, vec_lists, curve_list); 00057 00058 //int num_segs = 2; 00059 //double fraction =.5; 00060 //double distance = -1.; 00061 //RefEdge* from_curve_ptr = 0; 00062 //DLIList<RefVertex*> corner_vertex_list; 00063 //DLIList<RefVertex*> through_vertex_list; 00064 //RefEdge *curve_dir_ptr = 0; 00065 //CubitBoolean preview_flg = false; 00066 //CubitBoolean create_ref_edges_flg = false; 00067 //CubitBoolean just_curves_flg = false; 00068 //DLIList<DLIList<Curve*>*> curve_lists_list; 00069 00070 // sst.calculate_split_curves(ref_face_list, num_segs, fraction, distance, 00071 // from_curve_ptr, corner_vertex_list, through_vertex_list, 00072 // curve_dir_ptr, 00073 // preview_flg, create_ref_edges_flg, just_curves_flg, 00074 // curve_lists_list ); 00075 00076 //partition the_face 00077 DLIList<RefEdge*> new_edges; 00078 DLIList<RefFace*> result_faces; 00079 result = PartitionTool::instance()-> 00080 partition_face_by_curves( the_face, curve_list, result_faces, CUBIT_TRUE, &new_edges ); 00081 // clean up curves 00082 while (curve_list.size()) 00083 { 00084 Curve* curve = curve_list.pop(); 00085 if (curve) 00086 { 00087 GeometryQueryEngine* gqe = curve->get_geometry_query_engine(); 00088 gqe->delete_solid_model_entities(curve); 00089 } 00090 } 00091 if( result == CUBIT_FAILURE ) 00092 { 00093 PRINT_ERROR("Failed to partition surface %d into 2 distinct pieces\n", the_face->id()); 00094 return result; 00095 } 00096 00097 // We MUST clean up an ambiguous partition. 00098 if (new_edges.size() > 1) 00099 { 00100 PRINT_ERROR("Attempted to partition surface %d more than 2 parts,\n" 00101 "Ambiguous surface collapse. Collapse failed.\n", 00102 the_face->id()); 00103 DLIList<RefFace*> orig_faces; 00104 PartitionTool::instance()->unpartitionAll(result_faces, orig_faces); 00105 00106 DLIList<RefEdge*> edges, edge_results; 00107 edges.clean_out(); 00108 // We started out with one face, we should the same face back 00109 assert( the_face == orig_faces.next(0) ); 00110 the_face->ref_edges( edges ); 00111 00112 // Do a quick sort to find the PartitionCurves 00113 for ( i = edges.size(); i--; ) 00114 { 00115 if ( !dynamic_cast<PartitionCurve*>(edges.step_and_get()->get_curve_ptr())) 00116 edges.change_to(0); 00117 } 00118 edges.remove_all_with_value(0); 00119 00120 // Now remove the partitioned edges 00121 // TODO: what if we are collapsing with an adjacent partitioned surface. 00122 // What happens to the partitioned edges? 00123 if ( edges.size() ) 00124 PartitionTool::instance()->unpartitionAll(edges, edge_results); 00125 00126 return CUBIT_FAILURE; 00127 } 00128 00129 if (result_faces.size() < 2) 00130 { 00131 PRINT_WARNING("Surface %d has been improperly partitioned,\n" 00132 "Ambiguous surface collapse. Collapse failed.\n", 00133 the_face->id()); 00134 return result; 00135 } 00136 00137 //if(new_face == the_face) 00138 // new_face = GeometryQueryTool::instance()->get_last_ref_face (); 00139 00140 new_edges.clean_out(); 00141 //Re-composite surfaces 00142 DLIList<RefFace*> composite_result_faces; 00143 DLIList<RefFace*> remaining_faces; 00144 DLIList<RefFace*> surf_list; 00145 DLIList<int> id_list; 00146 RefFace* face_to_composite = NULL; 00147 RefFace* temp_face = NULL; 00148 RefFace* second_face = NULL; 00149 RefFace* composite_face = NULL; 00150 int num_common_edge1, num_common_edge2; 00151 int size; 00152 int composite_count = 0; 00153 while (0 < (composite_faces.size() + remaining_faces.size())) 00154 { 00155 if(composite_count == 2) 00156 break; 00157 00158 size = composite_faces.size(); 00159 if( size > 0) 00160 { 00161 composite_faces.reset(); 00162 face_to_composite = composite_faces.get(); 00163 composite_faces.remove(face_to_composite); 00164 } 00165 00166 else 00167 { 00168 remaining_faces.reset(); 00169 face_to_composite = remaining_faces.get(); 00170 remaining_faces.remove(face_to_composite); 00171 } 00172 00173 if (NULL != second_face) 00174 { 00175 num_common_edge1 = second_face->common_ref_edges(face_to_composite, 00176 new_edges); 00177 new_edges.clean_out(); 00178 if (num_common_edge1 == 0) 00179 continue; 00180 00181 if (NULL == composite_face) 00182 num_common_edge2 = 0; 00183 else 00184 num_common_edge2 = composite_face-> 00185 common_ref_edges(face_to_composite, new_edges); 00186 new_edges.clean_out(); 00187 } 00188 00189 else 00190 { 00191 if (NULL == result_faces[0]) 00192 num_common_edge1 = 0; 00193 else 00194 { 00195 num_common_edge1 = result_faces[0]->common_ref_edges(face_to_composite, 00196 new_edges); 00197 new_edges.clean_out(); 00198 } 00199 00200 if(NULL == result_faces[1]) 00201 num_common_edge2 = 0; 00202 else 00203 { 00204 num_common_edge2 = result_faces[1]->common_ref_edges(face_to_composite, 00205 new_edges); 00206 new_edges.clean_out(); 00207 } 00208 } 00209 00210 if (num_common_edge1 == 0 && num_common_edge2 == 0) 00211 continue; 00212 00213 else if(num_common_edge1 == 0 || num_common_edge2 == 0 || size == 0) 00214 { 00215 surf_list.clean_out(); 00216 if (NULL != second_face) 00217 surf_list.append(second_face); 00218 00219 else if (num_common_edge2 == 0 || size == 0) 00220 { 00221 temp_face = result_faces[0]; 00222 second_face = result_faces[1]; 00223 surf_list.append(temp_face); 00224 } 00225 00226 else 00227 { 00228 temp_face = result_faces[1]; 00229 second_face = result_faces[0]; 00230 surf_list.append(temp_face); 00231 } 00232 surf_list.append(face_to_composite); 00233 00234 // composite the surfaces together 00235 CompositeTool::instance()->composite(surf_list, composite_result_faces); 00236 composite_count++; 00237 00238 if( composite_result_faces.size() > 0 ) 00239 { 00240 DLIList<RefEdge*> surface_edges, new_edge_list; 00241 remaining_faces.clean_out(); 00242 for( i = 0; i < composite_result_faces.size(); i++) 00243 { 00244 // now composite together the edges of the new surface 00245 surface_edges.clean_out(); 00246 composite_result_faces.get_and_step()->ref_edges( surface_edges ); 00247 new_edge_list.clean_out(); 00248 CompositeTool::instance()->composite( surface_edges, new_edge_list); 00249 00250 // keep the lists coherent 00251 composite_face = composite_result_faces.pop(); 00252 composite_faces.remove(composite_face); 00253 id_list.append( composite_face->id() ); 00254 } 00255 } 00256 00257 else 00258 PRINT_ERROR("Composite surface %d and surface %d failed.\n", 00259 temp_face->id(), face_to_composite->id()); 00260 } 00261 00262 else 00263 remaining_faces.append(face_to_composite); 00264 } 00265 if (id_list.size() > 0) 00266 CubitUtil::list_entity_ids("Created composite surfaces ", id_list ); 00267 return result; 00268 } 00269 00270 CubitStatus remove_blends(DLIList<RefFace*>& ref_face_list, 00271 int num_segs, double fraction, double distance, 00272 RefEdge* from_curve_ptr, 00273 DLIList<RefVertex*>& corner_vertex_list, 00274 DLIList<RefVertex*>& through_vertex_list, 00275 RefEdge *curve_dir_ptr, 00276 CubitBoolean preview_flg, 00277 DLIList<CubitVector*>& locations, 00278 DLIList<RefFace*>& composite_faces) 00279 { 00280 CubitStatus result = CUBIT_SUCCESS; 00281 int i; 00282 00283 if (ref_face_list.size() <= 1) 00284 { 00285 PRINT_WARNING ("Must specify a chain of surfaces.\n"); 00286 return CUBIT_FAILURE; 00287 } 00288 locations.reset(); 00289 00290 // check and make sure that we aren't splitting virtual surfaces (yet) 00291 for (i = 0; i < ref_face_list.size(); i++) 00292 { 00293 RefFace* the_face = ref_face_list.get_and_step(); 00294 if (the_face && VirtualQueryEngine::is_virtual(the_face)) 00295 { 00296 PRINT_WARNING ("Can not collapse a virtual surface.\n"); 00297 return CUBIT_FAILURE; 00298 } 00299 } 00300 00301 // Find the curve to split along. 00302 SplitSurfaceTool sst; 00303 DLIList<DLIList<CubitVector*>*> vec_lists; 00304 DLIList<Curve*>* curve_list; 00305 DLIList<DLIList<Curve*>*> curve_lists_list; 00306 00307 DLIList<CubitVector*> *vec_list = new DLIList<CubitVector*>; 00308 00309 vec_list->append( new CubitVector( *locations.get_and_step() ) ); 00310 vec_list->append( new CubitVector( *locations.get_and_step() ) ); 00311 00312 vec_lists.append( vec_list ); 00313 00314 CubitBoolean create_ref_edges_flg = false; 00315 CubitBoolean just_curves_flg = false; 00316 00317 sst.calculate_split_curves(ref_face_list, num_segs, fraction, distance, 00318 from_curve_ptr, corner_vertex_list, through_vertex_list, 00319 curve_dir_ptr, 00320 preview_flg, create_ref_edges_flg, just_curves_flg, 00321 curve_lists_list ); 00322 00323 //partition the_face 00324 DLIList<RefEdge*> new_edges; 00325 DLIList<RefFace*> result_faces; 00326 RefFace* the_face; 00327 DLIList<int> id_list; 00328 00329 for (i = 0; i < ref_face_list.size(); i++) 00330 { 00331 // get the face and the curves that split this face 00332 the_face = ref_face_list.get_and_step(); 00333 curve_list = curve_lists_list.get_and_step(); 00334 00335 result = PartitionTool::instance()-> 00336 partition_face_by_curves( the_face, *curve_list, result_faces, CUBIT_FALSE, &new_edges ); 00337 if( result == CUBIT_FAILURE ) 00338 return result; 00339 00340 if (new_edges.size() > 1) 00341 { 00342 PRINT_WARNING("Surface %d has been partitioned into more than 2 parts,\n" 00343 "Ambiguous surface collapse.\n", 00344 the_face->id()); 00345 return result; 00346 } 00347 00348 new_edges.clean_out(); 00349 //Re-composite surfaces 00350 DLIList<RefFace*> composite_result_faces; 00351 DLIList<RefFace*> remaining_faces; 00352 DLIList<RefFace*> surf_list; 00353 RefFace* face_to_composite = NULL; 00354 RefFace* temp_face = NULL; 00355 RefFace* second_face = NULL; 00356 RefFace* composite_face = NULL; 00357 int num_common_edge1, num_common_edge2; 00358 int size; 00359 int composite_count = 0; 00360 while (0 < (composite_faces.size() + remaining_faces.size())) 00361 { 00362 if(composite_count == 2) 00363 break; 00364 00365 size = composite_faces.size(); 00366 if( size > 0) 00367 { 00368 composite_faces.reset(); 00369 face_to_composite = composite_faces.get(); 00370 composite_faces.remove(face_to_composite); 00371 } 00372 else 00373 { 00374 remaining_faces.reset(); 00375 face_to_composite = remaining_faces.get(); 00376 remaining_faces.remove(face_to_composite); 00377 } 00378 00379 if (NULL != second_face) 00380 { 00381 num_common_edge1 = second_face->common_ref_edges(face_to_composite, 00382 new_edges); 00383 new_edges.clean_out(); 00384 if (num_common_edge1 == 0) 00385 continue; 00386 00387 if (NULL == composite_face) 00388 num_common_edge2 = 0; 00389 else 00390 num_common_edge2 = composite_face-> 00391 common_ref_edges(face_to_composite, new_edges); 00392 new_edges.clean_out(); 00393 } 00394 else 00395 { 00396 if (NULL == result_faces[0]) 00397 num_common_edge1 = 0; 00398 else 00399 { 00400 num_common_edge1 = result_faces[0]->common_ref_edges(face_to_composite, 00401 new_edges); 00402 new_edges.clean_out(); 00403 } 00404 00405 if(NULL == result_faces[1]) 00406 num_common_edge2 = 0; 00407 else 00408 { 00409 num_common_edge2 = result_faces[1]->common_ref_edges(face_to_composite, 00410 new_edges); 00411 new_edges.clean_out(); 00412 } 00413 } 00414 00415 if (num_common_edge1 == 0 && num_common_edge2 == 0) 00416 continue; 00417 00418 else if(num_common_edge1 == 0 || num_common_edge2 == 0 || size == 0) 00419 { 00420 surf_list.clean_out(); 00421 if (NULL != second_face) 00422 surf_list.append(second_face); 00423 00424 else if (num_common_edge2 == 0 || size == 0) 00425 { 00426 temp_face = result_faces[0]; 00427 second_face = result_faces[1]; 00428 surf_list.append(temp_face); 00429 } 00430 00431 else 00432 { 00433 temp_face = result_faces[1]; 00434 second_face = result_faces[0]; 00435 surf_list.append(temp_face); 00436 } 00437 surf_list.append(face_to_composite); 00438 00439 // composite the surfaces together 00440 CompositeTool::instance()->composite(surf_list, composite_result_faces); 00441 composite_count++; 00442 00443 if( composite_result_faces.size() > 0 ) 00444 { 00445 DLIList<RefEdge*> surface_edges, new_edge_list; 00446 remaining_faces.clean_out(); 00447 for( i = 0; i < composite_result_faces.size(); i++) 00448 { 00449 // now composite together the edges of the new surface 00450 surface_edges.clean_out(); 00451 composite_result_faces.get_and_step()->ref_edges( surface_edges ); 00452 new_edge_list.clean_out(); 00453 CompositeTool::instance()->composite( surface_edges, new_edge_list); 00454 00455 // keep the lists coherent 00456 composite_face = composite_result_faces.pop(); 00457 composite_faces.remove(composite_face); 00458 id_list.append( composite_face->id() ); 00459 } 00460 } 00461 PRINT_ERROR("Composite surface %d and surface %d failed.\n", 00462 temp_face->id(), face_to_composite->id()); 00463 } 00464 } 00465 } 00466 if (id_list.size() > 0) 00467 CubitUtil::list_entity_ids("Created composite surfaces ", id_list ); 00468 return result; 00469 } 00470 } // namespace RemoveBlends